我可以在带返回的函数中使用URLSession吗?

时间:2017-02-16 15:59:39

标签: ios swift swift3 nsurlsession

我有这个功能从MySQL数据库中恢复玩家得分。从其他教程中,我发现在从应用程序发送数据时,URLSession方法很有用,但是我能在任何地方实际使用函数的返回吗?保持搜索类似

的东西
task.resume() 
task.end()
return (rank, name, score)

func downloadLocalScores(_ choice: Int) -> ([String], [String], [String]) {
    var url: URL
    let id: String = getUserID("id")
    if choice == 0 {
        url = NSURL(string: "myPHPscript.php")! as URL
    } else {
        url = NSURL(string: "myPHPscript2.php")! as URL
    }
    let request = NSMutableURLRequest(url: url)
    request.httpMethod = "POST"
    let postString = "id=\(id)"
    request.httpBody = postString.data(using: String.Encoding.utf8)
    var name: [String] = []
    var score: [String] = []
    var rank: [String] = []
    if Reachability().isInternetAvailable() == true {
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in
            if error == nil {
                let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                let variables = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray
                for i in 0..<variables.count {
                    let level = variables[i] as! [String:AnyObject]
                    name.append(level["name"] as! String)
                    score.append(level["score"] as! String)
                    rank.append(level["rank"] as! String)
                }
            } else {
                print(error)
            }
        }
        task.resume()
        return (rank, name, score)
    } else {
        return (["NO CONNECTION"], ["0"])
    }
}

我有另一个下载分数的功能,但是要求获得最高分,不需要从应用中获取任何输入

func downloadScores(_ choice: Int) -> ([String], [String]) {
var url: URL
if choice == 0 {
     url = NSURL(string: "myPHPscript.php")! as URL
} else {
     url = NSURL(string: "myPHPscript2.php")! as URL
}
let data = NSData(contentsOf: url)
var variables: NSArray = []
if Reachability().isInternetAvailable() == true {
    variables = try! JSONSerialization.jsonObject(with: data! as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSArray

    var name: [String] = []
    var score: [String] = []

    for i in 0..<variables.count {
        let level = variables[i] as! [String:AnyObject]
        name.append(level["name"] as! String)
        score.append(level["score"] as! String)
    }
    return (name, score)
} else {
    return (["No connection"], [""])
}

}

我仍然不完全熟悉从我的应用程序发送数据的其他选项,所以最后的功能是否可以适应POST?昨晚尝试了一些东西但是卡在了数据= NSData,要求输入类型的URL而不是我的NSMutableURLRequest。

应该提到我创建了全局变量并在第一个函数中追加,但结果在使用后会被恢复,一旦填充后我找不到延迟或刷新的方法。我不介意app等待它们,因为它们在viewDidLoad()之后使用。

2 个答案:

答案 0 :(得分:0)

您无法返回,因为网络请求是异步发生的。而不是使用return,使用在请求完成时调用的闭包。请查看以下内容:

func sendRequest(_ _request:URLRequest, completion:@escaping (_ success:Bool,_ error:Error?, _ _data:[String:AnyObject]?)->Void) -> URLSessionDataTask {
    let session:URLSession = URLSession(configuration: URLSessionConfiguration.default, delegate: nil, delegateQueue: self.queue)
    let task:URLSessionDataTask = session.dataTask(with: _request) { (_data, _response, _error) in
        if let resultsDic:[String:AnyObject] = self.parseJSONFromData(retrievedData, withInitalKey: self.getInitialKey()){
            completion(true, nil, resultsDic)
        } else {
            completion(false, nil, nil)
        }
    }
    task.resume()
    return task
}

答案 1 :(得分:0)

我创建了一个小例子来显示输入,返回和异步完成之间的区别。将其粘贴到您的游乐场并进行实验。

你会看到传入&#39;首先打印。

接下来是回归。

异步完成后,最后完成。

import UIKit
import PlaygroundSupport
import Foundation

func getStuffFromServer(_ passedIn: String, completion: @escaping (_ completion: String)->()) -> String {

    print(passedIn)

    PlaygroundPage.current.needsIndefiniteExecution = true

    URLSession.shared.dataTask(with: URL(string: "http://stackoverflow.com")!) {
    result in

        completion("I've completed")

        PlaygroundPage.current.finishExecution()

    }.resume()

    let returnValue = "I'm being returned"
    print(returnValue)
    return returnValue
}

let returned = getStuffFromServer("I'm passed in", completion: { completion in
    print(completion)
})