【问题标题】:iOS Callkit: CXProvider resets immediately after startingiOS Callkit:CXProvider 启动后立即重置
【发布时间】:2017-04-19 18:48:33
【问题描述】:

我正在将现有的 VoIP 应用程序转换为 Callkit。我有很多代码,但是当我初始化 CXProvider 时,它会调用providerDidBegin,然后立即调用providerDidReset。它没有给出理由。在那之后,我无法注册我的拨出电话,因为我的提供商未激活。

我已尝试查看证书、设置等,但基本上我不需要的 VoIP 应用程序似乎已经拥有更多。

CallKit调用reset方法如下:

CallKit`__42-[CXProvider handleConnectionInterruption]_block_invoke:

当我深入挖掘它的来源时,它与 NSXPCConnection 相关。这是什么连接,我需要如何设置?

当然连接没有中断。

这就是我初始化我的委托的方式:

- (id)init {
    self = [super init];

    self.configuration = [[ProviderConfiguration alloc] init];
    self.provider = [[CXProvider alloc] initWithConfiguration:self.configuration];

    [self.provider setDelegate:self queue:dispatch_get_main_queue()];

    return self;
}

这是配置的样子:

- (instancetype)init {
    self = [super initWithLocalizedName:@"MyCompany"];

    self.supportsVideo = NO;
    self.maximumCallsPerCallGroup = 1;
    self.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:(int)CXHandleTypePhoneNumber], nil];
    self.maximumCallGroups = 1;
    self.maximumCallsPerCallGroup = 5;


    return self;
}

两个回调都实现了:

- (void)providerDidBegin:(CXProvider *)provider {
    NSLog(@"Begun");
}

- (void)providerDidReset:(CXProvider *)provider {
    NSLog(@"Reset");
}

【问题讨论】:

    标签: ios objective-c callkit


    【解决方案1】:

    在我的情况下,同样的问题是由于 Info.plist 文件中缺少 VOIP 背景模式

    <key>UIBackgroundModes</key>
    <array>
        <string>audio</string>
        <string>voip</string>
    </array>
    

    由于某种未知原因,XCode 9 不允许使用 Capabilities 选项卡设置此后台模式。

    【讨论】:

    • 由于您的回答似乎对大多数人有所帮助,因此我将其设置为已接受的答案
    【解决方案2】:

    确保您使用有效的非空 UUID 调用 reportNewIncomingCallWithUUID:update:completion。苹果当前的实现调用完成没有错误但没有显示调用屏幕

    【讨论】:

    • 我在内部打赌,在对象的生命周期内某些东西被重置为零,因为内联代码在这种情况下有所帮助。
    【解决方案3】:

    不知何故,这些行是问题所在:

    self.configuration = [[ProviderConfiguration alloc] init];
    self.provider = [[CXProvider alloc] initWithConfiguration:self.configuration];
    

    它在调用 init 之前存储在 self.configuration 中。通过将相同的代码内联放置它就可以了。

    CXProviderConfiguration *configuration = [[CXProviderConfiguration alloc] initWithLocalizedName:@"MyCompany"];
    
    configuration.supportsVideo = NO;
    configuration.supportedHandleTypes = [[NSSet alloc] initWithObjects:[NSNumber numberWithInt:(int)CXHandleTypePhoneNumber], nil];
    configuration.maximumCallGroups = 1;
    configuration.maximumCallsPerCallGroup = 5;
    self.provider = [[CXProvider alloc] initWithConfiguration:configuration];
    

    【讨论】:

    • 为了其他可能遇到此问题的人的利益:问题在于,尽管 CXProviderConfiguration 是可变的,但 CXProvider 实际上并没有读取对其进行任何更改初始化之后(或者看起来如此)。当我们想动态更改铃声时遇到了这个问题;解决方案是动态创建一个 new 配置和提供程序(效果很好)。不幸的是,大多数 CallKit 文档仍然只是存根,并没有指出这些黑暗的角落(也没有指出其他任何东西!)
    【解决方案4】:

    我在模拟器上也有同样的行为。 在设备上没问题。

    【讨论】:

      【解决方案5】:

      您不能使用providerDidBegin 来处理调用,因为它用于标识您的类实例ProviderDelegate 的开头或CXProviderDelegate 的实例。要进行正确的管理,您必须创建可以为您执行此操作的辅助类。

      请参见 WWDC 2016 的以下示例: https://github.com/Lax/Learn-iOS-Swift-by-Examples/tree/master/Speakerbox

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-05
        • 1970-01-01
        • 2012-05-13
        • 1970-01-01
        • 1970-01-01
        • 2018-07-21
        相关资源
        最近更新 更多