Jak*_*ake 1 nsjsonserialization nsurlsession swift
我正在尝试从 URL 获取 JSON 文件并使用 Swift 返回内容。但是,代码let httpResponse = response as! NSHTTPURLResponse 在以下代码中的行失败。我在这一行遇到异常,Xcode 进入调试模式。
class func downloadJSONFile()->AnyObject
{
let requestURL: NSURL = NSURL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
let urlRequest: NSMutableURLRequest = NSMutableURLRequest(URL: requestURL)
let session = NSURLSession.sharedSession()
var json:AnyObject = ""
let task = session.dataTaskWithRequest(urlRequest) {
(data, response, error) -> Void in
let httpResponse = response as! NSHTTPURLResponse
let statusCode = httpResponse.statusCode
if (statusCode == 200) {
do{
json = try NSJSONSerialization.JSONObjectWithData(data!, options:.AllowFragments)
}catch {
print("Error with Json: \(error)")
}
}
}
task.resume()
return json
}
Run Code Online (Sandbox Code Playgroud)
我怎样才能解决这个问题?
有几个问题:
如果请求中有任何错误,responsewill nil,因此您尝试强制转换它会导致致命错误。处理网络响应时不要使用强制解包/强制转换。
这里有一个更深层次的问题,即您试图从异步运行的方法中返回数据。您应该更改您的方法,使其本身不返回任何内容,而是提供一个完成处理程序,您可以通过它异步传回相关数据:
class func downloadJSONFile(completionHandler: @escaping (Any?) -> Void) {
let requestURL = URL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
let urlRequest = URLRequest(url: requestURL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest) { data, response, error in
// check for fundamental networking errors
guard
error == nil,
let data = data
else {
print(error ?? "Other error")
completionHandler(nil)
return
}
guard
let httpResponse = response as? HTTPURLResponse,
(200 ..< 300) ~= httpResponse.statusCode
else {
print("Invalid status code")
completionHandler(nil)
return
}
do {
let json = try JSONSerialization.jsonObject(with: data)
completionHandler(json)
} catch let parseError {
print("Error parsing: \(parseError)")
completionHandler(nil)
}
}
task.resume()
}
Run Code Online (Sandbox Code Playgroud)
然后使用完成处理程序调用它(或使用尾随闭包语法,如下所示):
APIClass.downloadJSONFile() { json in
guard json != nil else {
print("there was some problem")
return
}
// now you can use `json` here
dispatch_async(dispatch_get_main_queue()) {
// and if you're doing any model or UI updates, dispatch that back to the main queue
}
}
// but do not use `json` here, as the above runs asynchronously
Run Code Online (Sandbox Code Playgroud)
请注意,如果您想将错误信息提供回调用例程,您可以将其更改为也返回错误信息,例如:
enum DownloadError: Error {
case networkError(Error)
case notHTTPResponse
case invalidHTTPResponse(Int)
case parseError(Error)
}
class func downloadJSONFile(completionHandler: @escaping (Result<Any, Error>) -> Void) {
let requestURL = URL(string: "http://www.learnswiftonline.com/Samples/subway.json")!
let urlRequest = URLRequest(url: requestURL)
let session = URLSession.shared
let task = session.dataTask(with: urlRequest) { data, response, error in
if let error = error {
completionHandler(.failure(DownloadError.networkError(error)))
return
}
guard let httpResponse = response as? HTTPURLResponse, let data = data else {
completionHandler(.failure(DownloadError.notHTTPResponse))
return
}
guard 200 ..< 300 ~= httpResponse.statusCode else {
completionHandler(.failure(DownloadError.invalidHTTPResponse(httpResponse.statusCode)))
return
}
do {
let json = try JSONSerialization.jsonObject(with: data)
completionHandler(.success(json))
} catch let parseError {
completionHandler(.failure(DownloadError.parseError(parseError)))
}
}
task.resume()
}
Run Code Online (Sandbox Code Playgroud)
而且,显然,调用将更改为采用两个参数:
APIClass.downloadJSONFile() { result in
switch result {
case .failure(let error):
print(error)
case .success(let value):
// and then it would be like before ...
}
}
Run Code Online (Sandbox Code Playgroud)
当使用URLSession在IOS 9和后,它不会允许明文请求(即“HTTP”是不允许的,只有“HTTPS”是,默认情况下)。您可以通过将以下内容添加到您的info.plist. 有关更多信息,请参阅/sf/answers/2187841211/
<key>NSAppTransportSecurity</key>
<dict>
<key>NSExceptionDomains</key>
<dict>
<key>learnswiftonline.com</key>
<dict>
<!--Include to allow subdomains-->
<key>NSIncludesSubdomains</key>
<true/>
<!--Include to allow HTTP requests-->
<key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
<true/>
<!--Include to specify minimum TLS version-->
<key>NSTemporaryExceptionMinimumTLSVersion</key>
<string>TLSv1.1</string>
</dict>
</dict>
</dict>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2121 次 |
| 最近记录: |