Swift 3:URLSession / URLRequest 不工作
Swift 3: URLSession / URLRequest Not Working
我仍在尝试将我们的应用程序从 Swift 2 转换为 Swift 3,因为我被迫这样做,因为我们所有的 Apple 设备现在都是 运行 iOS 10.
我已经完成了代码转换并认为我做得很好,但是,在尝试调试我的 JSON 问题(发布在另一个问题中)时,我现在正在处理甚至没有发送的请求。
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!)
request.httpBody = requestObject
request.httpMethod = "POST"
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
NSLog("Got here?")
session.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
return
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data)
NSLog("Object: \(object)")
}.resume()
NSLog("Got here 4?")
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
上面的代码产生以下输出:
2016-10-04 13:00:12.011969 OneTouch[1589:623015] [DYMTLInitPlatform] platform initialization successful
2016-10-04 13:00:12.264319 OneTouch[1589:622954] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2016-10-04 13:00:12.265321 OneTouch[1589:622954] [MC] Reading from public effective user settings.
2016-10-04 13:00:12.295055 OneTouch[1589:622954] Got here?
2016-10-04 13:00:12.295445 OneTouch[1589:622954] Got here 4?
2016-10-04 13:00:12.295515 OneTouch[1589:622954] End of getUser
(lldb)
这意味着甚至没有提出请求。有没有我必须再次添加到 PLIST 的密钥?这开始变得烦人了。
下面是我的旧代码,它甚至不再工作了:
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
let request = NSMutableURLRequest(url: URL(string: "http://domain.tld/path/" as String)!, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
NSLog("Got here?")
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
if error != nil {
NSLog("Got here 2?")
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data!)
NSLog("Object: \(object)")
})
NSLog("Got here 4?")
task.resume()
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
上面的代码产生与其他代码相同的输出!
如果您在调用 getUser
后立即设置断点,URLSession
任务的完成处理程序是异步的 运行(即通常稍后完成,除非请求立即失败或被对某些缓存响应感到满意)可能没有机会被调用。
如果您在 dataTask
完成处理程序中放置一个断点,您应该会在该点看到您的数据。
就我个人而言,我会确保为 getUser
提供一个完成处理程序,以便您知道它何时完成:
func getUser(completionHandler: @escaping (JSON?, Error?) -> Void) {
let params = [
"email":"\(preferences.string(forKey: "preference_email")!)"
]
let requestParams: [String: Any] = [
"action": "601",
"params": params
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams)
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
completionHandler(JSON(data: data), nil)
}
task.resume()
} catch {
completionHandler(nil, error)
}
}
然后当你调用它时,你可以这样做:
getUser { json, error in
guard let json = json else {
print(error)
return
}
// do something with json
print(json)
}
然后将断点放在 getUser
的完成处理程序中。请记住,您无法保证完成处理程序是否会 运行 在主队列中,因此您需要确保将 UI 或模型更新分派回主队列。
我仍在尝试将我们的应用程序从 Swift 2 转换为 Swift 3,因为我被迫这样做,因为我们所有的 Apple 设备现在都是 运行 iOS 10.
我已经完成了代码转换并认为我做得很好,但是,在尝试调试我的 JSON 问题(发布在另一个问题中)时,我现在正在处理甚至没有发送的请求。
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!)
request.httpBody = requestObject
request.httpMethod = "POST"
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config)
NSLog("Got here?")
session.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
print("error=\(error)")
return
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data)
NSLog("Object: \(object)")
}.resume()
NSLog("Got here 4?")
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
上面的代码产生以下输出:
2016-10-04 13:00:12.011969 OneTouch[1589:623015] [DYMTLInitPlatform] platform initialization successful
2016-10-04 13:00:12.264319 OneTouch[1589:622954] [MC] System group container for systemgroup.com.apple.configurationprofiles path is /private/var/containers/Shared/SystemGroup/systemgroup.com.apple.configurationprofiles
2016-10-04 13:00:12.265321 OneTouch[1589:622954] [MC] Reading from public effective user settings.
2016-10-04 13:00:12.295055 OneTouch[1589:622954] Got here?
2016-10-04 13:00:12.295445 OneTouch[1589:622954] Got here 4?
2016-10-04 13:00:12.295515 OneTouch[1589:622954] End of getUser
(lldb)
这意味着甚至没有提出请求。有没有我必须再次添加到 PLIST 的密钥?这开始变得烦人了。
下面是我的旧代码,它甚至不再工作了:
let params: [String:AnyObject] = [
"email":"\(self.preferences.string(forKey: "preference_email")!)" as AnyObject
]
let requestParams: [String:AnyObject] = [
"action":"601" as AnyObject,
"params":params as AnyObject
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams, options:[])
let request = NSMutableURLRequest(url: URL(string: "http://domain.tld/path/" as String)!, cachePolicy:NSURLRequest.CachePolicy.reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
NSLog("Got here?")
let task = URLSession.shared.dataTask(with: request as URLRequest, completionHandler: {data, response, error in
if error != nil {
NSLog("Got here 2?")
}
NSLog("Got here 3?")
let object:JSON = JSON(data:data!)
NSLog("Object: \(object)")
})
NSLog("Got here 4?")
task.resume()
} catch {
NSLog("Got here catch?")
}
NSLog("End of getUser")
上面的代码产生与其他代码相同的输出!
如果您在调用 getUser
后立即设置断点,URLSession
任务的完成处理程序是异步的 运行(即通常稍后完成,除非请求立即失败或被对某些缓存响应感到满意)可能没有机会被调用。
如果您在 dataTask
完成处理程序中放置一个断点,您应该会在该点看到您的数据。
就我个人而言,我会确保为 getUser
提供一个完成处理程序,以便您知道它何时完成:
func getUser(completionHandler: @escaping (JSON?, Error?) -> Void) {
let params = [
"email":"\(preferences.string(forKey: "preference_email")!)"
]
let requestParams: [String: Any] = [
"action": "601",
"params": params
]
do {
let requestObject = try JSONSerialization.data(withJSONObject: requestParams)
var request = URLRequest(url: URL(string: "http://domain.tld/path/")!, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 20)
request.httpBody = requestObject
request.httpMethod = "POST"
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request) {data, response, error in
guard let data = data, error == nil else {
completionHandler(nil, error)
return
}
completionHandler(JSON(data: data), nil)
}
task.resume()
} catch {
completionHandler(nil, error)
}
}
然后当你调用它时,你可以这样做:
getUser { json, error in
guard let json = json else {
print(error)
return
}
// do something with json
print(json)
}
然后将断点放在 getUser
的完成处理程序中。请记住,您无法保证完成处理程序是否会 运行 在主队列中,因此您需要确保将 UI 或模型更新分派回主队列。