我是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)
})
}
答案 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)")
}
}