简体   繁体   English

iOS联系人未显示在表格视图中

[英]iOS Contacts not showing in tableview

I am trying to retrieve contacts from address book on iOS. 我正在尝试从iOS上的通讯录中检索联系人。

In my NSLOG all seems ok, but when I put all contacts to tableview (Labels etc), it's showing white cell and accessory only but 3 times ( I have only 3 contacts, and count working well in this case) 在我的NSLOG中,一切似乎都很好,但是当我将所有联系人放到tableview(标签等)中时,它仅显示白色单元格和附件,但显示3次(我只有3个联系人,并且在这种情况下可以正常工作)

@interface ViewController ()
@end

@implementation ViewController

@synthesize  searchBar,contactsTableView, retrievedContacts;



 - (void)viewDidLoad {

    [super viewDidLoad];

    self.title = @"All Contacts";
    self.tableData = [[NSMutableArray alloc] init];
    retrievedContacts = [[NSMutableArray alloc] init];

    self.contactsTableView.dataSource = self;
    self.contactsTableView.delegate = self;




    [self getPersons];

    [self.contactsTableView reloadData];

}


-(void)getPersons {
   // [retrievedContacts removeAllObjects];
    int i;
    ABAddressBookRef contactBook = ABAddressBookCreate();
    NSMutableArray *allData = (__bridge_transfer NSMutableArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
    CFIndex contactNum = CFArrayGetCount((__bridge CFArrayRef)(allData));

    for (i = 0; i < contactNum; i++) {
        ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
        firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
        lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
        phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
        [retrievedContacts addObject:(__bridge id)(firstName)];
        [retrievedContacts addObject:(__bridge id)(lastName)];
        [retrievedContacts addObject:(__bridge id)(phonesNum)];

        NSLog(@"First name %@", firstName);
        NSLog(@"Last Name %@", lastName);
        NSLog(@"Phone %@", phonesNum);

    }

    NSLog(@"Count Contacts %li", contactNum);
    //self.tableData = retrievedContacts;

}





-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [retrievedContacts count];
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"Cell";

    abCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (!cell) {
       cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    }

    cell.firstNameLabel.text = [retrievedContacts objectAtIndex:indexPath.row];
    cell.lastNameLabel.text = [retrievedContacts objectAtIndex:indexPath.row];

    return cell;


}

And here NSLOG Output: 这是NSLOG输出:

2013-05-28 15:50:39.260 GTCallBack[39242:c07] First name: Anton
2013-05-28 15:50:39.261 GTCallBack[39242:c07] Last Name: SAnton
2013-05-28 15:50:39.262 GTCallBack[39242:c07] Phone numbers: ABMultiValueRef 0x797e6e0 with 2 value(s)
    0: _$!<Mobile>!$_ (0x797ee30) - +972 (58) 123 4567 (0x797ee50)
    1: iPhone (0x7976cc0) - +972 (58) 123 4567 (0x797ee10)
2013-05-28 15:50:39.262 GTCallBack[39242:c07] Contact Image: Anton
2013-05-28 15:50:39.263 GTCallBack[39242:c07] First name: Anton
2013-05-28 15:50:39.263 GTCallBack[39242:c07] Last Name: Anton
2013-05-28 15:50:39.264 GTCallBack[39242:c07] Phone numbers: ABMultiValueRef 0x6d8c560 with 1 value(s)
    0: _$!<Mobile>!$_ (0x6d8c940) - (058) 123 4567 (0x6d8c960)
2013-05-28 15:50:39.268 GTCallBack[39242:c07] Contact Image: Anton
2013-05-28 15:50:39.269 GTCallBack[39242:c07] First name: Shalom
2013-05-28 15:50:39.270 GTCallBack[39242:c07] Last Name: Shalom
2013-05-28 15:50:39.270 GTCallBack[39242:c07] Phone numbers: ABMultiValueRef 0x7c689d0 with 1 value(s)
    0: _$!<Mobile>!$_ (0x7c604c0) - (058) 123 4567 (0x7c6bff0)
2013-05-28 15:50:39.271 GTCallBack[39242:c07] Contact Image: Shalom
2013-05-28 15:50:39.301 GTCallBack[39242:c07] Count Contacts 3

Maybe there is another way to fill table with contacts data? 也许还有另一种用联系人数据填充表格的方法?

Thanks 谢谢

