Skip to content

Commit 37d5fb2

Browse files
fix(app, expo): match scene-based AppDelegate for Expo SDK 58 config plugin
Expo SDK 58 starts React Native from the scene delegate, so the config plugin no longer finds self.moduleName or factory.startReactNative and skips FirebaseApp.configure().
1 parent 50a946a commit 37d5fb2

4 files changed

Lines changed: 75 additions & 2 deletions

File tree

‎packages/app/plugin/__tests__/__snapshots__/iosPlugin.test.ts.snap‎

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -530,3 +530,38 @@ FirebaseApp.configure()
530530
}
531531
}"
532532
`;
533+
534+
exports[`Config Plugin iOS Tests works with Swift AppDelegate (SDK 58+ scene-based) 1`] = `
535+
"internal import Expo
536+
import FirebaseCore
537+
import React
538+
import ReactAppDependencyProvider
539+
540+
@main
541+
class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider {
542+
var window: UIWindow?
543+
544+
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
545+
var reactNativeFactory: RCTReactNativeFactory?
546+
547+
public override func application(
548+
_ application: UIApplication,
549+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
550+
) -> Bool {
551+
let delegate = ReactNativeDelegate()
552+
let factory = ExpoReactNativeFactory(delegate: delegate)
553+
delegate.dependencyProvider = RCTAppDependencyProvider()
554+
555+
reactNativeDelegate = delegate
556+
reactNativeFactory = factory
557+
558+
// The window is created and React Native is started by \`SceneDelegate\` under the
559+
// scene-based life cycle (required by the iOS 27 SDK).
560+
// @generated begin @react-native-firebase/app-didFinishLaunchingWithOptions - expo prebuild (DO NOT MODIFY) sync-10e8520570672fd76b2403b7e1e27f5198a6349a
561+
FirebaseApp.configure()
562+
// @generated end @react-native-firebase/app-didFinishLaunchingWithOptions
563+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
564+
}
565+
}
566+
"
567+
`;
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
internal import Expo
2+
import React
3+
import ReactAppDependencyProvider
4+
5+
@main
6+
class AppDelegate: ExpoAppDelegate, ExpoReactNativeFactoryProvider {
7+
var window: UIWindow?
8+
9+
var reactNativeDelegate: ExpoReactNativeFactoryDelegate?
10+
var reactNativeFactory: RCTReactNativeFactory?
11+
12+
public override func application(
13+
_ application: UIApplication,
14+
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
15+
) -> Bool {
16+
let delegate = ReactNativeDelegate()
17+
let factory = ExpoReactNativeFactory(delegate: delegate)
18+
delegate.dependencyProvider = RCTAppDependencyProvider()
19+
20+
reactNativeDelegate = delegate
21+
reactNativeFactory = factory
22+
23+
// The window is created and React Native is started by `SceneDelegate` under the
24+
// scene-based life cycle (required by the iOS 27 SDK).
25+
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
26+
}
27+
}

‎packages/app/plugin/__tests__/iosPlugin.test.ts‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,17 @@ describe('Config Plugin iOS Tests', function () {
9393
expect(result).toMatchSnapshot();
9494
});
9595

96+
it('works with Swift AppDelegate (SDK 58+ scene-based)', async function () {
97+
const appDelegate = await fs.readFile(
98+
path.join(__dirname, './fixtures/AppDelegate_sdk58.swift'),
99+
{
100+
encoding: 'utf8',
101+
},
102+
);
103+
const result = modifySwiftAppDelegate(appDelegate);
104+
expect(result).toMatchSnapshot();
105+
});
106+
96107
it('does not add the firebase import multiple times', async function () {
97108
const singleImport = '#import "AppDelegate.h"\n#import <Firebase/Firebase.h>';
98109
const doubleImport = singleImport + '\n#import <Firebase/Firebase.h>';

‎packages/app/plugin/src/ios/appDelegate.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,14 +101,14 @@ export function modifyObjcAppDelegate(contents: string): string {
101101
export function modifySwiftAppDelegate(contents: string): string {
102102
const methodInvocationBlock = `FirebaseApp.configure()`;
103103
const methodInvocationLineMatcher =
104-
/(?:self\.moduleName\s*=\s*"([^"]*)")|(?:factory\.startReactNative\()/;
104+
/(?:self\.moduleName\s*=\s*"([^"]*)")|(?:factory\.startReactNative\()|(?:return\s+super\.application\(\s*application\s*,\s*didFinishLaunchingWithOptions:\s*launchOptions\s*\))/;
105105

106106
// Add import
107107
contents = addImport(
108108
contents,
109109
'import FirebaseCore',
110110
/^[ \t]*import\s+FirebaseCore[ \t]*$/m,
111-
/^[ \t]*import\s+Expo[ \t]*$/m,
111+
/^[ \t]*(?:internal\s+)?import\s+Expo[ \t]*$/m,
112112
/^[ \t]*import\b[^\r\n]*$/m,
113113
);
114114

0 commit comments

Comments
 (0)