安装推送通知后React Native iOS构建失败,是否操作有误?
Hey there, let's break down your situation first: this is not normal—the build failure after modifying your AppDelegate files is a sign of a syntax error in your code, not expected behavior. Let's fix this step by step.
What Went Wrong
When you removed the AppDelegate changes, the build succeeded and you saw the push permission prompt because your Xcode project's basic push notification entitlement was set up correctly. But the modified AppDelegate code had a critical Objective-C syntax issue that caused the build to fail:
Your four push notification-related methods (like didRegisterForRemoteNotificationsWithDeviceToken) were defined outside the @implementation AppDelegate block. In Objective-C, all instance methods of a class must be declared inside the class's implementation block—otherwise, the compiler doesn't recognize them as part of the AppDelegate class, leading to build errors.
Additionally, your AppDelegate.h was missing the UNUserNotificationCenterDelegate protocol declaration, which is required since you set center.delegate = self; in the .m file.
Corrected Code Examples
1. Updated AppDelegate.h
Add the UNUserNotificationCenterDelegate protocol and import the UserNotifications header:
#import <React/RCTBridgeDelegate.h> #import <UIKit/UIKit.h> #import <UserNotifications/UserNotifications.h> @interface AppDelegate : UIResponder <UIApplicationDelegate, RCTBridgeDelegate, UNUserNotificationCenterDelegate> @property (nonatomic, strong) UIWindow *window; @end
2. Updated AppDelegate.m
Move all push-related methods inside the @implementation AppDelegate block, and ensure you call the completion handler in didReceiveNotificationResponse:
#import "AppDelegate.h" #import <React/RCTBridge.h> #import <React/RCTBundleURLProvider.h> #import <React/RCTRootView.h> #ifdef FB_SONARKIT_ENABLED #import <FlipperKit/FlipperClient.h> #import <FlipperKitLayoutPlugin/FlipperKitLayoutPlugin.h> #import <FlipperKitUserDefaultsPlugin/FKUserDefaultsPlugin.h> #import <FlipperKitNetworkPlugin/FlipperKitNetworkPlugin.h> #import <SKIOSNetworkPlugin/SKIOSNetworkAdapter.h> #import <FlipperKitReactPlugin/FlipperKitReactPlugin.h> #endif #import <UserNotifications/UserNotifications.h> #import <RNCPushNotificationIOS.h> static void InitializeFlipper(UIApplication *application) { FlipperClient *client = [FlipperClient sharedClient]; SKDescriptorMapper *layoutDescriptorMapper = [[SKDescriptorMapper alloc] initWithDefaults]; [client addPlugin:[[FlipperKitLayoutPlugin alloc] initWithRootNode:application withDescriptorMapper:layoutDescriptorMapper]]; [client addPlugin:[[FKUserDefaultsPlugin alloc] initWithSuiteName:nil]]; [client addPlugin:[FlipperKitReactPlugin new]]; [client addPlugin:[[FlipperKitNetworkPlugin alloc] initWithNetworkAdapter:[SKIOSNetworkAdapter new]]]; [client start]; } @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { #ifdef FB_SONARKIT_ENABLED InitializeFlipper(application); #endif RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"yuna" initialProperties:nil]; rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; // Define UNUserNotificationCenter UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter]; center.delegate = self; return YES; } // Required for the register event. - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { [RNCPushNotificationIOS didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; } // Required for the notification event. You must call the completion handler after handling the remote notification. - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { [RNCPushNotificationIOS didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; } // Required for the registrationError event. - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error { [RNCPushNotificationIOS didFailToRegisterForRemoteNotificationsWithError:error]; } // Required for localNotification event - (void)userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler { [RNCPushNotificationIOS didReceiveNotificationResponse:response]; completionHandler(); // Don't forget to call this to finish handling the notification } // Called when a notification is delivered to a foreground app. -(void)userNotificationCenter:(UNUserNotificationCenter *)center willPresentNotification:(UNNotification *)notification withCompletionHandler:(void (^)(UNNotificationPresentationOptions options))completionHandler { completionHandler(UNNotificationPresentationOptionSound | UNNotificationPresentationOptionAlert | UNNotificationPresentationOptionBadge); } - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge { #if DEBUG return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index" fallbackResource:nil]; #else return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; #endif } @end
Next Steps
- Replace your existing AppDelegate.h and .m files with the corrected versions above.
- Clean your Xcode build folder (
Cmd + Shift + K) and runnpx react-native run-iosagain. - You should now have a successful build, and your app will properly handle push notification registration, device token retrieval, and notification events.
内容的提问来源于stack exchange,提问作者Juan Pablo

