Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 在NSURLConnection中建立错误案例,在Swift中建立JSON解析_Ios_Json_Swift - Fatal编程技术网

Ios 在NSURLConnection中建立错误案例,在Swift中建立JSON解析

Ios 在NSURLConnection中建立错误案例,在Swift中建立JSON解析,ios,json,swift,Ios,Json,Swift,我试图从我网站上的JSON中提取信息。这样做时,如果连接有错误,它应该返回该错误并将其记录到控制台。我遇到的问题是,如果我更多地打开飞机或以其他方式丢失信号,错误:致命错误:在展开可选值时意外发现nil会使应用程序崩溃。当我设置了简单记录错误的条件时,为什么它会返回这个?提前谢谢你 我不确定为什么没有记录错误并防止应用程序崩溃。任何指示都会有帮助 JSONLoader.swift import Foundation var arrayOfMeals: [Meal] = [Meal]() var

我试图从我网站上的JSON中提取信息。这样做时,如果连接有错误,它应该返回该错误并将其记录到控制台。我遇到的问题是,如果我更多地打开飞机或以其他方式丢失信号,错误:
致命错误:在展开可选值时意外发现nil
会使应用程序崩溃。当我设置了简单记录错误的条件时,为什么它会返回这个?提前谢谢你

我不确定为什么没有记录错误并防止应用程序崩溃。任何指示都会有帮助

JSONLoader.swift

import Foundation

var arrayOfMeals: [Meal] = [Meal]()
var weekDayArray = ["monday"]


func getJSON(urlToRequest: String) -> NSDictionary {

    var url: NSURL = NSURL(string: urlToRequest)!
    var jsonRequest: NSURLRequest = NSURLRequest(URL: url)
    var jsonResponse: AutoreleasingUnsafeMutablePointer<NSURLResponse?> = nil

    var error: NSError?
    var dataValue: NSData =  NSURLConnection.sendSynchronousRequest(jsonRequest, returningResponse: jsonResponse, error:&error)!

    if error? == nil {
        var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(dataValue, options: NSJSONReadingOptions.MutableContainers , error: &error) as NSDictionary
        NSURLRequestCachePolicy.ReloadIgnoringLocalAndRemoteCacheData
        if error? == nil {
            return jsonResult
        }
        else {
            return NSDictionary(object: "Error: Something with parsing went wrong :(", forKey: "error")
        }
    }
    else {
        return NSDictionary(object: "Error: There was an error with your connection :(", forKey: "error")
    }

}

func loadJSON(jsonDictionary: NSDictionary) {

    for days in weekDayArray{
        var resultsArray = jsonDictionary[days] as NSArray
        for obj: AnyObject in resultsArray{
            let breakfast = (obj.objectForKey("breakfast")! as String)
            let lunch = (obj.objectForKey("lunch")! as String)
            let dinner = obj.objectForKey("dinner")! as String
            let dateString = obj.objectForKey("dateString")! as String
            let dayOfWeek = obj.objectForKey("dayOfWeek")! as String
            let newMeal = Meal(breakfast: breakfast, lunch: lunch, dinner: dinner, dayOfWeek: dayOfWeek, dateString: dateString)
            if theDays(newMeal.dateString) >= 0 {
                arrayOfMeals.append(newMeal)
            }
        }
    }


}
MealModel.swift-创建膳食实例

class Meal {

    let breakfast: String
    let lunch: String
    let dinner: String
    let dayOfWeek: String
    let dateString: String

    init(breakfast: String, lunch: String, dinner: String, dayOfWeek: String, dateString: String) {

        self.breakfast = breakfast
        self.lunch = lunch
        self.dinner = dinner
        self.dayOfWeek = dayOfWeek
        self.dateString = dateString

    }

}

如何防止应用程序在未能建立连接并将错误消息记录到控制台时崩溃?再次感谢。

关键观察结果是,在调用
sendSynchronousRequest
检索
NSData
时,您已将
NSData
定义为非可选,并添加了
将强制展开可选返回值。因此,如果可选的
NSData
nil
(如果存在任何网络问题,就会发生这种情况),则此代码将失败

相反,您只需将
NSData
保留为可选项(即
NSData?
),并在尝试打开它之前检查它是否为
nil
。因此,我可以提出如下建议:

