使用Swift 3从文件中加载JSON

4
我正在尝试使用以下代码从文件中加载json字符串。
if let filepath = Bundle.main.path(forResource: "data", ofType: "json") {
    do {
        let contents = try String(contentsOfFile: filepath)
        print(contents)
    } catch {
        // contents could not be loaded
        print("could not be loaded")
    }

} else {

}

但是我收到了“无法加载”的消息。代码有问题吗?或者我应该将文件放在特定的文件夹中?目前,我将其放在一个名为models的文件夹中。
编辑:我检查了错误内容,json文件的位置没有问题,问题出现在我尝试将其转换为字符串时。它告诉我编码不同...
错误领域=NSCocoaErrorDomain Code=264,“Die Datei „data.json“ konnte nicht geöffnet werden, da die Textcodierung des Inhalts nicht bestimmt werden kann。”

将该文件放置在您的目标根目录中。 - Sagar Bhut
打印错误:/*...*/ catch(error) { print(error) - 它说什么? - LinusGeffarth
请问您能否发布JSON内容?似乎您的文件格式有问题。或者您可以使用以下链接来验证您的JSON是否有效:https://jsonlint.com/ 或者您是否有GitHub或其他代码库的链接? - Renato Stauffer
1
将文件作为数据(而不是字符串)读取,并检查是否有效。无论如何,JSON解码都应从数据中完成。 - Nikolai Ruhe
1
请将错误信息翻译成英文。谢谢。 - rmaddy
显示剩余3条评论
2个回答

5

首先要确保你已经勾选了 copy item if needed 标记,并且在添加 .json 文件时,你的目标也被标记了。然后,你需要以 Data 的形式加载文件,而不是 String,这是你遇到的主要问题。

使用此方法加载你的 json 并在回调函数中获取结果

     func loadJSON(finishedClosure:@escaping ((_ jsonObject:[String:AnyObject]?,_ error: NSError?) ->Void))
{
    DispatchQueue.global().async {
        guard let path = Bundle.main.path(forResource: "yourJSON", ofType: "json") else{
            DispatchQueue.main.async {
                finishedClosure(nil, NSError(domain: "JSON file don't founded", code: 998, userInfo: nil)) 
            }
            return
        }
        //Load file data part
        guard let jsonData = (try? Data(contentsOf: URL(fileURLWithPath: path))) else{
            DispatchQueue.main.async {
                finishedClosure(nil, NSError(domain: "can convert to data", code: 999, userInfo: nil))  
            }
            return
        }

        do {
            if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: JSONSerialization.ReadingOptions.mutableContainers) as? [String:AnyObject]
            {
                DispatchQueue.main.async {
                    finishedClosure(jsonObject,nil)
                }
            }
        } catch let error as NSError {
            print(error)
            DispatchQueue.main.async {
                finishedClosure(nil,error)
            }
        }
    }
}

1
发布的截图和代码都与问题无关,不能帮助解决提问者的问题。如果您不同意,请解释为什么它们有帮助。 - Nikolai Ruhe
1
@NikolaiRuhe 我认为用户在从文件中加载json时遇到了问题,所以我添加了一个好的实现,并添加了一个截图,以确保他正确地将文件添加到自己的项目中。你能解释一下为什么你认为这不会有帮助吗?如果你阅读了我的方法实现,你会发现它做了你在评论中建议的加载json内容和读取文件数据的操作。 - Reinier Melian
屏幕截图突出显示了错误的复选框(如果您担心文件是否已正确复制到捆绑包中)。 - Nikolai Ruhe
@NikolaiRuhe 你关于这张图片的观点是正确的,我会将其移除。 - Reinier Melian
1
@ReinierMelian:你的免责声明“首先确保如果需要勾选复制项,已经标记了该项,并且在添加.json文件时也标记了目标”,真的帮了我大忙!我一直在想为什么代码中无法读取该文件..谢谢啊! - Vineet
显示剩余6条评论

1

Swift 4 - 将JSON文件解析为字符串和数据类型

该错误表明无法将文件读取为字符串,因为无法确定文本编码。您应明确提供json文件的实际编码。

要检查文件的编码,请在XCode中打开文件并查看右侧边栏的文件检查器:

Encoding of the file

if let filePath = Bundle.main.path(forResource: "data", ofType: "json"),
   let data = NSData(contentsOfFile: filePath) {
  do {

    // here you have your json parsed as string:
    let jsonString = try? String(contentsOfFile: filePath, encoding: String.Encoding.utf8)

    // but it is better to use the type data instead:
    let jsonData = try JSONSerialization.jsonObject(with: data as Data, options: JSONSerialization.ReadingOptions.allowFragments)
  }
  catch {
    //Handle error
  }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接