如何向特定用户发送 Apple 推送通知
How to send Apple push notification to specific users
我已经设法让推送通知正常工作,但我在如何向特定用户发送通知方面遇到了问题。也许使用客户编号或姓名等。
我什至不知道从哪里开始。
我花了数周时间阅读了数百个网站,但我似乎无法理解。
这些只是我浏览过的部分页面:
- Apple Push Notifications to specific Users
- How to send push notification to specific device
- Send push notification to specific user?
- https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server?language=objc
- https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns?language=objc
这是我在 Appdelegate 中的 objective-c 代码 - 如果不是很好,我很抱歉,我从几篇文章中拼凑而成。
@implementation AppDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog( @"for handling push in foreground" );
// Your code
NSLog(@"%@", notification.request.content.userInfo); //for getting response payload data
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionBanner);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UNUserNotificationCenter.currentNotificationCenter.delegate= self;
[self requestPushNotificationPermissions];
NSLog(@"need this:01 @");
return YES;
}
- (void)application:(UIApplication*)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken
{
NSLog(@"need this Token:02 @");
// parse token bytes to string
const char *data = [devToken bytes];
NSMutableString *token = [NSMutableString string];
for (NSUInteger i = 0; i < [devToken length]; i++)
{
[token appendFormat:@"%02.2hhX", data[i]];
}
// print the token in the console.
NSLog(@"Push Notification Token: %@", [token copy]);
}
- (void)requestPushNotificationPermissions
{
// iOS 10+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus)
{
// User hasn't accepted or rejected permissions yet. This block shows the allow/deny dialog
case UNAuthorizationStatusNotDetermined:
{
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
}];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if(granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
// [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
// notify user to enable push notification permission in settings
}
}];
break;
}
// the user has denied the permission
case UNAuthorizationStatusDenied:
{
// notify user to enable push notification permission in settings
break;
}
// the user has accepted; Register a PN token
case UNAuthorizationStatusAuthorized:
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
// [[UIApplication sharedApplication] registerForRemoteNotifications];
break;
}
default:
break;
}
}];
}
这是服务器端PHP代码
<?php
$device_token =
"AB028BLAH8A2BLAHE0485BLAHEABLAHEDFAKED3EBLAHFF0AFDBBBLAHBLAHBLAH";
//echo $key;
$kid = "6FAKEJFAKE";
$teamId = "FAKEZ2FAKE";
$app_bundle_id = "com.name.appname";
$base_url = "https://api.development.push.apple.com";
$header = ["alg" => "ES256", "kid" => $kid];
$header = base64_encode(json_encode($header));
$claim = ["iss" => $teamId, "iat" => time()];
$claim = base64_encode(json_encode($claim));
$token = $header.".".$claim;
// key in same folder as the script
$filename = "AuthKey_6FAKEJFAKE.p8";
$pkey = openssl_pkey_get_private("file://{$filename}");
$signature;
openssl_sign($token, $signature, $pkey, 'sha256');
$sign = base64_encode($signature);
$jws = $token.".".$sign;
$message = '{"aps":{"alert":"Push Test Message.","sound":"default"}}';
function sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws) {
$url = "{$base_url}/3/device/{$device_token}";
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
'Authorization: bearer ' . $jws
);
// other curl options
curl_setopt_array($curl, array(
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_HEADER => 1
));
// go...
$result = curl_exec($curl);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($curl));
}
print_r($result."\n");
// get response
$status = curl_getinfo($curl);
return $status;
}
// open connection
$curl = curl_init();
sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws);
?>
一切正常,但如何将其发送给特定用户?
您可以向选定的设备令牌发送推送通知。
发送前请执行以下步骤:
iOS应用端
- 在应用程序启动时,在 didRegisterForRemoteNotificationsWithDeviceToken 委托中获取设备令牌
- 当用户登录应用程序时,使用 API 将此令牌发送到服务器
服务器端
- 将这个token存储在对应用户id
的dbtable中
- 从与您要向其发送通知的用户相对应的数据库中获取设备令牌
- 在该令牌上发送通知
- 将在设备上收到通知
我已经设法让推送通知正常工作,但我在如何向特定用户发送通知方面遇到了问题。也许使用客户编号或姓名等。 我什至不知道从哪里开始。 我花了数周时间阅读了数百个网站,但我似乎无法理解。
这些只是我浏览过的部分页面:
- Apple Push Notifications to specific Users
- How to send push notification to specific device
- Send push notification to specific user?
- https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server?language=objc
- https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns?language=objc
这是我在 Appdelegate 中的 objective-c 代码 - 如果不是很好,我很抱歉,我从几篇文章中拼凑而成。
@implementation AppDelegate
- (void)userNotificationCenter:(UNUserNotificationCenter *)center
willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler{
NSLog( @"for handling push in foreground" );
// Your code
NSLog(@"%@", notification.request.content.userInfo); //for getting response payload data
completionHandler(UNNotificationPresentationOptionBadge | UNNotificationPresentationOptionBanner);
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
UNUserNotificationCenter.currentNotificationCenter.delegate= self;
[self requestPushNotificationPermissions];
NSLog(@"need this:01 @");
return YES;
}
- (void)application:(UIApplication*)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)devToken
{
NSLog(@"need this Token:02 @");
// parse token bytes to string
const char *data = [devToken bytes];
NSMutableString *token = [NSMutableString string];
for (NSUInteger i = 0; i < [devToken length]; i++)
{
[token appendFormat:@"%02.2hhX", data[i]];
}
// print the token in the console.
NSLog(@"Push Notification Token: %@", [token copy]);
}
- (void)requestPushNotificationPermissions
{
// iOS 10+
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
[center getNotificationSettingsWithCompletionHandler:^(UNNotificationSettings * _Nonnull settings) {
switch (settings.authorizationStatus)
{
// User hasn't accepted or rejected permissions yet. This block shows the allow/deny dialog
case UNAuthorizationStatusNotDetermined:
{
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:(UNAuthorizationOptionBadge | UNAuthorizationOptionSound | UNAuthorizationOptionAlert) completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
}
}];
center.delegate = self;
[center requestAuthorizationWithOptions:(UNAuthorizationOptionSound | UNAuthorizationOptionAlert | UNAuthorizationOptionBadge) completionHandler:^(BOOL granted, NSError * _Nullable error)
{
if(granted)
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
// [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else
{
// notify user to enable push notification permission in settings
}
}];
break;
}
// the user has denied the permission
case UNAuthorizationStatusDenied:
{
// notify user to enable push notification permission in settings
break;
}
// the user has accepted; Register a PN token
case UNAuthorizationStatusAuthorized:
{
dispatch_async(dispatch_get_main_queue(), ^{
[[UIApplication sharedApplication] registerForRemoteNotifications];
});
// [[UIApplication sharedApplication] registerForRemoteNotifications];
break;
}
default:
break;
}
}];
}
这是服务器端PHP代码
<?php
$device_token =
"AB028BLAH8A2BLAHE0485BLAHEABLAHEDFAKED3EBLAHFF0AFDBBBLAHBLAHBLAH";
//echo $key;
$kid = "6FAKEJFAKE";
$teamId = "FAKEZ2FAKE";
$app_bundle_id = "com.name.appname";
$base_url = "https://api.development.push.apple.com";
$header = ["alg" => "ES256", "kid" => $kid];
$header = base64_encode(json_encode($header));
$claim = ["iss" => $teamId, "iat" => time()];
$claim = base64_encode(json_encode($claim));
$token = $header.".".$claim;
// key in same folder as the script
$filename = "AuthKey_6FAKEJFAKE.p8";
$pkey = openssl_pkey_get_private("file://{$filename}");
$signature;
openssl_sign($token, $signature, $pkey, 'sha256');
$sign = base64_encode($signature);
$jws = $token.".".$sign;
$message = '{"aps":{"alert":"Push Test Message.","sound":"default"}}';
function sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws) {
$url = "{$base_url}/3/device/{$device_token}";
// headers
$headers = array(
"apns-topic: {$app_bundle_id}",
'Authorization: bearer ' . $jws
);
// other curl options
curl_setopt_array($curl, array(
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
CURLOPT_URL => $url,
CURLOPT_PORT => 443,
CURLOPT_HTTPHEADER => $headers,
CURLOPT_POST => TRUE,
CURLOPT_POSTFIELDS => $message,
CURLOPT_RETURNTRANSFER => TRUE,
CURLOPT_TIMEOUT => 30,
CURLOPT_SSL_VERIFYPEER => FALSE,
CURLOPT_HEADER => 1
));
// go...
$result = curl_exec($curl);
if ($result === FALSE) {
throw new Exception("Curl failed: " . curl_error($curl));
}
print_r($result."\n");
// get response
$status = curl_getinfo($curl);
return $status;
}
// open connection
$curl = curl_init();
sendHTTP2Push($curl, $base_url, $app_bundle_id, $message, $device_token, $jws);
?>
一切正常,但如何将其发送给特定用户?
您可以向选定的设备令牌发送推送通知。
发送前请执行以下步骤:
iOS应用端
- 在应用程序启动时,在 didRegisterForRemoteNotificationsWithDeviceToken 委托中获取设备令牌
- 当用户登录应用程序时,使用 API 将此令牌发送到服务器
服务器端
- 将这个token存储在对应用户id 的dbtable中
- 从与您要向其发送通知的用户相对应的数据库中获取设备令牌
- 在该令牌上发送通知
- 将在设备上收到通知