当前位置: 首页 > 知识库问答 >
问题:

iOS 13原因:“杀死app是因为它在收到PushKit VoIP推送回拨后从未向系统发布来电。”

弓泰
2023-03-14

从很多天起,我就陷入了这个问题...

AnyHashable("aps"): {
    alert =     {
        action = test;
        body = "{\"action\":\"connect\",\"meetingId\":\"mdkdkkydjgedjhd\",\"from\":\"sender\",\"fromToken\":\"9d739e878521cf770d9e5136161cf7611c242ef2a8b53c83c81b6b6021a7b31b\",\"to\":\"receiver\",\"toToken\":\"e65bf5e3d6a3e440eb364fb620539de4f4c2c1bf98be5f753f5abfbe7fecea74\",\"callUUID\":\"9EB823F3-F857-490B-BCFC-373D05E56933\"}";
        title = Call;
    };
}]

这是我正在接收的有效载荷,并根据动作发出传入呼叫

func getPushkitPayload(payload : [AnyHashable : Any], completionOfHandlingIncomingCall : @escaping (Bool) -> Void){
    let dict : Dictionary <String, AnyObject> = payload["aps"] as! Dictionary<String, AnyObject>
    let Alert : Dictionary <String, AnyObject> = dict["alert"] as! Dictionary<String, AnyObject>
    let strBody : String = Alert["body"] as? String ?? ""

    if let data = strBody.data(using: String.Encoding.utf8) {
        do {
            let model = try JSONDecoder().decode(PushkitModel.self, from: data)
            print("RES MODEL")
            dump(model)
            //if app background
            if  UIApplication.shared.applicationState == .background || UIApplication.shared.applicationState == .inactive {
                //here check action if it is connect then show incoming call
                if model.action == "connect" {
                    CallKitManager.shared.receiveCall(model: model, delegate: self) { (initiated) in
                        completionOfHandlingIncomingCall(initiated)
                    }
                } else {
                    let sendModelToNotCenter:[String: Model] = ["Model": model]
                    NotificationCenter.default.post(name: Notification.Name("DisconnectCallFromReceiver"), object: nil, userInfo: sendModelToNotCenter)
                }
            } else {
                //here check action if it is connect then show incoming call
                if model.action == "connect" {
                    CallKitManager.shared.receiveCall(model: model, delegate: self) { (initiated) in
                        completionOfHandlingIncomingCall(initiated)
                    }
                } else {
                    let sendModelToNotCenter:[String: Model] = ["Model": model]
                    NotificationCenter.default.post(name: Notification.Name("DisconnectCallFromReceiver"), object: nil, userInfo: sendModelToNotCenter)
                }
            }
        } catch let error as NSError {
            print(error)
        }
    }
}

在<code>CallKitManager.shared中。receiveCall(model:model,delegate:self){(initiated)in completionOfHandlingIncomingCall(initiate)我向callkit报告了接收到的uuid

public func receiveCall(model: PushkitModel, delegate : CallKitDelegate, completion : @escaping (Bool) -> ()) {
    self.delegate = delegate
    self.model = model
    receiveCallDetails(delay: 0){ (initiated) in
        completion(initiated)
    }
}

public func receiveCallDetails(delay: TimeInterval, completion : @escaping (Bool) -> ()) {
    if let model = self.model, let uuid = UUID(uuidString: model.callUUID) {
        let update = CXCallUpdate()
        update.remoteHandle = CXHandle(type: .emailAddress, value: model.from)

        let bgTaskID = UIApplication.shared.beginBackgroundTask(expirationHandler: nil)
        DispatchQueue.main.asyncAfter(deadline: DispatchTime.now() + delay) {
            self.provider?.reportNewIncomingCall(with: uuid, update: update, completion: { (error) in
                if error == nil {
                }
                completion(true)
            })
            /* If you didn’t put caller information in your notification’s payload, call the reportCall(with:updated:) method of your app's provider object to update the calling interface. You can call that method at any time to update calls. For example, call it after your app fetches updated caller information from your VoIP server.*/
            // Asynchronously register with the telephony server and
            // process the call. Report updates to CallKit as needed.
            **self.provider?.reportCall(with: uuid, updated: update)**
            UIApplication.shared.endBackgroundTask(bgTaskID)

        }
    }  
}

当应用程序打开并且传入呼叫也启动时,我可以接收有效负载。但是当我在iOS 13上关闭我的应用程序时,我收到一个错误

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push callback.'

因为我已经报告了我的电话。如果有人有解决办法,那就太好了。

共有1个答案

燕琛
2023-03-14

我认为问题是您在DispatchQueue.main.asyncAfter中报告调用。即使您将延迟设置为0,您的代码也会在下一个运行循环中运行,即不会立即运行。这样,push注册表(_: didReceiveIncomingPushWith: for:完成:)函数将在您的调用报告之前结束,因此系统会投诉。

因此,尝试删除DispatchQueue.main.asyncAfter

 类似资料:
  • 我正在寻找解决办法,但还没有找到。我的应用程序只接收VoIP推送,在iOS 13之后,当应用程序处于后台模式时,我无法再接收推送。我查看了其他问题,但我无法用建议的解决方案解决我的问题。有人能帮我吗? 在iOS13.0及更高版本上,必须在接收到传入的IP语音呼叫时以及在didReceiceIncomingPush()方法使用CallKit框架完成执行之前报告,否则系统将终止您的应用程序。 多次未能

  • 我有一个非常简单的< code>@RestController,我试图设置一个自定义的错误消息。但是由于某种原因,错误的< code >消息没有显示出来。 这是我的控制器: 这是我得到的回应: 我正在传递一个JSON,但我没有验证任何东西,我只是试图设置自定义消息。如果我更改状态代码,我会在响应中看到,但< code>message始终为空。 为什么这没有像预期的那样工作?这是一个如此简单的示例,

  • 我正在使用mybatis将数据插入到postgresql DB中。我有19629个记录要插入。我正在尝试一次插入所有记录。但是,如果我向查询传递超过6K条记录,我将得到原因:org.PostgreSQL L.util.psqlException:发送到后端时发生I/O错误。 设置参数SQL:insert到temp_overdrive_csv_dtls(LPAT_LIBRARY_CARD_NUMER

  • 我有一个大型git回购(由SVN回购创建),我想将其推送到github。由于它很大,我不能直接尝试推送它,因为它会出现“packtoo-large”错误。 到目前为止一切都很好,我可以一次提交一个回购。但是当我试图这样做的时候,会发生的是: 所以,在远程回购中还没有主分支,但我正试图推动它,但它失败了。 我该如何解决这个问题?或者,如何在远程创建一个空的主分支,以便推送到它?

  • 我有一个应用程序有推送通知功能。我注意到有些设备,特别是中国手机,像夏摩、oppo、一加等都有自动启动的选项,这就控制了推送通知。当应用程序不在后台或最近列表中时,我不会收到推送通知。默认情况下,我的应用程序自动启动是关闭的 是否有任何选项可以将“自动启动”设置为默认为“开启”

  • 及策-精细化移动归因解决方案 移动 APP 推广效果精准可视化呈现、国内独家曝光效果评估&多触点归因评估,深入剖析渠道广告贡献,助您科学评估媒体角色和定位,合理分配渠道预算,提升ROI。 更科学、更精细评估媒体效果,实现 ROI 最大化 国内独家 MTA 多触点归因模型,还原用户从广告曝光、点击到激活转化的完整链路。 可视化呈现用户媒体接触轨迹; 清晰查看媒体之间相互辅助转化,媒体重合度; 曝光转