Ios 在平面文件中保存自定义结构

Ios 在平面文件中保存自定义结构,ios,swift,swift5.2,Ios,Swift,Swift5.2,以下是自定义结构。我想存储自定义结构的数组,即[details]。我无法在文件中存储[详细信息]。在文件中写入此[详细信息]时,应用程序正在崩溃“无效json格式” struct details : Identifiable { let id = UUID() var name : String? var time : String? var msg : [MsgDetails]? var loc : String? var type : Str

以下是自定义结构。我想存储自定义结构的数组,即[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=[details]

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
将模型转换为数据并写入文件。假设您的模型只包含基本类型,您所要做的就是遵守
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
替换为其
数据
,则可以自动实现
Codable
一致性。使用
image.pngData()
UIImage
获取图像数据


您可以使用
Codable
而不是
NSKeyedArchiver
将模型转换为数据并写入文件。假设您的模型只包含基本类型,您所要做的就是遵守
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
替换为其
数据
,则可以自动实现
Codable
一致性。使用
image.pngData()
UIImage
获取图像数据


请向我们展示您迄今为止尝试过的代码。这不是一个“我们免费为您编写代码”平台,而是一个“我们帮助您使用现有代码”平台。@Chris,更新了我的后租约,向我们展示您迄今为止尝试过的代码。这不是一个“我们免费为您编写代码”平台,而是一个“我们帮助您使用现有代码”平台平台。@Chris,当我在类似结构的结构中实现Codable时更新了我的Post详细信息:可识别的,可编码的{let id=UUID()变量名称:String?变量时间:String?var msg:[MsgDetails]?变量位置:String?变量类型:String?}我收到错误,例如类型“details”不符合协议“Decodable”类型“details”不符合协议“Encodable”MsgDetails的内容是什么?如果要使用NSKeyedArchiver,您的模型必须是从NSObject继承的类,并采用NSCoding协议及其所需方法。请参阅此答案:MsgDetails is msg类的对象。class msg{//2.Properties var text:String?var image:UIImage?var date:NSDate?}UIImage不符合Codable。这就是为什么会出现此错误。当我在类似struct的struct中实现Codable时,struct details:identifible,Codable{let id=UUID()变量名称:字符串?变量时间:字符串?变量消息:[MsgDetails]?变量位置:字符串?变量类型:字符串?}我收到错误,例如类型“details”不符合协议“Decodable”类型“details”不符合协议“Encodable”MsgDetails的内容是什么?如果要使用NSKeyedArchiver,您的模型必须是从NSObject继承的类,并采用NSCoding协议及其所需方法。请参阅此答案:MsgDetails is msg class.class msg{//2.Properties var text:String?var image:UIImage?var date:NSDate?}UIImage的对象不符合Codable。这就是为什么会出现该错误。