1

我正在尝试从 AddressBook 中检索所有联系人并将以下详细信息存储在 Mutable 数组中。

属性是

@property (nonatomic, assign) ABAddressBookRef addressBook;
@property (nonatomic, strong) NSMutableArray *contactList;
@property (nonatomic, strong) IBOutlet UITableView *contactsTableView;

检索所有联系人的方法

- (void)getAllContacts {
    //line moved inside For loop as per Amar's answer. 
    //NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];
    self.addressBook = ABAddressBookCreateWithOptions(NULL, NULL); //iOS 6 and above
    CFArrayRef cList = ABAddressBookCopyArrayOfAllPeopleInSourceWithSortOrdering(self.addressBook, NULL, kABPersonSortByFirstName);
    CFIndex nPeople = ABAddressBookGetPersonCount(self.addressBook);
    for (int i=0; i<nPeople; i++) {
        //Moving this line here per Amar's answer below. The code works perfectly now.
        NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];
        ABRecordRef personRef = CFArrayGetValueAtIndex(cList, i); // Person will have name, phone number, address, email id and contact image

        //Get the name
        NSString *firstName = (__bridge NSString *)(ABRecordCopyValue(personRef, kABPersonFirstNameProperty));
        NSString *lastName = (__bridge NSString *)(ABRecordCopyValue(personRef, kABPersonLastNameProperty));
        NSString *name = nil;
        if(firstName!=nil && lastName!=nil) { //both names are available
            name = [NSString stringWithFormat:@"%@ %@",firstName,lastName];
        } else if(firstName!=nil && lastName==nil) { //last name not available
            name = [NSString stringWithFormat:@"%@",firstName];
        } else if(firstName==nil && lastName!=nil) { //first name not available
            name = [NSString stringWithFormat:@"%@",lastName];
        } else {
            name = @"Unnamed Contact"; //both names not available
        }
        //Get the phone numbers
        ABMultiValueRef phoneRef = ABRecordCopyValue(personRef, kABPersonPhoneProperty);
        NSMutableArray *phoneNumbers = [NSMutableArray new];
        CFIndex ctr = ABMultiValueGetCount(phoneRef);
        if(ctr!=0) {
            NSString *phoneNumber = nil;
            for (CFIndex i=0; i<ctr; i++) {
                phoneNumber = (__bridge NSString *) ABMultiValueCopyValueAtIndex(phoneRef, i);
                [phoneNumbers addObject:phoneNumber];
            }
        } else {
            [phoneNumbers addObject:@"Phone not available"];
        }

        //Get the contact address
        ABMultiValueRef addrRef = ABRecordCopyValue(personRef, kABPersonAddressProperty);
        NSMutableArray *addresses = [NSMutableArray new];
        ctr = ABMultiValueGetCount(addrRef);
        if(ABMultiValueGetCount(addrRef)!=0) {
            for(CFIndex i=0; i<ABMultiValueGetCount(addrRef); i++) {
                CFDictionaryRef addr = ABMultiValueCopyValueAtIndex(addrRef, i);
                NSString *street = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressStreetKey);
                NSString *city = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressCityKey);
                NSString *state = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressStateKey);
                NSString *zip = (__bridge NSString *)CFDictionaryGetValue(addr, kABPersonAddressZIPKey);
                NSString *address = [NSString stringWithFormat:@"%@, %@, %@ %@",street,city,state,zip];
                [addresses addObject:address];
            }
        } else {
            [addresses addObject:@"Address not available"];
        }

        //Get the email address
        ABMultiValueRef emailRef = ABRecordCopyValue(personRef, kABPersonEmailProperty);
        NSMutableArray *emailAddresses = [NSMutableArray new];
        ctr = ABMultiValueGetCount(emailRef);
        if(ctr!=0) {
            for(CFIndex i=0; i<ctr; i++) {
                NSString *eId = (__bridge NSString*)ABMultiValueCopyValueAtIndex(emailRef, i);
                [emailAddresses addObject:eId];
            }
        } else {
            [emailAddresses addObject:@"EmailID not available"];
        }

        //Get the contact image
        UIImage *image = nil;
        if(ABPersonHasImageData(personRef)) image = (__bridge UIImage *)(ABPersonCopyImageDataWithFormat(personRef, kABPersonImageFormatThumbnail));

        //Append the values to a dictionary
        [personModel setValue:name forKey:@"cName"];
        [personModel setValue:phoneNumbers forKey:@"cPhone"];
        [personModel setValue:addresses forKey:@"cAddresses"];
        [personModel setValue:emailAddresses forKey:@"cEmailID"];
        [personModel setValue:image forKey:@"cImage"];

        [self.contactList addObject: personModel];
    }
}

在 tableView 的数据源方法 cellForRowAtIndexPath

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:ContactsCell forIndexPath:indexPath];

    cell.textLabel.font = [UIFont fontWithName:@"Helvetica" size:16];
    cell.textLabel.textColor = [UIColor blackColor];
    cell.detailTextLabel.font = [UIFont systemFontOfSize:14.0];
    cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    NSDictionary *model = [self.contactList objectAtIndex:indexPath.row];
    NSLog(@"Name:%@",[model valueForKey:@"cName"]);
    cell.textLabel.text =[model valueForKey:@"cName"];
    return cell;
}

我的通讯录中有四个联系人。但是,我的 tableView 总是返回最后一个联系人的姓名(这是“未命名的联系人”,因为它没有名字/姓氏)。

Unnamed Contact
Unnamed Contact
Unnamed Contact
Unnamed Contact

知道为什么吗?

4

2 回答 2

2

那是因为这条线

NSMutableDictionary *personModel = [[NSMutableDictionary alloc]initWithCapacity:0];

for-loop 之外。在迭代联系人列表和修改同一个字典之前,您只创建了一次字典。因此,它将始终存储最后的联系信息。

相反,将上面的代码行移动到 for 循环中,它将创建一个新字典,用于存储列表中的每个联系人。

希望有帮助!

于 2013-09-30T05:56:44.843 回答
0

每次您将数据存储在具有相同 KEY 'cName' "[personModel setValue:name forKey:@"cName"];" 的字典中时 这就是为什么每次值都用相同的键覆盖并且最后一条记录存储在字典中的原因,这就是引发问题的原因,您需要使用不同的键存储数据或直接从数组而不是字典中获取数据

于 2013-09-30T06:02:44.223 回答