Apache Cordova
  1. Apache Cordova
  2. CB-902

iOS 6 - deal with new Privacy functionality in Contacts (ABAddressBook:: ABAddressBookCreateWithOptions)

    Details

    • Type: Bug Bug
    • Status: Resolved
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: 1.8.0
    • Fix Version/s: 2.2.0
    • Component/s: iOS
    • Labels:
    • Environment:

      iOS 6 DP1

      Description

      Currently crashes if the user does not have AddressBook permission on iOS 6.

      The user will get a popup dialog similar to the Geolocation permissions dialog. When creating an address book, we should handle the condition where the app does not have permission, and the address book returned is NULL.

        Activity

        Hide
        Shazron Abdullah added a comment -

        Tagged version as 2.0.0 since that's the latest version we have. iOS 6 is due in the "fall".

        Show
        Shazron Abdullah added a comment - Tagged version as 2.0.0 since that's the latest version we have. iOS 6 is due in the "fall".
        Hide
        Braden Shepherdson added a comment -

        I'm taking a look at this. This is my first venture into Objective-C and iOS development, so we'll see how it goes.

        Show
        Braden Shepherdson added a comment - I'm taking a look at this. This is my first venture into Objective-C and iOS development, so we'll see how it goes.
        Hide
        Braden Shepherdson added a comment -

        I can't reproduce this with MobileSpec on the iOS 6 simulator, iPhone or iPad. There doesn't seem to be anything in Settings to turn on the protection, and my MobileSpec app is not listed in the Privacy > Contacts list, which should show applications that have requested access to the contacts (and been allowed).

        Possibly Xcode is deliberately disabling that permissions check? I'm still investigating.

        Show
        Braden Shepherdson added a comment - I can't reproduce this with MobileSpec on the iOS 6 simulator, iPhone or iPad. There doesn't seem to be anything in Settings to turn on the protection, and my MobileSpec app is not listed in the Privacy > Contacts list, which should show applications that have requested access to the contacts (and been allowed). Possibly Xcode is deliberately disabling that permissions check? I'm still investigating.
        Hide
        Shazron Abdullah added a comment -

        It's possible something has changed since iOS 6 beta 2 and/or we are handling the NULL better since we are using ARC? Not sure yet.

        Show
        Shazron Abdullah added a comment - It's possible something has changed since iOS 6 beta 2 and/or we are handling the NULL better since we are using ARC? Not sure yet.
        Hide
        Shazron Abdullah added a comment -

        No crashes anymore, but mobile-spec reports 4 failures related to Contacts with beta 4.

        Show
        Shazron Abdullah added a comment - No crashes anymore, but mobile-spec reports 4 failures related to Contacts with beta 4.
        Hide
        Shazron Abdullah added a comment -

        It seems with beta 3 they added a manual function to request AddressBook access, which we need to implement. Details here:

        1. https://devforums.apple.com/message/708024#708024
        2. https://devforums.apple.com/message/720708#720708

        Note that the function used is NOT in the pre-release docs. Thanks Apple!

        Show
        Shazron Abdullah added a comment - It seems with beta 3 they added a manual function to request AddressBook access, which we need to implement. Details here: 1. https://devforums.apple.com/message/708024#708024 2. https://devforums.apple.com/message/720708#720708 Note that the function used is NOT in the pre-release docs. Thanks Apple!
        Hide
        Shazron Abdullah added a comment -

        It is only documented in the beta 4 Release Notes: https://developer.apple.com/library/prerelease/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html

        This is a huge change and may not go in 2.1.0

        Show
        Shazron Abdullah added a comment - It is only documented in the beta 4 Release Notes: https://developer.apple.com/library/prerelease/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html This is a huge change and may not go in 2.1.0
        Hide
        Shazron Abdullah added a comment -

        Punting to 2.2.0

        If you look at the links with sample code, usage of this new authorization API requires blocks in the authorization completion handler, thus we have to re-factor our code to use this - which is not trivial.

        Show
        Shazron Abdullah added a comment - Punting to 2.2.0 If you look at the links with sample code, usage of this new authorization API requires blocks in the authorization completion handler, thus we have to re-factor our code to use this - which is not trivial.
        Show
        Shazron Abdullah added a comment - Documentation: 1. https://developer.apple.com/library/prerelease/ios/#documentation/AddressBook/Reference/ABAddressBookRef_iPhoneOS/Reference/reference.html#//apple_ref/c/func/ABAddressBookRequestAccessWithCompletion 2. https://developer.apple.com/library/prerelease/ios/#documentation/AddressBook/Reference/ABAddressBookRef_iPhoneOS/Reference/reference.html%23//apple_ref/c/func/ABAddressBookGetAuthorizationStatus 3. https://developer.apple.com/library/prerelease/ios/#releasenotes/General/RN-iOSSDK-6_0/_index.html
        Show
        Becky Gibson added a comment - Other posts related to this issue: https://groups.google.com/forum/?fromgroups=#!searchin/phonegap/contacts$20crash/phonegap/c95P4L8sENk/Vq50C_Xc5o4J https://groups.google.com/forum/?fromgroups=#!topic/phonegap/x7i187AM9Q8
        Hide
        Becky Gibson added a comment -

        Fix is here: https://github.com/becka11y/incubator-cordova-ios/tree/cb902

        Would love to have some additional testing before I commit.

        Show
        Becky Gibson added a comment - Fix is here: https://github.com/becka11y/incubator-cordova-ios/tree/cb902 Would love to have some additional testing before I commit.
        Hide
        Ronnie Schaniel added a comment - - edited

        I use your updated CDVContacts.m and still get an EXC_BAD_ACCESS error.

        Show
        Ronnie Schaniel added a comment - - edited I use your updated CDVContacts.m and still get an EXC_BAD_ACCESS error.
        Hide
        Becky Gibson added a comment -

        Can you provide more specifics? What api's are you calling what is the xcode log? I never had any crashes with the original code - just empty contact list.

        Show
        Becky Gibson added a comment - Can you provide more specifics? What api's are you calling what is the xcode log? I never had any crashes with the original code - just empty contact list.
        Hide
        Ronnie Schaniel added a comment -

        Here is the javascript part of adding a contact:

        function addToContacts()
        {
        if(currentAddress != null)
        {
        console.log("Add " + currentAddress.company_name + " to contacts");
        var contact = navigator.contacts.create(

        { "displayName" : currentAddress.company_name }

        );
        contact.id = currentAddress.company_name;

        var contactCompany = new ContactOrganization();
        contactCompany.name = currentAddress.company_name;
        contact.organizations = new Array(contactCompany);

        street_and_house = $.trim(currentAddress.street + ' ' + currentAddress.house);
        var address = new ContactAddress();
        address.type = 'work';
        address.streetAddress = street_and_house;
        address.postalCode = currentAddress.zip
        address.locality = currentAddress.city;
        address.country = 'Switzerland';
        contact.addresses = new Array(address);

        var phoneNumbers = new Array();
        if(currentAddress.phone != null)

        { phoneNumbers.push(new ContactField('work', currentAddress.phone, true)); }

        if(currentAddress.fax != null)

        { phoneNumbers.push(new ContactField('work fax', currentAddress.fax, false));; }

        if(phoneNumbers.length > 0)

        { contact.phoneNumbers = phoneNumbers; }

        if(currentAddress.email != null)

        { contact.emails = new Array(new ContactField('work', currentAddress.email, true)); }

        if(currentAddress.homepage != null)

        { contact.urls = new Array(new ContactField('work', currentAddress.homepage, true)); }

        navigator.notification.confirm("Wollen Sie diese Adresse in Ihre Kontakte übernehmen?", function(button){ if(button == 1)

        { contact.save(); }

        }, "Kontakt speichern", "OK,Abbrechen");
        }
        }

        In CDVContacts.m I get a EXC_BAD_ACCESS at this point:
        [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errorCode) {

        I think there is an error in my App and not in your Fix.

        Show
        Ronnie Schaniel added a comment - Here is the javascript part of adding a contact: function addToContacts() { if(currentAddress != null) { console.log("Add " + currentAddress.company_name + " to contacts"); var contact = navigator.contacts.create( { "displayName" : currentAddress.company_name } ); contact.id = currentAddress.company_name; var contactCompany = new ContactOrganization(); contactCompany.name = currentAddress.company_name; contact.organizations = new Array(contactCompany); street_and_house = $.trim(currentAddress.street + ' ' + currentAddress.house); var address = new ContactAddress(); address.type = 'work'; address.streetAddress = street_and_house; address.postalCode = currentAddress.zip address.locality = currentAddress.city; address.country = 'Switzerland'; contact.addresses = new Array(address); var phoneNumbers = new Array(); if(currentAddress.phone != null) { phoneNumbers.push(new ContactField('work', currentAddress.phone, true)); } if(currentAddress.fax != null) { phoneNumbers.push(new ContactField('work fax', currentAddress.fax, false));; } if(phoneNumbers.length > 0) { contact.phoneNumbers = phoneNumbers; } if(currentAddress.email != null) { contact.emails = new Array(new ContactField('work', currentAddress.email, true)); } if(currentAddress.homepage != null) { contact.urls = new Array(new ContactField('work', currentAddress.homepage, true)); } navigator.notification.confirm("Wollen Sie diese Adresse in Ihre Kontakte übernehmen?", function(button){ if(button == 1) { contact.save(); } }, "Kontakt speichern", "OK,Abbrechen"); } } In CDVContacts.m I get a EXC_BAD_ACCESS at this point: [abHelper createAddressBook: ^(ABAddressBookRef addrBook, CDVAddressBookAccessError * errorCode) { I think there is an error in my App and not in your Fix.
        Hide
        Becky Gibson added a comment -

        On quick inspection of your code I do see a few things that might be an issue. First, iOS does not support displayName as specified in the docs: "displayName: This property is not supported by iOS and will be returned as null unless there is no ContactName". Can you try setting one of the other name fields just to see if that makes a difference?

        I do my best to handle displayName in the code and I'll try and double check to make sure that is not the reason for the crash. Also, you should not be setting the contact.id - that field gets set by the mobile operating system when the contact is saved. Also, what version of iOS are you using? I assume at least 4.1 (and 4.3 if you are using xcode 4.5). I think 4.1 is the minimum required to use blocks (which is where you are seeing the crash).

        Show
        Becky Gibson added a comment - On quick inspection of your code I do see a few things that might be an issue. First, iOS does not support displayName as specified in the docs: "displayName: This property is not supported by iOS and will be returned as null unless there is no ContactName". Can you try setting one of the other name fields just to see if that makes a difference? I do my best to handle displayName in the code and I'll try and double check to make sure that is not the reason for the crash. Also, you should not be setting the contact.id - that field gets set by the mobile operating system when the contact is saved. Also, what version of iOS are you using? I assume at least 4.1 (and 4.3 if you are using xcode 4.5). I think 4.1 is the minimum required to use blocks (which is where you are seeing the crash).
        Show
        Becky Gibson added a comment - Fixed with this commit: https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-ios.git;a=commit;h=4a3b22064e67c90a4237397ee8205b52cd2e14f1

          People

          • Assignee:
            Becky Gibson
            Reporter:
            Shazron Abdullah
          • Votes:
            0 Vote for this issue
            Watchers:
            5 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development