iOS Message Push: Overview, Configuration, Permissions, Local & Remote Notifications
This guide explains the complete iOS push notification workflow—from creating APNs certificates and enabling Xcode capabilities, to requesting user permission, implementing both local and remote notifications with the UserNotifications framework, debugging tools, and handling received messages across app states.
Message push is a crucial mechanism for iOS apps to deliver information to users, whether the app is in the foreground, background, or not running. This article walks through the complete workflow, from requesting push permissions to configuring Xcode, implementing local and remote notifications, debugging tools, and handling received push messages.
1. Overview
Push notifications can be sent locally (e.g., alarm apps) or remotely via Apple Push Notification service (APNs). Developers can add custom payload fields to direct users to specific pages or actions.
2. Xcode Configuration
Before using push features, a push certificate must be created in the Apple Developer Center (development or production). In Xcode, enable the Push Notifications capability under Signing & Capabilities , which adds the aps-environment entitlement.
3. Requesting Push Permission
From iOS 10 onward, the UserNotifications framework is used:
#import <UserNotifications/UserNotifications.h>
[[UNUserNotificationCenter currentNotificationCenter] requestAuthorizationWithOptions:UNAuthorizationOptionSound|UNAuthorizationOptionAlert|UNAuthorizationOptionBadge completionHandler:^(BOOL granted, NSError * _Nullable error) {
if (granted) {
// User allowed push notifications
} else {
// User denied push notifications
}
}];For iOS 9 the older API is used:
[[UIApplication sharedApplication] registerUserNotificationSettings:[UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeSound | UIUserNotificationTypeAlert | UIUserNotificationTypeBadge) categories:nil]];4. Local Push
Using the UserNotifications framework (iOS 10+):
UNMutableNotificationContent *content = [[UNMutableNotificationContent alloc] init];
content.title = @"Push Title";
content.body = @"Push Body";
content.sound = [UNNotificationSound defaultSound];
NSDateComponents *date = [[NSDateComponents alloc] init];
date.hour = 15; date.minute = 53;
UNCalendarNotificationTrigger *calendarTrigger = [UNCalendarNotificationTrigger triggerWithDateMatchingComponents:date repeats:NO];
UNNotificationRequest *request = [UNNotificationRequest requestWithIdentifier:@"testId" content:content trigger:calendarTrigger];
[[UNUserNotificationCenter currentNotificationCenter] addNotificationRequest:request withCompletionHandler:^(NSError * _Nullable error) {
if (error) { NSLog(@"%@", error.localizedDescription); }
}];For iOS 9 the legacy API:
UILocalNotification *notification = [[UILocalNotification alloc] init];
notification.fireDate = [NSDate dateWithTimeIntervalSinceNow:2];
notification.alertTitle = @"Push Title";
notification.alertBody = @"Push Body";
notification.soundName = @"mysound.wav"; // custom sound
[[UIApplication sharedApplication] scheduleLocalNotification:notification];5. Remote Push
APNs delivers remote notifications to devices identified by a deviceToken . The token is obtained as follows:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[[UIApplication sharedApplication] registerForRemoteNotifications];
return YES;
}
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
NSMutableString *hex = [NSMutableString new];
const unsigned char *bytes = (const unsigned char *)deviceToken.bytes;
for (NSInteger i = 0; i < deviceToken.length; i++) {
[hex appendFormat:@"%02x", bytes[i]];
}
NSLog(@"DeviceToken: %@", hex);
}
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
NSLog(@"Push registration error: %@", error);
}Server‑side, a typical PHP socket implementation for APNs looks like:
$deviceToken = '22124c450762170ca2ddb32a50381dd2c3026dbdb020f6dddcabefdca724fdd6';
$devUrl = 'ssl://gateway.sandbox.push.apple.com:2195';
$devCertificate = 'push_dev.pem';
$title = '标题';
$content = '消息内容';
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $devCertificate);
$fp = stream_socket_client($devUrl, $err, $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp) exit("Failed to connect: $err $errstr\n");
$body['aps'] = ['alert'=>['title'=>$title,'body'=>$content],'sound'=>'default'];
$body['userInfo'] = ['url'=>'https://www.qq.com'];
$payload = json_encode($body);
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
$result = fwrite($fp, $msg, strlen($msg));
if (!$result) echo 'Message not delivered\n'; else echo 'Message successfully delivered\n';
fclose($fp);Payloads are JSON objects containing the aps dictionary (alert, sound, badge) and optional custom fields. Keep the total size under 4 KB.
6. Debugging Tools
Two open‑source tools are mentioned for testing APNs payloads and certificates:
Knuff – https://github.com/KnuffApp/Knuff
SmartPush – https://github.com/shaojiankui/SmartPush
7. Handling Received Pushes in the App
Implement UNUserNotificationCenterDelegate to respond to notifications in different app states:
#import <UserNotifications/UserNotifications.h>
@interface AppDelegate () <UNUserNotificationCenterDelegate> @end
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[UNUserNotificationCenter currentNotificationCenter].delegate = self;
return YES;
}
// User taps a notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {
NSDictionary *userInfo = response.notification.request.content.userInfo;
NSDictionary *params = userInfo[@"userInfo"];
[PageSwitch handlePushSwitch:params];
completionHandler();
}
// App is in foreground and receives a notification
- (void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
completionHandler(UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge);
}For iOS 9 the older UIApplication callbacks are used:
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
NSLog(@"Foreground: %@", userInfo);
} else {
NSLog(@"From background: %@", userInfo);
NSDictionary *params = userInfo[@"userInfo"];
[PageSwitch handlePushSwitch:params];
}
}
- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification {
// Handle local notification
}8. Conclusion
The article summarizes the end‑to‑end process of iOS push notifications: configuring certificates, requesting user permission, implementing local and remote push, debugging, and handling received messages. Understanding these fundamentals helps developers use third‑party services (e.g., Tencent Cloud Push, Jiguang) more effectively.
Tencent Cloud Developer
Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.