Swift: Asynchronous callback

后端 未结 4 1164
傲寒
傲寒 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-08 00:04

    I'd like to recommend use a block or closure callback instead of using NSThread and selectors.

    For example, in my API I have follow method:

    Swift:

    Below you will find an updated implementation.

    func getUsers(completion: (result: NSArray?, error: NSError?)->())
    {
        var session = NSURLSession.sharedSession()
        var task = session.dataTaskWithRequest(request){
         (data, response, error) -> Void in
           if error != nil {
             completion(nil, error)
           } else {
             var result:NSArray = data to NSArray;
             completion(result, nil)
           }
        }
        task.resume()
    }
    

    Objective-C:

    ...
    typedef void (^CBSuccessBlock)(id result);
    typedef void (^CBFailureBlock)(NSError *error);
    ...
    
    - (void)usersWithSucces:(CBSuccessBlock)success failure:(CBFailureBlock)failure
    {
        NSURLSession *session = [NSURLSession sharedSession];
        [[session dataTaskWithURL:[NSURL URLWithString:url]
                completionHandler:^(NSData *data,
                                    NSURLResponse *response,
                                    NSError *error) {
    
                    NSArray *users = //convert data to array
    
                    if(error)
                        failure(error);
                    else
                        success(users);
                }] resume];
    }
    

    Then, just make a call to api from view controller:

    Objc:
    [api usersWithSucces:^(id result)
    {
       //Success callback
    } failure:^(NSError *error)
    {
       //Failure callback
    }];
    
    Swift:
    api.getUsers({(result: AnyObject?, error: NSError?) -> Int in
        // callback here
    })
    

    UPDATE:

    Meanwhile, I see that the question and answers are still being useful and interested. Well, here is an updated version of swift implementation using generic enum as a result object:

    //Generic enum that represents the result
    enum AsyncResult
    {
        case Success(T)
        case Failure(NSError?)
    }
    
    
    class CustomUserObject
    {
    
    }
    
    func getUsers(completion: (AsyncResult<[CustomUserObject]>)->())
    {
        let request = NSURLRequest()
        let session = NSURLSession.sharedSession()
        let task = session.dataTaskWithRequest(request){
            (data, response, error) -> Void in
            if let error = error
            {
                completion(AsyncResult.Failure(error))
            } else {
                let result: [CustomUserObject] = []//deserialization json data into array of [CustomUserObject]
                completion(AsyncResult.Success(result))
            }
        }
        task.resume()
    }
    
    //Usage:
    
    getUsers { (result) in
        switch result
        {
        case .Success(let users):
            /* work with users*/
            break
        case .Failure(let error):
            /* present an error */
            break
        }
    }
    

提交回复
热议问题