@@ -10,29 +10,56 @@ import Foundation
1010import UIKit
1111import Alamofire
1212
13+enum ResultR: Int {
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
22+ case badAccess = 400
23+ case tooMuchToAdd = 406
24+ case notFound = 404
25+ case success1 = 204
26+ case success = 200
27+}
28+
1329class Model{
1430
1531 static let invalidTocken = 498
1632
17− static var hashTagTree: CompletionTree?
33+ static var hashTagTree: CompletionTree?
1834
1935 private static var isValidTocken: ((Int)->())? = { responce in
2036 print(responce)
2137 if responce == invalidTocken {
38+
2239 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
2340 (UIApplication.shared.delegate as! AppDelegate).relaunch()
41+
42+ Model.logout {
43+ print("Logout Is Successful")
44+ }
2445 }
2546 }
2647
2748 private static let baseUrl = "https://valera-denis.herokuapp.com"
2849 static let decoder = JSONDecoder()
29−
50+
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")!
3055 static let authenticationURL = URL(string:"\(baseUrl)/authentication/login")!
56+ static let logOutURL = URL(string:"\(baseUrl)/authentication/logout")!
3157 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
3258 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
3359 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
3460 static let usersURL = URL(string:"\(baseUrl)/users")!
3561 static let usersAllURL = URL(string:"\(baseUrl)/users/all")!
62+ static let usersUpdateURL = URL(string:"\(baseUrl)/users/update")!
3663 static let channelsGetURL = URL(string: "\(baseUrl)/channels/get")!
3764 static let channelsUpdateURL = URL(string: "\(baseUrl)/channels/update")!
3865 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
@@ -40,7 +67,7 @@ class Model{
4067 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
4168 static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
4269 static let complexURL = URL(string: "\(baseUrl)/complex")!
43− static let hashTagTreeURL = URL(string: "\(baseUrl)/tagCompletions")!
70+ static let hashTagTreeURL = URL(string: "\(baseUrl)/tags/completions")!
4471 static let createGroupChatURL = URL(string: "\(baseUrl)/chats/createGroupChat")!
4572 static let chatsGetAllURL = URL(string: "\(baseUrl)/chats/getAll")!
4673 static let getGroupChatURL = URL(string: "\(baseUrl)/chats/getGroupChat")!
@@ -48,12 +75,13 @@ class Model{
4875 static let updateGroupChatURL = URL(string: "\(baseUrl)/chats/updateGroupChat")!
4976 static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
5077 static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
51− static let messagesUserChatURL = URL(string: "\(baseUrl)/messages/userChat")!
78+ static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
79+ static let facultySearchURL = URL(string: "\(baseUrl)/faculty/search")!
5280
5381
54− struct QueryPosts: Codable {
82+ struct QueryPosts<T: Codable>: Codable {
5583 var users: [Int: Users]
56− var response: [Posts]
84+ var response: [T]
5785 }
5886
5987 struct Posts: Codable {
@@ -120,6 +148,8 @@ class Model{
120148 var lastName: String
121149 var firstName: String
122150 var id: Int
151+ var faculty: Faculty
152+ var email: String
123153
124154 func fullName() -> String {
125155 return "\(firstName) \(lastName)"
@@ -183,24 +213,108 @@ class Model{
183213 }
184214 }
185215
186− static func authenticate(with id: Int, completion: @escaping ((Bool)->())) {
216+ struct AuthStatus: Codable {
217+ var userStatus: String
187218
188− let json: [String:Any] = ["authenticationId" : id]
189− let jsonData = try? JSONSerialization.data(withJSONObject: json)
219+ init(){
220+ userStatus = "invalid"
221+ }
222+ }
223+
224+ static func logout(completion: @escaping (()->())){
225+ var request = URLRequest(url: logOutURL)
226+ request.httpMethod = "POST"
227+
228+ AF.request(request).response { (responce) in
229+ isValidTocken?(responce.response?.statusCode ?? 498)
230+
231+ if let code = responce.response?.statusCode, code == 498 {
232+ return
233+ }
234+
235+ completion()
236+ }
237+ }
238+
239+ /*
240+ "email": "vchernyshev@hse.ru",
241+ "middleName": "Algebrovich",
242+ "lastName": "Leonidov",
243+ "faculty": "cs.hse.ru/dse",
244+ "firstName": "Seva"
245+ */
246+
247+ struct NewRegistration: Codable{
248+ var email: String
249+ var firstName: String?
250+ var middleName: String?
251+ var lastName: String?
252+ var faculty: String?
253+ }
254+
255+ static func register(object: NewRegistration, completion: @escaping (()->())) {
256+ var request = URLRequest(url: registerMeURL)
257+ request.httpBody = try? JSONEncoder().encode(object)
190258
191− var request = URLRequest(url: authenticationURL)
192259 request.httpMethod = "POST"
260+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
193261
194− // insert json data to the request
195− request.httpBody = jsonData
262+ AF.request(request).response { (responce) in
263+
264+ guard let code = responce.response?.statusCode else { return }
265+ isValidTocken?(code)
266+
267+ if let code = responce.response?.statusCode, code == 498 {
268+ return
269+ }
270+
271+ if code == 204 {
272+
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])
276+
277+ completion()
278+ }
279+ }
280+ }
281+
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)
196287 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
197288
198289 AF.request(request).response { (responce) in
199290
200− guard let realResponse = responce.response, realResponse.statusCode == 200 else
201− {
202− print("Not a 200 response")
291+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
292+ isValidTocken?(statusCode)
293+
294+ if let code = responce.response?.statusCode, code == 498 {
295+ return
296+ }
297+
298+ if statusCode == 204 {
299+ // at this point cookies are set
300+ completion(true)
301+ } else {
203302 completion(false)
303+ }
304+ }
305+ }
306+
307+ // yes or no
308+ static func authenticateMe(completion: @escaping ((Bool)->())){
309+ var request = URLRequest(url: authMeURL)
310+ request.httpMethod = "POST"
311+
312+ AF.request(request).response { (responce) in
313+
314+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
315+ isValidTocken?(statusCode)
316+
317+ if let code = responce.response?.statusCode, code == 498 {
204318 return
205319 }
206320
@@ -210,14 +324,45 @@ class Model{
210324 return
211325 }
212326
213− let fields = realResponse.allHeaderFields as? [String :String]
327+ DataStorage.standard.setIsLoggedIn(value: true, with: personId)
328+ completion(true)
329+ }
330+ }
331+
332+ // register, ok or invalid
333+ static func authenticate(with email: String, completion: @escaping ((AuthStatus)->())) {
334+
335+ let json: [String:Any] = ["authenticationEmail" : email]
336+ let jsonData = try? JSONSerialization.data(withJSONObject: json)
337+
338+ var request = URLRequest(url: authenticationURL)
339+ request.httpMethod = "POST"
340+
341+ // insert json data to the request
342+ request.httpBody = jsonData
343+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
344+
345+ AF.request(request).response { (response) in
214346
215− let cookies = HTTPCookie.cookies(withResponseHeaderFields: fields!, for: realResponse.url!)
347+ guard let realResponse = response.response, realResponse.statusCode == 200 else
348+ {
349+ print("Not a 200 response")
350+ completion(AuthStatus())
351+ return
352+ }
353+
354+ guard let json = response.data else { return }
355+ guard let res = try? decoder.decode(AuthStatus.self, from: json) else { return }
216356
217− HTTPCookieStorage.shared.setCookie(cookies[0])
357+ if realResponse.statusCode == 200 && res.userStatus == "registered"
358+ {
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!)
362+ HTTPCookieStorage.shared.setCookie(cookies[0])
363+ }
218364
219− DataStorage.standard.setIsLoggedIn(value: true, with: personId)
220− completion(true)
365+ completion(res)
221366 }
222367 }
223368
@@ -267,9 +412,13 @@ class Model{
267412
268413 isValidTocken?(response.response?.statusCode ?? 498)
269414
415+ if let code = response.response?.statusCode, code == 498 {
416+ return
417+ }
418+
270419 guard let json = response.data else { return }
271420
272− guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { print("no")
421+ guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { print("no")
273422 return }
274423
275424 idUser = newQueery.users
@@ -278,7 +427,7 @@ class Model{
278427 }
279428
280429
281− static func createAndPublish(body: [Attachments], tags: [String]){
430+ static func createAndPublish(body: [Attachments], tags: [String], completion: @escaping ((ResultR)->())){
282431 let jsonUpd = CreatedPost(body: body, tags: tags)
283432 var request = URLRequest(url: postsPublishURL)
284433
@@ -292,6 +441,18 @@ class Model{
292441 (response) in
293442
294443 isValidTocken?(response.response?.statusCode ?? 498)
444+
445+ if let code = response.response?.statusCode, code == 498 {
446+ return
447+ }
448+
449+ if let code = response.response?.statusCode,
450+ let result = ResultR(rawValue: code)
451+ {
452+ completion(result)
453+ } else {
454+ completion(.internalServerError)
455+ }
295456 }
296457 }
297458
@@ -317,9 +478,13 @@ class Model{
317478
318479 isValidTocken?(response.response?.statusCode ?? 498)
319480
481+ if let code = response.response?.statusCode, code == 498 {
482+ return
483+ }
484+
320485 guard let json = response.data else { return }
321486
322− guard let newPost = try? decoder.decode(QueryPosts.self, from: json) else { return }
487+ guard let newPost = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
323488
324489 completion(newPost.response)
325490 }
@@ -329,7 +494,7 @@ class Model{
329494
330495 static func getUsers(for ids: [Int], completion: @escaping (([Int:Users])->())){
331496 let json = "\(Set(ids))"
332− print(json)
497+
333498 var request = URLRequest(url: usersURL)
334499
335500 request.httpMethod = "POST"
@@ -343,11 +508,16 @@ class Model{
343508
344509 isValidTocken?(response.response?.statusCode ?? 498)
345510
511+ if let code = response.response?.statusCode, code == 498 {
512+ return
513+ }
514+
346515 guard let json = response.data else { return }
347516
348517 guard let users = try? decoder.decode([Users].self, from: json) else { return }
349518
350519 var dict: [Int:Users] = [:]
520+
351521 users.forEach({ (user) in
352522 dict[user.id] = user
353523 })
@@ -374,10 +544,13 @@ class Model{
374544
375545 isValidTocken?(response.response?.statusCode ?? 498)
376546
547+ if let code = response.response?.statusCode, code == 498 {
548+ return
549+ }
377550
378551 guard let json = response.data else { return }
379552
380− guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
553+ guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
381554
382555 idUser = newQueery.users
383556 completion((newQueery.users, newQueery.response))
@@ -385,7 +558,7 @@ class Model{
385558 }
386559
387560
388− static func createChannel(with channel: Channels) {
561+ static func createChannel(with channel: Channels, completion: @escaping ((ResultR)->())) {
389562
390563 var request = URLRequest(url: channelsCreateURL)
391564 request.httpMethod = "POST"
@@ -396,6 +569,13 @@ class Model{
396569 (response) in
397570
398571 isValidTocken?(response.response?.statusCode ?? 498)
572+
573+ if let code = response.response?.statusCode, let result = ResultR(rawValue: code) {
574+ completion(result)
575+ return
576+ }
577+
578+ completion(ResultR.internalServerError)
399579 }
400580
401581 }
@@ -408,6 +588,9 @@ class Model{
408588 AF.request(request).responseJSON { (response) in
409589
410590 isValidTocken?(response.response?.statusCode ?? 498)
591+ if let code = response.response?.statusCode, code == 498 {
592+ return
593+ }
411594
412595 guard let json = response.data else { return }
413596
@@ -426,6 +609,9 @@ class Model{
426609
427610 AF.request(request).response { (response) in
428611 isValidTocken?(response.response?.statusCode ?? 498)
612+ if let code = response.response?.statusCode, code == 498 {
613+ return
614+ }
429615 }
430616 completion()
431617 }
@@ -441,6 +627,9 @@ class Model{
441627 (response) in
442628
443629 isValidTocken?(response.response?.statusCode ?? 498)
630+ if let code = response.response?.statusCode, code == 498 {
631+ return
632+ }
444633 }
445634 }
446635
@@ -463,6 +652,9 @@ class Model{
463652 }
464653
465654 isValidTocken?(response.response?.statusCode ?? 498)
655+ if let code = response.response?.statusCode, code == 498 {
656+ return
657+ }
466658 }
467659 }
468660
@@ -525,23 +717,26 @@ class Model{
525717 }
526718 }
527719 */
528− static func getAnonymousChannel(by anonymousChannel: Model.AnonymousChannel, completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
720+ static func getAnonymousChannel(by anonymousChannel: Model.Channels, exclusiveFrom: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
529721
722+ let req = GeneralRequest<Model.Channels>(limit: 10, exclusiveFrom: exclusiveFrom, request: anonymousChannel)
723+
530724 var request = URLRequest(url: channelsGetAnonURL)
531725 request.httpMethod = "POST"
532− request.httpBody = try? JSONEncoder().encode(anonymousChannel)
726+ request.httpBody = try? JSONEncoder().encode(req)
533727
534728 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
535729 AF.request(request).response {
536730 (response) in
537731
538732 isValidTocken?(response.response?.statusCode ?? 498)
733+ if let code = response.response?.statusCode, code == 498 {
734+ return
735+ }
539736
540737 guard let json = response.data else { return }
541738
542− guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
543−
544− // idUser = newQueery.users
739+ guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
545740 completion((newQueery.users, newQueery.response))
546741 }
547742 }
@@ -550,11 +745,406 @@ class Model{
550745
551746 AF.request(URLRequest(url: hashTagTreeURL)).responseJSON {
552747 (response) in
553−
748+ isValidTocken?(response.response?.statusCode ?? 498)
749+ if let code = response.response?.statusCode, code == 498 {
750+ return
751+ }
554752 guard let json = response.data else { return }
555753 guard let tree = try? decoder.decode(CompletionTree.self, from: json) else { return }
556754 completion(tree)
557755 }
558756 }
559757
758+ static func getChatAll(limit: Int = 10, exclusiveFrom: Int? = nil, request: [Int] = [], completion: @escaping ((([Dialog],[Int:Model.Users]))->()))
759+ {
760+ let req = GeneralRequest<[Int]>(limit: limit, exclusiveFrom: exclusiveFrom, request: request)
761+ var request = URLRequest(url: chatsGetAllURL)
762+ request.httpMethod = "POST"
763+ request.httpBody = try? JSONEncoder().encode(req)
764+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
765+
766+ AF.request(request).responseJSON { response in
767+ isValidTocken?(response.response?.statusCode ?? 498)
768+
769+ if let code = response.response?.statusCode, code == 498 {
770+ return
771+ }
772+
773+ guard let json = response.data else { return }
774+ let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
775+
776+ completion((dialogs.response,dialogs.users))
777+ }
778+ }
779+
780+ enum Dialog: Codable
781+ {
782+ case groupChat(GroupChat)
783+ case userChat(UserChat)
784+
785+ private enum DialogKeys: CodingKey{
786+ case groupChat
787+ case userChat
788+ }
789+
790+ init(from decoder: Decoder) throws {
791+ let container = try decoder.container(keyedBy: DialogKeys.self)
792+ if container.contains(.groupChat){
793+ self = .groupChat(try GroupChat(from: container.superDecoder(forKey: .groupChat)))
794+ } else if container.contains(.userChat){
795+ self = .userChat(try UserChat(from: container.superDecoder(forKey: .userChat)))
796+ } else {
797+ throw DecodingError.keyNotFound(DialogKeys.groupChat, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz"))
798+ }
799+ }
800+
801+ func encode(to encoder: Encoder) throws {
802+ var container = encoder.container(keyedBy: DialogKeys.self)
803+ switch self{
804+ case .groupChat(let chat):
805+ try chat.encode(to: container.superEncoder(forKey: .groupChat))
806+ case .userChat(let chat):
807+ try chat.encode(to: container.superEncoder(forKey: .userChat))
808+ }
809+ }
810+ }
811+
812+ struct GroupChat: Codable {
813+ var group: Group
814+ var lastMessage: LastMessage?
815+
816+
817+ init(group: Group, lastMessage: LastMessage? = nil) {
818+ self.group = group
819+ self.lastMessage = lastMessage
820+ }
821+ }
822+
823+ struct UserChat: Codable {
824+ var user: Int
825+ var lastMessage: LastMessage?
826+
827+ init(user: Int, lastMessage: LastMessage? = nil) {
828+ self.user = user
829+ self.lastMessage = lastMessage
830+ }
831+ }
832+
833+ struct Group: Codable {
834+ var users: [Int: UserPermission]
835+ var name: String
836+ var id: Int
837+
838+ init(users: [Int: UserPermission] = [:], name: String = "", id: Int) {
839+ self.id = id
840+ self.users = users
841+ self.name = name
842+ }
843+ }
844+
845+ struct UserPermission: Codable {
846+ var isAdmin: Bool
847+ }
848+
849+ struct LastMessage: Codable {
850+ var body: Attachments
851+ var destination: MessageDestination
852+ var time: String
853+ var author: Int
854+ var id: Int
855+
856+ enum MessageCodingKeys: CodingKey{
857+ case user
858+ case group
859+ case body
860+ case time
861+ case author
862+ case id
863+ }
864+
865+ init(from decoder: Decoder) throws
866+ {
867+ let container = try decoder.container(keyedBy: MessageCodingKeys.self)
868+ time = try container.decode(String.self, forKey: .time)
869+ body = try container.decode(Attachments.self, forKey: .body)
870+ author = try container.decode(Int.self, forKey: .author)
871+ id = try container.decode(Int.self, forKey: .id)
872+
873+ if container.contains(.user){
874+ destination = MessageDestination.userChatDestination(try Int(from: container.superDecoder(forKey: .user)))
875+ } else if container.contains(.group){
876+ destination = MessageDestination.groupChatDestination(try Int(from: container.superDecoder(forKey: .group)))
877+ } else {
878+ throw DecodingError.keyNotFound(MessageCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
879+ }
880+ }
881+
882+ func encode(to encoder: Encoder) throws {
883+ var container = encoder.container(keyedBy: MessageCodingKeys.self)
884+
885+ try container.encode(time, forKey: .time)
886+ try container.encode(id, forKey: .id)
887+ try container.encode(author, forKey: .author)
888+ try container.encode(body, forKey: .body)
889+
890+ switch destination {
891+ case .userChatDestination(let uId):
892+ try uId.encode(to: container.superEncoder(forKey: .user))
893+ case .groupChatDestination(let gId):
894+ try gId.encode(to: container.superEncoder(forKey: .group))
895+ }
896+ }
897+ }
898+
899+ enum MessageDestination: Codable
900+ {
901+ func encode(to encoder: Encoder) throws
902+ {
903+ var container = encoder.container(keyedBy: MessCodingKeys.self)
904+ switch self {
905+ case .userChatDestination(let uId):
906+ try uId.encode(to: container.superEncoder(forKey: .user))
907+ case .groupChatDestination(let gId):
908+ try gId.encode(to: container.superEncoder(forKey: .group))
909+ }
910+ }
911+
912+ init(from decoder: Decoder) throws
913+ {
914+ let container = try decoder.container(keyedBy: MessCodingKeys.self)
915+ if container.contains(.user){
916+ self = .userChatDestination(try Int(from: container.superDecoder(forKey: .user)))
917+ } else if container.contains(.group){
918+ self = .groupChatDestination(try Int(from: container.superDecoder(forKey: .group)))
919+ } else {
920+ throw DecodingError.keyNotFound(MessCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
921+ }
922+ }
923+
924+ enum MessCodingKeys: CodingKey{
925+ case user
926+ case group
927+ }
928+
929+ case userChatDestination(Int)
930+ case groupChatDestination(Int)
931+
932+ }
933+
934+ static func createGroupChat(from group: Group, completion: @escaping ((Int)->())) {
935+ let req = group
936+ var request = URLRequest(url: createGroupChatURL)
937+ request.httpMethod = "POST"
938+ request.httpBody = try? JSONEncoder().encode(req)
939+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
940+
941+ AF.request(request).response { (response) in
942+
943+ isValidTocken?(response.response?.statusCode ?? 498)
944+ if let code = response.response?.statusCode, code == 498 {
945+ return
946+ }
947+
948+ guard let json = response.data else { return }
949+ let stringInt = String.init(data: json, encoding: String.Encoding.utf8)
950+ let intId = Int.init(stringInt!)
951+
952+ completion(intId!)
953+ }
954+ }
955+
956+ static func getMessagesFor(typeOfChat: Model.Dialog, chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 25, direction: String = "backward", completion: @escaping (([LastMessage])->()))
957+ {
958+ let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
959+ var request: URLRequest?
960+
961+ switch typeOfChat {
962+ case .groupChat:
963+ request = URLRequest(url: messagesGetGroupChatURL)
964+ case .userChat:
965+ request = URLRequest(url: messagesGetUserChatURL)
966+ }
967+
968+ request!.httpMethod = "POST"
969+ request!.httpBody = try? JSONEncoder().encode(req)
970+ request!.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
971+
972+ AF.request(request!).response { (response) in
973+
974+ isValidTocken?(response.response?.statusCode ?? 498)
975+ if let code = response.response?.statusCode, code == 498 {
976+ return
977+ }
978+
979+ guard let json = response.data else { return }
980+ guard let messages = try? decoder.decode([LastMessage].self, from: json) else { return }
981+
982+ completion(messages)
983+ }
984+ }
985+
986+ static func leaveGroupChat(id: Int, completion: @escaping (()->()))
987+ {
988+ var request = URLRequest(url: leaveGroupChatURL)
989+ request.httpMethod = "POST"
990+ request.httpBody = "\(id)".data(using: .utf8)
991+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
992+
993+ AF.request(request).response { (response) in
994+ isValidTocken?(response.response?.statusCode ?? 498)
995+
996+ if let code = response.response?.statusCode, code == 498 {
997+ return
998+ }
999+ }
1000+
1001+ completion()
1002+ }
1003+
1004+ static func updateGroupChat(with group: Model.Group)
1005+ {
1006+ var request = URLRequest(url: updateGroupChatURL)
1007+ request.httpMethod = "POST"
1008+ request.httpBody = try? JSONEncoder().encode(group)
1009+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
1010+
1011+ AF.request(request).response { (response) in
1012+ isValidTocken?(response.response?.statusCode ?? 498)
1013+
1014+ if let code = response.response?.statusCode, code == 498 {
1015+ return
1016+ }
1017+ }
1018+
1019+ // completion()
1020+ }
1021+
1022+ struct SendMessage: Codable {
1023+ var body: Attachments
1024+ var destination: MessageDestination
1025+
1026+ init(from decoder: Decoder) throws
1027+ {
1028+ let container = try decoder.container(keyedBy: LastMessage.MessageCodingKeys.self)
1029+ body = try container.decode(Attachments.self, forKey: .body)
1030+
1031+ if container.contains(.user){
1032+ destination = MessageDestination.userChatDestination(try Int(from: container.superDecoder(forKey: .user)))
1033+ } else if container.contains(.group){
1034+ destination = MessageDestination.groupChatDestination(try Int(from: container.superDecoder(forKey: .group)))
1035+ } else {
1036+ throw DecodingError.keyNotFound(LastMessage.MessageCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr1"))
1037+ }
1038+ }
1039+
1040+ func encode(to encoder: Encoder) throws {
1041+ var container = encoder.container(keyedBy: LastMessage.MessageCodingKeys.self)
1042+ try container.encode(body, forKey: .body)
1043+
1044+ switch destination {
1045+ case .userChatDestination(let uId):
1046+ try uId.encode(to: container.superEncoder(forKey: .user))
1047+ case .groupChatDestination(let gId):
1048+ try gId.encode(to: container.superEncoder(forKey: .group))
1049+ }
1050+ }
1051+
1052+ init(body: Attachments, destination: MessageDestination)
1053+ {
1054+ self.body = body
1055+ self.destination = destination
1056+ }
1057+ }
1058+
1059+ static func sendMessage(message: SendMessage, completion: @escaping ((ResultR)->())){
1060+
1061+ var request = URLRequest(url: messagesSendURL)
1062+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
1063+ request.httpMethod = "POST"
1064+ request.httpBody = try? JSONEncoder().encode(message)
1065+
1066+ AF.request(request).response { (response) in
1067+ isValidTocken?(response.response?.statusCode ?? 498)
1068+
1069+ if let code = response.response?.statusCode, code == 498 {
1070+ return
1071+ }
1072+
1073+ if let result = ResultR(rawValue: response.response!.statusCode){
1074+ completion(result)
1075+ } else {
1076+ completion(.internalServerError)
1077+ }
1078+ }
1079+ }
1080+
1081+ struct Faculty: Codable
1082+ {
1083+
1084+ var path: String
1085+ var url: String
1086+ var campusName: String
1087+ var campusCode: String
1088+ var name: String
1089+ var tags: [String]
1090+ var address: String
1091+
1092+ }
1093+
1094+ static func searchFaculty(string: String, completion: @escaping (([Model.Faculty])->()))
1095+ {
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")
1100+
1101+ AF.request(request).response { (response) in
1102+ isValidTocken?(response.response?.statusCode ?? 498)
1103+
1104+ if let code = response.response?.statusCode, code == 498 {
1105+ return
1106+ }
1107+
1108+ guard let json = response.data else { return }
1109+ guard let faculties = try? decoder.decode([Faculty].self, from: json) else { return }
1110+
1111+ completion(faculties)
1112+ }
1113+ }
1114+
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)
1120+
1121+ AF.request(request).response { (response) in
1122+ isValidTocken?(response.response?.statusCode ?? 498)
1123+
1124+ if let code = response.response?.statusCode, code == 498 {
1125+ return
1126+ }
1127+
1128+ if let code = response.response?.statusCode, code != 204{
1129+ completion (false)
1130+ } else {
1131+ completion(true)
1132+ }
1133+ }
1134+ }
1135+
1136+ static func deactivateAll(completion: @escaping (()->())){
1137+ var request = URLRequest(url: deactivateURL)
1138+ request.httpMethod = "DELETE"
1139+
1140+ AF.request(request).response { (responce) in
1141+ isValidTocken?(responce.response?.statusCode ?? 498)
1142+
1143+ if let code = responce.response?.statusCode, code == 498 {
1144+ return
1145+ }
1146+
1147+ completion()
1148+ }
1149+ }
5601150}