ios - How to prevent crash when selecting specific contact using AdressBookUI -


i'm getting crash on line.

    phonenumber = cfbridgingrelease(abmultivaluecopyvalueatindex(numbers, index)); 

if first phone number selected index of 1 wrong. should 0 , therefore choses wrong number. if select second number gives index of -1 crashes app.

#pragma mark helper methods  - (void)didselectperson:(abrecordref)person identifier:(abmultivalueidentifier)identifier {     nsstring *phonenumber = @"";     abmultivalueref numbers = abrecordcopyvalue(person, kabpersonphoneproperty);     if (numbers) {         if (abmultivaluegetcount(numbers) > 0) {             cfindex index = 0;             if (identifier != kabmultivalueinvalididentifier) {                 index = abmultivaluegetindexforidentifier(numbers, identifier);             }             phonenumber = cfbridgingrelease(abmultivaluecopyvalueatindex(numbers, index));         }         cfrelease(numbers);     }     self.numbertextfield.text = [nsstring stringwithformat:@"%@", phonenumber]; } 

there bug in ios 8.3 (and presumably previous version of ios 8) when working on copies of contacts have had phone numbers/emails removed. documentation abpeoplepickernavigationcontroller states that:

in ios 8 , later bringing people-picker navigtion controller not require app have access user’s contacts, , user not prompted grant access. if app not have access user’s contacts, temporary copy of contact selected user returned app.

in testing had contact had 3 phone numbers (let's call them 111, 222 , 333). appears identifiers fixed, stable zero-based values. 3 phone numbers identifier 0 2. if phone number deleted identifiers not change. zero-based indexes used access current list of phone numbers (or emails etc.) , abmultivaluegetindexforidentifier used convert identifier index.

in test deleted first phone number, 111. not change identifiers remaining phone numbers (222=1, 333=2).

when used abpeoplepickernavigationcontroller , chose first phone number (222) delegate method peoplepickernavigationcontroller: didselectperson:property:identifier: correctly passed identifier of 1. however, abmultivaluegetindexforidentifier returned index of 1, not 0 , app copied phone number 333 1 thought user had selected. if user picked 333 correctly passed identifier of 2 abmultivaluegetindexforidentifier converted -1 , unprotected call abmultivaluecopyvalueatindex crashed.

so, when working on copy of contact (which happens in ios 8 when app has not been authorised access address book), ios seems using identifiers based on real contact, indexes based on copy. copy seems have forgotten previously-deleted phone number , identifier-to-index mapping goes wrong if user picks phone number created after previously-deleted phone number. works if user hasn't deleted phone numbers, or if have deleted phone numbers after 1 pick.

the workaround complicate app making ask user permission access address book using abaddressbookrequestaccesswithcompletion. once granted, app not given copy of selected contact , identifier-to-index mapping works correctly.


Comments

Popular posts from this blog

c++ - Difference between pre and post decrement in recursive function argument -

php - Nothing but 'run(); ' when browsing to my local project, how do I fix this? -

php - How can I echo out this array? -