Swift:异步回调 [英] Swift: Asynchronous callback

查看:115
本文介绍了Swift:异步回调的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何在swift中进行异步回调?我正在为我的应用程序编写一个小框架,因为它应该在iOS和OS X上运行。所以我将非特定于设备的主代码放入此框架中,该框架也处理对我的在线API的请求。显然我也想要应用程序的GUI,因此我的ViewControllers会在api请求完成后立即做出反应。在Objective-C中,我通过保存包含必须在id变量中调用的函数的视图以及函数本身在选择器变量中来完成此操作。然后我使用以下代码调用该函数:

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 not device-specific into this framework that also handles requests to my online api. And obviously I also want the app's GUI and therefore my ViewControllers to react as soon as a api request has finished. In Objective-C I've done this by saving the view containing the function that had to be called in an id variable and the function itself in a selector variable. Then I invoked the function using the following code:

SEL selector = callbackMethod;
((void (*)(id, SEL))[callbackViewController methodForSelector:selector])(callbackViewController, selector);

如何在swift中完成此操作?或者有更好的方法吗?

How can I accomplish this in swift? Or is there a better way of doing this?

我非常感谢你的帮助!

推荐答案

我在以下要点中分享了我用于此场景的模式: https:// gist。 github.com/szehnder/84b0bd6f45a7f3f99306

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

基本上,我创建了一个单一的DataProvider.swift来设置AFNetworking客户端。然后View Controllers调用该DataProvider上的方法,每个方法都由一个闭包终止,我将其定义为一个名为ServiceResponse的类型。这个闭包返回字典或错误。

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.

它允许你非常干净地(imo)调用来自VC的异步数据操作,并清楚地指示你希望在异步响应返回时执行。

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!")
            }
        }
    }  
}

这篇关于Swift:异步回调的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