Сбой приложения iOS при получении уведомления pushkit voip после принудительного закрытия

Пытаюсь заставить работать pushkit voip сообщения при закрытии приложения. Звонки работают и отображаются, когда приложение находится на переднем плане или в фоновом режиме. Но после того, как пользователь принудительно убивает приложение, при получении уведомления приложение завершает работу с сигналом 9 (убит пользователем / ios).

Как я могу исправить эту проблему?

В моем приложении включены фоновая выборка, VoIP, аудио и push-уведомления. Также попытался удалить все методы Unity, поместить вызов Callkit в метод PushRegistry, создать нового поставщика при получении уведомления, даже подписаться на событие UIApplicationDidFinishLaunchingNotification, но ничего не сработало. Я сделал так, чтобы приложение отображало вызов при получении уведомления voip. Вот мой код:

@objcMembers class CallPlugin: UIResponder, UIApplicationDelegate, PKPushRegistryDelegate, CXProviderDelegate {

static var Instance: CallPlugin!
var provider: CXProvider!
var registry:PKPushRegistry!
var uuid:UUID!
var callController: CXCallController!

//class entry point
public static func registerVoIPPush(_ message: String) {
    Instance = CallPlugin()

    //Pushkit
    Instance.registry = PKPushRegistry(queue: DispatchQueue.main)
    Instance.registry.delegate = Instance
    Instance.registry.desiredPushTypes = [PKPushType.voIP]

    //Callkit
    let providerConfiguration = CXProviderConfiguration(localizedName: "testing")
    providerConfiguration.supportsVideo = true
    providerConfiguration.supportedHandleTypes = [.generic]
    Instance.provider = CXProvider(configuration: providerConfiguration)
    Instance.provider.setDelegate(Instance, queue: nil)        

    UnitySendMessage("ResponseHandler", "LogNative", "registration success")
}

//Get token
func pushRegistry( _ registry: PKPushRegistry, didUpdate credentials: PKPushCredentials, for type: PKPushType) {
    if type == PKPushType.voIP {
        let deviceTokenString = credentials.token.map { String(format: "%02.2hhx", $0) }.joined()
        UnitySendMessage("ResponseHandler", "CredentialsRecieved",deviceTokenString)
    }
}       

//Get notification
func pushRegistry( _ registry: PKPushRegistry, didReceiveIncomingPushWith payload: PKPushPayload, for type:PKPushType, completion: @escaping () -> Void) {

    //UnitySendMessage("ResponseHandler", "LogNative", "Got something push")
    reportInComingCallWith(uuidString: "111", handle: "Paul", isVideo: false)
    completion()
}

//show the call
func reportInComingCallWith(uuidString:String,handle:String,isVideo:Bool) {
    //UnitySendMessage("ResponseHandler", "LogNative", "attempting call")
    let callUpdate = CXCallUpdate()        
    callUpdate.remoteHandle = CXHandle(type: .generic, value: handle)        
    callUpdate.hasVideo = false

    uuid = NSUUID() as UUID

    provider.reportNewIncomingCall(with: uuid as UUID, update: callUpdate){ (error) in
        if let error = error {
            UnitySendMessage("ResponseHandler", "LogNative", "error in starting call"+error.localizedDescription)
        }
    }
}

person Paul Vinogradov    schedule 09.04.2020    source источник
comment
Это ваша проблема и решение. ответ   -  person Kasım Özdemir    schedule 10.04.2020
comment
Получаете ли вы журнал сбоев, трассировку стека или сообщение об исключении? @ KasımÖzdemir, это не должно быть их проблемой, поскольку они сообщают о входящем звонке   -  person Paulw11    schedule 10.04.2020
comment
Проблема та же. Поэтому, когда приложение забанят за 2–3 попытки, оно перестает получать голосовые сообщения. Вам необходимо удалить и переустановить приложение.   -  person Kasım Özdemir    schedule 10.04.2020
comment
@ KasımÖzdemir Мне известно о том, что приложение забанили, и о том, как это исправить путем переустановки, но проблема здесь не в этом. Когда вас забанят, приложение перестает получать push-уведомления. Мое приложение не перестает их получать, вместо этого просто вылетает с SIG-9, когда это происходит. Даже с первой попытки после переустановки. Я не думаю, что это проблема с правами, так как я звоню Callkit, когда получаю VOIP push.   -  person Paul Vinogradov    schedule 10.04.2020
comment
@ Paulw11 У меня нет отчетов о сбоях, так как я еще не загрузил его в рабочий appstore.et. Отладчик на самом деле ничего мне не показывает, так как приложение сразу вылетает, отладчик видит только сигнал 9. Может быть, есть способ увидеть локальные журналы предыдущих сбоев приложения, но я не знаю о них. Это приложение Unity, а не собственный Swift, поэтому проверка не намного упрощается.   -  person Paul Vinogradov    schedule 10.04.2020
comment
Вы можете открыть журнал своего устройства в консольном приложении Mac и посмотреть, есть ли там что-нибудь полезное.   -  person Paulw11    schedule 10.04.2020
comment
@ Paulw11 проверил журналы устройства, получив причину завершения 0xbaadca11, которая является ошибкой callkit, но перед этим происходит сбой потока с ошибкой размера адреса 0x56000080. Я предполагаю, что это связано с тем, что класс инициализируется не в appdelegate, а немного позже в приложении. Это потому, что я использую это в приложении Unity. Я обновил свое приложение, чтобы вызвать инициализацию из события параметров DidFinishLaunchingWith, но приложение закрывается сразу после того, как попадает в это событие, даже в операторе печати.   -  person Paul Vinogradov    schedule 13.04.2020


Ответы (1)


Проблема заключалась в том, что мое приложение не создавало объекты делегата и pushregistry вовремя, чтобы уведомление было полностью обработано.

Я решил это, переопределив делегат приложения и поместив инициализации уведомлений в WillFinishLaunching, например:

-(BOOL)application:(UIApplication *)application willFinishLaunchingWithOptions:(nullable NSDictionary<UIApplicationLaunchOptionsKey,id> *)launchOptions{
   [CallPlugin registerVoIPPush:@"hmm"];
   [super application:application willFinishLaunchingWithOptions:launchOptions];
   return true;
}

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

person Paul Vinogradov    schedule 13.04.2020
comment
У меня такая же проблема, и я использую для этого Кордову. В плагинах, которые я использую, я не вижу метода willFinishLaunchingWithOptions. Вы писали это с нуля? - person AleksandarT; 21.09.2020
comment
Да, это моя собственная реализация. Вы можете просто добавить его или любой другой метод делегата приложения и переопределить его в главном appController. - person Paul Vinogradov; 23.09.2020