获取并格式化联系人姓名和地址 swift 5
Fetching and formatting contact name and address swift 5
我正在从联系人列表中提取联系人姓名、邮寄地址和组织,但我有一些问题。我正在获取联系人标识符并将其存储到 SQLite 数据库中。然后我从数据库中提取 ID 并将其传递给函数。 IE。 contactID 这很好用。但是,我有 1 个问题,我有一个问题。
问题:
除非联系人地址为空,否则一切正常。在这种情况下,"if let" 语句会抛出此错误。我认为 "if let" 应该可以防止这种情况发生。由于未捕获的异常 'NSRangeException' 而终止应用程序,原因:'*** -[__NSArray0 objectAtIndex:]:索引 0 超出空 NSArray 的范围'
我该怎么做才能解决这个问题,还是我把自己逼到了墙角?
我也有一个问题。如何检查联系人是否有多个邮寄地址?如果有多个 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
。 =28=] 如果这些表达式中的任何一个为 nil,它就会崩溃,但只有当最后一个表达式即 value(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)
}
所以你正在做的是检查每个对象是否为 nil。
希望这有帮助。
我正在从联系人列表中提取联系人姓名、邮寄地址和组织,但我有一些问题。我正在获取联系人标识符并将其存储到 SQLite 数据库中。然后我从数据库中提取 ID 并将其传递给函数。 IE。 contactID 这很好用。但是,我有 1 个问题,我有一个问题。
问题: 除非联系人地址为空,否则一切正常。在这种情况下,"if let" 语句会抛出此错误。我认为 "if let" 应该可以防止这种情况发生。由于未捕获的异常 'NSRangeException' 而终止应用程序,原因:'*** -[__NSArray0 objectAtIndex:]:索引 0 超出空 NSArray 的范围'
我该怎么做才能解决这个问题,还是我把自己逼到了墙角?
我也有一个问题。如何检查联系人是否有多个邮寄地址?如果有多个 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
。 =28=] 如果这些表达式中的任何一个为 nil,它就会崩溃,但只有当最后一个表达式即 value(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)
}
所以你正在做的是检查每个对象是否为 nil。 希望这有帮助。