Reputation: 2082
I have seen many SO question curious about this case but still I am posting this as many of developers out there may also want to know this another reason is that no solution is working for me .
I have used following code but it only works when My app is in background. but I am not notified when my app is killed and meanwhile user has updated the info of any contact. So in this case I am not sure how to do it.
What I am doing: here is a code snippet what I am trying to do
From iOS 9 you can register your class to observe CNContactStoreDidChangeNotification
NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(addressBookDidChange),
name: NSNotification.Name.CNContactStoreDidChange,
object: nil)
And then:
@objc func addressBookDidChange(notification: NSNotification){
//Handle event here...
}
I found this solution over here:
Whats Happening: Through this way I am able to get my app notified once the user has updated his contact while app is in background.
What I want: I just want to know that if the user has updated any contact even though my app was killed then How to get my app notified with updated contacts?
Please let me know if you have solution of this issue in advance.
UPDATE: I have seen Whatsapp doing this. Is there anyone who can tell me how Whatsapp is doing this?
Upvotes: 3
Views: 1827
Reputation: 7290
To check if a contact has changed you can use a custom hash function because the native one only checks for the identifier:
extension CNContact {
var customHash : Int {
var hasher = Hasher()
hasher.combine(identifier)
hasher.combine(contactType)
hasher.combine(namePrefix)
hasher.combine(givenName)
hasher.combine(middleName)
hasher.combine(familyName)
hasher.combine(previousFamilyName)
hasher.combine(nameSuffix)
hasher.combine(nickname)
hasher.combine(organizationName)
hasher.combine(departmentName)
hasher.combine(jobTitle)
hasher.combine(phoneticGivenName)
hasher.combine(phoneticMiddleName)
hasher.combine(phoneticFamilyName)
if #available(iOS 10.0, *) {
hasher.combine(phoneticOrganizationName)
}
hasher.combine(note)
hasher.combine(imageData)
hasher.combine(thumbnailImageData)
if #available(iOS 9.0, *) {
hasher.combine(imageDataAvailable)
}
hasher.combine(phoneNumbers)
hasher.combine(emailAddresses)
hasher.combine(postalAddresses)
hasher.combine(urlAddresses)
hasher.combine(contactRelations)
hasher.combine(socialProfiles)
hasher.combine(instantMessageAddresses)
hasher.combine(birthday)
hasher.combine(nonGregorianBirthday)
hasher.combine(dates)
return hasher.finalize()
}
}
(You can remove fields you don't care)
Then you have to keep a dictionary inside your app to store the hash values of all the contacts, to build it just do:
let hashedContacts = [String:Int]()
for contact in allContacts {
hashedContacts[contact.identifier] = contact.customHash
}
You have to store it on the file system.
Whenever a contact is updated, you update it:
hashedContacts[updatedContact.identifier] = updatedContact.customHash
Then at every launch, you load the saved dictionary, and you check for differences:
for contact in allContacts {
if contact.customHash != savedHashedValues[contact.identifier] {
// This contact has changed since last launch
...
}
}
And voilà!
EDIT:
var hashedContacts = ...
guard let name = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("hashedContacts")
else { return }
try? (hashedContacts as NSDictionary).write(to: name)
guard
let name = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("hashedContacts"),
let loadedContacts = (try? NSDictionary(contentsOf: name, error: ())) as? [String:Int]
else { return }
// Do whatever you want with loaded contacts...
Upvotes: 3
Reputation: 757
Whenever you open your app you need to get all the contacts from the contact list and can compare to previous one which is saved inside of your app. After that you can push your contact list to server.
Upvotes: 0
Reputation: 123
What you can do is send an update notification to your application on launch screen. This might have an illusion to your user that you have done the changes while in background.
Upvotes: -2