ios - 在完成处理程序中使用类型 T 作为参数

标签 ios swift nsurlsession

我已经为 URL 请求编写了一个函数。这包含一个完成处理程序,该处理程序返回从 URL 中获取的 [String: AnyObject] 字典。

代码是:

func getDataAsyncFromURLRequest(url: NSURL, completion: ([String : AnyObject]) -> ()) {

    let request = NSMutableURLRequest(URL: url)
    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
        if error != nil {
            print("error=\(error)")
            return
        }
        else {
            let datastring = NSString(data: data!, encoding: NSUTF8StringEncoding)

            if let data = datastring!.dataUsingEncoding(NSUTF8StringEncoding) {
                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! [String : AnyObject]

                    completion(json)

                } catch {
                    print("json error: \(error)")

                }
            }
        }
    }
    task.resume()
}

然而,在某些情况下,我会收到一个 [String : AnyObject] 数组,而不是字典。因此,我没有创建一个将字典数组作为完成处理程序的参数的重复函数,而是可以这样做

func getDataAsyncFromURLRequest<T>(url: NSURL, completion: (T) -> ()) { 
    // code here
}

... 然后像这样 let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions()) as! T,但这给了我这个错误:无法使用类型为“(NSURL, completion: (_) -> ())”的参数列表调用“getDataAsyncFromURLRequest”

如果可能的话,让完成处理程序接受类型在运行时决定的参数的最佳方法是什么?

最佳答案

很简单为什么不用AnyObject

func getDataAsyncFromURLRequest(url: NSURL, completion: (AnyObject) -> ()) {

    let request = NSMutableURLRequest(URL: url)
    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithRequest(request) { (data, response, error) -> Void in
        if error != nil {
            print("error=\(error)")
            return
        }
        else {
            let datastring = NSString(data: data!, encoding: NSUTF8StringEncoding)

            if let data = datastring!.dataUsingEncoding(NSUTF8StringEncoding) {
                do {
                    let json = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions())

                    completion(json)

                } catch {
                    print("json error: \(error)")

                }
            }
        }
    }
    task.resume()
}

JSONObjectWithData 的结果可以是 [AnyObject](数组)或 [String:AnyObject] 以及这些项目的树。

所以在得到结果后,你也可以在完成 block 中检查结果类型

像这样

if result is [String:AnyObject]
... else if result is [AnyObject] ... else //throw error : because then it is not JSON

关于ios - 在完成处理程序中使用类型 T 作为参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33013839/

相关文章:

ios - 如何更改 tabBarController 中所选项目的背景颜色

ios - Freesound OAuth2 身份验证失败

ios - 是否可以在 Swift 中为特定的 iOS 版本定义一个变量?在类(class)层面

ios - 为什么 Apple 在类构造函数中对 instancetype 的使用不一致?

swift - 如何使用 willSet 来更新或更正 Swift 中的某些值?

ios - UISwitch 正在触发 UITableView 中的另一个 UISwitch 事件

ios - 无法使用mockURLSession调用非函数类型 'URLSession'错误的值

ios - 避免 Swift 同时调用 viewDidLoad 方法得到 "Index out of range"

ios - 在通用应用程序中禁用 iPhone 分屏 View Controller 的横向

ios - 导航栏中的重叠标题