Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- final class RestService {
- ///Singleton instance
- private static let instance: RestService = RestService()
- ///Singleton instance getter
- static var Instance: RestService {
- get { return instance }
- }
- /// *DispatchQueue* with midium priority.
- final let queue = DispatchQueue(label: "com.cnoon.response-queue", qos: .userInitiated, attributes: .concurrent)
- func createRequest(method: HTTPMethod, url: String, parameters: [String : AnyObject], completion: @escaping (Data, NetworkCode) -> Void) {
- // Do alamofire async request.
- Alamofire.request(url, method: method, parameters: parameters).responseData(queue: queue) { (data) in
- // Handle response.
- self.responseHandler(dataResponse: data, completion: { (data, networkCode) in
- completion(data, networkCode)
- })
- }
- }
- func responseHandler(dataResponse: DataResponse<Data>, completion: @escaping (Data, NetworkCode) -> Void) {
- guard (dataResponse.response?.statusCode) != nil else { completion(Data(), .error); return }
- guard Connectivity.Instance.isReachability else { completion(Data(), .noInternetConnection); return }
- // Response must be different than 401 - 401 code means we fucked up request.
- print(dataResponse.request)
- if dataResponse.response?.statusCode == 401 {
- // TODO: Handle message from server.
- completion(Data(), .error)
- return
- }
- // Return data from resonse if everything went ok ( status code 200 )
- guard let data = dataResponse.data else { completion(Data(), .error); return }
- completion(data, .success)
- }
- }
- enum NetworkCode: Int {
- case noInternetConnection = 0, error = 1, wrongToken = 2, unknownCode = 3, success = 4
- }
- protocol Requestable {
- /// Specifices needed request.
- ///
- /// - Parameter requestType: Which request.
- func request(requestType: RequestType<Any>)
- }
- enum RequestType<T> {
- case login(T), firstGroupRequest(T), secondGroupRequest(T)
- }
- /// Handling requests.
- ///
- /// - Parameter requestType: For which request.
- func request(requestType: RequestType<Any>) {
- switch requestType {
- case .login(let user):
- let loginQueryParams = buildQueryParams(requestType: .login(user))
- loginRequestWith(loginQueryParams, completion: { token in
- guard let token = token else { return }
- self.dispatchGroup(token: token, user: user as! User)
- })
- default:
- break
- }
- }
- private func dispatchGroup(token: String, user: User) {
- // Create dispatch group.
- let group = DispatchGroup()
- group.enter()
- let firstQueryParams = self.buildQueryParams(requestType: . firstGroupRequest(token))
- self.firstRequestWith(firstQueryParams, completion: {
- print("1 request")
- group.leave()
- })
- group.enter()
- let secondQueryParams = self.buildQueryParams(requestType: . secondGroupRequest(token))
- self.secondRequestWith(secondQueryParams, completion: {
- print("2 request")
- group.leave()
- })
- group.wait()
- group.notify(queue: .main, work: DispatchWorkItem(block: {
- print("Main")
- }))
- }
- private func firstRequestWith(_ params: [String: AnyObject], completion: @escaping () -> Void) {
- RestService.Instance.createRequest(method: .get, url: GET_FIRST, parameters: params, completion: { (data, networkCode) in
- switch networkCode {
- case .success:
- // YEAH we did it ! Got the correct data!
- completion()
- case .error:
- completion()
- case .noInternetConnection:
- completion()
- case .unknownCode:
- completion()
- case .wrongToken:
- completion()
- }
- })
- }
- private func secondRequestWith(_ params: [String: AnyObject], completion: @escaping () -> Void) {
- RestService.Instance.createRequest(method: .get, url: GET_SECOND, parameters: params, completion: { (data, networkCode) in
- switch networkCode {
- case .success:
- // YEAH we did it ! Got the correct data!
- completion()
- case .error:
- completion()
- case .noInternetConnection:
- completion()
- case .unknownCode:
- completion()
- case .wrongToken:
- completion()
- }
- })
- }
- func buildQueryParams(requestType: RequestType<Any>) -> [String : AnyObject] {
- var params: [String : String]!
- switch requestType {
- case .login(let user as User):
- params = [
- "username" : user.username,
- "password" : user.password,
- ]
- return params as [String: AnyObject]
- case .getFirstGroupRequest(let token as String), .getSecondGroupRequest(let token as String):
- params = [
- "token" : token,
- ]
- return params as [String: AnyObject]
- default:
- return [:]
- }
- }
- public final class User: Object {
- @objc dynamic var id = 0
- @objc dynamic var username = ""
- @objc dynamic var password = ""
- override public static func primaryKey() -> String? {
- return "id"
- }
- convenience init(id: Int, username: String, password: String) {
- self.init() // I need to call this to create an Object -> It's messy way I believie becouse realm has an initializer which is going to be called -> 2x work
- self.id.= id
- self.username = username
- self.password = password
- }
- }
- @IBAction func loginAction(_ sender: UIButton) {
- guard let username = usernameTextField.text, let password = passwordTextField.text else { return }
- request(requestType: .login(User(id: 0, username: username, password: password))
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement