为什么我会收到错误' Domain = NSCocoaErrorDomain Code = 3840"没有值。" UserInfo = {NSDebugDescription =没有价值。}'?

时间:2016-10-02 18:40:20

标签: ios mysql json swift xcode

我是Swift和iOS开发的新手,但我正在尝试下载和解析存储在MySQL数据库中的数据。

我一直收到错误:

  

Domain = NSCocoaErrorDomain Code = 3840"没有值。" UserInfo = {NSDebugDescription =无值。}

我已在下面发布了我的代码,但我不认为问题出在parseJSON函数中,而是在实际下载数据时,就像打印数据时一样。它返回'<>'。

这是我的代码:

//properties

weak var delegate: HomeModelProtocal!

var data : NSMutableData = NSMutableData()

let urlPath: String = "http://localhost/service.php" //this will be changed to the path where service.php lives

// Function to download the incoming JSON data
func downloadItems(){
    let url: URL = URL(string: urlPath)!
    var session: URLSession!
    let configuration = URLSessionConfiguration.default


    session = URLSession(configuration: configuration, delegate: self, delegateQueue: nil)

    let task = session.dataTask(with: url)

    task.resume()
}

func urlSession(_ session: URLSession, task: URLSessionDataTask, didCompleteWithError error: Error?) {
    self.data.append(data as Data)
}

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
    if error != nil{
        print("Failed to download data")
    }else{
        print("Data downloaded")
        print(data)
        self.parseJSON()
    }
}

func parseJSON(){

    var jsonResult: NSMutableArray = NSMutableArray()

    do{
        jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options: []) as! NSMutableArray
    } catch let error as NSError {
        print("**** sake its happened again \(error)")
    }

    var jsonElement: NSDictionary = NSDictionary()
    let locations: NSMutableArray = NSMutableArray()

    for i in 0 ..< jsonResult.count{
        jsonElement = jsonResult[i] as! NSDictionary

        let location = LocationModel()

        //the following insures none of the JsonElement values are nil through optional binding
        if let exerciseName = jsonElement["stationName"] as? String,
            let bodyPart = jsonElement["buildYear"] as? String
        {
            print(exerciseName, bodyPart)
            location.exerciseName = exerciseName
            location.bodyPart = bodyPart

        }

        locations.add(location)

    }

    DispatchQueue.main.async(execute: { () -> Void in

        self.delegate.itemsDownloaded(items:locations)

    })
}

1 个答案:

答案 0 :(得分:1)

代码特别糟糕:

//This method is not being called...
func urlSession(_ session: URLSession, task: URLSessionDataTask, didCompleteWithError error: Error?) {
    self.data.append(data as Data) //<-This line adding self.data to self.data
}

没有urlSession(_:task:didCompleteWithError:)方法将URLSessionDataTask作为其第二个参数。因此,永远不会调用此方法。

在方法中,self.data附加到self.data,因此即使调用该方法,self.data仍为空...

您需要实现此方法:

func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
    self.data.append(data)
}

但是如果除了累积收到的数据之外什么都不做,你就不需要使用代理了。

您在parseJSON()方法中使用强制转换:

    jsonResult = try JSONSerialization.jsonObject(with: self.data as Data, options: []) as! NSMutableArray

未指定.mutableContainers选项。这也会使你的应用程序崩溃。

您的代码使用了过多的NSSomethings

解决了所有这些问题后,你可以得到类似的东西:

//properties

weak var delegate: HomeModelProtocal!

let urlPath: String =  "http://localhost/service.php" //this will be changed to the path where service.php lives

// Function to download the incoming JSON data
func downloadItems() {
    let url: URL = URL(string: urlPath)!
    let session = URLSession.shared

    let task = session.dataTask(with: url) {data, response, error in
        if let error = error {
            print("Failed to download data: \(error)")
        } else if let data = data {
            print("Data downloaded")
            print(data as NSData)
            //print(String(data: data, encoding: .utf8))
            self.parseJSON(data: data)
        } else {
            print("Something is wrong...")
        }
    }

    task.resume()
}

func parseJSON(data: Data){

    do {
        if let jsonResult = try JSONSerialization.jsonObject(with: data) as? [[String: AnyObject]] {

            var locations: [LocationModel] = []

            for jsonElement in jsonResult {
                let location = LocationModel()

                //the following insures none of the JsonElement values are nil through optional binding
                if let exerciseName = jsonElement["stationName"] as? String,
                    let bodyPart = jsonElement["buildYear"] as? String
                {
                    print(exerciseName, bodyPart)
                    location.exerciseName = exerciseName
                    location.bodyPart = bodyPart

                }

                locations.append(location)

                DispatchQueue.main.async {
                    self.delegate.itemsDownloaded(items: locations)
                }
            }
        } else {
            print("bad JSON")
        }
    } catch let error as NSError {
        print("**** sake its happened again \(error)")
    }
}