iOS / Swift: можно ли заблокировать некоторые входящие вызовы с помощью CallKit для определенной страны?

Я хочу заблокировать звонки из определенных стран, которые меня расстраивают, звоня восемь раз в день. Я хотел бы создать приложение, которое позволяет блокировать любые номера с определенным расширением (например, +33 Франция, +212 Марокко, +973 Бахрейн и т. д.).

Я добавил CallKit, следуя руководству, но безуспешно. Я пробовал это, но кажется, что я не могу даже заблокировать простой номер...

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...
      }

Любые идеи ?


person ΩlostA    schedule 11.05.2020    source источник
comment
Вы на правильном пути (хотя нет никакого способа сделать это на уровне страны, вы должны перечислить каждый отдельный номер, который вы хотите). Этот учебник выглядит довольно хорошо; убедитесь, что вы внимательно следуете всем инструкциям. Этот код должен войти в расширение каталога вызовов, а не в приложение (что может быть неочевидным, если вы никогда раньше не создавали расширение).   -  person Rob Napier    schedule 11.05.2020


Ответы (2)


С помощью CallKit вы можете создать расширение приложения, называемое расширением приложения Call Directory. Apple сначала проверяет, заблокирован ли входящий номер в системном или пользовательском списке заблокированных, а затем проверяет список заблокированных каталогов вашего приложения.

Внизу этой страницы это подробно объясняется: https://developer.apple.com/documentation/calkit?language=objc

Блокировка входящих вызовов

Когда на телефон поступает входящий вызов, система сначала обращается к черному списку пользователя, чтобы определить, следует ли блокировать вызов. Если номер телефона не находится в списке заблокированных пользователей или системы, система обращается к расширению каталога вызовов вашего приложения, чтобы найти соответствующий заблокированный номер. Это полезно для приложений, которые, например, поддерживают базу данных известных адвокатов или позволяют пользователю блокировать любые номера, соответствующие набору критериев.

Чтобы заблокировать входящие вызовы для определенного номера телефона, вы используете метод addBlockingEntryWithNextSequentialPhoneNumber: в реализации beginRequestWithExtensionContext:.

Примечание

Вы можете указать, что расширение вашего приложения Call Directory будет добавлять идентификацию и/или блокировать телефонные номера в своей реализации 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
person Declan Stewart McPartlin    schedule 11.05.2020
comment
Кажется, что приложения работают, почему я не могу сделать это сам? mashtips.com/ios-apps-block-calls - person ΩlostA; 11.05.2020
comment
Это правда, я отстал от жизни, CallKit действительно поддерживает это сейчас. - person Declan Stewart McPartlin; 11.05.2020

Вы должны указать код страны и контакт в addBlockingPhoneNumbers и addIdentificationPhoneNumbers, и он заблокирует входящие вызовы:

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")
        }
       
    }
}
person SomuYadav    schedule 06.09.2020