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
Post a Comment