ΩlostA
ΩlostA

Reputation: 2601

iOS / Swift: Is it possible to block some incoming calls with CallKit for a specific country?

I would like to block calls from specific countries that are upsetting me by calling eight times a day. I would like to create an app that allows to block any numbers with a specific extension (for example +33 France, +212 Maroc, +973 Bahrain, etc...).

I added CallKit, I followed a tutorial with no success. I tried this, but it seems that I can't even block a simple number...

private func addAllBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
        print("1234")
        let phoneNumbers: [CXCallDirectoryPhoneNumber] = [ 1234 ]
        for phoneNumber in phoneNumbers {
          context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
        }
      }

      private func addOrRemoveIncrementalBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) {
        print("1234")
        // 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.
        let phoneNumbersToAdd: [CXCallDirectoryPhoneNumber] = [ 1234 ]
        for phoneNumber in phoneNumbersToAdd {
          context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
        }

        let phoneNumbersToRemove: [CXCallDirectoryPhoneNumber] = [ 1234 ]
        for phoneNumber in phoneNumbersToRemove {
          context.removeBlockingEntry(withPhoneNumber: phoneNumber)
        }

        // Record the most-recently loaded set of blocking entries in data store for the next incremental load...
      }

Any ideas ?

Upvotes: 0

Views: 4618

Answers (2)

SomuYadav
SomuYadav

Reputation: 123

You have to give country code & contact in addBlockingPhoneNumbers & addIdentificationPhoneNumbers and it will block the incoming calls :

class CallDirectoryHandler: CXCallDirectoryProvider {
    
    var callDirectory: CXCallDirectoryExtensionContext?
    
    override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        context.delegate = self
        self.callDirectory = context
        
        do {
            try removeFromBlock(to: context)
        } catch {
            NSLog("Unable to remove blocking phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }
    
        do {
            try addBlockingPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add blocking phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }
        
        do {
            try addIdentificationPhoneNumbers(to: context)
        } catch {
            NSLog("Unable to add identification phone numbers")
            let error = NSError(domain: "CallDirectoryHandler", code: 2, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }
        context.completeRequest()
    }
    
    // 1.
    private func addBlockingPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        let defaults =  UserDefaults(suiteName:"group._.in._._")
        if let countryCode =  defaults?.object(forKey:"countrycode") as? String {
            let num      =  Int64("\(countryCode)"+"\(defaults?.object(forKey:"Contact") as! String)")
            let blockedPhoneNumbers: [CXCallDirectoryPhoneNumber] = [num ?? 0000000]
            for phoneNumber in blockedPhoneNumbers.sorted(by: <) {
                context.addBlockingEntry(withNextSequentialPhoneNumber: phoneNumber)
            }
        }
    }
    
    // 2.
    private func addIdentificationPhoneNumbers(to context: CXCallDirectoryExtensionContext) throws {
        let defaults    =  UserDefaults(suiteName:"group._.in._._")
        if let countryCode =   defaults?.object(forKey:"countrycode") as? String {
            let num         =  Int64("+\(countryCode)"+"\(defaults?.object(forKey:"Contact") as! String)")
            let phoneNumbers: [CXCallDirectoryPhoneNumber] = [num ?? 0000000]
            let labels = ["_ Team"]
            
            for (phoneNumber, label) in zip(phoneNumbers, labels) {
                context.addIdentificationEntry(withNextSequentialPhoneNumber: phoneNumber, label: label)
            }
         }
    }
    
    // 1.
    private func removeFromBlock(to context: CXCallDirectoryExtensionContext) throws {
        let defaults    =  UserDefaults(suiteName:"group._.in._._")
        if let countryCode =  defaults?.object(forKey:"removeCountrycode") as? String {
            let num         =  Int64("\(countryCode)"+"\(defaults?.object(forKey:"ContactRemove") as! String)")
            let blockedPhoneNumber:CXCallDirectoryPhoneNumber = num ?? 0000000
            context.removeBlockingEntry(withPhoneNumber:blockedPhoneNumber)
            defaults!.removeObject(forKey:"ContactRemove")
            defaults!.removeObject(forKey:"removeCountrycode")
        }
       
    }
}

Upvotes: 0

With CallKit you can create an app extension, called Call Directory app extension. Apple first checks if the incoming number is blocked in the system or user's blocked list, then checks your app's directory's blocked list.

At the bottom of this page here it is explained in depth: https://developer.apple.com/documentation/callkit?language=objc

Blocking Incoming Calls

When a phone receives an incoming call, the system first consults the user’s block list to determine whether a call should be blocked. If the phone number is not on a user- or system-defined block list, the system then consults your app’s Call Directory extension to find a matching blocked number. This is useful for apps that, for example, maintain a database of known solicitors, or allow the user to block any numbers that match a set of criteria.

To block incoming calls for a particular phone number, you use the addBlockingEntryWithNextSequentialPhoneNumber: method in the implementation of beginRequestWithExtensionContext:.

Note

You can specify that your Call Directory app extension add identification and/or block phone numbers in its implementation of beginRequestWithExtensionContext:.

@interface CustomCallDirectoryProvider: CXCallDirectoryProvider
@end

@implementation CustomCallDirectoryProvider
- (void)beginRequestWithExtensionContext:(NSExtensionContext *)context {
    NSArray<NSNumber *> *blockedPhoneNumbers.sorted = @[ … ];
     for (NSNumber *phoneNumber in [blockedPhoneNumbers.sorted sortedArrayUsingSelector:@selector(compare:)]) {
        [context addBlockingEntryWithNextSequentialPhoneNumber:(CXCallDirectoryPhoneNumber)[phoneNumber unsignedLongLongValue]];
     }

    [context completeRequestWithCompletionHandler:nil];
}
@end

Upvotes: 4

Related Questions