Search code examples
iosswiftswift3callkit

Identify unknown GSM calls in iOS


I have been working on an app which stores all contacts details within an organization. The main goal is my app should detect incoming or outgoing calls and it should show that who is the person which the number belongs to. As an example, this app will work as Truecaller app.

I tried googling and found it is impossible to detect incoming call number in IOS.

I read about CallKit in ios and get to know about Call Directory extension. Though I don’t have a clear idea how to implement it & I have no idea whether this thing will be the solution for my problem.

If an IOS device gets a call from an unknown number, will the system pick my app and search for the contact for the unknown number and will it show relevant information on the caller screen? Or is there are any other approach?


Solution

  • After some sleepless nights, I found the solution for my problem.

    1. In Xcode, Goto File -> New -> Target
    2. Select Call Directory Extension and Click Next
    3. And give whatever the name for and click finish
    4. Now your app should look similar to this

    Goto CallDirectoryExtension.swift and replace the code with this

    import Foundation 
    import CallKit
    class CallDirectoryHandler: CXCallDirectoryProvider {
    override func beginRequest(with context: CXCallDirectoryExtensionContext) {
        guard let phoneNumbersToBlock = retrievePhoneNumbersToBlock() else {
            NSLog("Unable to retrieve phone numbers to block")
            let error = NSError(domain: "CallDirectoryHandler", code: 1, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }
    
        for phoneNumber in phoneNumbersToBlock {
            context.addBlockingEntry(withNextSequentialPhoneNumber: CXCallDirectoryPhoneNumber(phoneNumber)!)
        }
    
        guard let (phoneNumbersToIdentify, phoneNumberIdentificationLabels) = retrievePhoneNumbersToIdentifyAndLabels() else {
            NSLog("Unable to retrieve phone numbers to identify and their labels")
            let error = NSError(domain: "CallDirectoryHandler", code: 2, userInfo: nil)
            context.cancelRequest(withError: error)
            return
        }
    
        for (phoneNumber, label) in zip(phoneNumbersToIdentify, phoneNumberIdentificationLabels) {
            context.addIdentificationEntry(withNextSequentialPhoneNumber: CXCallDirectoryPhoneNumber(phoneNumber)!, label: label)
        }
    
        context.completeRequest { (suc) in
            print(suc)
        }
    }
    
    private func retrievePhoneNumbersToBlock() -> [String]? {
        // retrieve list of phone numbers to block
        return ["+8612345678901","+8618180100980"]
    }
    
    private func retrievePhoneNumbersToIdentifyAndLabels() -> (phoneNumbers: [String], labels: [String])? {
        // retrieve list of phone numbers to identify, and their labels
        return (["+94123456789", "+94234567891"],
                ["John Doe","Angelina Jollie",])
    }
    
    }
    

    Now run and launch your app. Then go to Setting -> Phone -> Call blocking & Identification then turn on the permission.

    NOTE: If you made any changes to your contact list in CallDirectoryHandler, first you must turn off the permission and then remove your app from your device.

    Redo the steps each time when you debug your app, whenever you update your list.