75082


`MyDataクラス`を`UserDefaults `, `NSSecureCoding
`を使って保存したいのですが、`String`などを保存する際には可能なのですが、`Dateクラス`を保存しようとするとエラーが発生してしまいます。  
エラー内容的にはNSDateクラスは許可されていないとのことなのですが、無理なのでしょうか？

エラー内容

[code]

    Error Domain=NSCocoaErrorDomain Code=4864 "value for key 'date' was of unexpected class 'NSDate (0x7fff86d7a4f8) [/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]'. Allowed classes are '{(
        "__lldb_expr_55.MyData (0x1070e1490) [/Users/zunda/Library/Developer/XCPGDevices/8A02217F-C0F4-435D-9A16-C5283F42F016/data/Containers/Bundle/Application/8BDEE3B1-A0D2-4A7F-9F9C-8647134716C9/MyPlayground-1996-4.app]"
    )}'." UserInfo={NSDebugDescription=value for key 'date' was of unexpected class 'NSDate (0x7fff86d7a4f8) [/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/Runtimes/iOS.simruntime/Contents/Resources/RuntimeRoot/System/Library/Frameworks/CoreFoundation.framework]'. Allowed classes are '{(
        "__lldb_expr_55.MyData (0x1070e1490) [/Users/zunda/Library/Developer/XCPGDevices/8A02217F-C0F4-435D-9A16-C5283F42F016/data/Containers/Bundle/Application/8BDEE3B1-A0D2-4A7F-9F9C-8647134716C9/MyPlayground-1996-4.app]"
    )}'.}
    
[/code]

以下のコード全体はコピペでPlaygroundで実行可能です。

[code]

    import Foundation
    
    class MyData: NSObject, NSSecureCoding {
        static var supportsSecureCoding: Bool = true
    
        var date: Date?
        
        override init() {
            super.init()
        }
        // load
        required init?(coder: NSCoder) {
            super.init()
            if let date = coder.decodeObject(forKey: "date") as? Date {
                self.date = date
            }
        }
    
        // save
        func encode(with coder: NSCoder) {
            coder.encode(self.date, forKey: "date")
        }
    }
    
    func saveCustomData(_ data: MyData) {
        //シリアライズ(オブジェクトの内容をバイナリに変換)
        //カスタムクラス(MyData)はそのままUserDefaultsで保存できないためシリアライズしてData型に変換する
        if let archiveData = try? NSKeyedArchiver.archivedData(withRootObject: data, requiringSecureCoding: true) {
            UserDefaults.standard.setValue(archiveData, forKey: "date")
            print("シリアライズ成功")
        } else {
            print("シリアライズ失敗")
        }
    }
    
       
    func loadCustomData() -> MyData? {
        guard let storedData: Data = UserDefaults.standard.object(forKey: "date") as? Data else {
            return MyData()
        }
        
        do {
            //デシリアライズ(バイナリをオブジェクトに変換)
            return try NSKeyedUnarchiver.unarchivedObject(ofClass: MyData.self, from: storedData)
        } catch let error {
            print(error)
            print("デシリアライズ失敗")
        }
    
        return nil
    }
    
    let data1 = MyData()
    data1.date = Date()
    saveCustomData(data1)
    print(data1.date)
    
    let data2 = loadCustomData()
    if let data2 = data2 {
        print(data2.date)
    }
    
[/code]


CC BY-SA 4.0
2021-04-04T12:41:52.253
75081
2021-04-04T13:33:47.793
2021-04-04T12:59:25.637
40856
40856
question
swift
Swiftでカスタムクラス内のDateクラスをUserDefaults, NSSecureCodingを使って保存したい


`NSSecureCoding`では、unarchiveの際に、アーカイブに含まれる可能性のあるすべてのクラスを指定する必要があります。`NSDate`クラスが出てくるのがわかっているのであれば、それも指定してやらないといけません。

`loadCustomData()`のtryの行を次のように書き換えてみてください。

[code]

            return try NSKeyedUnarchiver.unarchivedObject(ofClasses: [MyData.self, NSDate.self], from: storedData) as? MyData
    
[/code]


CC BY-SA 4.0
2021-04-04T13:33:47.793
75082
2021-04-04T13:33:47.793
13972
75081
answer