ios 上的远程通知
remote notification on ios
我正在尝试从自己的 php 服务器向应用程序发送远程通知。
这是 AppDelefate.m 中的代码:
#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self registerForRemoteNotifications];
return YES;
}
- (void)registerForRemoteNotifications {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
completionHandler();
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"%@", userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"%@", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)applicationDidFinishLaunching:(UIApplication *)app {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
// Handle remote notification registration.
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSString *token = [[devToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"content---%@", token);
}
- (void)application:(UIApplication *)app
didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Remote notification support is unavailable due to error: %@", err);
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
@end
当我运行应用程序时,它在接受后要求通知权限。控制台打印以下标记:
content---13eeb8d33de4f0ba55f520469f9b0970e973faa6904a38428b2193b04ac3782b
所以我在我的 PHP 服务器中使用这个令牌进行测试:
<?php
// Put your device token here (without spaces):
$deviceToken = '13eeb8d33de4f0ba55f520469f9b0970e973faa6904a38428b2193b04ac3782b';
// Put your private key's passphrase here:
$passphrase = 'xoxoxo';
// Put your alert message here:
$message = 'Test push.';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'BDSPKCertificates.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
var_dump($ctx);
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // production
echo "<p>Open Connection</p>";
if(!$apns)
{
echo "<p>Failed to connect!<br />Error Number: " . $err . " <br />Code: " . $errstr . "</p>";
return;
}
else
{
echo "<p>Connected</p>";
// Create the payload body
$body = array();
$body['aps'] = array(
"title"=>"Test title",
'alert' => $message,
'sound' => 'default',
'badge' => 1
);
// Encode the payload as JSON
$payload = json_encode($body);
echo "<p>Message: ";
print_r($payload);
echo "</p>";
// Build the binary notification
$msg = chr(0) . pack("n",32) . pack('H*',str_replace(' ', '', $deviceToken)) . pack ("n", strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($apns, $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($apns);
}
?>
当我 运行 这个 PHP 代码时,它打印以下内容:
resource(2) of type (stream-context)
Open Connection
Connected
Message: {"aps":{"title":"Test title","alert":"Test push.","sound":"default","badge":1}}
Message successfully delivered
但是我的应用程序什么也没收到。请帮助我找出代码中缺少的内容。谢谢。
请确认,您已在服务器防火墙中打开 2195 端口。通过 2195 端口发送 Apple 推送通知。所以它应该打开。
我认为您使用的是 sandbox
环境,但在您的 PHP 脚本中,您的套接字客户端是生产环境,使用 sandbox
进行如下开发。
沙盒
ssl://gateway.sandbox.push.apple.com:2195'
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // sandbox
生产
ssl://gateway.push.apple.com:2195'
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // production
我正在尝试从自己的 php 服务器向应用程序发送远程通知。
这是 AppDelefate.m 中的代码:
#import "AppDelegate.h"
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate ()
@end
@implementation AppDelegate
#define SYSTEM_VERSION_GRATERTHAN_OR_EQUALTO(v) ([[[UIDevice currentDevice] systemVersion] compare:v options:NSNumericSearch] != NSOrderedAscending)
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{
[self registerForRemoteNotifications];
return YES;
}
- (void)registerForRemoteNotifications {
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error){
if(!error){
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
}];
}
//Called when a notification is delivered to a foreground app.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog(@"User Info : %@",notification.request.content.userInfo);
completionHandler(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge);
}
//Called to let your app know which action was selected by the user for a given notification.
-(void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void(^)())completionHandler{
NSLog(@"User Info : %@",response.notification.request.content.userInfo);
completionHandler();
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSLog(@"%@", userInfo);
}
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(@"%@", userInfo);
completionHandler(UIBackgroundFetchResultNewData);
}
- (void)applicationDidFinishLaunching:(UIApplication *)app {
[[UIApplication sharedApplication] registerForRemoteNotifications];
}
// Handle remote notification registration.
- (void)application:(UIApplication *)app
didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSString *token = [[devToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
NSLog(@"content---%@", token);
}
- (void)application:(UIApplication *)app
didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
NSLog(@"Remote notification support is unavailable due to error: %@", err);
}
- (void)applicationWillResignActive:(UIApplication *)application {
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
}
- (void)applicationWillEnterForeground:(UIApplication *)application {
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
}
- (void)applicationWillTerminate:(UIApplication *)application {
}
@end
当我运行应用程序时,它在接受后要求通知权限。控制台打印以下标记:
content---13eeb8d33de4f0ba55f520469f9b0970e973faa6904a38428b2193b04ac3782b
所以我在我的 PHP 服务器中使用这个令牌进行测试:
<?php
// Put your device token here (without spaces):
$deviceToken = '13eeb8d33de4f0ba55f520469f9b0970e973faa6904a38428b2193b04ac3782b';
// Put your private key's passphrase here:
$passphrase = 'xoxoxo';
// Put your alert message here:
$message = 'Test push.';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'BDSPKCertificates.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
var_dump($ctx);
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // production
echo "<p>Open Connection</p>";
if(!$apns)
{
echo "<p>Failed to connect!<br />Error Number: " . $err . " <br />Code: " . $errstr . "</p>";
return;
}
else
{
echo "<p>Connected</p>";
// Create the payload body
$body = array();
$body['aps'] = array(
"title"=>"Test title",
'alert' => $message,
'sound' => 'default',
'badge' => 1
);
// Encode the payload as JSON
$payload = json_encode($body);
echo "<p>Message: ";
print_r($payload);
echo "</p>";
// Build the binary notification
$msg = chr(0) . pack("n",32) . pack('H*',str_replace(' ', '', $deviceToken)) . pack ("n", strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($apns, $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($apns);
}
?>
当我 运行 这个 PHP 代码时,它打印以下内容:
resource(2) of type (stream-context)
Open Connection
Connected
Message: {"aps":{"title":"Test title","alert":"Test push.","sound":"default","badge":1}}
Message successfully delivered
但是我的应用程序什么也没收到。请帮助我找出代码中缺少的内容。谢谢。
请确认,您已在服务器防火墙中打开 2195 端口。通过 2195 端口发送 Apple 推送通知。所以它应该打开。
我认为您使用的是 sandbox
环境,但在您的 PHP 脚本中,您的套接字客户端是生产环境,使用 sandbox
进行如下开发。
沙盒
ssl://gateway.sandbox.push.apple.com:2195'
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.sandbox.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // sandbox
生产
ssl://gateway.push.apple.com:2195'
// Open a connection to the APNS server
$apns = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx); // production