gpt4 book ai didi

swift - 在 NSHTTPURLResponse 下载 JSON 数据失败

转载 作者:搜寻专家 更新时间:2023-11-01 06:19:53 25 4
gpt4 key购买 nike

我正在尝试从 URL 获取 JSON 文件并使用 Swift 返回内容。但是,代码在 let httpResponse = response as! 行失败。以下代码中的 NSHTTPURLResponse。我在这一行遇到异常,Xcode 进入 Debug模式。

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
}

我该如何解决这个问题?

最佳答案

有几个问题:

  1. 如果请求中有任何错误,response 将为nil,因此您尝试强制转换它会导致 fatal error 。处理网络响应时不要使用强制展开/转换。

  2. 这里有一个更深层次的问题,您正试图从异步运行的方法返回数据。您应该更改您的方法,使其本身不返回任何内容,而是提供一个完成处理程序,您可以通过该处理程序异步传回相关数据:

     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()
    }

    然后使用完成处理程序调用它(或使用尾随闭包语法,如下所示):

     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
  3. 请注意,如果您想将错误信息提供回调用例程,您可以将其更改为也返回错误信息,例如:

    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()
    }

    而且,显然,调用会更改为采用两个参数:

    APIClass.downloadJSONFile() { result in
    switch result {
    case .failure(let error):
    print(error)

    case .success(let value):
    // and then it would be like before ...
    }
    }
  4. 在 iOS 9 及更高版本中使用 URLSession 时,它将不允许明文请求(即不允许“http”,默认情况下仅允许“https”)。您可以通过将以下内容添加到您的 info.plist 来强制应用程序允许非 https 请求。参见 https://stackoverflow.com/a/31254874/1271826了解更多信息

     <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>

关于swift - 在 NSHTTPURLResponse 下载 JSON 数据失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35876890/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com