iOS Callkit与Pushkit 的使用手册总结,折腾了我5天烦死了。

首先要说一下,callkit和pushkit的用途。我一开始误会了这个两货的用法导致浪费了很多时间。 callkit是可以让app调出打电话的页面,走打电话的流程,接听,挂掉。大概就是下图这样子。同时让这个通话能出现在通讯录里,所以这个功能一般用于app里的语音聊天,如果配合pushkit就可以实现在锁屏的情况下调出这个页面。

这里我就来简单介绍一下如何集成CallKit与PushKit

要集成,首先就要导入framework,图中的三个framework都要导入,第一个framework是从通讯录中直接拨打App电话所需要的。

Pushkit

首先从这个开始弄吧。

去苹果账号里申请voip的证书,这个证书和普通的推送证书一样,不懂的直接百度一下吧。或者参考这个www.jianshu.com/p/c85a58ab4…

然后在appdelegate里,导入

#import <PushKit/PushKit.h>
复制代码

然后,在didFinishLaunchingWithOptions里,初始化,并实现代理PKPushRegistryDelegate

PKPushRegistry .*pushRegistry = [[PKPushRegistry alloc] initWithQueue:dispatch_get_main_queue()];
pushRegistry.delegate = self;
pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
复制代码

然后,实现代理方法。如果能收到token代表,配置成功,token配置成功后就可以让后台给你发推送了。

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{     NSLog(@"%@",credentials.token);     //应用启动获取token,并上传服务器     token = [[[[credentials.token description] stringByReplacingOccurrencesOfString:@"<"withString:@""] stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""]; }

这个是接受推送的方法

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type

至于你想测试推送,由于我个人是兼职java开发,看这个里测试的,blog.csdn.net/m0_37954663…

Callkit

关于这个我觉得比起我干讲,还是先附上demo 感谢这个大大的demo,看完大体上就知道怎么用 github.com/itomorrow/C…

不过个人觉得还是有点复杂,简化了一下,大佬们都很喜欢搞一个CallKitManager来管理,但我并不需求这么复杂,能实现基础功能就完事了。 gitee.com/klkxxy/call…

创建一个文件实现Callkit的代理CXProviderDelegate

#import <CallKit/CallKit.h> **@interface** ProviderDelegate : NSObject<CXProviderDelegate>

里面实现的代理方法,无非就是,接电话,挂电话,打电弧,静音这种功能。

#import "ProviderDelegate.h"
#import <AVFoundation/AVFAudio.h>
@interface ProviderDelegate ()
@property (nonatomic ,strong) CXProvider *provider;
@end

@implementation** ProviderDelegate
static ProviderDelegate *shared = **nil**;
+ (instancetype)shared{
    @synchronized(self) {
        if (shared == nil) {
            shared = [[ProviderDelegate alloc]init];
        }
        return shared;
    } 
}

+(void)configureAudioSession{
    NSLog(@"Callkit& Configuring audio session");
    AVAudioSession *session = [AVAudioSession sharedInstance];
    [session setCategory:AVAudioSessionCategoryPlayAndRecord error:**nil**];
    [session setMode:AVAudioSessionModeVoiceChat error:**nil**];

}

//通过设置CXProviderConfiguration来支持视频通话、电话号码处理,并将通话群组的数字限制为 1 个,其实光看属性名大家也能看得懂吧。
- (CXProviderConfiguration *)config{
    **static** CXProviderConfiguration* configInternal = **nil**;
    **static** dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        configInternal = [[CXProviderConfiguration alloc] initWithLocalizedName:@"我的"];
        configInternal.supportsVideo = **NO**;
        configInternal.maximumCallsPerCallGroup = 1;
        configInternal.maximumCallGroups = 1;
        configInternal.supportedHandleTypes = [NSSet setWithObject:@(CXHandleTypePhoneNumber)];
        UIImage* iconMaskImage = [UIImage imageNamed:@"IconMask"];
        configInternal.iconTemplateImageData = UIImagePNGRepresentation(iconMaskImage);
        configInternal.ringtoneSound = @"voip_call.caf";

    });
    **return** configInternal;
}

- (**instancetype**)init{
    **if** (**self**) {
        //用一个 CXProviderConfiguration 初始化 CXProvider,前者在后面会定义成一个静态属性。CXProviderConfiguration 用于定义通话的行为和能力。
        **self**.provider = [[CXProvider alloc]initWithConfiguration:**self**.config];
        //为了能够响应来自于 CXProvider 的事件,你需要设置它的委托。
        [**self**.provider setDelegate:**self** queue:**nil**];
    }
    **return** **self**;
}


//这个方法牛逼了,它是用来更新系统电话属性的。。
-(CXCallUpdate *)callUpdate:(NSString *)handle andHasVideo:(BOOL)hasVideo{
    CXCallUpdate *update = [[CXCallUpdate alloc]init];
    update.localizedCallerName = @"aaaaaaaa";
    update.supportsGrouping = **NO**;
    update.supportsHolding = **NO**;
    update.remoteHandle = [[CXHandle alloc] initWithType:CXHandleTypePhoneNumber value:handle];
    update.hasVideo = hasVideo;
    **return** update;
}


- (**void**)providerDidReset:(**nonnull** CXProvider *)provider {


}


- (**void**)provider:(CXProvider *)provider performStartCallAction:(CXStartCallAction *)action{
    //向系统通讯录更新通话记录
    CXCallUpdate *update = [**self** callUpdate:action.handle.value andHasVideo:action.isVideo];
    [provider reportCallWithUUID:action.callUUID updated:update];
    [action fulfill];
}


- (**void**)provider:(CXProvider *)provider didActivateAudioSession:(AVAudioSession *)audioSession{
    //一定要记得播放铃声呐。。

}


//打电话方法

-(**void**)reportIncomingCall:(NSUUID *)uuid andHandle:(NSString *)handle andHasvideo:(**BOOL**)hasVideo andCompletion:(completion2)completion{

    CXCallUpdate *update = [**self** callUpdate:handle andHasVideo:hasVideo];
    [**self**.provider reportNewIncomingCallWithUUID:uuid update:update completion:^(NSError * **_Nullable** error) {
        **if** (!error) {

        }

        

        completion(error);

    }];

}

 

//接电话(按钮的返回)

- (**void**)provider:(CXProvider *)provider performAnswerCallAction:(CXAnswerCallAction *)action{
    [ProviderDelegate configureAudioSession];
    [action fulfill];

}


//挂电话的按钮,点击事件
- (**void**)provider:(CXProvider *)provider performEndCallAction:(CXEndCallAction *)action{
    //在这里添加自己App挂断电话的逻辑

    [action fulfill];

}

- (**void**)provider:(CXProvider *)provider performSetHeldCallAction:(CXSetHeldCallAction *)action{
    [action fulfill];

}

@end
复制代码

感觉看完上面大概就懂了吧。如果实在不懂,下载上面的demo体验一下。

参考文档

www.pianshen.com/article/110… www.jianshu.com/p/c85a58ab4…

demo

github.com/itomorrow/C…

gitee.com/klkxxy/call…


作者:庞然大虎
链接:https://juejin.cn/post/7137601079348297741/
来源:稀土掘金
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

这个是我的掘金账号,哈哈。 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值