在Swift 3中使用Async调用的CompletionHandler

时间:2016-11-24 09:39:40

标签: arrays swift dictionary completionhandler

我想从方法返回一个数组(arr)(使用异步调用)。我在方法中实现completionHandler,但我无法使用my方法获取数组:Cast from '(@escaping ((Array<Any>) -> Void)) -> ()' to unrelated type '[[String : Any]]' always fails

我该如何解决这个问题?

这是我的代码:

func dataWithURL(completion: @escaping ((_ result:Array<Any>) -> Void)) {
    let urlString = "https://api.unsplash.com/photos/?client_id=71ad401443f49f22556bb6a31c09d62429323491356d2e829b23f8958fd108c4"
    let url = URL(string: urlString)!
    let urlRequest = URLRequest(url: url)
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)

    var arr = [[String:String]]()
    let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in
        // do stuff with response, data & error here
        if let statusesArray = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? [[String: Any]] {
            for item in statusesArray! {
                let photos = item["urls"] as? [String: Any]
                let photo = photos?["small"] as? String
                let myDictionary = [
                    "name": "test",
                    "imageURL": photo]
                arr.append(myDictionary as! [String : String])
            }
            print(arr)
            completion(arr)
        }
    })

    task.resume()
}

当我想要获得我的阵列时:

lazy var photos: [Photo] = {

    var photos = [Photo]()

// HERE THE ERROR APPEARS
guard let data = self.dataWithURL as? [[String: Any]] else { return photos }
    for info in data {
        let photo = Photo(info: info)
        photos.append(photo)
    }
    return photos
}()

2 个答案:

答案 0 :(得分:4)

dataWithURL接受回调(完成处理程序),因此您只能访问回调中的结果。

<ChildA {...this.state} />

但是上面代码的问题是你期望dataWithURL返回它没有的结果。它返回void。

另一个问题是您正在尝试将dataWithURL的结果用于属性。访问lazy var self.dataWithURL { result in //do stuff with the result } 的调用不会产生任何结果(至少在第一次调用时),因为调用photos是异步的(立即返回)。

答案 1 :(得分:1)

你似乎也是 xcode_Dev 昨天问过this问题。

我写了一个对这个问题的评论:

您无法从包含异步任务的函数(或计算变量)返回某些内容

这仍然是真的。

dataWithURL是一个异步函数,它不返回任何东西,但你必须传递一个在返回时调用的闭包。

首先,数组显然是[[String:String]](带字符串键和字符串值的字典数组)所以使用更加未指定的类型[Any]

非常愚蠢
func dataWithURL(completion: @escaping ([[String:String]]) -> Void) {

在Swift 3中,仅指定声明中没有下划线和参数标签的类型。

你必须这样调用这个函数:

dataWithURL { result in
    for item in result { // the compiler knows the type
        print(item["name"], item["imageURL"])
    }
}

再次:dataWithURL没有返回值。关闭后来被称为。