func retrieveJSON(urlToRequest: String) -> NSDictionary {

    let url: NSURL = NSURL(string: urlToRequest)!
    let jsonRequest: NSURLRequest = NSURLRequest(URL: url)

    var jsonResponse: NSURLResponse?
    var error: NSError?
    let dataValue = NSURLConnection.sendSynchronousRequest(jsonRequest, returningResponse: &jsonResponse, error:&error)

    if dataValue != nil {
        if let jsonResult = NSJSONSerialization.JSONObjectWithData(dataValue!, options: .MutableContainers, error: &error) as? NSDictionary {
            return jsonResult
        } else {
            return [
                "error": "Error: Something with parsing went wrong :(",
                "localizedDescription": error?.localizedDescription ?? ""
            ];
        }
    }
    else {
        return [
            "error": "Error: There was an error with your connection :(",
            "localizedDescription": error?.localizedDescription ?? ""
        ];
    }
}
上述内容将修复因强制展开可选的
NSData
而导致的崩溃,如果存在网络问题,该数据将为
nil
。注意,您没有向我们显示调用
getJSON
然后随后调用
loadJSON
的代码,但我假设您正在进行必要的错误处理检查

注意,我还取消了笨拙的
autoreleasingusafemutablepointer
构造。我还将错误的
localizedDescription
添加到正在返回的字典中

就个人而言,我通常会返回完整的
NSError
对象和
nsurresponse
对象,以便调用方能够诊断错误的确切性质,而不仅仅是文本描述


在对代码进行更激进的编辑时,我建议您通常避免同步请求。永远不要执行来自主线程的同步请求

例如,您可以定义异步执行请求的方法,如下所示:

func retrieveJSON(urlToRequest: String, completionHandler:(responseObject: NSDictionary?, error: NSError?) -> ()) {

    let url: NSURL = NSURL(string: urlToRequest)!
    let jsonRequest: NSURLRequest = NSURLRequest(URL: url)

    var jsonResponse: NSURLResponse?
    NSURLConnection.sendAsynchronousRequest(jsonRequest, queue: NSOperationQueue.mainQueue()) {
        response, data, error in

        if data == nil {
            completionHandler(responseObject: nil, error: error)
        } else {
            var parseError: NSError?
            let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &parseError) as NSDictionary?
            completionHandler(responseObject: jsonResult, error: error)
        }
    }
}
retrieveJSON(urlString) {
    responseObject, error in

    if responseObject == nil {
        // handle error here, e.g.

        println(error)
        return
    }

    // handle successful the `NSDictionary` object, `responseObject`, here
}

// but don't try to use the object here, because the above runs asynchronously
然后使用“尾随闭包语法”调用它,如下所示:

func retrieveJSON(urlToRequest: String, completionHandler:(responseObject: NSDictionary?, error: NSError?) -> ()) {

    let url: NSURL = NSURL(string: urlToRequest)!
    let jsonRequest: NSURLRequest = NSURLRequest(URL: url)

    var jsonResponse: NSURLResponse?
    NSURLConnection.sendAsynchronousRequest(jsonRequest, queue: NSOperationQueue.mainQueue()) {
        response, data, error in

        if data == nil {
            completionHandler(responseObject: nil, error: error)
        } else {
            var parseError: NSError?
            let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error: &parseError) as NSDictionary?
            completionHandler(responseObject: jsonResult, error: error)
        }
    }
}
retrieveJSON(urlString) {
    responseObject, error in

    if responseObject == nil {
        // handle error here, e.g.

        println(error)
        return
    }

    // handle successful the `NSDictionary` object, `responseObject`, here
}

// but don't try to use the object here, because the above runs asynchronously

非常感谢您的回答-我正在用retrieveJSON实现您回答的后半部分。您提到没有在闭包中使用对象,因为它是异步运行的。这有什么特别糟糕的?此外,我是否应该简单地返回NSDictionary的内容以便在其他地方实现?很抱歉问了这么多问题。我曾经在应用程序中使用过JSON文件,但由于必须请求数据,因此引入了一组全新的特性,我正试图熟悉这些特性。再次感谢你,罗伯。