Mobile Development 21 min read

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.

Tencent Cloud Developer
Tencent Cloud Developer
Tencent Cloud Developer
iOS Message Push: Overview, Configuration, Permissions, Local & Remote Notifications

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.

iOSpush notificationsXcodeAPNSLocal NotificationRemote NotificationUserNotifications
Tencent Cloud Developer
Written by

Tencent Cloud Developer

Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.