First you need to get alloc init for array, custom cell labels also. 首先,您需要获取数组的alloc init,还需要定制单元格标签。 You not add data correctly in array. 您没有在数组中正确添加数据。

 for (i = 0; i < contactNum; i++) {
        ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
        firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
        lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
        phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);

        NSMutableDictionary *dic = [[NSMutableDictionary alloc] init];
        [dic setObject:(__bridge id)(firstName) forKey:@"firstName"];
        [dic setObject:(__bridge id)(lastName) forKey:@"lastName"];
        [dic setObject:(__bridge id)(phonesNum) forKey:@"phonesNum"];
        [retrievedContacts addObject:dic];

        NSLog(@"First name %@", [dic objectForKey:@"firstName"]);
        NSLog(@"Last Name %@", [dic objectForKey:@"lastName"]);
        NSLog(@"Phone %@",[dic objectForKey:@"phonesNum"]);

    }

Check if NSLog is printing working. 检查NSLog是否正在打印。

In cellForRow method access array in this way. 在cellForRow方法中以这种方式访问​​数组。

NSMutableDictionary *dic = [retrievedContacts objectAtIndex:indexPath.row];
cell.firstNameLabel.text = [dic objectForKey:@"firstName"];
    cell.lastNameLabel.text = [dic objectForKey:@"lastName"];

I have finished my issue yesterday. 我昨天完成我的问题。 Now all working. 现在一切正常。

Here is the code. 这是代码。

 #import "ViewController.h"
#import "ContactDetailsViewController.h"

@interface ViewController ()

@end

@implementation ViewController
@synthesize  searchBar, contactsTableView;


- (void)viewDidLoad {
    [super viewDidLoad];

    contacts = [[Contacts alloc] init];
    [contacts getContacts];

    self.title = @"All Contacts";

    self.contactsTableView.dataSource = self;
    self.contactsTableView.delegate = self;    
}

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [contacts.firstNames count];

}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellID = @"Cell";

    abCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];

    if (!cell) {
       cell = [tableView dequeueReusableCellWithIdentifier:cellID];
    }



    cell.firstNameLabel.text = [contacts.firstNames objectAtIndex:indexPath.row]; 
    cell.lastNameLabel.text = [contacts.lastNames objectAtIndex:indexPath.row];

    /*for (NSString *value in [retrievedContacts objectAtIndex:indexPath.row]) {
        NSMutableArray *tmp = [[NSMutableArray alloc] init];

        [tmp addObject:[[retrievedContacts objectAtIndex:indexPath.row] valueForKey:value]];
        NSLog(@"Contact: %@", tmp);
    }*/

    /*NSLog(@"Name: %@", [[retrievedContacts objectAtIndex:indexPath.row] valueForKey:@"First Name"]);
    NSLog(@"Familie: %@", [[retrievedContacts objectAtIndex:indexPath.row] valueForKey:@"Last Name"]);


    NSLog(@"PHONE TYPE: %@ • PHONE NUMBER: %@", [[[retrievedContacts objectAtIndex:indexPath.row] objectForKey:@"Phones"] valueForKey: @"Phone Label"], [[[retrievedContacts objectAtIndex:indexPath.row] objectForKey:@"Phones"] valueForKey: @"Phone Number"]);*/

    return cell;


}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {

    [self.contactsTableView deselectRowAtIndexPath:indexPath animated:YES];
}

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {


    if ([[segue identifier] isEqualToString:@"NextView"]) {

        ContactDetailsViewController *nextController = [segue destinationViewController];
        NSIndexPath *indexPath = [[[self contactsTableView] indexPathsForSelectedRows] objectAtIndex:0];
        [nextController setPhoneTypes:[contacts.phoneTypes objectAtIndex:[indexPath row]]];
        [nextController setPhoneNumbers:[contacts.phoneNumbers objectAtIndex:[indexPath row]]];

    }

}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end




    #import "Contacts.h"

@implementation Contacts
@synthesize firstNames, lastNames, phoneTypes, phoneNumbers, photos, retrievedContacts;

