在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
相关产品推荐
相关产品推荐

