ios - 快速获取和格式化联系人姓名和地址 5
问题描述
我正在从联系人列表中提取联系人姓名、邮寄地址和组织,我有一些问题。我正在获取联系人标识符并将其存储到 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)
}
}
解决方案
首先,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)
}
所以你正在做的是检查每个对象是否为零。希望这可以帮助。
推荐阅读
- python - 用 Python 填充模板 Word 中的表格(DocxTemplate,Jinja2)
- flutter - 如何使元素的动态列表水平显示到每个 6 个索引,然后在颤动中垂直显示
- javascript - 如何处理nodejs中的竞争条件
- android - 遇到 BleAlreadyConnectedException 时重新开始读取 onErrorResumeNext 中的数据
- python - Python:如何删除正在写入的文件
- java - 以 adm 用户 Java 运行 Runtime.getRuntime
- python - 如何使用python将数据附加到databricks中的现有文件?
- python - 使用本地证书不再起作用
- python - OneHotEncoder 条带化标头
- javascript - 可以用导航栏和标签打开新窗口吗?