Удаленное уведомление на 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

Однако мое приложение ничего не получает. Пожалуйста, помогите мне найти то, что отсутствует в моих кодах. Благодарю.

2 ответа

Решение

Пожалуйста, подтвердите, у вас есть открытый порт 2195 в брандмауэре сервера. Push-уведомление от Apple отправлено через порт 2195. Так и должно открыться.

Я думаю, что вы используете 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
Другие вопросы по тегам