@@ -10,27 +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
33+ static var hashTagTree: CompletionTree?
17 private static var isValidTocken: ((Int)->())? = { responce in
35 private static var isValidTocken: ((Int)->())? = { responce in
18 print(responce)
36 print(responce)
19 if responce == invalidTocken {
37 if responce == invalidTocken {
20 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
39 DataStorage.standard.setIsLoggedIn(value: false, with: 0)
21 (UIApplication.shared.delegate as! AppDelegate).relaunch()
40 (UIApplication.shared.delegate as! AppDelegate).relaunch()
43+ print("Logout Is Successful")
25 private static let baseUrl = "https://valera-denis.herokuapp.com"
48 private static let baseUrl = "https://valera-denis.herokuapp.com"
26 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")!
28 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")!
29 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
57 static let postsLastURL = URL(string:"\(baseUrl)/posts/last")!
30 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
58 static let postsForUserURL = URL(string:"\(baseUrl)/posts/forUser")!
31 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
59 static let postsPublishURL = URL(string:"\(baseUrl)/posts/publish")!
32 static let usersURL = URL(string:"\(baseUrl)/users")!
60 static let usersURL = URL(string:"\(baseUrl)/users")!
33 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")!
34 static let channelsGetURL = URL(string: "\(baseUrl)/channels/get")!
63 static let channelsGetURL = URL(string: "\(baseUrl)/channels/get")!
35 static let channelsUpdateURL = URL(string: "\(baseUrl)/channels/update")!
64 static let channelsUpdateURL = URL(string: "\(baseUrl)/channels/update")!
36 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
65 static let channelsListURL = URL(string: "\(baseUrl)/channels")!
@@ -38,10 +67,21 @@ class Model{
38 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
67 static let channelsDeleteURL = URL(string: "\(baseUrl)/channels/delete")!
39 static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
68 static let channelsGetAnonURL = URL(string: "\(baseUrl)/channels/getAnonymous")!
40 static let complexURL = URL(string: "\(baseUrl)/complex")!
69 static let complexURL = URL(string: "\(baseUrl)/complex")!
70+ static let hashTagTreeURL = URL(string: "\(baseUrl)/tags/completions")!
71+ static let createGroupChatURL = URL(string: "\(baseUrl)/chats/createGroupChat")!
72+ static let chatsGetAllURL = URL(string: "\(baseUrl)/chats/getAll")!
73+ static let getGroupChatURL = URL(string: "\(baseUrl)/chats/getGroupChat")!
74+ static let leaveGroupChatURL = URL(string: "\(baseUrl)/chats/leaveGroupChat")!
75+ static let updateGroupChatURL = URL(string: "\(baseUrl)/chats/updateGroupChat")!
76+ static let messagesGetGroupChatURL = URL(string: "\(baseUrl)/messages/get/groupChat")! //r
77+ static let messagesSendURL = URL(string: "\(baseUrl)/messages/send")!
78+ static let messagesGetUserChatURL = URL(string: "\(baseUrl)/messages/get/userChat")!
79+ static let facultySearchURL = URL(string: "\(baseUrl)/faculty/search")!
42− struct QueryPosts: Codable {
82+ struct QueryPosts<T: Codable>: Codable {
43 var users: [Int: Users]
83 var users: [Int: Users]
44− var response: [Posts]
84+ var response: [T]
47 struct Posts: Codable {
87 struct Posts: Codable {
@@ -108,7 +148,12 @@ class Model{
108 var lastName: String
148 var lastName: String
109 var firstName: String
149 var firstName: String
110 var id: Int
150 var id: Int
151+ var faculty: Faculty
154+ func fullName() -> String {
155+ return "\(firstName) \(lastName)"
114 struct Attachments: Codable {
159 struct Attachments: Codable {
@@ -130,7 +175,7 @@ class Model{
131 struct Channels: Codable {
176 struct Channels: Codable {
133− static var fullTags = Set<String>()
178+ // static var fullTags = Set<String>()
134 static var fullPeople = [Users]()
179 static var fullPeople = [Users]()
135 static var fullPeopleDict = [Int:Users]()
180 static var fullPeopleDict = [Int:Users]()
@@ -168,24 +213,108 @@ class Model{
171− static func authenticate(with id: Int, completion: @escaping ((Bool)->())) {
216+ struct AuthStatus: Codable {
217+ var userStatus: String
173− let json: [String:Any] = ["authenticationId" : id]
219+ init(){
174− 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)
176− var request = URLRequest(url: authenticationURL)
177 request.httpMethod = "POST"
259 request.httpMethod = "POST"
260+ request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
179− // insert json data to the request
262+ AF.request(request).response { (responce) in
180− 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)
181 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
287 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
183 AF.request(request).response { (responce) in
289 AF.request(request).response { (responce) in
185− guard let realResponse = responce.response, realResponse.statusCode == 200 else
291+ guard let statusCode = responce.response?.statusCode else { completion(false); return }
186− {
292+ isValidTocken?(statusCode)
187− 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
188 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 {
@@ -195,26 +324,67 @@ class Model{
198− 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
200− 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!)
202− HTTPCookieStorage.shared.setCookie(cookies[0])
362+ HTTPCookieStorage.shared.setCookie(cookies[0])
204− DataStorage.standard.setIsLoggedIn(value: true, with: personId)
205− completion(true)
365+ completion(res)
209− struct PostsLastRequest: Codable {
369+ struct GeneralRequest<T: Codable>: Codable
371+ var direction: String
210 var limit: Int
372 var limit: Int
211 var exclusiveFrom: Int?
373 var exclusiveFrom: Int?
212− var request: [Int] = []
374+ var request: T
376+ init(direction: String = "backward", limit: Int, exclusiveFrom: Int?, request: T) {
377+ self.direction = direction
379+ self.exclusiveFrom = exclusiveFrom
380+ self.request = request
214 enum CodingKeys: String, CodingKey {
383 enum CodingKeys: String, CodingKey {
215 case limit
384 case limit
216 case exclusiveFrom
385 case exclusiveFrom
217 case request
386 case request
220 func encode(to encoder: Encoder) throws {
390 func encode(to encoder: Encoder) throws {
@@ -222,12 +392,13 @@ class Model{
222 try container.encode(limit, forKey: .limit)
392 try container.encode(limit, forKey: .limit)
223 try container.encode(exclusiveFrom, forKey: .exclusiveFrom)
393 try container.encode(exclusiveFrom, forKey: .exclusiveFrom)
224 try container.encode(request, forKey: .request)
394 try container.encode(request, forKey: .request)
395+ try container.encode(direction, forKey: .direction)
228 static func getLast(on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
399 static func getLast(on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
230− let postRequest = PostsLastRequest(limit: limit, exclusiveFrom: pointInTime, request: [])
401+ let postRequest = GeneralRequest<[Int]>(limit: limit, exclusiveFrom: pointInTime, request: [])
232 var request = URLRequest(url: postsLastURL)
403 var request = URLRequest(url: postsLastURL)
233 request.httpBody = try? JSONEncoder().encode(postRequest)
404 request.httpBody = try? JSONEncoder().encode(postRequest)
@@ -241,9 +412,13 @@ class Model{
242 isValidTocken?(response.response?.statusCode ?? 498)
413 isValidTocken?(response.response?.statusCode ?? 498)
415+ if let code = response.response?.statusCode, code == 498 {
244 guard let json = response.data else { return }
419 guard let json = response.data else { return }
246− 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")
249 idUser = newQueery.users
424 idUser = newQueery.users
@@ -252,7 +427,7 @@ class Model{
255− static func createAndPublish(body: [Attachments], tags: [String]){
430+ static func createAndPublish(body: [Attachments], tags: [String], completion: @escaping ((ResultR)->())){
256 let jsonUpd = CreatedPost(body: body, tags: tags)
431 let jsonUpd = CreatedPost(body: body, tags: tags)
257 var request = URLRequest(url: postsPublishURL)
432 var request = URLRequest(url: postsPublishURL)
@@ -266,17 +441,30 @@ class Model{
266 (response) in
441 (response) in
268 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)
459+// static func requestForPosts(limit: Int = 10, ){
273− static func getPostsForUser(with id: Int, completion: @escaping (([Posts])->())){
463+ static func getPostsForUser(for limit: Int = 10, from pointInTime: Int? = nil, with id: Int, completion: @escaping (([Posts])->()))
275− "request" : id,
465+ let postsRequest = GeneralRequest<Int>(limit: limit, exclusiveFrom: pointInTime, request: id)
279− let jsonData = try? JSONSerialization.data(withJSONObject: json)
467+ let jsonData = try? JSONEncoder().encode(postsRequest)
281 var request = URLRequest(url: postsForUserURL)
469 var request = URLRequest(url: postsForUserURL)
282 request.httpMethod = "POST"
470 request.httpMethod = "POST"
@@ -290,9 +478,13 @@ class Model{
291 isValidTocken?(response.response?.statusCode ?? 498)
479 isValidTocken?(response.response?.statusCode ?? 498)
481+ if let code = response.response?.statusCode, code == 498 {
293 guard let json = response.data else { return }
485 guard let json = response.data else { return }
295− 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 }
297 completion(newPost.response)
489 completion(newPost.response)
@@ -302,7 +494,7 @@ class Model{
303 static func getUsers(for ids: [Int], completion: @escaping (([Int:Users])->())){
495 static func getUsers(for ids: [Int], completion: @escaping (([Int:Users])->())){
304 let json = "\(Set(ids))"
496 let json = "\(Set(ids))"
306 var request = URLRequest(url: usersURL)
498 var request = URLRequest(url: usersURL)
308 request.httpMethod = "POST"
500 request.httpMethod = "POST"
@@ -316,11 +508,16 @@ class Model{
317 isValidTocken?(response.response?.statusCode ?? 498)
509 isValidTocken?(response.response?.statusCode ?? 498)
511+ if let code = response.response?.statusCode, code == 498 {
319 guard let json = response.data else { return }
515 guard let json = response.data else { return }
321 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 }
323 var dict: [Int:Users] = [:]
519 var dict: [Int:Users] = [:]
324 users.forEach({ (user) in
521 users.forEach({ (user) in
325 dict[user.id] = user
522 dict[user.id] = user
@@ -330,13 +527,10 @@ class Model{
332 // get channel (with id): in responce -- PostQuery
529 // get channel (with id): in responce -- PostQuery
333− static func getChannel(with channelId: Int, completion: @escaping (((users:[Int: Users], posts:[Posts]))->())){
530+ static func getChannel(with channelId: Int, on limit: Int = 10, from pointInTime: Int? = nil, completion: @escaping (((users:[Int: Users], posts:[Posts]))->()))
335− "request" : channelId,
532+ let postRequest = GeneralRequest<Int>(limit: limit, exclusiveFrom: pointInTime, request: channelId)
336− "limit": 10
533+ let jsonData = try? JSONEncoder().encode(postRequest)
339− let jsonData = try? JSONSerialization.data(withJSONObject: json)
341 var request = URLRequest(url: channelsGetURL)
535 var request = URLRequest(url: channelsGetURL)
342 request.httpMethod = "POST"
536 request.httpMethod = "POST"
@@ -350,10 +544,13 @@ class Model{
351 isValidTocken?(response.response?.statusCode ?? 498)
545 isValidTocken?(response.response?.statusCode ?? 498)
547+ if let code = response.response?.statusCode, code == 498 {
354 guard let json = response.data else { return }
551 guard let json = response.data else { return }
356− 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 }
358 idUser = newQueery.users
555 idUser = newQueery.users
359 completion((newQueery.users, newQueery.response))
556 completion((newQueery.users, newQueery.response))
@@ -361,7 +558,7 @@ class Model{
364− static func createChannel(with channel: Channels) {
561+ static func createChannel(with channel: Channels, completion: @escaping ((ResultR)->())) {
366 var request = URLRequest(url: channelsCreateURL)
563 var request = URLRequest(url: channelsCreateURL)
367 request.httpMethod = "POST"
564 request.httpMethod = "POST"
@@ -372,6 +569,13 @@ class Model{
372 (response) in
569 (response) in
374 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)
@@ -384,6 +588,9 @@ class Model{
384 AF.request(request).responseJSON { (response) in
588 AF.request(request).responseJSON { (response) in
386 isValidTocken?(response.response?.statusCode ?? 498)
590 isValidTocken?(response.response?.statusCode ?? 498)
591+ if let code = response.response?.statusCode, code == 498 {
388 guard let json = response.data else { return }
595 guard let json = response.data else { return }
@@ -402,6 +609,9 @@ class Model{
403 AF.request(request).response { (response) in
610 AF.request(request).response { (response) in
404 isValidTocken?(response.response?.statusCode ?? 498)
611 isValidTocken?(response.response?.statusCode ?? 498)
612+ if let code = response.response?.statusCode, code == 498 {
406 completion()
616 completion()
@@ -417,6 +627,9 @@ class Model{
417 (response) in
627 (response) in
419 isValidTocken?(response.response?.statusCode ?? 498)
629 isValidTocken?(response.response?.statusCode ?? 498)
630+ if let code = response.response?.statusCode, code == 498 {
@@ -439,6 +652,9 @@ class Model{
441 isValidTocken?(response.response?.statusCode ?? 498)
654 isValidTocken?(response.response?.statusCode ?? 498)
655+ if let code = response.response?.statusCode, code == 498 {
@@ -501,27 +717,434 @@ class Model{
504− 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]))->())){
722+ let req = GeneralRequest<Model.Channels>(limit: 10, exclusiveFrom: exclusiveFrom, request: anonymousChannel)
506 var request = URLRequest(url: channelsGetAnonURL)
724 var request = URLRequest(url: channelsGetAnonURL)
507 request.httpMethod = "POST"
725 request.httpMethod = "POST"
508− request.httpBody = try? JSONEncoder().encode(anonymousChannel)
726+ request.httpBody = try? JSONEncoder().encode(req)
510 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
728 request.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
511 AF.request(request).response {
729 AF.request(request).response {
512 (response) in
730 (response) in
514 isValidTocken?(response.response?.statusCode ?? 498)
732 isValidTocken?(response.response?.statusCode ?? 498)
733+ if let code = response.response?.statusCode, code == 498 {
516 guard let json = response.data else { return }
737 guard let json = response.data else { return }
518− guard let newQueery = try? decoder.decode(QueryPosts.self, from: json) else { return }
739+ guard let newQueery = try? decoder.decode(QueryPosts<Posts>.self, from: json) else { return }
520− // idUser = newQueery.users
521 completion((newQueery.users, newQueery.response))
740 completion((newQueery.users, newQueery.response))
744+ static func getCompl(completion: @escaping ((CompletionTree)->())) {
746+ AF.request(URLRequest(url: hashTagTreeURL)).responseJSON {
748+ isValidTocken?(response.response?.statusCode ?? 498)
749+ if let code = response.response?.statusCode, code == 498 {
752+ guard let json = response.data else { return }
753+ guard let tree = try? decoder.decode(CompletionTree.self, from: json) else { return }
758+ static func getChatAll(limit: Int = 10, exclusiveFrom: Int? = nil, request: [Int] = [], completion: @escaping ((([Dialog],[Int:Model.Users]))->()))
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")
766+ AF.request(request).responseJSON { response in
767+ isValidTocken?(response.response?.statusCode ?? 498)
769+ if let code = response.response?.statusCode, code == 498 {
773+ guard let json = response.data else { return }
774+ let dialogs = try! decoder.decode(QueryPosts<Dialog>.self, from: json)
776+ completion((dialogs.response,dialogs.users))
780+ enum Dialog: Codable
782+ case groupChat(GroupChat)
783+ case userChat(UserChat)
785+ private enum DialogKeys: CodingKey{
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)))
797+ throw DecodingError.keyNotFound(DialogKeys.groupChat, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz"))
801+ func encode(to encoder: Encoder) throws {
802+ var container = encoder.container(keyedBy: DialogKeys.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))
812+ struct GroupChat: Codable {
814+ var lastMessage: LastMessage?
817+ init(group: Group, lastMessage: LastMessage? = nil) {
819+ self.lastMessage = lastMessage
823+ struct UserChat: Codable {
825+ var lastMessage: LastMessage?
827+ init(user: Int, lastMessage: LastMessage? = nil) {
829+ self.lastMessage = lastMessage
833+ struct Group: Codable {
834+ var users: [Int: UserPermission]
838+ init(users: [Int: UserPermission] = [:], name: String = "", id: Int) {
845+ struct UserPermission: Codable {
849+ struct LastMessage: Codable {
850+ var body: Attachments
851+ var destination: MessageDestination
856+ enum MessageCodingKeys: CodingKey{
865+ init(from decoder: Decoder) throws
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)
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)))
878+ throw DecodingError.keyNotFound(MessageCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
882+ func encode(to encoder: Encoder) throws {
883+ var container = encoder.container(keyedBy: MessageCodingKeys.self)
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)
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))
899+ enum MessageDestination: Codable
901+ func encode(to encoder: Encoder) throws
903+ var container = encoder.container(keyedBy: MessCodingKeys.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))
912+ init(from decoder: Decoder) throws
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)))
920+ throw DecodingError.keyNotFound(MessCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr"))
924+ enum MessCodingKeys: CodingKey{
929+ case userChatDestination(Int)
930+ case groupChatDestination(Int)
934+ static func createGroupChat(from group: Group, completion: @escaping ((Int)->())) {
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")
941+ AF.request(request).response { (response) in
943+ isValidTocken?(response.response?.statusCode ?? 498)
944+ if let code = response.response?.statusCode, code == 498 {
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!)
956+ static func getMessagesFor(typeOfChat: Model.Dialog, chat id: Int, exclusiveFrom: Int? = nil, limit l: Int = 25, direction: String = "backward", completion: @escaping (([LastMessage])->()))
958+ let req = GeneralRequest<Int>(direction: direction, limit: l, exclusiveFrom: exclusiveFrom, request: id)
959+ var request: URLRequest?
963+ request = URLRequest(url: messagesGetGroupChatURL)
965+ request = URLRequest(url: messagesGetUserChatURL)
968+ request!.httpMethod = "POST"
969+ request!.httpBody = try? JSONEncoder().encode(req)
970+ request!.setValue("application/json; charset=utf-8", forHTTPHeaderField: "Content-Type")
972+ AF.request(request!).response { (response) in
974+ isValidTocken?(response.response?.statusCode ?? 498)
975+ if let code = response.response?.statusCode, code == 498 {
979+ guard let json = response.data else { return }
980+ guard let messages = try? decoder.decode([LastMessage].self, from: json) else { return }
982+ completion(messages)
986+ static func leaveGroupChat(id: Int, completion: @escaping (()->()))
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")
993+ AF.request(request).response { (response) in
994+ isValidTocken?(response.response?.statusCode ?? 498)
996+ if let code = response.response?.statusCode, code == 498 {
1004+ static func updateGroupChat(with group: Model.Group)
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")
1011+ AF.request(request).response { (response) in
1012+ isValidTocken?(response.response?.statusCode ?? 498)
1014+ if let code = response.response?.statusCode, code == 498 {
1022+ struct SendMessage: Codable {
1023+ var body: Attachments
1024+ var destination: MessageDestination
1026+ init(from decoder: Decoder) throws
1028+ let container = try decoder.container(keyedBy: LastMessage.MessageCodingKeys.self)
1029+ body = try container.decode(Attachments.self, forKey: .body)
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)))
1036+ throw DecodingError.keyNotFound(LastMessage.MessageCodingKeys.group, DecodingError.Context(codingPath: container.codingPath, debugDescription: "hz gr1"))
1040+ func encode(to encoder: Encoder) throws {
1041+ var container = encoder.container(keyedBy: LastMessage.MessageCodingKeys.self)
1042+ try container.encode(body, forKey: .body)
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))
1052+ init(body: Attachments, destination: MessageDestination)
1055+ self.destination = destination
1059+ static func sendMessage(message: SendMessage, completion: @escaping ((ResultR)->())){
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)
1066+ AF.request(request).response { (response) in
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 {