0

我正在从联系人列表中提取联系人姓名、邮寄地址和组织,我有一些问题。我正在获取联系人标识符并将其存储到 SQLite DB。然后我从数据库中提取 ID 并将其传递给函数。IE。contactID 这工作正常。但是,我有 1 个问题,我有一个问题。

问题:除非联系人地址为空,否则一切正常。在这种情况下,“if let”语句会引发此错误。我认为“如果让”应该防止这种情况。由于未捕获的异常“NSRangeException”而终止应用程序,原因:“*** -[__NSArray0 objectAtIndex:]: index 0 beyond bounds for empty NSArray”

我能做些什么来解决这个问题,还是我把自己编码到了一个角落?

我也有一个疑问。如何检查联系人是否有多个 mailingAddresses?如果有多个 mailingAddresses,那么我的计划是显示一个警报以允许用户选择要使用的一个。显示警报不是问题,我只需要检查和获取地址方面的帮助。

func getContactFromID_Ouote(contactID: String)
    {
        let store = CNContactStore()
        var theName = CNContact()

        let theKeys = [CNContactNamePrefixKey,
                       CNContactGivenNameKey,
                       CNContactFamilyNameKey,
                       CNContactOrganizationNameKey,
                       CNContactPostalAddressesKey,
                       CNContactFormatter.descriptorForRequiredKeys(for: .fullName)] as! [CNKeyDescriptor]

        do {
            theName = try store.unifiedContact(withIdentifier: contactID, keysToFetch: theKeys)

            contactName = CNContactFormatter.string(from: theName, style: .fullName)!

            contactPrefix = theName.namePrefix
            contactFirst = theName.givenName
            contactLast = theName.familyName
            companyName = theName.organizationName == "" ? "" : theName.organizationName

        } catch {
            print("Fetching contact data failed: \(error)")
        }

        if let addressString = (((theName.postalAddresses[0] as AnyObject).value(forKey: "labelValuePair") as AnyObject).value(forKey: "value")) as? CNPostalAddress
        {
            mailAddress = CNPostalAddressFormatter.string(from: addressString, style: .mailingAddress)
        }
}
4

1 回答 1

1

首先,if let将检查是否addressString为nil。而不是这个表达式的部分。
(((theName.postalAddresses[0] as AnyObject).value(forKey: "labelValuePair") as AnyObject).value(forKey: "value")) as? CNPostalAddress

上面的表达式是逐步执行的,就像先(theName.postalAddresses[0] as AnyObject)执行,
然后执行value(forKey: "labelValuePair") as AnyObject)
然后执行.value(forKey: "value")) as? CNPostalAddress
如果这些表达式中的任何一个为 nil,它就会崩溃,但只有当最后一个表达式 ievalue(forKey: "value")) as? CNPostalAddress为 nil 时,它才会崩溃并按照您的期望工作。

第二件事是theName.postalAddresses[0]使用下标来获取索引 0 处的对象,这始终是强制解包的。因此它不会检查nil并崩溃。
你必须做的是这样的事情。

if let firstPostalAddress = (theName.postalAddresses.first as? AnyObject),
                let labelValuePair = firstPostalAddress.value(forKey: "labelValuePair") as? AnyObject,
            let finalPostalAddress = labelValuePair.value(forKey: "value") as? CNPostalAddress
            {
                mailAddress = CNPostalAddressFormatter.string(from: finalPostalAddress, style: .mailingAddress)

}

所以你正在做的是检查每个对象是否为零。希望这可以帮助。

于 2020-02-06T04:13:26.167 回答