如何将 PushKit 的完成处理程序用于 reportNewIncomingCallWithUUID
How to use completion handler of PushKit for reportNewIncomingCallWithUUID
我正在为我的应用程序使用 CallKit。
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
}];
if (completion) {
completion();
}
}
我的问题是:是写if completion then call completion,还是直接调用completion();
?那么哪一个是正确的?
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
}];
completion();
}
这是来电上报方法
- (void)reportIncomingCallFrom:(NSString *) from withUUID:(NSUUID *)uuid completion:(nullable void (^)(NSError *_Nullable error))completion
{
CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:from];
CXCallUpdate *callUpdate = [[CXCallUpdate alloc] init];
callUpdate.remoteHandle = callHandle;
callUpdate.supportsDTMF = YES;
callUpdate.supportsHolding = NO;
callUpdate.supportsGrouping = NO;
callUpdate.supportsUngrouping = NO;
callUpdate.hasVideo = NO;
NSLog(@"income uuid here for income call %@",uuid);
[self.callKitProvider reportNewIncomingCallWithUUID: uuid update:callUpdate completion:^(NSError *error) {
if (!error) {
NSLog(@"Incoming call successfully reported.");
} else {
NSLog(@"Failed to report incoming call successfully: %@.", [error localizedDescription]);
}
completion(error);
}];
}
有时我在后台收不到推送。
我想知道我上面的方法是否正确。
这种情况下,直接调用completion()
或者之前检查是否不是nil
,是等价的,因为completion
已经声明为nonnull
.
所以,你可以直接打电话给 completion()
,如果你有问题,那不是因为那个。
虽然检查 completion()
并不重要,因为它是 nonnull
- 我发现代码存在另一个问题,可能导致 VOIP 推送未传送。
您应该从 CallKit 提供程序完成块内部调用 completion()
。这会通知系统您已完成 VOIP 推送处理并调用了 CallKit。
但是,您通过通知 CallKit 异步调用它,因此当您内部有多个 NSLog()
调用时,可能会出现竞争条件。如果您在通知 CallKit 有来电之前调用推送处理完成块 - 从 iOS 13 开始,系统很可能会终止您的应用程序。
正确的方法如下:
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
completion();
}];
}
我还会在调用完成块后将调用移至 NSLog()
。
我正在为我的应用程序使用 CallKit。
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
}];
if (completion) {
completion();
}
}
我的问题是:是写if completion then call completion,还是直接调用completion();
?那么哪一个是正确的?
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
}];
completion();
}
这是来电上报方法
- (void)reportIncomingCallFrom:(NSString *) from withUUID:(NSUUID *)uuid completion:(nullable void (^)(NSError *_Nullable error))completion
{
CXHandle *callHandle = [[CXHandle alloc] initWithType:CXHandleTypeGeneric value:from];
CXCallUpdate *callUpdate = [[CXCallUpdate alloc] init];
callUpdate.remoteHandle = callHandle;
callUpdate.supportsDTMF = YES;
callUpdate.supportsHolding = NO;
callUpdate.supportsGrouping = NO;
callUpdate.supportsUngrouping = NO;
callUpdate.hasVideo = NO;
NSLog(@"income uuid here for income call %@",uuid);
[self.callKitProvider reportNewIncomingCallWithUUID: uuid update:callUpdate completion:^(NSError *error) {
if (!error) {
NSLog(@"Incoming call successfully reported.");
} else {
NSLog(@"Failed to report incoming call successfully: %@.", [error localizedDescription]);
}
completion(error);
}];
}
有时我在后台收不到推送。
我想知道我上面的方法是否正确。
这种情况下,直接调用completion()
或者之前检查是否不是nil
,是等价的,因为completion
已经声明为nonnull
.
所以,你可以直接打电话给 completion()
,如果你有问题,那不是因为那个。
虽然检查 completion()
并不重要,因为它是 nonnull
- 我发现代码存在另一个问题,可能导致 VOIP 推送未传送。
您应该从 CallKit 提供程序完成块内部调用 completion()
。这会通知系统您已完成 VOIP 推送处理并调用了 CallKit。
但是,您通过通知 CallKit 异步调用它,因此当您内部有多个 NSLog()
调用时,可能会出现竞争条件。如果您在通知 CallKit 有来电之前调用推送处理完成块 - 从 iOS 13 开始,系统很可能会终止您的应用程序。
正确的方法如下:
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type withCompletionHandler:(nonnull void (^)(void))completion
{
NSDictionary *payloadDict = payload.dictionaryPayload[@"aps"];
[self reportIncomingCallFrom:callerName withUUID:self.uuidCallkit completion:^(NSError * _Nullable error) {
completion();
}];
}
我还会在调用完成块后将调用移至 NSLog()
。