-(void)getContacts {

    ABAddressBookRef addressBook = ABAddressBookCreate();

    __block BOOL accessGranted = NO;
    if (ABAddressBookRequestAccessWithCompletion != NULL) { // we're on iOS 6
        dispatch_semaphore_t sema = dispatch_semaphore_create(0);
        ABAddressBookRequestAccessWithCompletion(addressBook, ^(bool granted, CFErrorRef error) {
            accessGranted = granted;
            dispatch_semaphore_signal(sema);
        });
        dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
        dispatch_release(sema);
    }
    else { // we're on iOS 5 or older
        accessGranted = YES;
    }

    if (accessGranted) {

        int i;

        firstNames = [[NSMutableArray alloc] init];
        lastNames = [[NSMutableArray alloc] init];
        phoneTypes = [[NSMutableArray alloc] init];
        phoneNumbers = [[NSMutableArray alloc] init];
        photos = [[NSMutableArray alloc] init];

        ABAddressBookRef contactBook = ABAddressBookCreate();
        NSMutableArray *allData = (__bridge_transfer NSMutableArray *)(ABAddressBookCopyArrayOfAllPeople(contactBook));
        contactNum = CFArrayGetCount((__bridge CFArrayRef)(allData));

        retrievedContacts  = [[NSMutableArray alloc] init];

        for (i = 0; i < contactNum; i++) {

            ABRecordRef ref = CFArrayGetValueAtIndex((__bridge CFMutableArrayRef)(allData), i);
            firstName = ABRecordCopyValue(ref, kABPersonFirstNameProperty);
            lastName = ABRecordCopyValue(ref, kABPersonLastNameProperty);
            phonesNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
            ContactImg = ABRecordCopyValue(ref, kABPersonImageFormatThumbnail);

            ABMutableMultiValueRef phoneNum = ABRecordCopyValue(ref, kABPersonPhoneProperty);
            CFIndex phoneNumberCount = ABMultiValueGetCount( phoneNum );

            if (!firstName) {

                [firstNames addObject:@"NO NAME"];
                //NSLog(@"FN %@ • LN %@ • CI %@", firstName, lastName, ContactImg);
            } else if (!lastName) {

                [lastNames addObject:@"NO LAST NAME"];

            } else if (!ContactImg) {

                [photos addObject:@"NOIMG.png"];

            } else {

                /*NSMutableArray *person = [[NSMutableArray alloc] init];
                 [person addObject:(__bridge id)(firstName)];
                 [person addObject:(__bridge id)(lastName)];
                 //[person addObject:(__bridge id)(phonesNum)];
                 [person addObject:(__bridge id)(ContactImg)];
                 [retrievedContacts addObject:person];*/

                [firstNames addObject:(__bridge id)(firstName)];
                [lastNames addObject:(__bridge id)(lastName)];
                [photos addObject:(__bridge id)(ContactImg)];

                NSMutableArray *tmpType = [[NSMutableArray alloc] init];
                NSMutableArray *tmpNumbr = [[NSMutableArray alloc] init];

                for (int k = 0; k < phoneNumberCount; k++ )
                {
                    CFStringRef phoneNumberLabel = ABMultiValueCopyLabelAtIndex( phoneNum, k );
                    CFStringRef phoneNumberValue = ABMultiValueCopyValueAtIndex( phoneNum, k );
                    CFStringRef phoneNumberLocalizedLabel = ABAddressBookCopyLocalizedLabel( phoneNumberLabel );    // converts "_$!<Work>!$_" to "work" and "_$!<Mobile>!$_" to "mobile"


                    NSLog(@"-----PHONE ENTRY -> %@ : %@\nPERSON NUM. %i • PHONE NUM. %i", phoneNumberLocalizedLabel, phoneNumberValue, i, k );

                    [tmpType addObject:(__bridge id)(phoneNumberLocalizedLabel)];
                    [tmpNumbr addObject:(__bridge id)(phoneNumberValue)];

                    CFRelease(phoneNumberLocalizedLabel);
                    CFRelease(phoneNumberLabel);
                    CFRelease(phoneNumberValue);
                }

                [phoneTypes addObject:tmpType];
                [phoneNumbers addObject:tmpNumbr];

#ifdef DEBUG
                //NSLog(@"First name: %@", firstName);
                //NSLog(@"Last Name: %@", lastName);
                //NSLog(@"Phone numbers: %@", phonesNum);
                //NSLog(@"Contact Image: %@", ContactImg);
                //NSLog(@"Some Text %@", retrievedContacts); //Here everething is OK :)
#endif
            }
        }
    }
}



@end

Hope it will save to someone a time. 希望可以节省时间。

Thanks to all 谢谢大家

Try type casting like this: 尝试像这样进行类型转换:

cell.firstNameLabel.text = (NSString*)[retrievedContacts objectAtIndex:indexPath.row];
cell.lastNameLabel.text = (NSString*)[retrievedContacts objectAtIndex:indexPath.row];

Or you can try this before adding to array: 或者您可以在添加到数组之前尝试以下操作:

   NSString *firstName = (NSString *)ABRecordCopyValue(ref, kABPersonFirstNameProperty);
   NSString *lastName = (NSString *)ABRecordCopyValue(ref, kABPersonLastNameProperty);

I have used similar code and it worked for me. 我使用了类似的代码,它为我工作。

Hope this helps. 希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM