当我想要取得联系人时,ios 11上的应用程序崩溃?

当我想要取得联系人时,ios 11上的应用程序崩溃?

问题描述:

我的应用程序很好地工作在iOS 9和10,但是当我要访问iOS上的接触11应用程序崩溃 (实际上得到螺纹8:信号SIGABRT当点击选项卡中的联系人)当我想要取得联系人时,ios 11上的应用程序崩溃?


的malloc :*错误对象0x1c401b410:免费列表 *离队无效的指针设置malloc_error_break断点调试


ContactsViewController.m

#import "ContactsViewController.h" 
    #import "PhoneMainView.h" 
    #import "Utils.h" 
    #import "Utility.h" 
    #import "Reachability.h" 
    #import "AddContactViewController.h" 
    #import <AddressBook/ABPerson.h> 

    @implementation ContactSelection 

    static ContactSelectionMode sSelectionMode = ContactSelectionModeNone; 
    static NSString* sAddAddress = nil; 
    static NSString* sSipFilter = nil; 
    static BOOL sEnableEmailFilter = FALSE; 
    static NSString* sNameOrEmailFilter; 

    + (void)setSelectionMode:(ContactSelectionMode)selectionMode { 
     sSelectionMode = selectionMode; 
    } 

    + (ContactSelectionMode)getSelectionMode { 
     return sSelectionMode; 
    } 

    + (void)setAddAddress:(NSString*)address { 
     if(sAddAddress != nil) { 
      [sAddAddress release]; 
      sAddAddress= nil; 
     } 
     if(address != nil) { 
      sAddAddress = [address retain]; 
     } 
    } 

    + (NSString*)getAddAddress { 
     return sAddAddress; 
    } 

    + (void)setSipFilter:(NSString*)domain { 
     [sSipFilter release]; 
     sSipFilter = [domain retain]; 
    } 

    + (NSString*)getSipFilter { 
     return sSipFilter; 
    } 

    + (void)enableEmailFilter:(BOOL)enable { 
     sEnableEmailFilter = enable; 
    } 

    + (BOOL)emailFilterEnabled { 
     return sEnableEmailFilter; 
    } 

    + (void)setNameOrEmailFilter:(NSString*)fuzzyName { 
     [sNameOrEmailFilter release]; 
     sNameOrEmailFilter = [fuzzyName retain]; 
    } 

    + (NSString*)getNameOrEmailFilter { 
     return sNameOrEmailFilter; 
    } 


    @end 

    @implementation ContactsViewController 

    @synthesize tableController; 
    @synthesize tableView; 

    @synthesize sysViewController; 

    @synthesize allButton; 
    @synthesize linphoneButton; 
    @synthesize backButton; 
    @synthesize addButton; 
    @synthesize toolBar; 

    typedef enum _HistoryView { 
     History_All, 
     History_Linphone, 
     History_Search, 
     History_MAX 
    } HistoryView; 

    bool noInternetConnection; 

    #pragma mark - Lifecycle Functions 

    - (id)init { 
     return [super initWithNibName:@"ContactsViewController" bundle:[NSBundle mainBundle]]; 
    } 

    - (void)dealloc { 
     [tableController release]; 
     [tableView release]; 

     [allButton release]; 
     [linphoneButton release]; 
     [backButton release]; 
     [addButton release]; 

     [_searchBar release]; 
     [_headerView release]; 
     [super dealloc]; 
    } 

    #pragma mark - UICompositeViewDelegate Functions 

    static UICompositeViewDescription *compositeDescription = nil; 

    + (UICompositeViewDescription *)compositeViewDescription { 
     if(compositeDescription == nil) { 
      compositeDescription = [[UICompositeViewDescription alloc] init:@"Contacts" 
              content:@"ContactsViewController" 
              stateBar:nil 
              stateBarEnabled:false 
              tabBar:@"UIMainBar" 
              tabBarEnabled:true 
              fullscreen:false 
              landscapeMode:[LinphoneManager runningOnIpad] 
              portraitMode:true]; 
     } 
     return compositeDescription; 
    } 


    #pragma mark - ViewController Functions 

    - (void)viewWillDisappear:(BOOL)animated { 
     [super viewWillDisappear:animated]; 
     self.allButton.backgroundColor=self.headerView.backgroundColor; 
     self.linphoneButton.backgroundColor=self.headerView.backgroundColor; 
     [[NSNotificationCenter defaultCenter] removeObserver:self 
                 name:kReachabilityChangedNotification 
                 object:nil]; 
    } 

    - (void)relayoutTableView { 
     CGRect subViewFrame= self.view.frame; 
     // let the toolBar be visible 
     subViewFrame.origin.y = self.searchBar.frame.size.height+self.searchBar.frame.origin.y; 
     subViewFrame.size.height -= (self.headerView.frame.size.height+self.searchBar.frame.size.height); 
     [UIView animateWithDuration:0.2 animations:^{ 
      self.tableView.frame = subViewFrame; 
     }]; 
    } 

    - (void)viewWillAppear:(BOOL)animated { 
     [super viewWillAppear:animated]; 
     //[self onSyncButton:nil]; 
     Reachability *reachability = [Reachability reachabilityWithHostname:@"www.google.com"]; 
     [self reactInternetConnection:reachability]; 
     [[NSNotificationCenter defaultCenter] addObserver:self 
               selector:@selector(reachabilityDidChange:) 
                name:kReachabilityChangedNotification 
                object:nil]; 

     // cannot change search bar icon nor text font from the interface builder... 
     // [_searchBar setImage:[UIImage imageNamed:@"contact_search.png" ] forSearchBarIcon:UISearchBarIconSearch state:UIControlStateNormal]; 
     // UITextField *searchText = [_searchBar valueForKey:@"_searchField"]; 
     // [searchText setFont:[UIFont fontWithName:@"CustomFont" size:12]]; 
     _searchBar.showsCancelButton = (_searchBar.text.length > 0); 

     BOOL use_system = [[LinphoneManager instance] lpConfigBoolForKey:@"use_system_contacts"]; 
     if(use_system && !self.sysViewController){// use system contacts 
      ABPeoplePickerNavigationController* picker = [[ABPeoplePickerNavigationController alloc] init]; 
      picker.peoplePickerDelegate = self; 
      picker.view.frame = self.view.frame; 

      [self.view addSubview:picker.view]; 

      self.sysViewController = picker; 
      self.searchBar.hidden = TRUE; 

     } else if(!use_system && !self.tableController){ 


      self.tableController = [[[ContactsTableViewController alloc] init] autorelease]; 
      self.tableView = [[[UITableView alloc] init] autorelease]; 

      self.tableController.view = self.tableView; 

      [self relayoutTableView]; 

      self.tableView.dataSource = self.tableController; 
      self.tableView.delegate = self.tableController; 

      self.tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | 
               UIViewAutoresizingFlexibleWidth | 
              UIViewAutoresizingFlexibleTopMargin | 
             UIViewAutoresizingFlexibleBottomMargin | 
              UIViewAutoresizingFlexibleLeftMargin | 
             UIViewAutoresizingFlexibleRightMargin; 

      [self.view addSubview:tableView]; 
      [self update]; 
     } 
    } 

    - (void)viewDidAppear:(BOOL)animated { 
     [super viewDidAppear:animated]; 
     if(![FastAddressBook isAuthorized]) { 
      UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Address book",nil) 
                  message:NSLocalizedString(@"You must authorize the application to have access to address book.\n" 
                         "Toggle the application in Settings > Privacy > Contacts",nil) 
                  delegate:nil 
                cancelButtonTitle:NSLocalizedString(@"Continue",nil) 
                otherButtonTitles:nil]; 
      [error show]; 
      [error release]; 
     //me 
     // [[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]]; 
     } 
    } 

    - (void)viewDidDisappear:(BOOL)animated { 
     [super viewDidDisappear:animated]; 
    } 

    - (void)viewDidLoad { 
     [super viewDidLoad]; 

     [self changeView:History_All]; 

     // Set selected+over background: IB lack ! 
     [linphoneButton setBackgroundImage:[UIImage imageNamed:@"buttonR"] 
        forState:(UIControlStateHighlighted | UIControlStateSelected)]; 

     [linphoneButton setTitle:[[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"] 
         forState:UIControlStateNormal]; 

     [LinphoneUtils buttonFixStates:linphoneButton]; 

     // Set selected+over background: IB lack ! 
     [allButton setBackgroundImage:[UIImage imageNamed:@"buttonch2"] 
         forState:(UIControlStateHighlighted | UIControlStateSelected)]; 

     [LinphoneUtils buttonFixStates:allButton]; 

     [tableController.tableView setBackgroundColor:[UIColor clearColor]]; // Can't do it in Xib: issue with ios4 
     [tableController.tableView setBackgroundView:nil]; // Can't do it in Xib: issue with ios4 
    } 


    #pragma mark - 

    - (void)reachabilityDidChange:(NSNotification *)notification { 
     Reachability *reachability = (Reachability *)[notification object]; 
     [self reactInternetConnection:reachability]; 
    } 

    - (void)reactInternetConnection:(Reachability*)reachability { 
     if ([reachability isReachable]) { 
      noInternetConnection = false; 
     } else { 
      noInternetConnection = true; 
     } 
    } 

    - (void)changeView:(HistoryView)view { 
     if(view == History_All) { 
      [ContactSelection setSipFilter:nil]; 
      [ContactSelection enableEmailFilter:FALSE]; 
      [tableController loadData]; 
      allButton.selected = TRUE; 
     } else { 
      allButton.selected = FALSE; 
     } 

     if(view == History_Linphone) { 
      [ContactSelection setSipFilter:[LinphoneManager instance].contactFilter]; 
      [ContactSelection enableEmailFilter:FALSE]; 
      [tableController loadData]; 
      linphoneButton.selected = TRUE; 
     } else { 
      linphoneButton.selected = FALSE; 
     } 
    } 

    - (void)changeAvafoneView { 
     [self changeView: History_Linphone]; 
    } 


    - (void)update { 
     switch ([ContactSelection getSelectionMode]) { 
      case ContactSelectionModePhone: 
      case ContactSelectionModeMessage: 
       [addButton setHidden:TRUE]; 
       [backButton setHidden:FALSE]; 
       break; 
      default: 
       [addButton setHidden:FALSE]; 
       [backButton setHidden:TRUE]; 
       break; 
     } 
     if([ContactSelection getSipFilter]) { 
      allButton.selected = FALSE; 
      linphoneButton.selected = TRUE; 
     } else { 
      allButton.selected = TRUE; 
      linphoneButton.selected = FALSE; 
     } 
     [tableController loadData]; 
    } 


    #pragma mark - Action Functions 

    - (IBAction)onAllClick:(id)event { 
     [self changeView: History_All]; 
    } 

    - (IBAction)onLinphoneClick:(id)event { 
     [self changeView: History_Linphone]; 
    } 

    - (IBAction)onAddContactClick:(id)event { 
     // Go to Contact details view 
    // ContactDetailsViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[ContactDetailsViewController compositeViewDescription] push:TRUE], ContactDetailsViewController); 
    // if(controller != nil) { 
    //  if([ContactSelection getAddAddress] == nil) { 
    //   [controller newContact]; 
    //  } else { 
    //   [controller newContact:[ContactSelection getAddAddress]]; 
    //  } 
    // } 
     AddContactViewController *add = [[UIStoryboard storyboardWithName:@"DialerStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:@"addContacts"]; 

     [self presentViewController:add animated:YES completion:^{ 

     }]; 
    } 

    - (IBAction)onBackClick:(id)event { 
     [[PhoneMainView instance] popCurrentView]; 
    } 

    - (IBAction)onSyncButton:(id)sender { 
     if (!noInternetConnection) { 
      [Utility showProgressBar:@"Synchronize" message:nil]; 
      dispatch_queue_t jogvoiceCheckingQueue = dispatch_queue_create("JogvoiceContactListChecking",NULL); 
      dispatch_async(jogvoiceCheckingQueue, ^{ 
       [[LinphoneManager instance].fastAddressBook checkContactListForJogvoiceList]; 
       [Utility stopProgressBar]; 
       NSLog(@"Finish checking jogvoice contact list!"); 
      }); 
     } else { 
      UIAlertView* error = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Network is unreachable",nil) 
                  message:NSLocalizedString(@"",nil) 
                  delegate:nil 
                cancelButtonTitle:NSLocalizedString(@"OK",nil) 
                otherButtonTitles:nil]; 
      [error show]; 
      [error release]; 
     } 
    } 


    - (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar { 
     [self searchBar:searchBar textDidChange:nil]; 
     [searchBar resignFirstResponder]; 
    } 

    #pragma mark - Rotation handling 

    - (void)didRotateFromInterfaceOrientation:(UIInterfaceOrientation)fromInterfaceOrientation { 
     [super didRotateFromInterfaceOrientation:fromInterfaceOrientation]; 
     // the searchbar overlaps the subview in most rotation cases, we have to re-layout the view manually: 
     [self relayoutTableView]; 
    } 


    #pragma mark - ABPeoplePickerDelegate 

    -(void)peoplePickerNavigationControllerDidCancel:(ABPeoplePickerNavigationController *)peoplePicker 
    { 
     [[PhoneMainView instance] popCurrentView]; 
     return; 
    } 

    - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker 
      shouldContinueAfterSelectingPerson:(ABRecordRef)person { 
     return true; 

    } 

    - (BOOL)peoplePickerNavigationController:(ABPeoplePickerNavigationController *)peoplePicker 
      shouldContinueAfterSelectingPerson:(ABRecordRef)person 
            property:(ABPropertyID)property 
            identifier:(ABMultiValueIdentifier)identifier { 

     CFTypeRef multiValue = ABRecordCopyValue(person, property); 
     CFIndex valueIdx = ABMultiValueGetIndexForIdentifier(multiValue,identifier); 
     NSString *phoneNumber = (NSString *)ABMultiValueCopyValueAtIndex(multiValue, valueIdx); 
     // Go to dialer view 
     DialerViewController *controller = DYNAMIC_CAST([[PhoneMainView instance] changeCurrentView:[DialerViewController compositeViewDescription]], DialerViewController); 
     if(controller != nil) { 
      [controller call:phoneNumber displayName:[(NSString*)ABRecordCopyCompositeName(person) autorelease]]; 
     } 
     [phoneNumber release]; 
     CFRelease(multiValue); 
     return false; 
    } 

    #pragma mark - searchBar delegate 

    - (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText { 
     // display searchtext in UPPERCASE 
     // searchBar.text = [searchText uppercaseString]; 
     searchBar.showsCancelButton = (searchText.length > 0); 
     [ContactSelection setNameOrEmailFilter:searchText]; 
     [tableController loadData]; 
    } 

    - (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar { 
     [searchBar setShowsCancelButton:FALSE animated:TRUE]; 
    } 

    - (void)searchBarTextDidBeginEditing:(UISearchBar *)searchBar { 
     [searchBar setShowsCancelButton:TRUE animated:TRUE]; 
    } 

    -(void)searchBarSearchButtonClicked:(UISearchBar *)searchBar { 
     [searchBar resignFirstResponder]; 
    } 

    - (void)viewDidUnload { 
     [self setToolBar:nil]; 
     [super viewDidUnload]; 
    } 
    @end 

PS:当我关闭访问隐私联系,应用程序不会崩溃,但获取联系人失败

+0

你对这个项目运行了一个静态分析(“产品”»“分析”)吗?它很好地识别许多手动引用计数问题。确保你没有警告。或者,考虑使用ARC,并摆脱这种愚蠢。 – Rob

+1

有太多的代码可以期待我们任何人都能经历。我建议你使用[最简单的可能的例子来显示你描述的问题]创建一个新的空白项目(http://*.com/help/mcve)。 – Rob

+0

“ABPeoplePickerNavigationController”代码不正确。一般来说,你不能只抓住一个控制器的'view'并将其添加到层次结构中,而是必须在这种情况下执行包含调用。在'ABPeoplePickerNavigationController'的情况下,根本不要将它添加到你的视图层次结构中,而是将它放在'presentViewController'中。 – Rob

您可以验证两件事情

1.Allow用户给予准许的接触详细信息

CNContactStore * contactStore = [CNContactStore new]; 
[contactStore requestAccessForEntityType:entityType completionHandler:^(BOOL granted, NSError * _Nullable error) { 
      if(granted){ 
       // User gave permission 
      } 
     }]; 

2.Plist.Info文件具有对NSContactsUsageDescription的说明。

+0

他没有使用联系人框架。他使用AddressBook框架。所以,第1点应该是'ABAddressBookRequestAccessWithCompletion'。 – Rob

+0

谢谢Rob。我忘了提及使用Contact框架作为其新框架。无论如何它的正确使用ABAddressBookRequestAccessWithCompletion,如果你想坚持相同的框架。 –

+0

由于MD阿斯拉姆安萨里,但它'在FastAddressBook类授权非常好,还可以添加到NSContactsUsageDescription plist.info –