Swift URL 会话和 URL 请求无效
Swift URL Session and URL Request not working
我遇到的问题与 非常相似,但我不完全理解答案。我已经创建了一个完成处理程序,但它似乎没有按预期工作。
func updateTeam(teamID: Int) {
startConnection {NSArray, Int in
//Do things with NSArray
}
}
func startConnection(completion: (NSArray, Int) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
dataTask.resume()
completion(NSArray(object: teamResult), Int(teamInput.text!)!)
}
dataTask 语句中似乎没有任何内容 运行,或者至少在我尝试使用结果数据之前它没有完成。这个完成处理程序有什么问题?
提前致谢!
我认为您还应该处理关闭时的错误。
func updateTeam(teamID: Int) {
startConnection {array, teamId, error in
// Do things with NSArray or handle error
}
}
func startConnection(completion: @escaping (NSArray?, Int, Error?) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
DispatchQueue.main.async() {
completion(NSArray(object: self.teamResult), Int(teamInput.text!)!, nil)
}
} catch let error as NSError {
print(error.localizedDescription)
DispatchQueue.main.async() {
completion(nil, Int(teamInput.text!)!, error)
}
}
}
dataTask.resume()
}
您的代码结构不正确。
URLSession
创建异步任务 运行。您设置一个任务,然后传入一个完成块,或者设置一个委托。
task.resume() 立即调用 returns,远远早于网络下载完成。
任务完成后,系统会调用您的完成处理程序(或您的委托,如果您使用委托样式)。
请注意,URLSession 的完成处理程序和委托调用是在后台线程上完成的。如果您执行任何 UIKit 调用以响应任务完成,则需要在主线程上执行。
正如@keithbhunter 在他的评论中所说,您需要将对完成处理程序的调用放在任务的完成处理程序中。如果将整个完成处理程序调用包装在对主线程的调用中,这可能是最安全的:
func startConnection(completion: (NSArray, Int) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
//Use GCD to invoke the completion handler on the main thread
DispatchQueue.main.async() {
completion(NSArray(object: teamResult), Int(teamInput.text!)!)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
dataTask.resume()
}
请注意,您对 teamInput.text 的强制展开非常脆弱,如果 teamInput.text 为 nil 或无法将其转换为 Int,则会崩溃。你最好编写你的完成处理程序来为你从 teamInput.text:
返回的数据和 int 值取可选项
func startConnection(completion: (NSArray?, Int?) -> Void) {
并调用它传入一个可选的:
let value: Int? = teamInput.text != nil ? Int(teamInput.text!) : nil
completion(NSArray(object: teamResult), value)
试试这个:
let urlString = "www.yoururl.com"
let url = URL(string: string.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
这对我有很多帮助
我遇到的问题与
func updateTeam(teamID: Int) {
startConnection {NSArray, Int in
//Do things with NSArray
}
}
func startConnection(completion: (NSArray, Int) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
dataTask.resume()
completion(NSArray(object: teamResult), Int(teamInput.text!)!)
}
dataTask 语句中似乎没有任何内容 运行,或者至少在我尝试使用结果数据之前它没有完成。这个完成处理程序有什么问题?
提前致谢!
我认为您还应该处理关闭时的错误。
func updateTeam(teamID: Int) {
startConnection {array, teamId, error in
// Do things with NSArray or handle error
}
}
func startConnection(completion: @escaping (NSArray?, Int, Error?) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
DispatchQueue.main.async() {
completion(NSArray(object: self.teamResult), Int(teamInput.text!)!, nil)
}
} catch let error as NSError {
print(error.localizedDescription)
DispatchQueue.main.async() {
completion(nil, Int(teamInput.text!)!, error)
}
}
}
dataTask.resume()
}
您的代码结构不正确。
URLSession
创建异步任务 运行。您设置一个任务,然后传入一个完成块,或者设置一个委托。
task.resume() 立即调用 returns,远远早于网络下载完成。
任务完成后,系统会调用您的完成处理程序(或您的委托,如果您使用委托样式)。
请注意,URLSession 的完成处理程序和委托调用是在后台线程上完成的。如果您执行任何 UIKit 调用以响应任务完成,则需要在主线程上执行。
正如@keithbhunter 在他的评论中所说,您需要将对完成处理程序的调用放在任务的完成处理程序中。如果将整个完成处理程序调用包装在对主线程的调用中,这可能是最安全的:
func startConnection(completion: (NSArray, Int) -> Void) {
let url = URL(string: "http://www.example.com/path")
var request : URLRequest = URLRequest(url: url!)
request.httpMethod = "POST"
let postString = "a=\(Int(teamInput.text!)!)"
request.httpBody = postString.data(using: .utf8)
let dataTask = URLSession.shared.dataTask(with: request) {
data,response,error in
print("anything")
do {
if let jsonResult = try JSONSerialization.jsonObject(with: data!, options: []) as? NSDictionary {
self.teamResult = jsonResult
print(jsonResult)
//Use GCD to invoke the completion handler on the main thread
DispatchQueue.main.async() {
completion(NSArray(object: teamResult), Int(teamInput.text!)!)
}
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
dataTask.resume()
}
请注意,您对 teamInput.text 的强制展开非常脆弱,如果 teamInput.text 为 nil 或无法将其转换为 Int,则会崩溃。你最好编写你的完成处理程序来为你从 teamInput.text:
返回的数据和 int 值取可选项func startConnection(completion: (NSArray?, Int?) -> Void) {
并调用它传入一个可选的:
let value: Int? = teamInput.text != nil ? Int(teamInput.text!) : nil
completion(NSArray(object: teamResult), value)
试试这个:
let urlString = "www.yoururl.com"
let url = URL(string: string.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!)
这对我有很多帮助