tracking certain email change in ABRecordRef - ios

I am creating an application to sync the addressbook. I have synced the addressbook records into the local core data based database and I could already fetch them. Syncing a record is easy using the ABRecordId. I store the record id for certain addressbook record into my local database, and so I can fetch a certain record based on the id. I can also implement the callback by implementing the ABAddressBookRegisterExternalChangeCallback. But is there a way to track change of a particular email. A user could change his email, how is it possible to know if a certain email has changed.

There is no way to attach a "listener" that will somehow call a function in your app every time someone edits a contact. But, there is a way to keep your app up-to-date:
Store a variable in NSUserDefaults that contains the date of the last time you imported new contacts from the phone.
When your app resumes from the background or opens for the first time, you should query the phone's contacts for all of the records that have been modified since the date of the last time you synced with the contacts. This way, you can only process the updated contacts without iterating over every saved contact every time.
You should be able to sort the person records by this property:
kABPersonModificationDateProperty (reference)

Related

How would I be able to uniquely identify a contact in a contact store in a iOS device?

I need someway to uniquely identify a contact in contact store even if the contact is changed.
Is there a way to put code in iOS that is always watching in the background for the contact store to change? That way I can track a contact that I identify with a UUID value and make sure I can always match that specific contact with its UUID value even if the contact changes. If I put it in my app, then the user can close the app, and the app won't receive notifications when the contact store changes? Is there an app extension I can use that would allow me to do this, whether that is the intent of the extension or not?
Perhaps I can use key-value observing. Is it possible to observe the iOS Contacts app or the contacts store of a device using key-value observing? How would I find out? I can't find information on it when I do a search on Google.
I found information about the ABAddressBookRegisterExternalChangeCallback(::_:) function of the Address Book Framework, but that function has been deprecated, and only works with iOS 2.0–9.0. I don't see a function in the Contacts Framework that does what that function does.
Content Added Thursday, March 3, 2022, 12:03 AM:
I need the unique identifier to be saved in a record in a private iCloud database. The objective is to be able to query the database for the record associated with that contact. That would probably mean that the identifier would have to be unique across all iOS devices in existence.Is that so?

Query Changes after receiving CKDatabaseNotification

I'm currently building an app that allows user to share events and check in their guests simultaneously using multiple phones. I managed to set up CKQuerySubscription and update, delete and create works fine but only on the primary phone (the one sharing the event).
I recently found out that for a non-primary user to get notifications, it has to get notifications from CKDatabaseNotification which i set up and it works as I am getting remote notifications when I make changes through CloudKit Dashboard.
But the notification i get (CKDatabaseNotification) does not come with anything that would allow me to find what records changed. I've tried casting it as CKNotification as suggested on this link but as expected it fails.
I have a custom zone set up and my questions are as below:
How do I get any information about what changed from a CKDatabaseNotification?
Am I even doing that the right way? I've read somewhere else as well that some people managed to set up subscription through CKQuerySubscription on a shared database as long as it is on a custom zone, which I have but my codes told me subscription failed.
The CKDatabaseNotification will only tell you that something has changed, not what it is. The recommended path forward is you use a CKFetchDatabaseChangesOperation to find out what record zones have changes. Then you use the record zone IDs from that operation in a CKFetchRecordZoneChangesOperation to get all the changes.
There's a bit more information in the CloudKit Quick Start Guide
I'm cherry picking some relevant info below:
After app launch or the receipt of a push, your app uses CKFetchDatabaseChangesOperation and then CKFetchRecordZoneChangesOperation to ask the server for only the changes since the last time it updated.
The key to these operations is the previousServerChangeToken object,
which tells the server when your app last spoke to the server,
allowing the server to return only the items that were changed since
that time.
First your app will use a CKFetchDatabaseChangesOperation to find out
which zones have changed
Then
Next your app uses a CKFetchRecordZoneChangesOperation object with the
set of zone IDs you just collected to do the following:
• Create and update any changed records
• Delete any records that no longer exist
• Update the zone change tokens
The WWDC video CloudKit Best Practices addresses this topic as well.

What is considered too heavy for UserDefaults?

I'm building a simple iOS app that will be the first I'll have put on Apple's App Store. At one point, the app accesses the user's contact list and lets them select any number of contacts they want to save as favorites.
For ease of building version one, I am currently using UserDefaults to save these favorites. While it has worked well in my limited testing, I know that Core Data and CloudKit are stable options for larger solutions.
For an app like mine, where I'm only using UserDefaults to save a select number of contacts as favorites, is UserDefaults an adequate solution? Or should I transition to something more robust like Core Data or CloudKit? There is no limit on the number of contacts a user could select as a favorite, so there is the edge-case possibility of a user selecting all of their contacts one by one and attempting to save them all as favorites.
If the user gets a new phone and loses all existing data due to UserDefaults being local on the device, it would not take long to get this app back to where they previously had it.
You can use CoreData to store favorite contact locally for large data as per your concern. Now when user switch device or delete app then all data will removed. So for that you can sync with cloudKit or other option is backend server. When user add any contact as favourite same time that contact will add to Core data as well as in backend server. You can sync this backend server data when user login first time in the app, then you no need to sync again. other all thing are as per requirement.

Realm Object Server - When does syncing occur?

I have an iOS app powered by a Realm Object Server hosted on Amazon and I am curious as to when syncing actually occurs. Is syncing lazy on queries, real-time for all open realms, or something else?
For example, let's say I have a realm called /common and all SyncUsers have read/write permissions to this realm. Each active SyncUser also has a notification block listening to a GlobalProfile object in the /common realm corresponding to their SyncUser identity. If one user makes changes to another user's GlobalProfile object, will all users download this change immediately, or will only the user with the notification block on this object immediately download the change?
Specifically, I want to create a way for a user (let's name it Tom) to search for other users and send them read/write permissions to Tom's realm. My current solution is a public realm in which each user adds a GlobalProfile object. To search for a user named Jerry, Tom can simply query the public realm. To grant Jerry read/write permissions to Tom's realm, Tom can write a SyncPermissionOffer.token into Jerry's GlobalProfile. Because Jerry has a notification block listening to his GlobalProfile, he will be immediately notified of this token and can accept the SyncPermissionOffer to Tom's realm. My worry, however, is that all users, not just Jerry, will sync this change in the /common realm, which is unnecessary. If the app has 100,000 users, I don't want each user to constantly sync all SyncPermissionOffer tokens being sent between other users.
Please let me know if this question is not clear. Thank you so much for the help!
Sync is real-time on all changes. Sync is not waiting for, or contingent on, a notification block. The notification block is executed locally and is not used to alter the client-server communication in any way.
If you have a /common Realm, it will contain all your permission offers and
all users will download all other users permission offers. It will grow large over time.
What you could do is to have a /common Realm that only contains the user ids, their "names", and a path to their "inbox" Realm. When user A wants to
invite user B, A looks up B in /common, obtains the Realm path for B's inbox, and sends a permission offer to that.
With this approach, the common Realm would not grow that big, because the data par user could be kept below 100 bytes, say.

Checking if any contact in contact app has been changes (Swift)

Right now I build an app that provide sync contacts. For that, every time the app comeback to foreground, I check all contacts(CNContact) and compare to my contact in app's core data and detect if any contact that different and merge the data. It works okay but it takes a lot of memory.
Is that any way to detect if any contact in contact app has changed without comparing all contact?

Resources