Severyn Katolyk
Severyn Katolyk

Reputation: 107

CallKit doesn't block numbers from array

I create numbers array from CNContact in singleton. But when I reload my CallKit extensions CallKit doesn't block number that I blocked before. Number length is 11 characters. Array isn't null. After reload CallKit Extension there is no error.

static let shared = BlockNumbersManager()
    private init() { }
    open var blockNumbers: [CXCallDirectoryPhoneNumber] = []
open func getIntegerBlockNumbers() -> [CXCallDirectoryPhoneNumber] {
        return blockNumbers
    }



private func addBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        let phoneNumbers: [CXCallDirectoryPhoneNumber] = BlockNumbersManager.shared.getIntegerBlockNumbers() // TODO: add numbers for block dynamically.
        for phoneNumber in phoneNumbers {
            context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
        }
    }

What have I missed?

Upvotes: 3

Views: 2505

Answers (5)

Bilal Khan
Bilal Khan

Reputation: 1413

It blocks the array. There are several limitations:-

I followed all these steps and its working flawless.

  1. When you install app which has extension make sure you enable your extension from Setting -> Phone -> Call Blocking & Identifications , turn on the switch for your extension.
  2. Verify the phone number, just to make sure you don't enter invalid numbers , because a single wrong number will void the number blocking.Use PhoneNumberKit its a great library. https://github.com/marmelroy/PhoneNumberKit
  3. Remember sorting array doesn't work on Array of string. Make sure u convert array string to Int64.
let arrayInt64 = decodedItems.map { str in
    if let intValue = Int64(str){
       return intValue
    }else{
       return 0
    }
}
  1. Make sure u remove the duplicates before passing to context.addBlockingEntry
import Algorithms
let numbers = [1, 2, 3, 3, 2, 3, 3, 2, 2, 2, 1]  
print(numbers.uniqued()) // prints [1, 2, 3]

OR

var uniqueArray : [Int64] = []
for element in arrayInt64{
    if !uniqueArray.contains(element){
        uniqueArray.append(element)
    }
}
  1. Most Important sort the array in ascending order.
uniqueArray.sorted(by: <)

Upvotes: 0

Darshak Suhagiya
Darshak Suhagiya

Reputation: 21

while parsing an array to blocking function you should note 5 points

  1. Check that Extension is enabled in settings (give permission to your app extention)
  2. must include country code
  3. Array must be in ascending order. while you sort your array it should be in integer or any numeric form (do not sort array in String form)
  4. In Array there should not be any duplicate numbers
  5. there should be proper numbers ( you should not block 123 like this do not wrong number )

Upvotes: 2

dilip
dilip

Reputation: 163

Check each phone number in your contact list, if any number without country code are listed then it will not added to blocking list, you must have to provide Country code + Number

Upvotes: 1

Wei WANG
Wei WANG

Reputation: 1778

While @Stuart 's answer makes quite good points, I'd like to add some tips from my side, after I spent over 1 hour to figure out why my Call Directory extension did not work...

  1. The phone number format: check if you've added the country code. In my case I tested with Australian mobile number like 0412345678, so it should be either 61412345678, or +61412345678. Yes both worked for me.

  2. Mind the iOS cache! What you've written in your Call Directory extension does not get executed/called each time you restart or run your app. i.e. You think you've appended some new phone numbers in the blocking array but iOS actually may not load it as you expected. The trick is to toggle your app's option in Settings -> Phone -> Call Blocking & Identification.

  3. You may want to call CXCallDirectoryManager.reloadExtension in your main app when a reload is needed to invalidate the iOS cache.

Upvotes: 3

Stuart M
Stuart M

Reputation: 11588

Currently in iOS 10.x, every time your Call Directory extension runs it must provide a complete set of phone numbers to either block or identify with a label. In other words, if it runs once and adds blocked phone numbers [A, B, C], and you wish to also block phone number D, then the next time the extension is run it must provide the complete list [A, B, C, D].

In iOS 11, some new APIs have been added which allow the extension to provide data incrementally whenever possible. For instance, if the extension has already run once and added blocked phone numbers [A, B, C], and you wish to also block phone number D, then the next time the extension is run it may first check if the system allows incremental loading, and if it does then it may add blocked numbers [D] and the full list of blocked numbers will become [A, B, C, D].

Note that when using the new iOS 11 incremental loading APIs, your extension must always check whether incremental loading is currently allowed. The system may occasionally need to reload the complete list of phone numbers and your extension must remain able to provide the complete list.

See the documentation for these new APIs at https://developer.apple.com/documentation/callkit/cxcalldirectoryextensioncontext

In addition, you may view the 'Call Directory Extension' iOS extension template in Xcode 9 which has been updated to demonstrate the new incremental loading APIs:

Xcode Call Directory Extension target template screenshot

Upvotes: 1

Related Questions