TableViewController不显示联系人

时间:2013-12-19 08:07:08

标签: uitableview contacts

我是编程新手。我有一个粗略的c ++知识库,但Objective-c对我来说是全新的。

我正在尝试在应用中实现一个简单的UITableViewController,系统会提示用户从其联系人列表中添加电子邮件收件人。 TableViewController加载但不加载TableViewCell数据。我一直在搜索iOS开发人员库,我觉得这些信息非常像千篇一律。我找到了他们的示例代码并将其复制/粘贴到我的ViewController文件中。我做了必要的更改以符合我的文件,删除了一些不必要的电话,并按照我在这个网站上找到的远程处理我的问题的每个答案......无济于事!这是我到目前为止所做的:

·H

    @interface RecipientsViewController : UITableViewController <UITableViewDelegate, UITableViewDataSource>

的.m

#import "RecipientsViewController.h"
#import <AddressBook/AddressBook.h>
#import <AddressBookUI/AddressBookUI.h>
enum TableRowSelected
{
    kUIDisplayPickerRow = 0,
    kUICreateNewContactRow,
    kUIDisplayContactRow,
    kUIEditUnknownContactRow
};

// Height for the Edit Unknown Contact row
#define kUIEditUnknownContactRowHeight 81.0


@interface RecipientsViewController () < ABPeoplePickerNavigationControllerDelegate,ABPersonViewControllerDelegate,
ABNewPersonViewControllerDelegate, ABUnknownPersonViewControllerDelegate>

@property (nonatomic, assign) ABAddressBookRef addressBook;
@property (nonatomic, strong) NSMutableArray *menuArray;

@end

@implementation RecipientsViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
        self.title = @"Recipients";
    }
    return self;
}

#pragma mark Load views
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad
{
    [super viewDidLoad];
    // Create an address book object
    _addressBook = ABAddressBookCreateWithOptions(NULL, NULL);
    self.menuArray = [[NSMutableArray alloc] initWithCapacity:0];
    [self checkAddressBookAccess];
    [self.tableView reloadData];
}

