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