You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native 0.66.4升级至0.69.6:保留AppDelegate.swift逻辑方案

React Native 0.66.4 升级到0.69.6:保留Swift版AppDelegate逻辑的方案

核心结论

完全不需要把Swift代码硬整合到AppDelegate.mm里,最优方案是让Swift版AppDelegate继续承载业务逻辑,通过Objective-C桥接,用.mm文件作为RN要求的入口层转发调用,既满足RN 0.69+对.mm文件的要求,又能100%复用原有Swift代码。

具体实现步骤

  1. 保留原有Swift代码:不要修改你的AppDelegate.swift,所有业务逻辑(比如推送配置、RN初始化、第三方SDK集成等)继续留在这个文件里。
  2. 确保桥接配置正常:如果项目之前没有桥接文件,需要在Xcode的Build Settings里设置Objective-C Bridging Header,指向你的桥接文件(比如YourProject-Bridging-Header.h);如果已经有,确认它能正常导入Swift需要的Objective-C依赖。
  3. 创建AppDelegate.mm作为入口:这个文件只做转发,把UIApplication的生命周期事件传递给Swift版的AppDelegate实例。

示例代码

原有AppDelegate.swift(保留逻辑)

import UIKit
import React

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    var bridge: RCTBridge?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // 原有RN初始化逻辑
        let jsCodeLocation: URL
        #if DEBUG
        jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
        #else
        jsCodeLocation = Bundle.main.url(forResource: "main", withExtension: "jsbundle")!
        #endif

        bridge = RCTBridge(delegate: self, launchOptions: launchOptions)
        let rootView = RCTRootView(bridge: bridge!, moduleName: "YourAppName", initialProperties: nil)
        
        window = UIWindow(frame: UIScreen.main.bounds)
        let rootViewController = UIViewController()
        rootViewController.view = rootView
        window?.rootViewController = rootViewController
        window?.makeKeyAndVisible()
        
        // 原有其他逻辑:比如推送注册、第三方SDK初始化等
        registerPushNotifications()
        
        return true
    }

    // 其他生命周期方法,比如推送回调、RN模块注册等
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        // 原有处理逻辑
    }
}

extension AppDelegate: RCTBridgeDelegate {
    func sourceURL(for bridge: RCTBridge!) -> URL! {
        #if DEBUG
        return RCTBundleURLProvider.sharedSettings().jsBundleURL(forBundleRoot: "index")
        #else
        return Bundle.main.url(forResource: "main", withExtension: "jsbundle")
        #endif
    }
}

private extension AppDelegate {
    func registerPushNotifications() {
        // 原有推送注册逻辑
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .badge, .sound]) { granted, error in
            if granted {
                DispatchQueue.main.async {
                    UIApplication.shared.registerForRemoteNotifications()
                }
            }
        }
    }
}

新创建的AppDelegate.mm(仅做转发)

#import <UIKit/UIKit.h>
// 导入Swift自动生成的头文件,注意替换成你的项目名称
#import "YourProjectName-Swift.h"

@interface AppDelegate () <UIApplicationDelegate>
@property (nonatomic, strong) AppDelegate *swiftDelegate;
@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.swiftDelegate = [[AppDelegate alloc] init];
    return [self.swiftDelegate application:application didFinishLaunchingWithOptions:launchOptions];
}

// 转发所有需要的生命周期方法到SwiftDelegate
- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [self.swiftDelegate application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    [self.swiftDelegate application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler];
}

// 其他需要的生命周期方法,比如applicationWillResignActive、applicationDidBecomeActive等,按需添加
- (void)applicationWillResignActive:(UIApplication *)application {
    [self.swiftDelegate applicationWillResignActive:application];
}

@end

注意事项

  • 替换示例中的YourProjectName为你的实际项目名称,Swift自动生成的头文件格式是项目名-Swift.h
  • 如果Swift版AppDelegate里有自定义方法,需要在Swift代码前加上@objc修饰,才能在.mm文件中调用
  • 确保Xcode的Build Settings里,Objective-C Generated Interface Header Name设置正确(默认就是项目名-Swift.h)

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.16 13:01:09