首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在NSHTTPURLResponse下载JSON数据失败

在NSHTTPURLResponse下载JSON数据失败
EN

Stack Overflow用户
提问于 2016-03-08 19:57:52
回答 1查看 2.6K关注 0票数 1

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

代码语言:javascript
复制
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
    }

我怎么才能解决这个问题?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-08 22:37:52

有几个问题:

  1. 如果请求中有任何错误,response将是nil,因此您试图强制转换它将导致致命错误。在处理网络响应时,不要使用强制展开/强制转换。
  2. 这里还有一个更深层次的问题,您试图从异步运行的方法返回数据。您应该更改您的方法,使其本身不返回任何内容,而是提供一个完成处理程序,通过该处理程序可以异步地传回相关数据: 类func downloadJSONFile(completionHandler:@转义(任意?) -> Void) { let requestURL =URL(字符串:“http://www.learnswiftonline.com/Samples/subway.json"”)!让urlRequest = URLRequest(url: requestURL)让会话= URLSession.shared let任务=session.dataTask(有: urlRequest) {数据、响应、//检查中的基本网络错误保护错误==为零,让数据=其他数据{打印(错误?(“其他错误”) completionHandler(nil)返回} httpResponse = response?HTTPURLResponse,(200 ..< 300) ~= httpResponse.statusCode catch { print(“无效状态代码”) completionHandler(nil)返回} do { let json = try JSONSerialization.jsonObject(with: data) completionHandler(json) } else {print(错误解析:(ParseError)) completionHandler(nil) } task.resume() } 然后调用它,使用完成处理程序(或者使用尾随闭包语法,如下所示): APIClass.downloadJSONFile() { json in守护json != nil back {print(“出现了一些问题”)返回} //现在您可以在这里使用json dispatch_async(dispatch_get_main_queue()) { //,如果您正在进行任何模型或UI更新,则将其分派回主队列} //,但不要在这里使用json,因为上面的操作异步运行。
  3. 注意,如果您希望将错误信息返回到调用例程,则可以将其更改为还返回错误信息,例如: 枚举DownloadError: Error { case networkError(错误) case notHTTPResponse case invalidHTTPResponse(Int) case parseError(错误)}类func downloadJSONFile(completionHandler:@转义(Result) -> Void) { let requestURL =URL(字符串:“http://www.learnswiftonline.com/Samples/subway.json"”)!设urlRequest = URLRequest(url: requestURL)让session = URLSession.shared let任务= session.dataTask(with: urlRequest) { data,response,error in if let error = error {requestURL返回}保护let httpResponse = response as?HTTPURLResponse,让数据=数据其他{ completionHandler(.failure(DownloadError.notHTTPResponse))返回}保护200 ..< 300 ~= httpResponse.statusCode guard { completionHandler(.failure(DownloadError.invalidHTTPResponse(httpResponse.statusCode)))返回} do { let json = try JSONSerialization.jsonObject(with: data) completionHandler(.success())让completionHandler(.failure(DownloadError.parseError(parseError))) { parseError } task.resume() } 而且,很明显,调用将改变为接受这两个参数: APIClass.downloadJSONFile() {导致切换结果{ case .failure(let error):print(error) case .success(let value)://,然后它将类似于.}
  4. URLSession 9和更高版本中使用iOS时,它将不允许明文请求(即不允许"http“,默认情况下只有"https”)。通过向info.plist添加以下内容,您可以强制应用程序允许非https请求。有关更多信息,请参见https://stackoverflow.com/a/31254874/1271826 NSAppTransportSecurity NSExceptionDomains learnswiftonline.com NSIncludesSubdomains NSTemporaryExceptionAllowsInsecureHTTPLoads NSTemporaryExceptionMinimumTLSVersion TLSv1.1
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/35876890

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档