我可以在带有 return 的函数中使用 URLSession 吗?
Can I use URLSession in a function with return?
我有这个功能可以从 MySQL 数据库中恢复玩家得分。从其他教程中,我发现 URLSession 方法在从应用程序发送数据时很有用,但我真的可以在任何地方使用函数的 return 吗?一直在寻找类似
的东西
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?昨晚尝试了一些东西,但卡在 data = NSData 请求类型 URL 而不是我的 NSMutableURLRequest。
应该提到我创建了全局变量并在第一个函数中追加,但结果在使用后恢复,一旦它们被填充我就找不到延迟或刷新的方法。我不介意应用程序等待它们,因为它们在 viewDidLoad() 之后使用。
您不能 return 因为网络请求是异步发生的。不要使用 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
}
我创建了一个小示例来展示输入、return 和异步完成之间的区别。将其粘贴到您的 playground 中并进行实验。
您会先看到 'passed in' 打印件。
接着是return。
并在异步完成时最后完成。
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://whosebug.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)
})
我有这个功能可以从 MySQL 数据库中恢复玩家得分。从其他教程中,我发现 URLSession 方法在从应用程序发送数据时很有用,但我真的可以在任何地方使用函数的 return 吗?一直在寻找类似
的东西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?昨晚尝试了一些东西,但卡在 data = NSData 请求类型 URL 而不是我的 NSMutableURLRequest。
应该提到我创建了全局变量并在第一个函数中追加,但结果在使用后恢复,一旦它们被填充我就找不到延迟或刷新的方法。我不介意应用程序等待它们,因为它们在 viewDidLoad() 之后使用。
您不能 return 因为网络请求是异步发生的。不要使用 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
}
我创建了一个小示例来展示输入、return 和异步完成之间的区别。将其粘贴到您的 playground 中并进行实验。
您会先看到 'passed in' 打印件。
接着是return。
并在异步完成时最后完成。
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://whosebug.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)
})