ios - 从 URLSession Completion Handler 函数返回字符串 Swift 3

标签 ios swift swift3 nsurlsession completionhandler

我需要这个函数(它从数据库中获取一些数据)来返回一个字符串,但我不知道如何返回。我发现了一些类似的问题/解决方案,但我仍在努力实现合适的解决方案(我对 swift 还很陌生)

class Helper{
static func pReq(jsonURL : String, col : String) -> String {
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)
    let url  = URL(string: jsonURL)!
    let request = URLRequest(url: url)
    var string = ""

    let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in
        if(error == nil){ 
            print("data = \(String(describing: data))")
            do{
                print(jsonURL)
                let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
                print("dataDownloadedAsJson = \(dataDownloadedAsJson)")
                do{

                    if(dataDownloadedAsJson[col] as? String != nil){
                        string = (dataDownloadedAsJson[col] as? String)!

                    }
                }
            }
            catch{
            }
        }
        else{
            print("Error downloading data. Error = \(String(describing: error))")
        }
    })
    downloadTask.resume()
    return string
}
}

谢谢!

最佳答案

您的 session.dataTask(with: 方法是异步的。这意味着它将“在后台”执行并通知您它何时完成从其调用中获得响应。它会在 session.dataTask(with: 部分内的“{}”下方的 block 内通知您这一点。就像出现的那样,您正在使用您收到的 JSON 并将其格式化为您希望从此函数返回的字符串。但是在您的调用完成之前,您在底部调用了return string ,所以你将什么都不返回 ""。你真正需要做的是不从你的函数返回任何东西,而是使用一个完成 block :

1) 在您的文件顶部声明:

typealias StringCompletion      = (_ success: Bool, _ string: String) -> Void

2) 修改你的函数,为你的完成获取一个参数

// This
static func pReq(jsonURL : String, col : String) -> String

// Becomes This
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion)

3) 在你的函数中调用你的完成并传回一个 Bool 以表明它是一个成功的调用并传回 string 以及

class Helper{
static func pReq(jsonURL : String, col : String, completion: @escaping StringCompletion) {
    let config = URLSessionConfiguration.default
    let session = URLSession(configuration: config)
    let url  = URL(string: jsonURL)!
    let request = URLRequest(url: url)
    var string = ""

    let downloadTask = session.dataTask(with: request, completionHandler: {(data, response, error) in
        if(error == nil){ 
            print("data = \(String(describing: data))")
            do{
                print(jsonURL)
                let dataDownloadedAsJson = try JSONSerialization.jsonObject(with: data!, options: .allowFragments) as! [String:AnyObject]
                print("dataDownloadedAsJson = \(dataDownloadedAsJson)")
                do{

                    if(dataDownloadedAsJson[col] as? String != nil){
                        string = (dataDownloadedAsJson[col] as? String)! 
                        completion(true, string)
                    }
                }
                catch { completion(false, string) }
            }
            catch{
                completion(false, string)
            }
        }
        else{
            print("Error downloading data. Error = \(String(describing: error))")       
            completion(false, string)
        }
    })
    downloadTask.resume()
}
}

4) 用法:

Helper().pReq(jsonURL: jsonURL, col: col) { (success, string) in
    if success {
        print("Success: \(string)")
    }
    else {
        print("Failure: Unable To Get String")
    }
}

关于ios - 从 URLSession Completion Handler 函数返回字符串 Swift 3,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44706119/

相关文章:

Swift 3 - 如何将 NSMutableArray 对象附加到另一个 NSMutableArray

javascript - 尝试将屏幕锁定为纵向。英特尔 XDK 3922

ios - 如何更改 UISearchController 中文本字段的背景颜色?

ios - UICollectionView 渲染得比 Storyboard 中的要高

ios - 相同的数据在 swift 4 中的 UITableView 和 UICollectionView 部分中重复

http请求命令行工具

iphone - 在 iOS 中处理排队的 WebSocket 消息

swift - 在 Flutter 的 VS 代码中更改相应平台的 native 编程语言

ios - 如何有效解析数据

ios - AnyObject 在 Xcode8 beta6 中不工作?