【问题标题】:Swift: URLSession Completion HandlersSwift:URLSession 完成处理程序
【发布时间】:2017-12-29 09:51:17
【问题描述】:

我正在尝试使用在 Xcode 游乐场文件中工作的一段代码从本地服务器获取一些数据:

       URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) -> Void in


            if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
                friend_ids = (jsonObj!.value(forKey: "friends") as? NSArray)!
            }

        }).resume()

return friend_ids

在阅读了有关此主题的一些类似问题后,我知道 URLSession 是异步运行的,因此该函数在从服务器获取任何数据之前返回 nil 值。我还认为我理解完成处理程序可用于确保在继续之前实际获取数据,但不幸的是我并不能真正理解如何实现一个。是否有人可以向我展示如何在这个简单的示例中使用完成处理程序,以确保在返回变量之前从服务器获取?

谢谢!

【问题讨论】:

    标签: swift completionhandler urlsession


    【解决方案1】:

    如果你有一个函数本身在做异步工作,它就不能有一个返回值来表示异步工作的结果(因为函数返回是立即的)。因此,做异步工作的函数必须将闭包作为参数,接受预期的结果,并在异步工作完成时调用。因此,对于您的代码:

    func getFriendIds(completion: @escaping (NSArray) -> ()) {
        URLSession.shared.dataTask(with: url!, completionHandler: {(data, response, error) -> Void in
            if let jsonObj = try? JSONSerialization.jsonObject(with: data!, options: .allowFragments) as? NSDictionary {
                friend_ids = (jsonObj!.value(forKey: "friends") as? NSArray)!
                completion(friend_ids) // Here's where we call the completion handler with the result once we have it
            }
        }).resume()
    }
    
    //USAGE:
    
    getFriendIds(completion:{
        array in
        print(array) // Or do something else with the result
    })
    

    【讨论】:

    • 我试过这个,但它似乎忽略了完成块。如果我逐行执行,它只是从 URLSession 行到 resume 行两次,然后退出函数?
    • 您要检索哪个 URL?请求可能超时或失败。特别是如果 URL 是 http:// 而不是 https://,在这种情况下它将被 iOS App Transport Security 阻止,除非您创建异常。任何信息打印到控制台?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-05-03
    • 2015-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多