CXCallDirectoryProvider I block a number when that number call he can not reach me everything is ok.But next time that number calls it is already not in block list and he can call me.How to fix it . CXCallDirectoryManager.sharedInstance.reloadExtension works currectly.
I want that it stays in block list until I manualy remove it from there.
enum LockAndUnlockType {
case lock
case unlock
}
class CallDirectoryHandler: CXCallDirectoryProvider {
static var lockType: LockAndUnlockType = .lock
static var isBlockingAction = MutableProperty<Bool?>(nil)
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.
CallDirectoryHandler.isBlockingAction.value = true
if context.isIncremental {
addOrRemoveIncrementalBlockingPhoneNumbers(to: context)
addOrRemoveIncrementalIdentificationPhoneNumbers(to: context)
} else {
addAllBlockingPhoneNumbers(to: context)
addAllIdentificationPhoneNumbers(to: context)
}
context.completeRequest()
}
private func addAllBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
// Retrieve all phone numbers to block 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.
let numbers = RealmDataBase.shered.fetchAllObjectsAt(Number.self).uniqued().sorted(by: { $0.phone > $1.phone})
for phoneNumber in numbers {
context.addBlockingEntry(withNextSequentialPhoneNumber: CXCallDirectoryPhoneNumber(phoneNumber.phone))
do {
try? Realm().write {
phoneNumber.isBlocked = true
}
}
}
}
private func addOrRemoveIncrementalBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
// Retrieve any changes to the set of phone numbers to block 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.
switch CallDirectoryHandler.lockType {
case .lock:
// guard let number = UserDefaults.standard.string(forKey: "phoneNumber") else { return }
let numbers = RealmDataBase.shered.fetchAllObjectsAt(Number.self).uniqued().sorted(by: { $0.phone > $1.phone})
for number in numbers {
context.addBlockingEntry(withNextSequentialPhoneNumber: CXCallDirectoryPhoneNumber(number.phone))
do {
try? Realm().write {
number.isBlocked = true
}
}
}
case .unlock:
let numbers = RealmDataBase.shered.fetchAllObjectsAt(Number.self).uniqued().sorted(by: { $0.phone > $1.phone})
for number in numbers {
context.removeBlockingEntry(withPhoneNumber: CXCallDirectoryPhoneNumber(number.phone))
do {
try? Realm().write {
number.isBlocked = false
}
}
}
}
// Record the most-recently loaded set of blocking entries in data store for the next incremental load...
}
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.
let allPhoneNumbers: [CXCallDirectoryPhoneNumber] = [ 1_877_555_5555, 1_888_555_5555 ]
let labels = [ "Telemarketer", "Local business" ]
for (phoneNumber, label) in zip(allPhoneNumbers, labels) {
context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
}
}
private func addOrRemoveIncrementalIdentificationPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
// Retrieve any changes to the set of 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.
// let phoneNumbersToAdd: [CXCallDirectoryPhoneNumber] = [ 1_408_555_5678 ]
// let labelsToAdd = [ "New local business" ]
//
// for (phoneNumber, label) in zip(phoneNumbersToAdd, labelsToAdd) {
// context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
// }
//
// let phoneNumbersToRemove: [CXCallDirectoryPhoneNumber] = [ 1_888_555_5555 ]
//
// for phoneNumber in phoneNumbersToRemove {
// context.removeIdentificationEntry(withPhoneNumber: phoneNumber)
// }
switch CallDirectoryHandler.lockType {
case .lock:
let numbers = RealmDataBase.shered.fetchAllObjectsAt(Number.self).uniqued().sorted(by: { $0.phone > $1.phone})
for number in numbers {
context.addBlockingEntry(withNextSequentialPhoneNumber: CXCallDirectoryPhoneNumber(number.phone))
}
case .unlock:
let numbers = RealmDataBase.shered.fetchAllObjectsAt(Number.self).uniqued().sorted(by: { $0.phone > $1.phone})
for number in numbers {
context.removeBlockingEntry(withPhoneNumber: CXCallDirectoryPhoneNumber(number.phone))
}
}
// Record the most-recently loaded set of identification entries in data store for the next incremental load...
}
}
extension CallDirectoryHandler: CXCallDirectoryExtensionContextDelegate {
func requestFailed(for extensionContext: CXCallDirectoryExtensionContext, withError error: Error) {
// An error occurred while adding blocking or identification entries, check the NSError for details.
// For Call Directory error codes, see the CXErrorCodeCallDirectoryManagerError enum in <CallKit/CXError.h>.
//
// This may be used to store the error details in a location accessible by the extension's containing app, so that the
// app may be notified about errors which occurred while loading data even if the request to load data was initiated by
// the user in Settings instead of via the app itself.
}
}