- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
[背景:iOS 7、Xcode 5,均为 2014 年 2 月最新版本。测试数据是 iPhone 5(真实设备,非模拟器)]
我的目标是使用 AddressBookUI 方法允许用户指定联系人,然后使用各种字段(地址、电话号码等)在我的代码中填充 GUI。 ABPeoplePickerNavigationController
是允许用户按姓名选择联系人的标准机制。这样做会导致调用此委托(delegate)方法:
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker
shouldContinueAfterSelectingPerson:(ABRecordRef)person
但是,如果我此时检查人员记录,则多值字段都没有任何数据。所以我提取了 RecordID
,检索了它,生成的 ABRecordRef
也没有填充多值字段。
如果我从委托(delegate)方法中返回 YES
,则会向用户显示另一个 UI,其中会显示联系人详细信息。触摸任何字段都会导致此委托(delegate)方法调用
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
ABRecordRef
已填充所有多值字段。
我找不到有关延迟加载记录的任何信息,或者存在所需的延迟或权限问题会阻止填写字段。我用来检查记录的代码是方法,因此在第二个实例中找到值的完全相同的代码无法在第一个实例中找到它。
关于可能发生的事情,或者我如何在不向用户显示第二个 UI 的情况下检索完整记录的任何建议?
我正在使用 Apple 的 QuickContacts 示例代码。以下是我所做的添加和更改。
+(NSMutableDictionary *)convertABRecordRef:(ABRecordRef)person
{
// Initialize a mutable dictionary and give it initial values.
NSMutableDictionary *contactInfoDict = [[NSMutableDictionary alloc] initWithCapacity:12];
// Use a general Core Foundation object.
CFTypeRef generalCFObject = ABRecordCopyValue(person, kABPersonFirstNameProperty);
ABRecordID foundId = ABRecordGetRecordID(person);
NSNumber *personIDNum = [NSNumber numberWithInteger:foundId];
[contactInfoDict setObject:personIDNum forKey:@"recordID"];
// Get the first name.
if (generalCFObject)
{
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"firstName"];
CFRelease(generalCFObject);
}
// Get the last name.
generalCFObject = ABRecordCopyValue(person, kABPersonLastNameProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"lastName"];
CFRelease(generalCFObject);
}
generalCFObject = ABRecordCopyValue(person, kABPersonOrganizationProperty);
if (generalCFObject) {
[contactInfoDict setObject:(__bridge NSString *)generalCFObject forKey:@"companyName"];
CFRelease(generalCFObject);
}
//ABMultiValueRef phones = ABRecordCopyValue(person, kABPersonPhoneProperty);
//NSArray *numbers = (NSArray *)ABMultiValueCopyArrayOfAllValues(phones);
// Get the phone numbers as a multi-value property.
ABMultiValueRef phonesRef = ABRecordCopyValue(person, kABPersonPhoneProperty);
CFIndex phoneCount = ABMultiValueGetCount(phonesRef);
for (CFIndex i=0; i<ABMultiValueGetCount(phonesRef); i++) {
CFStringRef currentPhoneLabel = ABMultiValueCopyLabelAtIndex(phonesRef, i);
CFStringRef currentPhoneValue = ABMultiValueCopyValueAtIndex(phonesRef, i);
if (CFStringCompare(currentPhoneLabel, kABPersonPhoneMobileLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"mobileNumber"];
}
if (CFStringCompare(currentPhoneLabel, kABHomeLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"homeNumber"];
}
if (CFStringCompare(currentPhoneLabel, kABWorkLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *)currentPhoneValue forKey:@"workNumber"];
}
CFRelease(currentPhoneLabel);
CFRelease(currentPhoneValue);
}
CFRelease(phonesRef);
// Get the e-mail addresses as a multi-value property.
ABMultiValueRef emailsRef = ABRecordCopyValue(person, kABPersonEmailProperty);
for (int i=0; i<ABMultiValueGetCount(emailsRef); i++)
{
CFStringRef currentEmailLabel = ABMultiValueCopyLabelAtIndex(emailsRef, i);
CFStringRef currentEmailValue = ABMultiValueCopyValueAtIndex(emailsRef, i);
if (CFStringCompare(currentEmailLabel, kABHomeLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *)currentEmailValue forKey:@"homeEmail"];
}
if (CFStringCompare(currentEmailLabel, kABWorkLabel, 0) == kCFCompareEqualTo) {
[contactInfoDict setObject:(__bridge NSString *)currentEmailValue forKey:@"workEmail"];
}
CFRelease(currentEmailLabel);
CFRelease(currentEmailValue);
}
CFRelease(emailsRef);
// Get the first street address among all addresses of the selected contact.
ABMultiValueRef addressRef = ABRecordCopyValue(person, kABPersonAddressProperty);
if (ABMultiValueGetCount(addressRef) > 0)
{
CFIndex numberOfAddresses = ABMultiValueGetCount(addressRef);
for (CFIndex i=0; i<numberOfAddresses; i++)
{
CFStringRef label = ABMultiValueCopyLabelAtIndex(addressRef, i);
if (label)
{
if (CFEqual(label, kABHomeLabel))
{
NSDictionary *addressDict = (__bridge NSDictionary *)ABMultiValueCopyValueAtIndex(addressRef, 0);
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressStreetKey] forKey:@"homeAddress"];
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressZIPKey] forKey:@"homeZipCode"];
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressCityKey] forKey:@"homeCity"];
}
else if (CFEqual(label, kABWorkLabel))
{
NSDictionary *addressDict = (__bridge NSDictionary *)ABMultiValueCopyValueAtIndex(addressRef, 0);
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressStreetKey] forKey:@"workAddress"];
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressZIPKey] forKey:@"workZipCode"];
[contactInfoDict setObject:[addressDict objectForKey:(NSString *)kABPersonAddressCityKey] forKey:@"workCity"];
}
CFRelease(label);
}
}
}
CFRelease(addressRef);
// If the contact has an image then get it too.
if (ABPersonHasImageData(person)) {
NSData *contactImageData = (__bridge NSData *)ABPersonCopyImageDataWithFormat(person, kABPersonImageFormatThumbnail);
[contactInfoDict setObject:contactImageData forKey:@"image"];
}
return contactInfoDict;
}
// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
// only returns a few fields, and none of the multi value ones :-(
NSMutableDictionary *results = [QuickContactsViewController convertABRecordRef:person];
ABAddressBookRef addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
ABRecordID foundId = ABRecordGetRecordID(person);
ABRecordRef fullPerson = ABAddressBookGetPersonWithRecordID(addressBook, foundId);
// also only returns a few fields!?
NSMutableDictionary *selectedFromID = [QuickContactsViewController convertABRecordRef:fullPerson];
return YES;
}
// Does not allow users to perform default actions such as dialing a phone number, when they select a person property.
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
// returns all simple and multi-value fields!?
NSMutableDictionary *results = [QuickContactsViewController convertABRecordRef:person];
return NO;
}
编辑:添加我的解决方案(感谢 Thorsten!)。
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
NSArray *allPersonRecords = (NSArray *)CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
NSLog(@"Count Linked People: %i", allPersonRecords.count);
NSMutableDictionary *results = [[NSMutableDictionary alloc]initWithCapacity:12];
for (int x=0; x<[allPersonRecords count]; x++)
{
ABRecordRef user = CFBridgingRetain([allPersonRecords objectAtIndex:x]);
NSMutableDictionary *userFromArray = [QuickContactsViewController convertABRecordRef:user];
[results addEntriesFromDictionary:userFromArray]; // mush them together
CFRelease(user);
}
NSLog(@"finished! Total number of contact fields found:%d", [results count]);
// do something with the data here...
return NO;
}
最佳答案
一个人可以由多个人组成。遍历所有人以获取您的数据:
NSArray *people = (NSArray *)CFBridgingRelease(ABPersonCopyArrayOfAllLinkedPeople(person));
...
ABRecordRef user = CFBridgingRetain([people objectAtIndex:i]);
...
valuesRef = ABRecordCopyValue(user, kABPersonPhoneProperty);
valuesCount = 0;
if (valuesRef != nil) valuesCount = ABMultiValueGetCount(valuesRef);
...
HTH
关于ios - ABRecordRef 字段似乎没有填充?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21845440/
我想将 ABRecordRef 转换为 vCard 或 NSData 以通过蓝牙传输。我遇到了你的问题,我想知道你是否能弄清楚该怎么做。 谢谢 最佳答案 非常简单,我正在使用 iOS 6 并使用以下代
[背景:iOS 7、Xcode 5,均为 2014 年 2 月最新版本。测试数据是 iPhone 5(真实设备,非模拟器)] 我的目标是使用 AddressBookUI 方法允许用户指定联系人,然后使
我有以下cpde: ABRecordRef person = ABAddressBookGetPersonWithRecordID(addressBook, ABRecordGetRecordID(s
我正在创建一个应用程序来同步地址簿。我已经将地址簿记录同步到基于本地核心数据的数据库中,并且我已经可以获取它们了。使用 ABRecordId 可以轻松同步记录。我将某条地址簿记录的记录id存储到我的本
当遍历所有地址簿联系人时,有没有办法查看记录是否为 Facebook-only 记录?即在iOS设置中添加Facebook时插入的地址簿记录。 我试图跳过这些记录,只查看用户输入的或从其他来源同步的记
我正在尝试使用 swift 从地址簿中获取人们的生日。 let ab = ABAddressBook.sharedAddressBook() var birthday: CFDateR
我想获取 ABPersonRef 和 ABGroupRef 的所有属性的列表,而不必使用 kABPersonFirstNameProperty、kABPersonLastNameProperty
ABRecordRef addressBookRecord = ...; ABNewPersonViewController *newPersonViewController = [[[ABNewPe
我有以下类,它是 ABPerson (ABRecordRef) 的包装器: @interface Recipient : NSObject { ABRecordRef person; } - (id
我想将 ABRecordRef 保存到 SQLite3 DB。我应该为 SQLite 字段使用哪种类型的数据类型? 最佳答案 您必须提取地址的各个组成部分并将它们保存为文本字符串。 更新: 如果您只需
我已经访问了地址簿并且成功地从中完全提取了记录和必要的信息。我还提取了 recordid。我的问题是以后如何使用这个 recordid 来提取记录。我使用的代码是: ABRecordID record
我想存储 Content的 ABRecordRef在我自己的应用程序中独立于 AdressBook 中的条目.在通过 stackoverflow 和苹果开发者网站交叉阅读后,我发现这是最好的方法: 如
我手动将电子邮件 ID 添加到 ABRecordRef,这会返回异常。查看代码 ABRecordRef person=ABPersonCreate(); NSString *email=@"adsas
我想存储 ABRecordRef对象,即格式为 使用 Coredata。 虽然我尝试像这样存储 NSEntityDescription *entityDescriptionStrings = [NSE
我需要在 AdreesBook 中找到联系人才能添加新的社交网络。有时我必须通过其电话和电子邮件或通过其电话、名字和姓氏来查找联系人,是否有任何类型的查询来获取 ABRecordRef 联系人而不是等
您好,我使用以下代码并通过了 abid,我能够向安装了 WhatsApp 的用户发送消息,但是在我发送消息之前我如何知道用户已经设置了 WhatsApp?如果该选项不适用于特定用户,我不想启用该选项。
我正在将一组 ABRecordID(实际上包装在 NSNumber 中)存储到 NSUserDefaults 中。到目前为止一切顺利,但现在我需要将它们加载到 ABRecordRef 中,但找不到要使
我想创建一个 ABRecordRef 数组来存储具有有效生日字段的联系人。 NSMutableArray* bContacts = [[NSMutableArray alloc] init];
我想将 ABRecordRef 存储在核心数据的“客户端”实体中。 我在苹果文档中读到 ABRecordRef 是一种原始的 C 数据类型。据我所知,您只能在核心数据中插入对象。考虑到这一点,将其存储
所以我需要将一个 Twitter 帐户添加到 ABRecordRef 中。然而,最快的方法似乎是获取社交资料属性的多值引用,创建它的可变版本,查找它是否有 Twitter 条目,如果已经有,则创建
我是一名优秀的程序员,十分优秀!