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

时间:2017-10-28 18:36:11

标签: ios objective-c xcode abaddressbook linphone

我的应用程序在ios 9和10上工作得非常好,但是当我想在ios 11应用程序崩溃时访问联系人时 (实际上,当单击选项卡访问联系人时,获取线程8:信号SIGABRT。)

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.s.:当我在隐私中取消联系时,应用程序不会崩溃,但取消联系失败

1 个答案:

答案 0 :(得分:1)

您可以验证两件事

1.允许用户授予联系方式的权限

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

2.Plist.Info文件包含NSContactsUsageDescription的描述。