iOS swift, как узнать, обновляется ли какой-либо контакт, даже если приложение убито - PullRequest
3 голосов
/ 07 января 2020

Я видел много ТАК любопытных вопросов об этом случае, но все же я публикую это, так как многие разработчики могут также захотеть узнать об этой другой причине, что ни одно решение не работает для меня.

Я использовал следующий код, но он работает, только когда мое приложение работает в фоновом режиме. но я не уведомлен, когда мое приложение будет убито, и тем временем пользователь обновил информацию о любом контакте. Так что в этом случае я не уверен, как это сделать.

Что я делаю: Вот фрагмент кода, который я пытаюсь сделать

From iOS 9 you can register your class to observe CNContactStoreDidChangeNotification

NSNotificationCenter.defaultCenter().addObserver(
self,
selector: #selector(addressBookDidChange),
name: NSNotification.Name.CNContactStoreDidChange,
object: nil)

А затем:

@objc func addressBookDidChange(notification: NSNotification){     
//Handle event here...
}

I нашел это решение более здесь :

Что происходит: Таким образом, я могу получать уведомление о своем приложении, как только пользователь обновил его контакт, пока приложение находится в фоновом режиме.

Что я хочу: я просто хочу знать, что если пользователь обновил какой-либо контакт, даже если мое приложение было уничтожено, то как получить уведомление о моем приложении с обновленными контактами?

Пожалуйста, дайте мне знать, если у вас есть решение этой проблемы заранее.

ОБНОВЛЕНИЕ: Я видел, как Whatsapp делал это. Есть кто-нибудь, кто может сказать мне, как это делает Whatsapp?

Ответы [ 3 ]

2 голосов
/ 09 января 2020

Чтобы проверить, изменился ли контакт, вы можете использовать пользовательскую функцию ha sh, потому что собственная проверяет только идентификатор:

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()
    }
}

(Вы можете удалить поля, которые вам не нужны)

Затем вам нужно сохранить словарь внутри приложения, чтобы хранить значения ha sh всех контактов, для его построения просто выполните:

let hashedContacts = [String:Int]()

for contact in allContacts {
    hashedContacts[contact.identifier] = contact.customHash
}

Вы должны сохранить его в файловая система.

При каждом обновлении контакта вы обновляете его:

hashedContacts[updatedContact.identifier] = updatedContact.customHash

Затем при каждом запуске загружается сохраненный словарь и проверяются различия:

for contact in allContacts {
    if contact.customHash != savedHashedValues[contact.identifier] {
        // This contact has changed since last launch 
        ...
    }
}

И вуаля!

РЕДАКТИРОВАТЬ :

Как сохранить карту ha sh на диске ...

var hashedContacts = ...

guard let name = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("hashedContacts")
    else { return }

try? (hashedContacts as NSDictionary).write(to: name)

Как загрузить карта ha sh с диска ...

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...
0 голосов
/ 07 января 2020

Что вы можете сделать, это отправить уведомление об обновлении приложения на экране запуска. Это может создать иллюзию у вашего пользователя, что вы сделали изменения в фоновом режиме.

0 голосов
/ 07 января 2020

Каждый раз, когда вы открываете свое приложение, вам нужно получить все контакты из списка контактов и сравнить с предыдущим, сохраненным внутри вашего приложения. После этого вы можете отправить sh свой список контактов на сервер.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...