实现 PushKit 并测试开发行为

2024-03-29

我想在我的应用程序(Voip 应用程序)中实现 PushKit 服务,但我有以下疑问:我看到我只能生成生产 voip 证书,如果我尝试在开发设备上测试 voip 推送通知服务,它可以工作吗?

这是我的实施测试:

通过这 3 行代码,我可以在 didUpdatePushCredentials 回调上获取推送令牌,我用它保存到我的服务器中。

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

服务器端我生成一个“正常”有效负载推送通知,仅包含警报文本,然后发送到存储在我的服务器中的 voip 令牌。

我将回调与调试日志一起使用,但它们从未被调用!

- (void)pushRegistry:(PKPushRegistry *)registry didInvalidatePushTokenForType:(NSString *)type {

          NSLog(@"didInvalidatePushTokenForType");

}

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

          NSLog(@"didReceiveIncomingPushWithPayload: %@", payload.description);

}

-(void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type {
     if([credentials.token length] == 0) {
           NSLog(@"voip token NULL");

          return;
     }

      NSLog(@"didUpdatePushCredentials: %@ - Type: %@", credentials.token, type);

}

如果我尝试从我的服务器生成一条推送通知消息到之前上传的 voip 设备令牌,我永远不会收到 didReceiveIncomingPushWithPayload 回调的通知,但从服务器我收到 200 ok 消息(消息已成功发送)


以防万一有人有兴趣使用 Pushkit 测试 voip 推送通知,我在这里留下了一个我成功遵循的小程序:

1 - 创建(如果您还没有)CSR使用钥匙串访问并在本地保存您的 CSR。

2 - 转到 Apple Developer 并获取访问证书、标识符和配置文件。在会员中心。

  • Inside Identifiers-> App IDs 创建一个新的应用程序 ID
  • 在“设备”->“全部”内添加要用于测试 voip 推送的设备 UDID
  • 内部证书 -> 全部 创建新的生产证书:VoIP 服务证书。选择之前为您的 voip 服务证书创建的应用程序 ID。选择之前创建的 CSR(证书签名请求),创建后下载新的 voip_services.cer

下载后双击voip_services.cer为了打开钥匙串访问应用程序并导出生成证书的私钥:右键导出证书.p12 file.

Save voip_services.cer and 证书.p12文件放在文件夹中以创建服务器推送通知生成器

最后再次访问 Apple Developer 网站,在 Provisioning Profiles->Distribution 中创建一个新的临时分发配置文件包括您想要用于测试 voip 推送的所有设备 UDID。下载此配置文件并将其拖放到您的 xcode 中,以便在您的应用程序中使用它。

现在让我们创建将接收 voip 推送通知的 iOS 应用程序:

  • 从 Xcode 新项目菜单创建一个新的单视图应用程序。
  • 根据上一节中创建的应用程序 ID 填写其捆绑包标识符。
  • 在“常规”->“链接的框架和库”中添加 PushKit.framework。
  • 在功能中启用后台模式并选择 IP 语音选项。
  • 在“构建设置”->“代码签名”中,选择您之前下载的配置文件,然后选择“分发”作为“代码签名身份”。

让我们在应用程序中添加代码Pasquale https://stackoverflow.com/users/2289654/pasquale在他的问题中添加:

在您的根视图控制器标头中(视图控制器.h) PushKit.framework 的导入:

#import <PushKit/PushKit.h>

添加委托以实现其功能:

@interface ViewController : UIViewController <PKPushRegistryDelegate>

在根视图控制器(ViewController.m)的 viewDidLoad 函数中添加推送注册:

- (void)viewDidLoad {
    [super viewDidLoad];

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

实现所需的委托函数:

- (void)pushRegistry:(PKPushRegistry *)registry didUpdatePushCredentials:(PKPushCredentials *)credentials forType:(NSString *)type{
    if([credentials.token length] == 0) {
        NSLog(@"voip token NULL");
        return;
    }

    NSLog(@"PushCredentials: %@", credentials.token);
}

- (void)pushRegistry:(PKPushRegistry *)registry didReceiveIncomingPushWithPayload:(PKPushPayload *)payload forType:(NSString *)type
{
    NSLog(@"didReceiveIncomingPushWithPayload");
}

一切编译完毕后,归档您的项目并导出您的 ipa 文件,以便将其安装在测试设备上(您可以使用 Testflight 来完成这项工作)。

执行它并从日志中获取我们将用于发送推送的 PushCredentials。

现在让我们转到服务器端(我遵循了这个很棒的指南raywenderlich 教程 http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1):

返回到放置三个文件的文件夹:

  • voip_services.cer
  • 证书.p12

1 - 打开终端并从证书文件创建 pem 文件:

#openssl x509 -in voip_services.cer -inform der -out PushVoipCert.pem

2 - 从导出的私钥文件创建 pem 文件:

#openssl pkcs12 -nocerts -out PushVoipKey.pem -in certificate.p12

3 - 将两个 pem 文件合并为一个:

#cat PushVoipCert.pem PushVoipKey.pem > ck.pem

为了发送推送,您可以使用Pusher https://github.com/noodlewerk/NWPusher from raywenderlich 教程 http://www.raywenderlich.com/32960/apple-push-notification-services-in-ios-6-tutorial-part-1教程或使用简单的 php 脚本:

<?php

// Put your device token here (without spaces):
$deviceToken = '0f744707bebcf74f9b7c25d48e3358945f6aa01da5ddb387462c7eaf61bbad78';

// Put your private key's passphrase here:
$passphrase = 'pushchat';

// Put your alert message here:
$message = 'My first push notification!';

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

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.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(
    '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);

你应该在脚本中修改:

  • $deviceToken 通过添加您的 PushCredentials(来自应用程序日志)
  • $passphrase 为您在创建 PushVoipKey.pem 时在步骤 2 中添加的密码

就是这样。执行php脚本:

#php simplePushScript.php

并且您应该收到 voip 推送通知(您应该看到应用程序日志:“didReceiveIncomingPushWithPayload”)

在那次测试之后,我想知道如何通过pushkit框架接收标准推送通知,但不幸的是我没有答案,因为在注册推送类型时我找不到任何其他PKPushType,但PKPushTypeVoIP...

pushRegistry.desiredPushTypes = [NSSet setWithObject:PKPushTypeVoIP];

就这样!谢谢阅读!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

实现 PushKit 并测试开发行为 的相关文章

  • 如何在WKInterfaceLabel下面放置一个WKInterfaceLabel?

    大家好 我在 watchkit 开发中有新的东西 我有特殊要求 我将一个 WKInterfaceLabel 安排在另一个 WKInterfaceLabel 下面 我尝试使用很多关闭选项 例如编辑位置 但 WKInterfaceLabel 未
  • 如何在 Swift 编程中获得基于导航的模板功能

    我的项目需要一个导航控制器 并且我的应用程序最初有一个社交登录 一旦验证通过 用户将被推送到另一个视图 我在其中显示一个具有 2 个选项卡的选项卡控制器 我不知道如何在 Swift 编程中做到这一点 我已将视图控制器嵌入到导航控制器中 一旦
  • GIDSignIn 在提示前指定范围

    我在 iOS 上升级到 GoogleSignIn 6 0 但找不到在登录时指定登录范围的方法 我只能看到一个名为 addScopes 的 API 我可以在基本登录后指定范围 但这会导致两个单独的登录提示 这很奇怪 之前 我们可以简单地指定登
  • Swift 中的 AURenderCallback

    我正在创建一个使用音频单元的应用程序 虽然 Objective C 中有很多代码示例 包括 Apple 自己的 aurioTouch 等 但我正在尝试用 Swift 编写整个代码 我已经能够设置我的 AUGraph 并通过它运行一些音频 但
  • 如何区分iphone4和iphone 3

    我正在尝试使用 cocos2d 引擎为 iphone 构建游戏 我想知道如何区分用户使用的是 iphone 4 还是 iphone 3 因为我想为 iphone4 加载高分辨率图形 为 iphone 3 加载低分辨率图形 我知道我是否在以下
  • Xcode 找不到我的静态库!

    这是链接器错误 i686 apple darwin10 gcc 4 2 1 Users william Documents SettingsLibrary build Debug iphonesimulator libSettingsLib
  • 在 swift 中从本地视频创建缩略图

    如何从本地视频文件快速创建缩略图 例如 如果视频文件路径位于此处 file Users Dev Library Developer CoreSimulator Devices F33222DF D8F0 448B A127 C5B03C64
  • 如何在pop UIViewController中删除UIParallaxDimmingView?

    我有一个UIViewController vc1这是在之后推送的UIViewController vc2 Both vc1 and vc2具有透明背景 问题 当我尝试弹出时vc2使用交互式弹出手势 从边缘平移 在我看来堆栈显得很神秘UIPa
  • 使用UDID创建唯一的用户身份

    我正在开发一个 iPhone 应用程序 它与服务器通信以存储和交换数据 因为我想让它尽可能简单 所以我想避免用户帐户的注册 或者也可能使用密码 是否有可能 并且允许 获取 iPhone 设备的 UDID 并制作例如 它的 MD5 哈希值 我
  • UITableViewCell 内的 UIPageViewController

    嘿我想问如何在 UITableViewCell 内实现 UIPageViewController 我一直在阅读周围的内容 但到目前为止似乎对任何尝试的人都不起作用 我希望得到一些提示 不需要完整的答案 谢谢 目前还不清楚你到底想做什么 但让
  • “Firebase Storage”,用于图像 - 但是,获取实际的 URL?

    正在将图像发送到 Firebase Storage 系统 sr a StorageReference ie FIRStorageReference let task sr putData data task observe success
  • 如何使用 PKAddPassButton 创建“添加到苹果钱包”按钮以进行本地化通行证

    在我的 iOS 项目中 我有一个屏幕 允许用户创建苹果通行证并将其添加到钱包中 Apple 建议使用 PKAddPassButton 创建 添加到苹果钱包 按钮 当我尝试使用以下代码创建苹果通行证时 let passButton PKAdd
  • TestFlight iOS 应用程序 get-task-allow 问题

    我在 ios 的 testflight 中有一个名为 MapItTrackIt 的应用程序 一切都进展顺利 我刚刚更新到 xcode 5 1 我按照以往的方式构建了该应用程序 相同的配置文件和临时证书 这次 当我尝试上传 IPA 文件时 我
  • 检测用户何时清除通知中心的通知

    我的应用程序需要知道用户是否使用清除按钮从通知中心删除 清除应用程序通知 是否可以检测用户何时从通知中心删除通知或抓取通知中心上的一组通知 你 即App 无法与NotificationCenter交互 NotificationCenter与
  • 子视图的子层与更高的子视图重叠

    我有一个问题 我正在创建一个UIView这是从方法返回的 这部分很好 但我注意到 当我将子层添加到其中一个子视图时 这些层与子层添加的层次结构中较高的子视图 textView 和 imageView 重叠到testViewCopy出现在这些
  • 沙盒测试帐户反复询问 iOS 应用内购买的密码

    我用 Swift 语言开发了一个应用程序 我添加了应用内购买来删除广告 我还创建了一个沙箱帐户来测试 但后来我忘记了这个账户的信息 我不确定信息 密码输入屏幕仍然以闪烁的屏幕显示方式显示 即使我重置设备并重新加载它 也没有任何好处 实际上一
  • prepareForSegue 和 PerformSegueWithIdentifier 发送方

    我想知道标题中的函数如何工作以及发送者参数 假设单击按钮调用了performSegue方法 那么这是否也调用了prepareSegue方法 是否在performSegue方法之前但在按下按钮之后调用prepareSegue方法 另外 这两个
  • 解包可选值时意外发现 nil - 使用 ALAMOFIRE

    我正在尝试使用 Alamofire 获取 JSON 格式的数据 当我使用一个 URL 时 它工作正常 当我使用另一个 URL 时 我在解包可选值时收到错误 我似乎无法追踪错误来自哪里 我已采取将代码放入 ViewDidLoad 来跟踪错误
  • 了解 React Native 中的默认字体大小

    在过去的几个月里 我一直在开发一个 React Native 应用程序 但有些事情总是让我困惑 而我现在正试图弄清楚它的真相 我正在尝试标准化应用程序中的字体大小 正文 标题等 并且正在努力了解 React Native 究竟从哪里获取默认
  • 从基元创建自定义形状

    我正在尝试通过组合原始形状来创建自定义物理形状 目标是创建一个圆形立方体 合适的方法似乎是初始化 形状 变换 我在这里找到的https developer apple com library prerelease ios documenta

随机推荐

  • sizeof(*ptr) 和 sizeof(struct) 之间的区别

    我尝试了以下程序 struct temp int ab int cd int main int argc char argv struct temp ptr1 printf Sizeof struct temp d n sizeof str
  • Safari 中的 CSS 间距问题?

    我为我的最新项目制作了一个基于列表的导航栏 并在导航的每一侧添加了两个信息栏 它在 Firefox 和 IE 中的表现符合预期 但奇怪的是 Safari 却表现不佳 它在导航栏和右侧信息栏之间留出了很大的空间 CSS body backgr
  • Laravel 雄辩的变异器不适用于更新数据

    我的模型中有用于数据库表字段中的哈希 重新哈希数据的访问器和修改器 例如 public function setFullNameAttribute value this gt attributes full name Helper gete
  • 安装nodejs npm 和 grunt 出现错误

    我不熟悉 Python NodeJS NPM 或 Grunt 但我需要安装它 因为我想尝试一下Github项目 https github com raphaelluchini popcorntime smarttv 我从 node org
  • 如何在 AppFog 中使用 Apache 提供静态内容(WSGI Python 应用程序)

    我在用着AppFog http www appfog comPaaS 系统使用了几天 我喜欢它 它可能是我测试过的最好的 PaaS 系统 我之前使用过其他 3 个 但没有找到有关如何使用 Web 服务器提供静态内容的信息在前端 Apache
  • 从地图中获取一段键

    有没有更简单 更好的方法从 Go 中的映射中获取键的切片 目前我正在迭代地图并将键复制到切片 i 0 keys make int len mymap for k range mymap keys i k i 这是一个老问题 但这是我的两分钱
  • 在 C# 中获取特定时区的日期时间时出现 System.TimeZoneNotFoundException 错误

    我有一个 JSON 文件 其中包含time zone范围 它的值如下London Casablanca Arizona Pacific Time US Canada 等 基于time zone 我想得到DateTime该时区的结果 例如 C
  • Ubuntu 17.04 上 sudo apt-get 更新失败

    运行时sudo apt get update在 ubuntu 17 04 Zesty Zapus 上 我收到以下错误 我已经在错误行上发布了 我想安装 python 库 如 matplotlib 和 tkinter 但由于上述命令未成功运行
  • CSS 文件和不需要的覆盖

    我有一个简单的 HTML 页面 它引用了 3 个 CSS 文件 第一个是仅适用于页面的样式表 另外两个是针对两个独特情态动词的样式 这些模态 CSS 文件不是我创建的 它们很高兴被使用分别地在整个网站的其他页面上 我的问题是 这两个模态 C
  • 1-2 秒后暂停 YouTube 视频

    我正在使用 Youtube Player api 在我的应用程序中播放 YouTube 视频 视频开始播放并在 1 2 秒后暂停 我创建了视频片段和视图组 随后我创建了一些 youtobe 视频视图 视频片段 public static f
  • OpenCV 中 minEnclosureCircle 的意外结果

    我最近使用了 OpenCV 2 4 2 的函数 minEnendingCircle 因为我需要测量一团点的直径 一段时间后 我意识到结果不正确 因此我决定编写一个小例程来计算一组非常小的点的直径 我测试了该函数 1个单点 连续2 4分 仅由
  • 保留一个新对象而无需获取关联

    我在广告实体中有以下映射 class Ad Id Column name id unique true nullable false GeneratedValue strategy GenerationType SEQUENCE gener
  • 实现 ActiveRecord before_find

    我正在使用缓存在表中的关键字构建搜索 在表中查找用户输入的关键字之前 它会被标准化 例如 删除了一些标点符号 如 并对大小写进行了标准化 然后使用规范化的关键字来查找获取搜索结果 我目前正在使用 before filter 处理控制器中的标
  • 导入 React-Router-Dom 后 React App 变为空白

    导入前react router一切正常 现在它构建成功但显示空白页面 这是我的代码 App js import ReactDOM from react dom client import BrowserRouter Routes Route
  • 如何调查 imp.load_module 上的 python2 段错误

    我正在尝试安装和使用dolfin https aur archlinux org packages dolfin bzr 在 Arch Linux 上 使用 Python 2 7 3 找出导致分段的原因的最佳方法是什么 诸如此类的故障 py
  • 无法获取在Firebase存储中上传的图像的实际下载网址[重复]

    这个问题在这里已经有答案了 我正在尝试获取上传到 firebase 数据库的图像的下载网址 但任务Uri imageURL storageReference getDownloadUrl 没有给出存储在 firebase 存储中的图像的实际
  • 实体框架 4 Single() vs First() vs FirstOrDefault()

    我花了很长时间寻找查询单个项目的不同方法的比较 以及何时使用每种方法 有谁有一个比较所有这些的链接 或者一个关于为什么你会使用其中一个而不是另一个的快速解释 还有更多我不知道的运营商吗 谢谢 以下是不同方法的概述 Find 当您想通过主键获
  • 如何对 Flask 应用程序进行守护进程?

    我有一个使用 Flask 用 Python 编写的小应用程序 现在我正在 nohup 下运行它 但我想将它守护进程化 这样做的正确方法是什么 部署 Flask 项目有多种方式 http flask pocoo org docs deploy
  • 在 Mac OS X Lion 上设置环境变量

    当有人说 编辑你的 plist 文件 或 你的 profile 或 bash profile 等时 这让我很困惑 我不知道这些文件在哪里 如果必须这样做的话如何创建它们等等 也不知道为什么似乎有这么多不同的文件 为什么 它们做不同的事情吗
  • 实现 PushKit 并测试开发行为

    我想在我的应用程序 Voip 应用程序 中实现 PushKit 服务 但我有以下疑问 我看到我只能生成生产 voip 证书 如果我尝试在开发设备上测试 voip 推送通知服务 它可以工作吗 这是我的实施测试 通过这 3 行代码 我可以在 d