【问题标题】:Swift closure with Alamofire使用 Alamofire 快速关闭
【发布时间】:2014-09-28 07:02:16
【问题描述】:

我正在对服务器进行 API 调用。我正在利用 Alamofire 来处理这个问题。我正在尝试创建一个函数,该函数使用 Alamofire 的 GET 函数返回一个基于自定义类的对象,该类包含此 GET 函数提供的各种输出。

我不清楚该怎么做。

这是我的自定义类,它将包含有关响应的详细信息:

import Foundation

class ResponsePackage {

    var success = false
    var response: AnyObject? = nil
    var error: NSError? = nil

}

在另一个类中,我有以下功能:

func get(apiEndPoint: NSString) -> ResponsePackage {

    let responsePackage = ResponsePackage()

        Alamofire
            .request(.GET, apiEndPoint)
            .responseJSON {(request, response, JSON, error) in
                responsePackage.response = JSON
                responsePackage.success = true
                responsePackage.error = error
        }

    return responsePackage

}

这将返回nil,因为在执行return 之前对服务器的调用尚未完成。我知道我应该能够使用闭包来做到这一点,但我不确定如何构造它。

【问题讨论】:

    标签: swift alamofire


    【解决方案1】:

    我做了一个例子来跟随你关于 responseJSON 的问题 closures

    按照这个小步骤:​​

    首先,您可以在通用类(例如 Constants.swift 类)中创建自定义类型:

    typealias apiSuccess = (result: NSDictionary?) -> Void
    typealias apiProgress = (result: NSDictionary?) -> Void // when you want to download or upload using Alamofire..
    typealias apiFailure = (error: NSDictionary?) -> Void
    

    然后在你的课堂上:

    // Normal http request with JSON response..
    func callJSONrequest(url:String, params:[String: AnyObject]?, success successBlock :apiSuccess,
        failure failureBlock :apiFailure) {
    
            Alamofire.request(.GET, url, parameters: params, encoding: ParameterEncoding.URL)
                .responseJSON { response in
                    print("\(response.request?.URL)")  // original URL request
                    //print(response.response) // URL response
                    //print(response.data)     // server data
                    //print(response.result)   // result of response serialization
                    if response.result.isSuccess {
                        let jsonDic = response.result.value as! NSDictionary
                        successBlock(result: jsonDic)
    
                    } else {
                        let httpError: NSError = response.result.error!
                        let statusCode = httpError.code
                        let error:NSDictionary = ["error" : httpError,"statusCode" : statusCode]
                            failureBlock(error: error)
                        }
                    }
            }
    }
    
    func myCommonFunction() {
       let myApiSuccess: apiSuccess = {(result: NSDictionary?) -> Void in 
          print ("Api Success : result is:\n \(result)")
          // Here you can make whatever you want with result dictionary
       }
       let myApiFailure: apiFailure = {(error: NSDictionary?) -> Void in 
          print ("Api Failure : error is:\n \(error)")
          // Here you can check the errors with error dictionary looking for http error type or http status code
       }
       var params :[String: AnyObject]?
       let name : String! = "this is my name"
       let id : String! = "000a"
       params = ["name" : name, "id" : id]
       let url : String! = "https://etc..."
       callJSONrequest(url, params:params, success: myApiSuccess, failure: myApiFailure)
    }
    

    【讨论】:

    • 您不能在类型别名中指定闭包(不再)。例如。改为使用:typealias apiSuccess = (Dictionary?) -> Void
    【解决方案2】:

    {} 之间的代码相当于 Objective-C 中的块:这是一段异步执行的代码。

    你犯的错误是你把你的 return 语句放在哪里:当你启动你的请求时,{} 中的代码在框架收到响应之前不会执行,所以当到达return 语句时,很可能,仍然没有回应。你可以简单地移动这条线:

    return responsePackage
    

    在闭包内部,所以func 仅在收到响应时才返回。这是一种简单的方法,但并不是真正的最佳方法:您的代码将陷入等待答案的困境。最好的方法是使用闭包。这看起来像:

       func get(apiEndPoint: NSString, completion: (response: ResponsePackage) -> ()) -> Bool {
    
            let responsePackage = ResponsePackage()
            Alamofire
                .request(.GET, apiEndPoint)
                .responseJSON {(request, response, JSON, error) in
                    responsePackage.response = JSON
                    responsePackage.success = true
                    responsePackage.error = error
    
                    completion(response: responsePackage)
            }
        }
    

    【讨论】:

    • 谢谢@Emilie。我该如何调用这个函数?
    • @shawnzizzo 我也有类似的问题……你能解决这个问题吗?如果是这样,你是如何调用这个函数来返回你的包的?
    • client.get(apiEndPoint: NSString) { (responsePackage) -> println(responsePackage) 中的无效 }
    • 我也知道如何调用上面这个例子的completionhandler..
    猜你喜欢
    • 1970-01-01
    • 2019-04-27
    • 1970-01-01
    • 1970-01-01
    • 2017-05-20
    • 2015-04-22
    • 1970-01-01
    • 1970-01-01
    • 2016-11-09
    相关资源
    最近更新 更多