#pragma mark -
#pragma mark Address Book Access
    // Check the authorization status of our application for Address Book
    -(void)checkAddressBookAccess
    {
        switch (ABAddressBookGetAuthorizationStatus())
        {
                // Update our UI if the user has granted access to their Contacts
            case  kABAuthorizationStatusAuthorized:
                [self accessGrantedForAddressBook];
                break;
                // Prompt the user for access to Contacts if there is no definitive answer
            case  kABAuthorizationStatusNotDetermined :
                [self requestAddressBookAccess];
                break;
                // Display a message if the user has denied or restricted access to Contacts
            case  kABAuthorizationStatusDenied:
            case  kABAuthorizationStatusRestricted:
            {
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Privacy Warning"
                                                                message:@"Permission was not granted for Contacts."
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK"
                                                      otherButtonTitles:nil];
                [alert show];
            }
                break;
            default:
                break;
        }
    }

    // Prompt the user for access to their Address Book data
    -(void)requestAddressBookAccess
    {
        RecipientsViewController * __weak weakSelf = self;

        ABAddressBookRequestAccessWithCompletion(self.addressBook, ^(bool granted, CFErrorRef error)
                                                 {
                                                     if (granted)
                                                     {
                                                         dispatch_async(dispatch_get_main_queue(), ^{
                                                             [weakSelf accessGrantedForAddressBook];

                                                         });
                                                     }
                                                 });
    }

    // This method is called when the user has granted access to their address book data.
    -(void)accessGrantedForAddressBook
    {
        // Load data from the plist file
        NSString *plistPath = [[NSBundle mainBundle] pathForResource:@"Menu" ofType:@"plist"];
        self.menuArray = [NSMutableArray arrayWithContentsOfFile:plistPath];
        [self.tableView reloadData];
    }

    // Uncomment the following line to preserve selection between presentations.
    // self.clearsSelectionOnViewWillAppear = NO;

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;

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

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{

    // Return the number of sections.
    return [self.menuArray count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{

    // Return the number of rows in the section.
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *aCell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    if (aCell == nil)
    {
        // Make the Display Picker and Create New Contact rows look like buttons
        if (indexPath.section < 2)
        {
            aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
            aCell.textLabel.textAlignment = NSTextAlignmentCenter;
        }
        else
        {
            aCell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
            aCell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
            aCell.detailTextLabel.numberOfLines = 0;
            // Display descriptions for the Edit Unknown Contact and Display and Edit Contact rows
            aCell.detailTextLabel.text = [[self.menuArray objectAtIndex:indexPath.section] valueForKey:@"description"];
        }
    }

    // Configure the cell...

    return aCell;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    switch (indexPath.section)
    {
        case kUIDisplayPickerRow:
            [self showPeoplePickerController];
            break;
        case kUICreateNewContactRow:
            [self showNewPersonViewController];
            break;
        case kUIDisplayContactRow:
            [self showPersonViewController];
            break;
        case kUIEditUnknownContactRow:
            [self showUnknownPersonViewController];
            break;
        default:
            [self showPeoplePickerController];
            break;
    }
}

#pragma mark TableViewDelegate method
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Change the height if Edit Unknown Contact is the row selected
    return (indexPath.section==kUIEditUnknownContactRow) ? kUIEditUnknownContactRowHeight : tableView.rowHeight;
}

#pragma mark Show all contacts
// Called when users tap "Display Picker" in the application. Displays a list of contacts and allows users to select a contact from that list.
// The application only shows the phone, email, and birthdate information of the selected contact.
-(void)showPeoplePickerController
{
    ABPeoplePickerNavigationController *picker = [[ABPeoplePickerNavigationController alloc] init];
    picker.peoplePickerDelegate = self;
    // Display only a person's phone, email, and birthdate
    NSArray *displayedItems = [NSArray arrayWithObjects:[NSNumber numberWithInt:kABPersonPhoneProperty],
                               [NSNumber numberWithInt:kABPersonEmailProperty],
                               [NSNumber numberWithInt:kABPersonBirthdayProperty], nil];


    picker.displayedProperties = displayedItems;
    // Show the picker
    [self presentViewController:picker animated:YES completion:nil];
}

#pragma mark Display and edit a person
// Called when users tap "Display and Edit Contact" in the application. Searches for a contact named "Appleseed" in
// in the address book. Displays and allows editing of all information associated with that contact if
// the search is successful. Shows an alert, otherwise.
-(void)showPersonViewController
{
    // Search for the person named "Appleseed" in the address book
    NSArray *people = (NSArray *)CFBridgingRelease(ABAddressBookCopyPeopleWithName(self.addressBook, CFSTR("Appleseed")));
    // Display "Appleseed" information if found in the address book
    if ((people != nil) && [people count])
    {
        ABRecordRef person = (__bridge ABRecordRef)[people objectAtIndex:0];
        ABPersonViewController *picker = [[ABPersonViewController alloc] init];
        picker.personViewDelegate = self;
        picker.displayedPerson = person;
        // Allow users to edit the person’s information
        picker.allowsEditing = YES;
        [self.navigationController pushViewController:picker animated:YES];
    }
    else
    {
        // Show an alert if "Appleseed" is not in Contacts
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                        message:@"Could not find Appleseed in the Contacts application"
                                                       delegate:nil
                                              cancelButtonTitle:@"Cancel"
                                              otherButtonTitles:nil];
        [alert show];
    }
}

#pragma mark Create a new person
// Called when users tap "Create New Contact" in the application. Allows users to create a new contact.
-(void)showNewPersonViewController
{
    ABNewPersonViewController *picker = [[ABNewPersonViewController alloc] init];
    picker.newPersonViewDelegate = self;

    UINavigationController *navigation = [[UINavigationController alloc] initWithRootViewController:picker];
    [self presentViewController:navigation animated:YES completion:nil];
}

