JSON 文件下载后 Swift 3 中解析 JSON,NSCocoaErrorDomain Code=3840
Parsing JSON in Swift 3 after JSON file download, NSCocoaErrorDomain Code=3840
因此,当我尝试对我为正在构建的应用程序下载的 JSON 对象执行 JSON 序列化时,我不断收到以下错误。基本上,我所做的是创建一个 JSON 文件,将其保存在 SugarSync 上,然后直接下载 link 以在我的程序中下载和使用。有点像我自己的盗版 API。
我知道它会下载,因为如果我使用 URL 将文件转换为字符串,它会打印出文件。问题是我无法克服这个错误。
Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 2."
这是一个文件读取的例子(超级简单!):
{"buddy": "pal",
"brother": "bear"}
我试过更改为 NSData 而不是 Data,但这会产生更多问题。尝试在 JSONSerialization 行上执行 NSDictionary,但这引发了更多错误。我也试过.mutableContainers,也没有用。
下面是完整代码,包括 SugarSync 文件 URL 以便您自己重现错误。我不明白我做错了什么,如果有人能提供帮助,那就太好了。
谢谢!
// Create destination URL
let documentsURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsURL.appendingPathComponent("downloadedFile.json")
// Create URL to the source file you want to download
let fileURL = URL(string: "https://www.sugarsync.com/pf/D7126167_796_275761334?directDownload=true")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url: fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
print("move files")
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
let fileData: Data = try Data(contentsOf: destinationFileUrl, options: Data.ReadingOptions.mappedIfSafe)
print(fileData)
let myJson = try JSONSerialization.jsonObject(with: fileData, options: []) as? [[String: Any]]
print(myJson!)
do {
// This converts the file into String and is printed (doesn't get to this because of the error, but it works!)
let jsonText = try String(contentsOf: tempLocalUrl, encoding: String.Encoding.utf8)
print(jsonText)
} catch {
print("failed to print json file")
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading file. Error description: %@", error?.localizedDescription ?? "unknown")
}
}
task.resume()
编辑 --------------------------
看起来序列化非常敏感。它需要这样的东西才能工作:
{"widget": {
"debug": "on",
"window": {
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
},
"image": {
"src": "Images/Sun.png",
"name": "sun1",
"hOffset": 250,
"vOffset": 250,
"alignment": "center"
},
"text": {
"data": "Click Here",
"size": 36,
"style": "bold",
"name": "text1",
"hOffset": 250,
"vOffset": 100,
"alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
}
}}
但是这个不行:
{“website”: {
“iPhone”: {
“blogURL”: ”string”,
“blogHead”: “string”,
“reportURL”: “string”,
“reportHead”: “string”
}
}}
注意:此网站未正确显示 JSON 缩进。 This is where I'm getting my JSON examples.
您正在尝试解析类型为 [[String: Any]]
的 JSON,而 JSON 只是一个字典 ([String: Any]
) 而不是数组字典。
试试改成这样:
let myJson = try JSONSerialization.jsonObject(with: fileData, options: []) as? [String: Any]
最后成功了。事实证明,正如我在编辑中所述,json 序列化程序非常敏感。所以,我决定使用 this JSON online editor 来确保我需要的一切都是绝对正确的,包括正确的字体和大小等
因此,当我尝试对我为正在构建的应用程序下载的 JSON 对象执行 JSON 序列化时,我不断收到以下错误。基本上,我所做的是创建一个 JSON 文件,将其保存在 SugarSync 上,然后直接下载 link 以在我的程序中下载和使用。有点像我自己的盗版 API。
我知道它会下载,因为如果我使用 URL 将文件转换为字符串,它会打印出文件。问题是我无法克服这个错误。
Error Domain=NSCocoaErrorDomain Code=3840 "No string key for value in object around character 2."
这是一个文件读取的例子(超级简单!):
{"buddy": "pal",
"brother": "bear"}
我试过更改为 NSData 而不是 Data,但这会产生更多问题。尝试在 JSONSerialization 行上执行 NSDictionary,但这引发了更多错误。我也试过.mutableContainers,也没有用。
下面是完整代码,包括 SugarSync 文件 URL 以便您自己重现错误。我不明白我做错了什么,如果有人能提供帮助,那就太好了。
谢谢!
// Create destination URL
let documentsURL: URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsURL.appendingPathComponent("downloadedFile.json")
// Create URL to the source file you want to download
let fileURL = URL(string: "https://www.sugarsync.com/pf/D7126167_796_275761334?directDownload=true")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url: fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
print("move files")
try FileManager.default.copyItem(at: tempLocalUrl, to: destinationFileUrl)
let fileData: Data = try Data(contentsOf: destinationFileUrl, options: Data.ReadingOptions.mappedIfSafe)
print(fileData)
let myJson = try JSONSerialization.jsonObject(with: fileData, options: []) as? [[String: Any]]
print(myJson!)
do {
// This converts the file into String and is printed (doesn't get to this because of the error, but it works!)
let jsonText = try String(contentsOf: tempLocalUrl, encoding: String.Encoding.utf8)
print(jsonText)
} catch {
print("failed to print json file")
}
} catch (let writeError) {
print("Error creating a file \(destinationFileUrl) : \(writeError)")
}
} else {
print("Error took place while downloading file. Error description: %@", error?.localizedDescription ?? "unknown")
}
}
task.resume()
编辑 -------------------------- 看起来序列化非常敏感。它需要这样的东西才能工作:
{"widget": {
"debug": "on",
"window": {
"title": "Sample Konfabulator Widget",
"name": "main_window",
"width": 500,
"height": 500
},
"image": {
"src": "Images/Sun.png",
"name": "sun1",
"hOffset": 250,
"vOffset": 250,
"alignment": "center"
},
"text": {
"data": "Click Here",
"size": 36,
"style": "bold",
"name": "text1",
"hOffset": 250,
"vOffset": 100,
"alignment": "center",
"onMouseUp": "sun1.opacity = (sun1.opacity / 100) * 90;"
}
}}
但是这个不行:
{“website”: {
“iPhone”: {
“blogURL”: ”string”,
“blogHead”: “string”,
“reportURL”: “string”,
“reportHead”: “string”
}
}}
注意:此网站未正确显示 JSON 缩进。 This is where I'm getting my JSON examples.
您正在尝试解析类型为 [[String: Any]]
的 JSON,而 JSON 只是一个字典 ([String: Any]
) 而不是数组字典。
试试改成这样:
let myJson = try JSONSerialization.jsonObject(with: fileData, options: []) as? [String: Any]
最后成功了。事实证明,正如我在编辑中所述,json 序列化程序非常敏感。所以,我决定使用 this JSON online editor 来确保我需要的一切都是绝对正确的,包括正确的字体和大小等