You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在didReceiveIncomingPushWithPayload中获UUID/Handle为nil,求Sinch集成CallKit/PushKit方案

解决Sinch集成CallKit/PushKit时推送Payload获取UUID/Handle为nil的问题

我帮你分析下这个问题——你在didReceiveIncomingPushWithPayload里从payload.dictionaryPayload取UUID和handle得到nil,大概率是解析方式不对或者没用到Sinch官方的解析逻辑,下面是具体的排查和解决步骤:

1. 先搞清楚Sinch推送Payload的真实结构

Sinch的通话推送数据不是直接放在顶层字典里的,你手动取@"UUID"肯定拿不到。先把完整的Payload打出来看看实际结构:

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    NSLog(@"完整推送Payload: %@", payload.dictionaryPayload);
    // 先看日志再继续解析
}

打印后你会发现,通话相关的UUID和对方ID(也就是你要的handle),一般都嵌套在@"sinch"这个子字典里,部分版本可能在@"data"下的嵌套结构中。

2. 用Sinch SDK官方方法解析,别自己硬拆字典

Sinch SDK本身提供了专门处理推送的方法,比你手动拆字典靠谱多了,还能适配SDK版本更新带来的结构变化。直接用SINClient的relayRemotePushNotification:方法解析,然后从返回结果里拿数据:

#import <Sinch/Sinch.h>

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    // 假设你已经初始化好SINClient实例存在self.sinchClient里
    SINNotificationResult *result = [self.sinchClient relayRemotePushNotification:payload.dictionaryPayload];
    
    if (result.isCall) {
        SINCallNotificationResult *callResult = (SINCallNotificationResult *)result;
        NSUUID *callUUID = callResult.callUUID; // 这就是你要的CallKit通话UUID
        NSString *handle = callResult.remoteUserId; // 通话对方的用户ID,对应CallKit的handle
        // 接下来就可以用这些数据初始化CXCallUpdate了
        CXCallUpdate *update = [[CXCallUpdate alloc] init];
        update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:handle];
        update.hasVideo = callResult.isVideoCall;
        // 然后通过CXCallController发起来电请求即可
        // ...
    }
}

这是Sinch官方推荐的做法,绝对比你自己拆字典稳。

3. 检查Sinch后台和App的配置是否匹配

  • 确认Sinch控制台里的APNs证书是正确的,并且推送类型选对了VoIP推送。
  • 检查Sinch后台填写的Bundle ID和你当前运行的App完全一致,不然Sinch可能发不出包含通话数据的推送。

4. 确认PushKit的基础配置没出错

  • 确保App的Capabilities里开了Push Notifications,并且Background Modes下勾选了Voice over IP。
  • 检查PKPushRegistry的初始化代码,注册的类型必须是PKPushTypeVoIP:
PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

5. 过滤非Sinch的推送

有时候可能会收到测试推送或者其他第三方推送,这类Payload里自然没有Sinch的通话数据。你可以先判断一下,只处理带Sinch标识的推送:

if (payload.dictionaryPayload[@"sinch"]) {
    // 处理Sinch通话推送
} else {
    // 其他推送忽略或者做别的处理
}

按照上面的步骤排查,应该能解决你拿不到UUID和handle的问题。

内容的提问来源于stack exchange,提问作者Vvk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 11:39:22