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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/39820358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 09:22:49  来源:igfitidea点击:

Why do I get the error 'Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}'?

iosmysqljsonswiftxcode

提问by MHDev

I am new to Swift and iOS development but I am trying to download and parse data that is stored in a MySQL Database.

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

I keep getting the error:

我不断收到错误:

Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}

域=NSCocoaErrorDomain 代码=3840 “无值。” UserInfo={NSDebugDescription=无值。}

I have posted my code below but I don't think the problem is in the parseJSON function but instead in the actual download of the data as when I print the 'data' out it returns '<>'.

我已经在下面发布了我的代码,但我不认为问题出在 parseJSON 函数中,而是在数据的实际下载中,因为当我打印“数据”时它返回“<>”。

Here is my code:

这是我的代码:

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

    })
}

采纳答案by OOPer

Especially bad thing in your code:

在您的代码中尤其糟糕的是:

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

There is no urlSession(_:task:didCompleteWithError:)method which takes URLSessionDataTaskas its second parameter. So, this method would never be called.

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

And inside the method, self.datais appended to self.data, so even if the method is called, self.datais still being empty...

并且在方法内部,self.data被附加到self.data,所以即使调用了方法,self.data仍然是空的......

You need to implement this method instead:

您需要改为实现此方法:

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

But if you want to do nothing other than accumulating received data, you have no need to use delegates.

但是如果你只想累积接收到的数据,你就没有必要使用委托。

And you are using forced casting in your parseJSON()method:

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

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

without specifying .mutableContainersoption. This also would crash your app.

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

And your code uses too much of NSSomethings.

而且您的代码使用了太多的NSSomethings.



With all such things fixed, you can get something like this:

解决所有这些问题后,您可以获得如下内容:

//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)")
    }
}