2013-12-19 1 views
0

저는 프로그래밍에 익숙하지 않습니다. 나는 C++의 거친 지식 기반을 가지고 있지만 objective-c는 완전히 새로운 것이다.TableViewController 연락처가 표시되지 않습니다.

사용자가 연락처 목록에서 전자 메일받는 사람을 추가 할 것인지 묻는 응용 프로그램에서 간단한 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, @"[email protected]", 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; 
} 

미안! 어떤 코드 섹션이 문제와 가장 관련이 있는지 확실하지 않습니다.

* 많은 코드가 문제 해결을 위해 다소 압도적 인 경우이 문제에 대한 도움을 크게 주시면 감사하겠습니다. 오류나 문제가 나타나면 TableViewController가로드됩니다. 사용자에게 몇 번만 연락처에 대한 액세스를 허용하고 이후로는하지 않았습니다. 프롬프트가 표시 되더라도 시뮬레이터의 연락처로 이동하지 않았습니다. iOS 시뮬레이터에 연락처를 추가했습니다.

나는 어떤 도움에 진심으로 감사드립니다!

답변

0

나는 모든 코드를 살펴 보지 못했지만 설명 된 문제는 주로 배열이 비어있을 때 발생합니다. 배열 내용의 NSLog를 objets를 추가하는 위치에 놓으십시오. 해당 수가 0보다 큰지 확인하십시오.

+0

감사합니다! 좋아, 그래서 방금 0으로 계산했다. 어떻게 해결할 수 있을까요? 다음은 NSLog를 추가 한 코드입니다. - (void) viewDidLoad { [super viewDidLoad]; // 주소록 개체 만들기 _addressBook = ABAddressBookCreateWithOptions (NULL, NULL); self.menuArray = [[NSMutableArray alloc] initWithCapacity : 0]; [self checkAddressBookAccess]; [self.tableView reloadData]; NSLog (@ "배열의 항목 수 : % lu", [_menuArray count]); } – FundamentalClue

관련 문제