iOS 仿微信语音推送响铃

最近做一个门铃项目,需要voip的方式通知客户端,需要用到pushkit来进行推送,首先这里讲一下如何制作后台所需要的.pem文件。
1.点击 “Certificates -> All” ,在 iOS Certificates界面,点击右上角的加号;
2.选择 Production -> VoIP Services Certificate,点击 “Continue”;
3.选择应用对应的App ID,然后点击 “Continue”;
4.点击 "Create Certificate",这时候会提示需要 Certificate Signing Request(CSR),用证书助理生成一个CSR文件即可。
5.回到Apple Developer页面,点击 "Continue",上传生成的 .certSigningRequest文件,点击 “Generate”,即可生成推送证书;
6.将刚才创建的证书下载到本地,然后双击打开,这时候系统会将其导入钥匙串中。 我们再打开钥匙串应用,选中对应的证书,右键选择导出,设置好密码然后导出到本地这样我们就得到了voip.cer文件
7.进入钥匙串,上边选择登录,下边选证书,找到刚才安装在钥匙串中的的voip.cer,右击选择到处voip.p12文件。
8.创建一个文件夹,随意命名,将voip.cer和voip.p12文件放入文件夹中
9.打开电脑的命令终端,进入(cd 文件夹名字)存储 voip.cer和voip.p12的文件夹
10.分别执行下列命令,最终生成.pem文件 ps:所有的文件名皆可以自定义,后缀不可随意更改

openssl x509 -in voip.cer -inform der -out PushVoipCert.pem
openssl pkcs12 -nocerts -out PushVoipKey.pem -in voip.p12
cat PushVoipCert.pem PushVoipKey.pem > xbell.pem

这三句命令会生成3个.pem,选择最后一个.pem文件给服务端即可

然后我们需要测试一下,我们需要一个php文件,内容如下
<?php

  // Put your device token here (without 
  $deviceToken = '设备deviceToken';

  // Put your private key's passphrase here:
  $passphrase = 'pem证书的密码';

  // Put your alert message here:
  $message = '推送的信息';

  ////////////////////////////////////////////////////////////////////////////////

  $ctx = stream_context_create([
    'ssl' =>[
            'verify_peer'   =>false,
            'verify_peer_name' => false
                               ]
    ]);
  stream_context_set_option($ctx, 'ssl', 'local_cert', '你的pem证书.pem');
  stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

  // Open a connection to the APNS server
  $fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

  if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);

  echo 'Connected to APNS' . PHP_EOL;

  // Create the payload body 
  $body['aps'] = array(
    'event' => 'push',
    'alert' => $message,
    'sound' => 'default'
    );

  // Encode the payload as JSON
  $payload = json_encode($body);

  // Build the binary notification
  $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

  // Send it to the server
  $result = fwrite($fp, $msg, strlen($msg));

  if (!$result)
    echo 'Message not delivered' . PHP_EOL;
  else
    echo 'Message successfully delivered' . PHP_EOL;

  // Close the connection to the server
  fclose($fp);

  ?>

这样我们后台工作就已经完成了!下面我们只需要在AppDelegate中注册一下通知,就可以愉快的收到通知啦!直接上代码
1、首先注册一下通知
-(void)registerVoipAndLocationNotifications{
    if ([UIDevice currentDevice].systemVersion.doubleValue >= 8.0) {
        UIUserNotificationSettings *userNotifiSetting = [UIUserNotificationSettings settingsForTypes:UIUserNotificationTypeBadge|UIUserNotificationTypeSound|UIUserNotificationTypeAlert categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:userNotifiSetting];
        PKPushRegistry *pushRegistry = [[PKPushRegistry alloc] initWithQueue:nil];
        pushRegistry.delegate = self;
        pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];
    }
    if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
        center.delegate = self;
        [center requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (!error) {
                NSLog(@"request authorization succeeded!");
            }
        }];
        [center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
            NSLog(@"%@",settings);
        }];
    }
}

