Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iPhone: address book is erased sometimes

I use the ABAddressBook in my app.
The access to the AB is from a separate thread in order to release the UI.
I am aware of the fact that the access to the AB instance has to be from the same thread all the time and I have built a wrapper for this reason.
The wrapper is a singleton and it maintains its own background thread.
All the messages that come to the wrapper are automatically redirected to the background thread, while the calling thread waits until the end of implementation and in the end fills the out argument with the relevant data (contacts list, a specific contact etc.).

Even though, the address book on the device gets empty (erased) sometimes.
After every 10-20-th use of the app.

So, I have few questions:

  • After I get the ABRecordRef from the AB in the dedicated thread do I have to retrieve data from the ABRecordRef also in the same thread or may it be another thread? I also have a wrapper for ABRecordRef, so when I retrieve a contact from AB I fill the person wrapper object and after that I use it (read from ABRecordRef) from the original thread.
  • When I use the AB UI APIs (person picker navigation controller, new person view controller etc.) and pass them my instance of ABAddressBook do I have to worry about the fact that the API won't use this AB instance from the same thread that created it? I have seen that I can pass NULL instead of the AB instance and then the API will use its own AB, but what can I do when I want to modify a contact? In this case I have to pass it the ABRecordRef instance...
  • Is there something else I didn't think about?

Thank you in advance.

--
Michael

like image 616
Michael Kessler Avatar asked Jan 18 '11 09:01

Michael Kessler


1 Answers

You must only access the Address Book from the same thread that called ABAddressBookCreate(). You cannot use ABRecordRef in another thread. Only record id's and copied data are safe to pass between threads.

Typically, I create a serial dispatch queue and use it as a wrapper for Address Book calls that can't block the main thread.

When you use the UI, you need to call ABAddressBookCreate() on the main thread and use that for your UI calls.

If you need to modify a contact with the UI, you would modify the contact, save it, then update the address book on your background thread or queue, so that it contains the latest changes. There is a notification callback ABAddressBookRegisterExternalChangeCallback, for this purpose.

like image 58
Eric Avatar answered Oct 30 '22 21:10

Eric