簡體   English   中英

將自定義結構保存在平面文件中

[英]Save custom struct in Flat file

以下是自定義結構。 我想存儲 [details] 的自定義結構數組。 我無法將 [詳細信息] 存儲在文件中。 在編寫此 [文件中的詳細信息時,應用程序正在崩潰“無效的 json 格式”

struct details : Identifiable {
    let id  = UUID()
    var name : String?
    var time : String?
    var msg : [MsgDetails]?
    var loc : String?
    var type : String?
}

在文件中寫入: msgArray 是詳細信息數組。 msgArray = [詳細信息]。

extension Array {
    var jsonStringRepresentation: String? {
        let jsonData = try? JSONSerialization.data(withJSONObject: self, options: [])
        guard jsonData != nil else {return nil}
        let jsonString = String(data: jsonData!, encoding: .utf8)
        guard jsonString != nil else {return nil}
        return jsonString! as String

    }
}

在下面的代碼中 NSKeyedArchiver.archivedData 返回 nil

if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first{
            let fileURL = dir.appendingPathComponent(self.fileName)
            let data = try? NSKeyedArchiver.archivedData(withRootObject: msgArray.jsonStringRepresentation!, requiringSecureCoding: true)
            do {
                try data!.write(to: fileURL)
            } catch let error {
                print("\(error.localizedDescription)")
            }
        }

您可以使用Codable而不是NSKeyedArchiver將模型轉換為數據並寫入文件。 假設您的 model 僅包含基本類型,您所要做的就是符合Codable協議。

struct Details : Identifiable, Codable {
    ...
}

寫入文件:

extension Array where Element: Encodable {

    func saveToFile(fileName: String) throws {
        do {
            let data = try JSONEncoder().encode(self)
            if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
                let fileURL = dir.appendingPathComponent(fileName)
                try data.write(to: fileURL)
            } else {
                //throw some error
            }
        } catch {
            throw error
        }
    }

}

保存的文件可以這樣讀取:

func readFile(fileName: String) throws {
    do {
        if let dir = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first {
            let url = dir.appendingPathComponent(fileName)
            let data = try Data(contentsOf: url)
            let decoded = try JSONDecoder().decode([Details].self, from: data)
            print("decoded: ", decoded)
        } else {
            //throw some error
        }
    } catch {
        throw error
    }

}

如果您可以將UIImage中的 UIImage 替換為其Data ,則可以自動實現Codable一致性。 使用image.pngData()UIImage獲取 imageData。

struct MsgDetails: Codable {
    var imageData: Data?
    var text: String?
    var date: Date?

    var image: UIImage? {
        if let data = imageData {
            return UIImage(data: data)
        }
        return nil
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM