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
Why do I get the error 'Domain=NSCocoaErrorDomain Code=3840 "No value." UserInfo={NSDebugDescription=No value.}'?
提问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 URLSessionDataTask
as its second parameter. So, this method would never be called.
没有urlSession(_:task:didCompleteWithError:)
方法将URLSessionDataTask
其作为第二个参数。所以,这个方法永远不会被调用。
And inside the method, self.data
is appended to self.data
, so even if the method is called, self.data
is 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 .mutableContainers
option. 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)")
}
}