#pragma mark Add data to an existing person
// Called when users tap "Edit Unknown Contact" in the application.
-(void)showUnknownPersonViewController
{
    ABRecordRef aContact = ABPersonCreate();
    CFErrorRef anError = NULL;
    ABMultiValueRef email = ABMultiValueCreateMutable(kABMultiStringPropertyType);
    bool didAdd = ABMultiValueAddValueAndLabel(email, @"John-Appleseed@mac.com", kABOtherLabel, NULL);

    if (didAdd == YES)
    {
        ABRecordSetValue(aContact, kABPersonEmailProperty, email, &anError);
        if (anError == NULL)
        {
            ABUnknownPersonViewController *picker = [[ABUnknownPersonViewController alloc] init];
            picker.unknownPersonViewDelegate = self;
            picker.displayedPerson = aContact;
            picker.allowsAddingToAddressBook = YES;
            picker.allowsActions = YES;
            picker.alternateName = @"John Appleseed";
            picker.title = @"John Appleseed";
            picker.message = @"Company, Inc";

            [self.navigationController pushViewController:picker animated:YES];
        }
        else
        {
            UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                            message:@"Could not create unknown user"
                                                           delegate:nil
                                                  cancelButtonTitle:@"Cancel"
                                                  otherButtonTitles:nil];
            [alert show];
        }
    }
    CFRelease(email);
    CFRelease(aContact);
}

#pragma mark ABPeoplePickerNavigationControllerDelegate methods
// Displays the information of a selected person
- (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker shouldContinueAfterSelectingPerson:(ABRecordRef)person
{
    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
{
    return NO;
}

// Dismisses the people picker and shows the application when users tap Cancel.
- (void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker;
{
    [self dismissViewControllerAnimated:YES completion:NULL];
}

#pragma mark ABPersonViewControllerDelegate methods
// Does not allow users to perform default actions such as dialing a phone number, when they select a contact property.
- (BOOL)personViewController:(ABPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person
                    property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifierForValue
{
    return NO;
}


#pragma mark ABNewPersonViewControllerDelegate methods
// Dismisses the new-person view controller.
- (void)newPersonViewController:(ABNewPersonViewController *)newPersonViewController didCompleteWithNewPerson:(ABRecordRef)person
{
    [self loadView];
}

#pragma mark ABUnknownPersonViewControllerDelegate methods
// Dismisses the picker when users are done creating a contact or adding the displayed person properties to an existing contact.
- (void)unknownPersonViewController:(ABUnknownPersonViewController *)unknownPersonView didResolveToPerson:(ABRecordRef)person
{
    [self.navigationController popViewControllerAnimated:YES];
}

// Does not allow users to perform default actions such as emailing a contact, when they select a contact property.
- (BOOL)unknownPersonViewController:(ABUnknownPersonViewController *)personViewController shouldPerformDefaultActionForPerson:(ABRecordRef)person property:(ABPropertyID)property identifier:(ABMultiValueIdentifier)identifier
{
    return NO;
}

SORRY !!!不确定代码的哪些部分与问题最相关。

* 鉴于这么多代码对我来说有点压倒性的问题,我会非常感谢对此的一些帮助。我没有出现任何错误或问题,TableViewController加载。它只是提示用户允许访问联系人几次,而且从那时起就没有。即使提示确实显示,它也从未将我带到模拟器上的联系人。我在iOS模拟器中添加了联系人。

我真诚地感谢任何帮助!

2 个答案:

答案 0 :(得分:0)

我还没有完成你的所有代码,但是我所描述的问题主要发生在我的数组为空时,尝试将数组内容的NSLog放在你要添加objets的地方,以便查看如果它的计数大于0。

答案 1 :(得分:0)

您使用的是哪个版本的iOS?这将决定它是否会显示,如果它是iOS 7,那么你需要获得查看地址簿的权限,这就是他们添加的新内容。

此链接 https://developer.apple.com/library/ios/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/Chapters/QuickStart.html#//apple_ref/doc/uid/TP40007744-CH2-SW1