将未存档的数据存档到 CNContact 时崩溃

Crash when unarchived data to CNContact

提问人:Roei Nadam 提问时间:11/6/2023 最后编辑:Roei Nadam 更新时间:11/8/2023 访问量:60

问:

您好,当未存档数据到CNContact时,我崩溃了:

行中 : var decodedContacts = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [CNContact.self], from: archived) as? [CNContact?]

错误日志:

NSKeyedUnarchiver.unarchivedObject(ofClasses: [CNContact.self], from: contactsData) 作为?[CNContact?]错误 Domain=NSCocoaErrorDomain Code=4864“键'root'的值属于意外的类'NSArray' (0x1d97a9ed8) [/System/Library/Frameworks/CoreFoundation.framework]。允许的类包括: {( “'CNContact' (0x1d9881018) [/System/Library/Frameworks/Contacts.framework]” )}“ UserInfo={NSDebugDescription=键”root“的值属于意外类 允许的类包括:{( ”'CNContact' (0x1d9881018) [/System/Library/Frameworks/Contacts.framework]“ )}}

import Contacts

class ContactsManager {

static let numberOfSavedContacts = 12

static let shared = ContactsManager()
private init() {
    loadContacts()
}

private(set) var contacts: [CNContact?] = Array(repeating: nil, count: numberOfSavedContacts)

func add(contact: CNContact, at index: Int, phone: CNLabeledValue<CNPhoneNumber>? = nil) {
    if index < ContactsManager.numberOfSavedContacts {
        let editContact = contact.mutableCopy() as! CNMutableContact
        if phone != nil {
            editContact.phoneNumbers = [phone!]
        }
        contacts[index] = editContact
        saveContacts()
    }
}

func deleteContact(_ index: Int) {
    if index < ContactsManager.numberOfSavedContacts {
        contacts[index] = nil
        saveContacts()
    }
}

func saveContacts() {
    do {
        let contactsData = try NSKeyedArchiver.archivedData(withRootObject:contacts,requiringSecureCoding:false)
        UserDefaults.standard.set(contactsData, forKey: "contacts")
    }
    catch {
        print(error)
    }
}


func loadContacts() {
    if let contactsData = UserDefaults.standard.object(forKey: "contacts") as? Data {
        do {
            if var decodedContacts = try NSKeyedUnarchiver.unarchivedObject(ofClasses: [NSArray.self, CNContact.self, NSNull.self], from: contactsData) as? [CNContact?] {
                print(decodedContacts)
                contacts = decodedContacts
            } else {
                print("decodedContacts is nil")
            }
        } catch {
            print(error)
        }
    }
}

}

swift cncontact nskeyedunarchiver

评论

0赞 Larme 11/7/2023
你的代码不清楚:是,所以是“数据的数据”,那么你期望从哪个未存档的联系人。contactsDataDataarchiveddecodedContactsarchived
0赞 Roei Nadam 11/7/2023
这是我在另一个问题中看到的一个例子。现在,我已在此处编辑了代码,当我运行它时,我在控制台中得到了以下内容:
0赞 HangarRash 11/7/2023
@RoeiNadam请不要在评论中发布详细信息。请在您的问题中填写这些详细信息。
0赞 Roei Nadam 11/7/2023
@HangarRash好的,编辑。
1赞 Larme 11/7/2023
[NSArray.self, CNContact.self, NSNull.self]然后,我没有看到您可能已经保存了值(在初始化中)nil

答:

0赞 Larme 11/8/2023 #1

NSKeyedUnarchiver是归档对象的“旧方式”。它是面向 Objective-C 的。

看到错误:was of unexpected class 'NSArray'

然后,您需要指定在解码时会遇到对象:NSArray

ofClasses: [NSArray.self, CNContact.self]

现在,您收到另一个错误: . ~ .was of unexpected class 'NSNull'"NSNullnil

您正在使用 保存联系人。nilArray(repeating: nil, count: numberOfSavedContacts)

因此,您需要告诉解压缩器可能会遇到 nil 值:

ofClasses: [NSArray.self, NSNull.self, CNContact.self]

我不知道你为什么要保存价值,这很奇怪,你可能想改变这种行为。nil