为全局使用嵌套 Alamofire 回调或返回值

Posted

技术标签:

【中文标题】为全局使用嵌套 Alamofire 回调或返回值【英文标题】:Nesting Alamofire callbacks or return value for Global Usage 【发布时间】:2016-01-13 01:15:48 【问题描述】:

我目前正在尝试嵌套 Alamofire 请求,以使用我已经通过 GET 请求成功接收的数据。

对于这段代码,我在这个问题中使用了 Rob 的答案

How to return value from Alamofire

但是,我不能嵌套 Alamofire 请求或单独使用它们。

这就是我想做的事情

override func viewDidLoad() 
    super.viewDidLoad()


    var currentFoodType: String = ""
    var currentFoodList: String = ""

    //debug

    //this is how I get back the token from NSUserDefault
    if let myToken = userDefaults.valueForKey("token")


        // calling method to get the user info
        getUserInfo(myToken as! String)

        // calling method to get the product type
        func getFoodCategory(completionHandler: (NSDictionary?, NSError?) -> ()) 
            getProductTypes(myToken as! String, completionHandler: completionHandler)
        
        getFoodCategory()  responseObject, error in
            // use responseObject and error here

            let foodTypesJSON = JSON(responseObject!)
            //to get one single food category
            currentFoodType = (foodTypesJSON["types"][0].stringValue)
            print(currentFoodType)


            /////////////////////////////////////////
            func getFoodsByCategory(completionHandler: (NSDictionary?, NSError?) -> ()) 
                print("getting " + currentFoodType)
                self.getProductsByType(myToken as! String, productType: currentFoodType, completionHandler: completionHandler)
            

            getFoodsByCategory()  responseObject, error in
                // use responseObject and error here
                print("responseObject = \(responseObject); error = \(error)")

                return
            

           return
        

    

然后我从那里调用的另外两个函数是非常直接的 Alamofire 请求,带有对上述完成处理程序的回调

    //GET THE PRODUCT TYPES FROM THE SERVER
func getProductTypes(myToken: String, completionHandler: (NSDictionary?, NSError?) -> ())  

    let requestToken = "Bearer " + myToken
    let headers = ["Authorization": requestToken]
    let getProductTypesEndpoint: String = BASE_URL + PRODUCT_TYPES


    Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
        .responseJSON response in
            switch response.result 
            case .Success(let value):
                completionHandler(value as? NSDictionary, nil)
            case .Failure(let error):
                completionHandler(nil, error)
            
    //END ALAMOFIRE GET responseJSON



上面的函数返回一个像“甜点”这样的食物,它将在下面的函数中用于从服务器获取所有甜点

//GET THE PRODUCTS FROM THE SERVER GIVEN A CATEGORY
func getProductsByType(myToken: String, productType: String, completionHandler: (NSDictionary?, NSError?) -> ())

    let requestToken = "Bearer " + myToken
    let headers = ["Authorization": requestToken]
    let getProductTypesEndpoint: String = BASE_URL + PRODUCT_BY_TYPE + productType

    Alamofire.request(.GET, getProductTypesEndpoint, headers: headers)
        .responseJSON  response in
            switch response.result 
            case .Success(let value):
                print("no errors")
                let auth = JSON(value)
                print("The pbt GET description is: " + auth.description)
                completionHandler(value as? NSDictionary, nil)
            case .Failure(let error):
                print("there was an error")

                completionHandler(nil, error)
            
    //END ALAMOFIRE GET responseJSON

这很好用,因为当我在 getProductsByType 函数

中打印时

使用

print("The pbt GET description is: " + auth.description)

我得到所有产品的 JSON 但问题出在我嵌套回调的 viewDidload 函数中

getFoodsByCategory()  responseObject, error in
                // use responseObject and error here
                print("responseObject = \(responseObject); error = \(error)")                   
                return
            

该位中的打印显示我出了点问题,因此我无法按我的意愿解析我的响应。

因为我得到以下信息

responseObject = nil; error = nil

所以我的猜测是必须有不同的方法来嵌套这些回调?

【问题讨论】:

【参考方案1】:

看看来自PromiseKit 的链式承诺。这也适用于 Alamofire:

func loadFoo() -> Promise<Bar> 
    return Promise<Bar>  fulfill, reject in 
        Alamofire.request(.GET, "url")
        .responseJSON  response in
            switch response.result 
                case .Success(let value):
                     let bar = Bar(fromJSON: value)
                     fulfill(bar)
                case .Failure(let error):
                     reject(error)
            
        
    



// Usage    
getBar()
.then  bar -> Void in
    // do something with bar

.error  error in
    // show error

这是一个非常简单的示例,但您可以在文档中找到更多相关示例。

【讨论】:

以上是关于为全局使用嵌套 Alamofire 回调或返回值的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Alamofire 和 SwiftyJSON 访问嵌套的 JSON 值?

带有嵌套参数的 Alamofire POST 请求不返回任何内容

使用 Alamofire 和 Swift 返回嵌套 JSON 数组中的值

从 Reduce 方法合并嵌套数组

Alamofire - 有没有办法设置自定义默认队列来处理所有请求回调

Alamofire 请求最初返回值,但在通过完成处理程序时被接收为 nil