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 identifier
s fixed, stable zero-based values. 3 phone numbers identifier 0
2
. if phone number deleted identifiers not change. zero-based index
es 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
Post a Comment