从联系人中获取所有电子邮件地址(iOS)

10

我知道可以通过一个联系人来查看信息。但是否有办法获取您已输入电子邮件地址的联系人的所有电子邮件,然后将其存储在NSArray中?这是我第一次处理联系人,所以我对此并不了解。


2
天哪,希望不是这样。你能想象将那些数据暴露给一些随机的应用程序吗? - George Johnston
我猜是这样,但这是为了客户,所以我只是想看看是否可能。 - SimplyKiwi
我相信这是可能的,一定有一些方法可以枚举联系人... - Alex Coplan
4个回答

30

是的,你可以这样做。虽然不清楚你为什么需要这些信息而显得有些可疑,但实现起来并不难。

你可以使用 ABAddressBookCopyArrayOfAllPeople 获取包含所有人的 CFArrayRef,然后针对每个人使用 ABRecordCopyValue 查询其 kABPersonEmailProperty 属性。代码大致如下(未经测试):

ABAddressBookRef addressBook = ABAddressBookCreate();
CFArrayRef people = ABAddressBookCopyArrayOfAllPeople(addressBook);
NSMutableArray *allEmails = [[NSMutableArray alloc] initWithCapacity:CFArrayGetCount(people)];
for (CFIndex i = 0; i < CFArrayGetCount(people); i++) {
    ABRecordRef person = CFArrayGetValueAtIndex(people, i);
    ABMultiValueRef emails = ABRecordCopyValue(person, kABPersonEmailProperty);
    for (CFIndex j=0; j < ABMultiValueGetCount(emails); j++) {
        NSString* email = (NSString*)ABMultiValueCopyValueAtIndex(emails, j);
        [allEmails addObject:email];
        [email release];
    }
    CFRelease(emails);
}
CFRelease(addressBook);
CFRelease(people);

(内存分配可能有一点偏差;我已经有一段时间没有开发Cocoa/Core Foundation代码了。)

但说真的,为什么要这样做呢?很可能只需在适当的时候使用Apple提供的API来呈现联系人选择器就能找到更好的解决方案。


可疑……删掉它!认真地说,根据您的实现方式,苹果可能会拒绝:/ - Alex Coplan
2
我这样做是为了提供一种简单的方式来给所有联系人发送电子邮件或短信。这并不是为了恶意使用。 - SimplyKiwi
此外,在[emails addObject:email];一行中,我遇到了一个错误。错误是坏的接收器类型'ABMultiValueRef'(又名'const void *')。我该如何修复这个问题?还有一件事,您给NSMutableArray和ABMultiValueRef相同的变量名称?这是有意为之吗? - SimplyKiwi
糟糕!我刚刚两次使用了相同的变量名。我已经将上面代码示例中的NSMutableArray*重命名为allEmails,这应该可以解决问题。另外,为了清晰起见,我已经将email的类型从CFStringRef更改为NSString* - Jeremy Roman
谢谢,很好用!另外,我不确定是否可能,但您能否使用ABAddressBook并从列表中隐藏没有输入电子邮件地址的联系人?最终,我想从已输入电子邮件地址的人员列表中选择特定的人员,然后将它们添加到一个数组中。这是可能的吗? - SimplyKiwi
显示剩余6条评论

20
ABAddressBookRef allPeople = ABAddressBookCreate();
CFArrayRef allContacts = ABAddressBookCopyArrayOfAllPeople(allPeople);
CFIndex numberOfContacts  = ABAddressBookGetPersonCount(allPeople);

NSLog(@"numberOfContacts------------------------------------%ld",numberOfContacts);


for(int i = 0; i < numberOfContacts; i++){
    NSString* name = @"";
    NSString* phone = @"";
    NSString* email = @"";

    ABRecordRef aPerson = CFArrayGetValueAtIndex(allContacts, i);
    ABMultiValueRef fnameProperty = ABRecordCopyValue(aPerson, kABPersonFirstNameProperty);
    ABMultiValueRef lnameProperty = ABRecordCopyValue(aPerson, kABPersonLastNameProperty);

    ABMultiValueRef phoneProperty = ABRecordCopyValue(aPerson, kABPersonPhoneProperty);\
    ABMultiValueRef emailProperty = ABRecordCopyValue(aPerson, kABPersonEmailProperty);

    NSArray *emailArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
    NSArray *phoneArray = (__bridge NSArray *)ABMultiValueCopyArrayOfAllValues(phoneProperty);


    if (fnameProperty != nil) {
        name = [NSString stringWithFormat:@"%@", fnameProperty];
    }
    if (lnameProperty != nil) {
        name = [name stringByAppendingString:[NSString stringWithFormat:@" %@", lnameProperty]];
    }

    if ([phoneArray count] > 0) {
        if ([phoneArray count] > 1) {
            for (int i = 0; i < [phoneArray count]; i++) {
                phone = [phone stringByAppendingString:[NSString stringWithFormat:@"%@\n", [phoneArray objectAtIndex:i]]];
            }
        }else {
            phone = [NSString stringWithFormat:@"%@", [phoneArray objectAtIndex:0]];
        }
    }

    if ([emailArray count] > 0) {
        if ([emailArray count] > 1) {
            for (int i = 0; i < [emailArray count]; i++) {
                email = [email stringByAppendingString:[NSString stringWithFormat:@"%@\n", [emailArray objectAtIndex:i]]];
            }
        }else {
            email = [NSString stringWithFormat:@"%@", [emailArray objectAtIndex:0]];
        }
    }

    NSLog(@"NAME : %@",name);
    NSLog(@"PHONE: %@",phone);
    NSLog(@"EMAIL: %@",email);
    NSLog(@"\n");
}

