Swift: Asynchronous callback

后端 未结 4 1161
傲寒
傲寒 2020-12-07 23:29

How do I make asynchronous callbacks in swift? I\'m writing a little Framework for my app because it\'s supposed to run on both, iOS und OS X. So I put the main code that is

4条回答
  •  陌清茗
    陌清茗 (楼主)
    2020-12-07 23:45

    I've shared the pattern that I use for this scenario in the following gist: https://gist.github.com/szehnder/84b0bd6f45a7f3f99306

    Basically, I create a singleton DataProvider.swift that setups an AFNetworking client. Then the View Controllers call methods on that DataProvider, each of which is terminated by a closure that I've defined as a typealias called ServiceResponse. This closure returns either a dictionary or an error.

    It allows you to very cleanly (imo) call for an async data action from the VC's with a very clear indication of what you want performed when that async response returns.

    DataProvider.swift

    typealias ServiceResponse = (NSDictionary?, NSError?) -> Void
    
    class DataProvider: NSObject {
    
        var client:AFHTTPRequestOperationManager?
        let LOGIN_URL = "/api/v1/login"
    
        class var sharedInstance:DataProvider {
            struct Singleton {
                static let instance = DataProvider()
            }
            return Singleton.instance
        }
    
        func setupClientWithBaseURLString(urlString:String) {
            client = AFHTTPRequestOperationManager(baseURL: NSURL.URLWithString(urlString))
            client!.operationQueue = NSOperationQueue.mainQueue()
            client!.responseSerializer = AFJSONResponseSerializer()
            client!.requestSerializer = AFJSONRequestSerializer()
        }
    
        func loginWithEmailPassword(email:String, password:String, onCompletion: ServiceResponse) -> Void {
            self.client!.POST(LOGIN_URL, parameters: ["email":email, "password":password] , success: {(operation:AFHTTPRequestOperation!, responseObject:AnyObject!) -> Void in
    
                self.setupClientWithBaseURLString("http://somebaseurl.com")
    
                let responseDict = responseObject as NSDictionary
                    // Note: This is where you would serialize the nsdictionary in the responseObject into one of your own model classes (or core data classes)
                    onCompletion(responseDict, nil)
                }, failure: {(operation: AFHTTPRequestOperation!, error:NSError!) -> Void  in
                    onCompletion(nil, error)
                })
        }
    }
    

    MyViewController.swift

    import UIKit
    
    class MyViewController: UIViewController {
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            // Do any additional setup after loading the view.
        }
    
        override func viewWillAppear(animated: Bool)  {
            super.viewWillAppear(animated)
            DataProvider.sharedInstance.loginWithEmailPassword(email:"some@email.com", password:"somepassword") { (responseObject:NSDictionary?, error:NSError?) in
    
                if (error) {
                    println("Error logging you in!")
                } else {
                    println("Do something in the view controller in response to successful login!")
                }
            }
        }  
    }
    

提交回复
热议问题