使用swift 4进行JSON编码/解码

问题描述 投票:0回答:1

Swift 4.0 iOS 11.2.x.

我在这里创建了一个名为products的Codable结构,并使用此方法将其保存到文件中。

 func saveImage() {
    let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    let file2ShareURL = documentsDirectoryURL.appendingPathComponent("config.n2kHunt")

    var json: Any?
    let encodedData = try? JSONEncoder().encode(products)
    if let data = encodedData {
        json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments)
        if let json = json {
            do {
                try String(describing: json).write(to: file2ShareURL, atomically: true, encoding: .utf8)
            } catch {
                print("unable to write")
            }
        }
    }
}

它工作,并假设我输入两个记录我得到这个文件。 [这不是json,但无论如何]。

(
    {
    identity = "blah-1";
    major = 245;
    minor = 654;
    url = "https://web1";
    uuid = f54321;
},
    {
    identity = "blah-2";
    major = 543;
    minor = 654;
    url = "https://web2";
    uuid = f6789;
}

)

我将文件空投到第二个iOS设备,我尝试在appDelegate中使用此过程对其进行解码。

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    do {
        let string2D = try? String(contentsOf: url)
        let jsonData = try? JSONSerialization.data(withJSONObject: string2D)
        do {
            products = try JSONDecoder().decode([BeaconDB].self, from: jsonData!)
        } catch let jsonErr {
            print("unable to read \(jsonErr)")
        }

    }  catch {
        print("application error")
    }
   }

我得到一个母亲崩溃,有这个错误信息......

2018-03-06 21:20:29.248774 + 0100 blah [2014:740956] *由于未捕获的异常'NSInvalidArgumentException'而终止应用程序,原因:'* + [NSJSONSerialization dataWithJSONObject:options:error:]:顶级类型无效JSON写'

我究竟做错了什么;如何将json写入文件以便我可以将其读回!!具有讽刺意味的是,几天前我用这个代码使用了这个代码,我讨厌json。

ios json decode swift4 encode
1个回答
2
投票

为什么要将结构编码为JSON,然后将JSON反序列化为Swift数组并将集合类型字符串表示(!)保存到磁盘?反过来不能工作,这会导致错误。

它更容易:

func saveImage() {
    let documentsDirectoryURL = try! FileManager().url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
    let file2ShareURL = documentsDirectoryURL.appendingPathComponent("config.n2kHunt")

    do {
        let encodedData = try JSONEncoder().encode(products)
        try encodedData.write(to: file2ShareURL)
    } catch {
        print("unable to write", error)
    }
}

func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {

    do {
        let jsonData = try Data(contentsOf: url)
        products = try JSONDecoder().decode([BeaconDB].self, from: jsonData)
    } catch {
        print("unable to read", error)
    }
}

笔记:

  • 永远不要在catch子句中打印无意义的文字字符串,至少打印实际的error
  • 永远不要在try?区块写do - catch。写try没有问号,以捕捉错误。
© www.soinside.com 2019 - 2024. All rights reserved.