2、设置一下通知回调
别忘了加
<PKPushRegistryDelegate,UNUserNotificationCenterDelegate>
UILocalNotification *_callNotification;
UNNotificationRequest *_request;//ios 10
进入正题,代理方法如下
//当VoIP推送过来会调用此方法,一般在这里调起本地通知实现连续响铃、接收视频呼叫请求等操作
- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type {
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {//应用程序运行在前台,目前接收事件。
        //这里可以直接执行你需要做的事
    }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateInactive){//应用程序运行在前台但不接收事件。这可能发生的由于一个中断或因为应用过渡到后台或者从后台过度到前台。
    }else if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground){
        //应用程序在后台
        //直接响铃
        [self beginCallingWithNotificationName:@"door bell is singing~~~~"];
    }else{
        //反正是不在前台  直接响铃
        [self beginCallingWithNotificationName:@"door bell is singing~~~~"];
    }
}
//应用启动此代理方法会返回设备Token 、一般在此将token上传服务器
- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
    NSString *str = [NSString stringWithFormat:@"%@",credentials.token];
    NSString *deviceToken = @"";
    deviceToken = [[[str stringByReplacingOccurrencesOfString:@"<" withString:@""]
                    stringByReplacingOccurrencesOfString:@">" withString:@""] stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"deviceToken------>>>%@",deviceToken);
    //这里可以吧deviceTokens上传到服务器
}
- (void)beginCallingWithNotificationName:(NSString *)NotificationName {
    if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter* center = [UNUserNotificationCenter currentNotificationCenter];
        UNMutableNotificationContent* content = [[UNMutableNotificationContent alloc] init];
        content.body =[NSString localizedUserNotificationStringForKey:[NSString              stringWithFormat:@"%@", NotificationName] arguments:nil];;
        UNNotificationSound *customSound = [UNNotificationSound soundNamed:@"voip_call.caf"];
        content.sound = customSound;
        UNTimeIntervalNotificationTrigger* trigger = [UNTimeIntervalNotificationTrigger triggerWithTimeInterval:1 repeats:NO];
        _request = [UNNotificationRequest requestWithIdentifier:@"Voip_Push"  content:content trigger:trigger];
        [center addNotificationRequest:_request withCompletionHandler:^(NSError * _Nullable error) {
            
        }];
    }else{
        _callNotification = [[UILocalNotification alloc] init];
        _callNotification.alertBody = [NSString stringWithFormat:@"%@", NotificationName];
        _callNotification.soundName = @"voip_call.caf";
        [[UIApplication sharedApplication]
         presentLocalNotificationNow:_callNotification];
    }
}
3、开启提送测试
将.pem证书和php文件放在一个随意命名的文件夹中,比如说命名为voip,打开终端,cd voip文件夹 ,然后输入 php php文件名称.php,然后enter如果你看到
Connected to APNS
message successfully delivered
那么恭喜你,推送成功啦!
ok,这样就完成了voip推送了!喜欢的小伙伴可以点个赞哟~
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容

  • 本文转自 此处 (注:此文转到简书是感觉文章写的很详细,方便一下其他人,如作者看到需要撤下会立马撤下) 由于项目中...
    Arvin_雾里看花阅读 7,260评论 7 14
  • 1、为什么使用PushKit? iOS10之后,苹果推出了CallKit框架增强VoIP应用的体验,主要表现在3个...
    子瑜愚阅读 17,961评论 10 27
  • 前言 本文大部分参考 iOS利用voip push实现类似微信(QQ)电话连续响铃效果 有兴趣的可以多参考它下自己...
    dandelionYD阅读 2,857评论 0 6
  • 对于APNS证书,要分别制作开发证书和生产证书,不同环境下使用不同的证书,但是对于VoIP证书只有一个,不过在服务...
    修_远阅读 3,249评论 0 5
  • 前言 现在第三方推送也很多 ,比如极光,融云,信鸽,其原理也是相同利用APNS推送机制 ,公司让做自己的推送。避免...
    修_远阅读 10,752评论 9 19