截至iOS 6.0,这是更好的答案。 - Marc Cenedella
这对我来说也更好,因为我只需要一个电子邮件,它会返回剥离了不必要数据的值。谢谢! - Simon

2
@import AddressBook;

- (void)addressBookInit {
    if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusDenied || ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusRestricted){
//        NSLog(@"Denied");
        UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle: @"Cannot get contacts" message: @"You must give the app permission to read the contacts first." delegate:nil cancelButtonTitle: @"OK" otherButtonTitles: nil];
        [cantAddContactAlert show];
    } else if (ABAddressBookGetAuthorizationStatus() == kABAuthorizationStatusAuthorized){
//        NSLog(@"Authorized");
        [self getEmails];
    } else {
//        NSLog(@"Not determined");
        ABAddressBookRequestAccessWithCompletion(ABAddressBookCreateWithOptions(NULL, nil), ^(bool granted, CFErrorRef error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if (!granted){
                    //4
                    UIAlertView *cantAddContactAlert = [[UIAlertView alloc] initWithTitle: @"Cannot get contacts" message: @"You must give the app permission to read the contacts first." delegate:nil cancelButtonTitle: @"OK" otherButtonTitles: nil];
                    [cantAddContactAlert show];
                    return;
                }
//                NSLog(@"Authorized 2");
                [self getEmails];

            });
        });
    }
}

-(NSArray *)getEmails
{
    NSMutableArray *emails = [NSMutableArray array];
    ABAddressBookRef addressBookRef = ABAddressBookCreateWithOptions(NULL, nil);
    NSArray *allContacts = (__bridge NSArray *)ABAddressBookCopyArrayOfAllPeople(addressBookRef);
    for (id record in allContacts)
    {
        ABRecordRef person = (__bridge ABRecordRef)record;
        ABMultiValueRef emailProperty = ABRecordCopyValue(person, kABPersonEmailProperty) ;
        NSArray *personEmails = (__bridge_transfer NSArray *)ABMultiValueCopyArrayOfAllValues(emailProperty);
        [emails addObjectsFromArray:personEmails];
        CFRelease(person);
        CFRelease(emailProperty);
    }
    CFRelease(addressBookRef) ;
    for (NSString *email in emails)
    {
        NSLog(@"%@", email) ;
    }
    return emails;
}

1
对于iOS 9及以上版本,请使用Contacts框架,使用Objective C语言。保留HTML格式,不进行解释。
-(NSArray*)getAllContacts{
__block NSMutableArray *allContacts = nil;
CNContactStore *store = [[CNContactStore alloc] init];
[store requestAccessForEntityType:CNEntityTypeContacts completionHandler:^(BOOL granted, NSError * _Nullable error) {
    if (granted == YES) {
        //keys with fetching properties
        NSArray *keys = @[CNContactFamilyNameKey, CNContactGivenNameKey, CNContactEmailAddressesKey, CNContactImageDataKey];
        NSString *containerId = store.defaultContainerIdentifier;
        NSPredicate *predicate = [CNContact predicateForContactsInContainerWithIdentifier:containerId];
        NSError *error;
        NSArray *cnContacts = [store unifiedContactsMatchingPredicate:predicate keysToFetch:keys error:&error];
        if (error) {
            NSLog(@"error fetching contacts %@", error);
        } else {
            allContacts = [NSMutableArray array];
            for (CNContact *contact in cnContacts) {
                // copy data to my custom Contacts class.
                // create custom class Contacts with firstName,lastName,image and emailAddress
                for (CNLabeledValue<NSString*> *email in contact.emailAddresses) {
                    Contact *newContact = [[Contact alloc] init];
                    newContact.firstName = contact.givenName;
                    newContact.lastName = contact.familyName;
                    UIImage *image = [UIImage imageWithData:contact.imageData];
                    newContact.image = image;
                    newContact.emailAddress = email.value;
                    [allContacts addObject:newContact];
                }
            }
        }
    }
}];
return allContacts;}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接