@@ -10,29 +10,56 @@ import Foundation
10import UIKit
10import UIKit
11import Alamofire
11import Alamofire
14+ case internalServerError = 500
15+ case exceededContent = 470
16+ case longContent = 471
17+ case incorrectContent = 472
18+ case impossibleContent = 473
19+ case invalidTocken = 498
20+ case alreadyRegistered = 409
21+ case invalidCode = 403
23+ case tooMuchToAdd = 406
13class Model{
29class Model{
15 static let invalidTocken = 498
31 static let invalidTocken = 498
17− static var hashTagTree: CompletionTree?
33+ static var hashTagTree: CompletionTree?
19 private static var isValidTocken: ((Int)->())? = { responce in
35 private static var isValidTocken: ((Int)->())? = { responce in
20 print(responce)
36 print(responce)
21 if responce == invalidTocken {
37 if responce == invalidTocken {
22 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
39 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
23 (UIApplication.shared.delegate as! AppDelegate).relaunch()
40 (UIApplication.shared.delegate as! AppDelegate).relaunch()
43+ print("Logout Is Successful")
27 private static let baseUrl = "https://valera-denis.herokuapp.com"
48 private static let baseUrl = "https://valera-denis.herokuapp.com"
28 static let decoder = JSONDecoder()
49 static let decoder = JSONDecoder()
51+ static let authMeURL = URL(string: "\(baseUrl)/authentication/me")!
52+ static let deactivateURL = URL(string: "\(baseUrl)/deactivateAll")!
53+ static let registerMeURL = URL(string: "\(baseUrl)/authentication/register")!
54+ static let authVerifyURL = URL(string: "\(baseUrl)/authentication/verify")!
30 static let authenticationURL = URL(string:"\(baseUrl)/authentication/login")!
55 static let authenticationURL = URL(string:"\(baseUrl)/authentication/login")!
56+ static let logOutURL = URL(string:"\(baseUrl)/authentication/logout")!
31 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
57 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
32 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
58 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
33 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
59 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
34 static let usersURL = URL(string:"\(baseUrl)/users")!
60 static let usersURL = URL(string:"\(baseUrl)/users")!
35 static let usersAllURL = URL(string:"\(baseUrl)/users/all")!
61 static let usersAllURL = URL(string:"\(baseUrl)/users/all")!
62+ static let usersUpdateURL = URL(string:"\(baseUrl)/users/update")!
36 static let channelsGetURL = URL(string: "\(baseUrl)/channels/get")!
63 static let channelsGetURL = URL(string: "\(baseUrl)/channels/get")!
37 static let channelsUpdateURL = URL(string: "\(baseUrl)/channels/update")!
64 static let channelsUpdateURL = URL(string: "\(baseUrl)/channels/update")!
38 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
65 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
@@ -49,6 +76,7 @@ class Model{
49 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
76 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
50 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
77 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
51 static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
78 static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
79+ static let facultySearchURL = URL(string: "\(baseUrl)/faculty/search")!
54 struct QueryPosts<T: Codable>: Codable {
82 struct QueryPosts<T: Codable>: Codable {
@@ -120,6 +148,8 @@ class Model{
120 var lastName: String
148 var lastName: String
121 var firstName: String
149 var firstName: String
122 var id: Int
150 var id: Int
151+ var faculty: Faculty
124 func fullName() -> String {
154 func fullName() -> String {
125 return "\(firstName) \(lastName)"
155 return "\(firstName) \(lastName)"
@@ -183,24 +213,108 @@ class Model{
186− static func authenticate(with id: Int, completion: @escaping ((Bool)->())) {
216+ struct AuthStatus: Codable {
217+ var userStatus: String
188− let json: [String:Any] = ["authenticationId" : id]
219+ init(){
189− let jsonData = try? JSONSerialization.data(withJSONObject: json)
220+ userStatus = "invalid"
224+ static func logout(completion: @escaping (()->())){
225+ var request = URLRequest(url: logOutURL)
226+ request.httpMethod = "POST"
228+ AF.request(request).response { (responce) in
229+ isValidTocken?(responce.response?.statusCode ?? 498)
231+ if let code = responce.response?.statusCode, code == 498 {
240+ "email": "vchernyshev@hse.ru",
241+ "middleName": "Algebrovich",
242+ "lastName": "Leonidov",
243+ "faculty": "cs.hse.ru/dse",
247+ struct NewRegistration: Codable{
249+ var firstName: String?
250+ var middleName: String?
251+ var lastName: String?
252+ var faculty: String?
255+ static func register(object: NewRegistration, completion: @escaping (()->())) {
256+ var request = URLRequest(url: registerMeURL)
257+ request.httpBody = try? JSONEncoder().encode(object)
191− var request = URLRequest(url: authenticationURL)
192 request.httpMethod = "POST"
259 request.httpMethod = "POST"
260+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
194− // insert json data to the request
262+ AF.request(request).response { (responce) in
195− request.httpBody = jsonData
263+
264+ guard let code = responce.response?.statusCode else { return }
265+ isValidTocken?(code)
267+ if let code = responce.response?.statusCode, code == 498 {
273+ let fields = responce.response?.allHeaderFields as? [String :String]
274+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: responce.response!.url!)
275+ HTTPCookieStorage.shared.setCookie(cookies[0])
282+ // true only if everything is good
283+ static func verify(with code: Int, completion: @escaping ((Bool)->())){
284+ var request = URLRequest(url: authVerifyURL)
285+ request.httpMethod = "POST"
286+ request.httpBody = "\(code)".data(using: .utf8)
196 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
287 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
198 AF.request(request).response { (responce) in
289 AF.request(request).response { (responce) in
200− guard let realResponse = responce.response, realResponse.statusCode == 200 else
291+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
201− {
292+ isValidTocken?(statusCode)
202− print("Not a 200 response")
293+
294+ if let code = responce.response?.statusCode, code == 498 {
298+ if statusCode == 204 {
299+ // at this point cookies are set
203 completion(false)
302 completion(false)
308+ static func authenticateMe(completion: @escaping ((Bool)->())){
309+ var request = URLRequest(url: authMeURL)
310+ request.httpMethod = "POST"
312+ AF.request(request).response { (responce) in
314+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
315+ isValidTocken?(statusCode)
317+ if let code = responce.response?.statusCode, code == 498 {
@@ -210,14 +324,45 @@ class Model{
213− let fields = realResponse.allHeaderFields as? [String :String]
327+ DataStorage.standard.setIsLoggedIn(value: true, with: personId)
332+ // register, ok or invalid
333+ static func authenticate(with email: String, completion: @escaping ((AuthStatus)->())) {
335+ let json: [String:Any] = ["authenticationEmail" : email]
336+ let jsonData = try? JSONSerialization.data(withJSONObject: json)
338+ var request = URLRequest(url: authenticationURL)
339+ request.httpMethod = "POST"
341+ // insert json data to the request
342+ request.httpBody = jsonData
343+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
345+ AF.request(request).response { (response) in
215− let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: realResponse.url!)
347+ guard let realResponse = response.response, realResponse.statusCode == 200 else
349+ print("Not a 200 response")
350+ completion(AuthStatus())
354+ guard let json = response.data else { return }
355+ guard let res = try? decoder.decode(AuthStatus.self, from: json) else { return }
357+ if realResponse.statusCode == 200 && res.userStatus == "registered"
359+ // at this point cookies are set
360+ let fields = realResponse.allHeaderFields as? [String :String]
361+ let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: realResponse.url!)
217− HTTPCookieStorage.shared.setCookie(cookies[0])
362+ HTTPCookieStorage.shared.setCookie(cookies[0])
219− DataStorage.standard.setIsLoggedIn(value: true, with: personId)
220− completion(true)
365+ completion(res)
@@ -267,6 +412,10 @@ class Model{
268 isValidTocken?(response.response?.statusCode ?? 498)
413 isValidTocken?(response.response?.statusCode ?? 498)
415+ if let code = response.response?.statusCode, code == 498 {
270 guard let json = response.data else { return }
419 guard let json = response.data else { return }
272 guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { print("no")
421 guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { print("no")
@@ -278,7 +427,7 @@ class Model{
281− static func createAndPublish(body: [Attachments], tags: [String]){
430+ static func createAndPublish(body: [Attachments], tags: [String], completion: @escaping ((ResultR)->())){
282 let jsonUpd = CreatedPost(body: body, tags: tags)
431 let jsonUpd = CreatedPost(body: body, tags: tags)
283 var request = URLRequest(url: postsPublishURL)
432 var request = URLRequest(url: postsPublishURL)
@@ -292,6 +441,18 @@ class Model{
292 (response) in
441 (response) in
294 isValidTocken?(response.response?.statusCode ?? 498)
443 isValidTocken?(response.response?.statusCode ?? 498)
445+ if let code = response.response?.statusCode, code == 498 {
449+ if let code = response.response?.statusCode,
450+ let result = ResultR(rawValue: code)
454+ completion(.internalServerError)
@@ -317,6 +478,10 @@ class Model{
318 isValidTocken?(response.response?.statusCode ?? 498)
479 isValidTocken?(response.response?.statusCode ?? 498)
481+ if let code = response.response?.statusCode, code == 498 {
320 guard let json = response.data else { return }
485 guard let json = response.data else { return }
322 guard let newPost = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
487 guard let newPost = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
@@ -329,7 +494,7 @@ class Model{
330 static func getUsers(for ids: [Int], completion: @escaping (([Int:Users])->())){
495 static func getUsers(for ids: [Int], completion: @escaping (([Int:Users])->())){
331 let json = "\(Set(ids))"
496 let json = "\(Set(ids))"
333 var request = URLRequest(url: usersURL)
498 var request = URLRequest(url: usersURL)
335 request.httpMethod = "POST"
500 request.httpMethod = "POST"
@@ -343,11 +508,16 @@ class Model{
344 isValidTocken?(response.response?.statusCode ?? 498)
509 isValidTocken?(response.response?.statusCode ?? 498)
511+ if let code = response.response?.statusCode, code == 498 {
346 guard let json = response.data else { return }
515 guard let json = response.data else { return }
348 guard let users = try? decoder.decode([Users].self, from: json) else { return }
517 guard let users = try? decoder.decode([Users].self, from: json) else { return }
350 var dict: [Int:Users] = [:]
519 var dict: [Int:Users] = [:]
351 users.forEach({ (user) in
521 users.forEach({ (user) in
352 dict[user.id] = user
522 dict[user.id] = user
@@ -374,6 +544,9 @@ class Model{
375 isValidTocken?(response.response?.statusCode ?? 498)
545 isValidTocken?(response.response?.statusCode ?? 498)
547+ if let code = response.response?.statusCode, code == 498 {
378 guard let json = response.data else { return }
551 guard let json = response.data else { return }
@@ -385,7 +558,7 @@ class Model{
388− static func createChannel(with channel: Channels) {
561+ static func createChannel(with channel: Channels, completion: @escaping ((ResultR)->())) {
390 var request = URLRequest(url: channelsCreateURL)
563 var request = URLRequest(url: channelsCreateURL)
391 request.httpMethod = "POST"
564 request.httpMethod = "POST"
@@ -396,6 +569,13 @@ class Model{
396 (response) in
569 (response) in
398 isValidTocken?(response.response?.statusCode ?? 498)
571 isValidTocken?(response.response?.statusCode ?? 498)
573+ if let code = response.response?.statusCode, let result = ResultR(rawValue: code) {
578+ completion(ResultR.internalServerError)
@@ -408,6 +588,9 @@ class Model{
408 AF.request(request).responseJSON { (response) in
588 AF.request(request).responseJSON { (response) in
410 isValidTocken?(response.response?.statusCode ?? 498)
590 isValidTocken?(response.response?.statusCode ?? 498)
591+ if let code = response.response?.statusCode, code == 498 {
412 guard let json = response.data else { return }
595 guard let json = response.data else { return }
@@ -426,6 +609,9 @@ class Model{
427 AF.request(request).response { (response) in
610 AF.request(request).response { (response) in
428 isValidTocken?(response.response?.statusCode ?? 498)
611 isValidTocken?(response.response?.statusCode ?? 498)
612+ if let code = response.response?.statusCode, code == 498 {
430 completion()
616 completion()
@@ -441,6 +627,9 @@ class Model{
441 (response) in
627 (response) in
443 isValidTocken?(response.response?.statusCode ?? 498)
629 isValidTocken?(response.response?.statusCode ?? 498)
630+ if let code = response.response?.statusCode, code == 498 {
@@ -463,6 +652,9 @@ class Model{
465 isValidTocken?(response.response?.statusCode ?? 498)
654 isValidTocken?(response.response?.statusCode ?? 498)
655+ if let code = response.response?.statusCode, code == 498 {
@@ -538,12 +730,13 @@ class Model{
538 (response) in
730 (response) in
540 isValidTocken?(response.response?.statusCode ?? 498)
732 isValidTocken?(response.response?.statusCode ?? 498)
733+ if let code = response.response?.statusCode, code == 498 {
542 guard let json = response.data else { return }
737 guard let json = response.data else { return }
544 guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
739 guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
546− // idUser = newQueery.users
547 completion((newQueery.users, newQueery.response))
740 completion((newQueery.users, newQueery.response))
@@ -553,6 +746,9 @@ class Model{
553 AF.request(URLRequest(url: hashTagTreeURL)).responseJSON {
746 AF.request(URLRequest(url: hashTagTreeURL)).responseJSON {
554 (response) in
747 (response) in
555 isValidTocken?(response.response?.statusCode ?? 498)
748 isValidTocken?(response.response?.statusCode ?? 498)
749+ if let code = response.response?.statusCode, code == 498 {
556 guard let json = response.data else { return }
752 guard let json = response.data else { return }
557 guard let tree = try? decoder.decode(CompletionTree.self, from: json) else { return }
753 guard let tree = try? decoder.decode(CompletionTree.self, from: json) else { return }
558 completion(tree)
754 completion(tree)
@@ -570,6 +766,10 @@ class Model{
570 AF.request(request).responseJSON { response in
766 AF.request(request).responseJSON { response in
571 isValidTocken?(response.response?.statusCode ?? 498)
767 isValidTocken?(response.response?.statusCode ?? 498)
769+ if let code = response.response?.statusCode, code == 498 {
573 guard let json = response.data else { return }
773 guard let json = response.data else { return }
574 let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
774 let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
@@ -622,7 +822,12 @@ class Model{
623 struct UserChat: Codable {
823 struct UserChat: Codable {
624 var user: Int
824 var user: Int
625− var lastMessage: LastMessage
825+ var lastMessage: LastMessage?
827+ init(user: Int, lastMessage: LastMessage? = nil) {
829+ self.lastMessage = lastMessage
628 struct Group: Codable {
833 struct Group: Codable {
@@ -736,6 +941,9 @@ class Model{
736 AF.request(request).response { (response) in
941 AF.request(request).response { (response) in
738 isValidTocken?(response.response?.statusCode ?? 498)
943 isValidTocken?(response.response?.statusCode ?? 498)
944+ if let code = response.response?.statusCode, code == 498 {
740 guard let json = response.data else { return }
948 guard let json = response.data else { return }
741 let stringInt = String.init(data: json, encoding: String.Encoding.utf8)
949 let stringInt = String.init(data: json, encoding: String.Encoding.utf8)
@@ -745,7 +953,7 @@ class Model{
748− static func getMessagesFor(typeOfChat: Model.Dialog, chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 10, direction: String = "backward", completion: @escaping (([LastMessage])->()))
956+ static func getMessagesFor(typeOfChat: Model.Dialog, chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 25, direction: String = "backward", completion: @escaping (([LastMessage])->()))
750 let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
958 let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
751 var request: URLRequest?
959 var request: URLRequest?
@@ -764,6 +972,9 @@ class Model{
764 AF.request(request!).response { (response) in
972 AF.request(request!).response { (response) in
766 isValidTocken?(response.response?.statusCode ?? 498)
974 isValidTocken?(response.response?.statusCode ?? 498)
975+ if let code = response.response?.statusCode, code == 498 {
768 guard let json = response.data else { return }
979 guard let json = response.data else { return }
769 guard let messages = try? decoder.decode([LastMessage].self, from: json) else { return }
980 guard let messages = try? decoder.decode([LastMessage].self, from: json) else { return }
@@ -781,6 +992,10 @@ class Model{
782 AF.request(request).response { (response) in
993 AF.request(request).response { (response) in
783 isValidTocken?(response.response?.statusCode ?? 498)
994 isValidTocken?(response.response?.statusCode ?? 498)
996+ if let code = response.response?.statusCode, code == 498 {
786 completion()
1001 completion()
@@ -795,6 +1010,10 @@ class Model{
796 AF.request(request).response { (response) in
1011 AF.request(request).response { (response) in
797 isValidTocken?(response.response?.statusCode ?? 498)
1012 isValidTocken?(response.response?.statusCode ?? 498)
1014+ if let code = response.response?.statusCode, code == 498 {
800 // completion()
1019 // completion()
@@ -837,7 +1056,7 @@ class Model{
840− static func sendMessage(message: SendMessage, completion: @escaping (()->())){
1059+ static func sendMessage(message: SendMessage, completion: @escaping ((ResultR)->())){
842 var request = URLRequest(url: messagesSendURL)
1061 var request = URLRequest(url: messagesSendURL)
843 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
1062 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
@@ -847,6 +1066,84 @@ class Model{
847 AF.request(request).response { (response) in
1066 AF.request(request).response { (response) in
848 isValidTocken?(response.response?.statusCode ?? 498)
1067 isValidTocken?(response.response?.statusCode ?? 498)
1069+ if let code = response.response?.statusCode, code == 498 {
1073+ if let result = ResultR(rawValue: response.response!.statusCode){
1076+ completion(.internalServerError)
1081+ struct Faculty: Codable
1086+ var campusName: String
1087+ var campusCode: String
1090+ var address: String
1094+ static func searchFaculty(string: String, completion: @escaping (([Model.Faculty])->()))
1096+ var request = URLRequest(url: facultySearchURL)
1097+ request.httpMethod = "POST"
1098+ request.httpBody = string.data(using: .utf8)
1099+ request.setValue("text/plain;charset=utf-8", forHTTPHeaderField: "Content-Type")
1101+ AF.request(request).response { (response) in
1102+ isValidTocken?(response.response?.statusCode ?? 498)
1104+ if let code = response.response?.statusCode, code == 498 {
1108+ guard let json = response.data else { return }
1109+ guard let faculties = try? decoder.decode([Faculty].self, from: json) else { return }
1111+ completion(faculties)
1115+ static func userUpdate(with newUser: NewRegistration, completion: @escaping ((Bool)->())) {
1116+ var request = URLRequest(url: usersUpdateURL)
1117+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
1118+ request.httpMethod = "POST"
1119+ request.httpBody = try? JSONEncoder().encode(newUser)
1121+ AF.request(request).response { (response) in
1122+ isValidTocken?(response.response?.statusCode ?? 498)
1124+ if let code = response.response?.statusCode, code == 498 {
1128+ if let code = response.response?.statusCode, code != 204{
1136+ static func deactivateAll(completion: @escaping (()->())){
1137+ var request = URLRequest(url: deactivateURL)
1138+ request.httpMethod = "DELETE"
1140+ AF.request(request).response { (responce) in
1141+ isValidTocken?(responce.response?.statusCode ?? 498)
1143+ if let code = responce.response?.statusCode, code == 498 {
850 completion()
1147 completion()