You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Objective-C推送通知分步实现指南及问题求助

Hey there! Let's walk through everything you need to know about implementing push notifications in Objective-C, including where to put the permission request code and how to handle those tricky key operations—since I see you've already been working with OpenSSL commands, I'll tie those in too.

Objective-C推送通知完整实现指南(含权限请求与密钥处理)

一、分步实现推送通知流程

Let's break this down into actionable steps:

  • Step 1: 配置开发者账号与APNs证书
    First, head to the Apple Developer Portal: create an App ID with Push Notifications enabled, generate APNs certificates (separate for development and production environments), download them, double-click to add to your Keychain, then export the certificate and private key as .p12 files (you can export them separately or together, but your commands suggest separate exports).
  • Step 2: 项目配置
    In Xcode, open your project's Signing & Capabilities tab, add the Push Notifications capability. Make sure your Bundle ID matches the one in the Developer Portal. For iOS 10+, add the UserNotifications framework to your project.
  • Step 3: 请求通知权限
    We'll dive deeper into where to put this code in the next section.
  • Step 4: 注册APNs获取Device Token
    After getting permission, register with APNs to get a unique device token—this is what your backend will use to target the device for pushes.
  • Step 5: 处理通知接收
    Handle notifications differently based on iOS versions: use UNUserNotificationCenterDelegate for iOS 10+, and older AppDelegate methods for earlier versions. Cover foreground, background, and lock screen scenarios.
  • Step 6: 后端发送推送请求
    Use the generated .pem files to send HTTP/2 requests to Apple's APNs servers.

二、通知权限请求代码的编写位置

Most apps request push permission right when the app launches—this way users see the prompt early, and you can start registering for APNs as soon as possible. The best place for this is in AppDelegate.m's application:didFinishLaunchingWithOptions: method.

If your push notifications are tied to a specific feature (e.g., a messaging module), you can wait to request permission until the user interacts with that feature, but launch-time requests are standard.

Here's the code example:

#import <UserNotifications/UserNotifications.h>

@interface AppDelegate () <UNUserNotificationCenterDelegate>
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // iOS 10+ uses UNUserNotificationCenter
    if (@available(iOS 10.0, *)) {
        UNUserNotificationCenter *notificationCenter = [UNUserNotificationCenter currentNotificationCenter];
        notificationCenter.delegate = self;
        
        [notificationCenter requestAuthorizationWithOptions:(UNAuthorizationOptionAlert | UNAuthorizationOptionSound | UNAuthorizationOptionBadge)
                                      completionHandler:^(BOOL granted, NSError * _Nullable error) {
            if (granted) {
                NSLog(@"Push permissions granted!");
                // Register with APNs now that we have permission
                [[UIApplication sharedApplication] registerForRemoteNotifications];
            } else {
                NSLog(@"Push permissions denied. You might want to guide users to enable them in Settings later.");
            }
        }];
    } else {
        // For iOS 9 and below
        UIUserNotificationType allowedTypes = UIUserNotificationTypeAlert | UIUserNotificationTypeSound | UIUserNotificationTypeBadge;
        UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:allowedTypes categories:nil];
        [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
    return YES;
}

// Callback for iOS 9 and below permission status
- (void)application:(UIApplication *)application didRegisterUserNotificationSettings:(UIUserNotificationSettings *)notificationSettings {
    if (notificationSettings.types != UIUserNotificationTypeNone) {
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    }
}

// Get the device token after successful APNs registration
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    NSString *tokenString = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];
    tokenString = [tokenString stringByReplacingOccurrencesOfString:@" " withString:@""];
    NSLog(@"Device Token: %@", tokenString);
    // Send this token to your backend server
}

@end

三、密钥相关操作方法(结合你的OpenSSL命令)

You were on the right track with those OpenSSL commands—they convert .p12 files (which are Keychain-friendly) to .pem files that APNs servers can understand. Let's break down each command and fix a common pitfall:

  1. Extract the certificate to cert.pem

    openssl pkcs12 -clcerts -nokeys -out cert.pem -in cert.p12
    

    This pulls the public certificate from your cert.p12 file. You'll be prompted to enter the password you set when exporting the .p12—make sure it's correct!

  2. Extract the encrypted private key to key.pem

    openssl pkcs12 -nocerts -out key.pem -in key.p12
    

    This extracts your private key, but it's still encrypted. Using this directly will require entering the password every time you send a push, which is a hassle for backend systems.

  3. Generate an unencrypted private key

    openssl rsa -in key.pem -out key.unencrypted.pem
    

    This converts the encrypted key to an unencrypted version. Important: Store this file securely—never commit it to version control or share it publicly!

  4. Combine certificate and unencrypted key into ck.pem

    cat cert.pem key.unencrypted.pem > ck.pem
    

    Notice I used key.unencrypted.pem instead of key.pem here—this is likely where you hit a bottleneck earlier! If you use the encrypted key, your backend will keep asking for a password when sending pushes, which will break automation.

Key Tips for Success:

  • Double-check that your .p12 files match the environment (development vs production)—using a dev certificate for production pushes will fail.
  • Verify that the certificate and private key are paired: if they're from different Keychain entries, the combined ck.pem won't work.
  • For development, use Apple's sandbox APNs server (api.development.push.apple.com:443); for production, use api.push.apple.com:443.

Common Bottleneck Fixes

If you ran into issues before, here are a few things to check:

  • Permission prompt not showing: Make sure you're calling the permission request code in didFinishLaunchingWithOptions, and that you haven't denied permission already (check Settings > Your App > Notifications).
  • No device token: Verify the Push Notifications capability is enabled in Xcode, your Bundle ID matches the Developer Portal, and your APNs certificate is valid.
  • Push delivery failures: Ensure your ck.pem uses the unencrypted private key, and that your backend is targeting the correct APNs server for your environment.

内容的提问来源于stack exchange,提问作者sumi

火山引擎 最新活动