I have successfully installed an extension CXCallDirectoryProvider in order to identify pre-added phone entries. The documentation I found online was rather insufficient. Nevertheless I've managed to reach at the point were I do the initial import of necessary phone entries. By overriding func beginRequest(with context: CXCallDirectoryExtensionContext). More specific:
override func beginRequest(with context: CXCallDirectoryExtensionContext) {
context.delegate = self
// Check whether this is an "incremental" data request. If so, only provide the set of phone number blocking
// and identification entries which have been added or removed since the last time this extension's data was loaded.
// But the extension must still be prepared to provide the full set of data at any time, so add all blocking
// and identification phone numbers if the request is not incremental.
if #available(iOS 11, *) {
if context.isIncremental {
addOrRemoveIncrementalBlockingPhoneNumbers(to: context)
addOrRemoveIncrementalIdentificationPhoneNumbers(to: context)
} else {
addAllBlockingPhoneNumbers(to: context)
addAllIdentificationPhoneNumbers(to: context)
}
} else {
addAllBlockingPhoneNumbers(to: context)
addAllIdentificationPhoneNumbers(to: context)
}
context.completeRequest()
}
The called function above which initially installs phone records, is addAllIdentificationPhoneNumbers and works like a charm.
private func addAllIdentificationPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
// Retrieve phone numbers to identify and their identification labels from data store. For optimal performance and memory usage when there are many phone numbers,
// consider only loading a subset of numbers at a given time and using autorelease pool(s) to release objects allocated during each batch of numbers which are loaded.
//
// Numbers must be provided in numerically ascending order.
var allNumbers = [(Number: String, Fullname: String)]()
// load allNumbers from local db
// ...
// ...
// ...
var test = allNumbers.map { s -> (Number: CXCallDirectoryPhoneNumber, Fullname:String) in
(CXCallDirectoryPhoneNumber(s.Number)!, s.Fullname)
}
// inc order
test.sort(by: { $0.Number < $1.Number })
// do the mapping to satisfy CallKit
let allPhoneNumbers = test.map { $0.Number }
let labels = test.map { $0.Fullname }
for (phoneNumber, label) in zip(allPhoneNumbers, labels) {
context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
}
}
Above code runs when user reach Settings -> Phone -> Call Blocking & Identification and enables handle next to app name.
And now the question part...
How does this code block
if context.isIncremental {
addOrRemoveIncrementalBlockingPhoneNumbers(to: context)
addOrRemoveIncrementalIdentificationPhoneNumbers(to: context)
}
get triggered in order to update records that often change?
Are there any guidelines/patterns or pretty much anything that could point me to the right direction regarding how to maintain these entries and keep them up to date as they change, or add new, even delete obsolete ones. I can not find anything online regarding incrementals just for the initial addAllIdentificationPhoneNumbers.
The incremental set of data will be requested only after your extension has run once and provided its initial, full baseline set of data.
For example, if your extension runs once after installing, provides its baseline set of data, and then your app calls CXCallDirectoryManager.reloadExtension(identifier:completion:) to request that the extension be re-run, the subsequent re-run should be incremental.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With