Skip to content

Commit 7ec5f8a

Browse files
authored
Don't require FLTLibraryPath and FLTAssetsPath from the main NSBundle (flutter#5986)
We'd like the ability to add Flutter to existing iOS applications without requiring that they set `FLTLibraryPath` and `FLTAssetsPath` in the main bundle's `Info.plist`. 1. Modify `-[FlutterDartProject initWithPrecompiledDartBundle:]` to support setting the library and assets path from the specified `NSBundle` instead. 2. If no `NSBundle` is explicitly specified, look for one with a default bundle identifier ("io.flutter.flutter.app") before falling back to the main NSBundle. Also remove `+[FlutterDartProject pathForFlutterAssetsFromBundle:]` because we don't use it internally, and it isn't exposed in the header file.
1 parent 73e52ba commit 7ec5f8a

File tree

2 files changed

+43
-27
lines changed

2 files changed

+43
-27
lines changed

shell/platform/darwin/ios/framework/Headers/FlutterDartProject.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,12 @@ FLUTTER_EXPORT
4343
*/
4444
+ (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package;
4545

46+
/**
47+
Returns the default identifier for the bundle where we expect to find the Flutter Dart
48+
application.
49+
*/
50+
+ (NSString*)defaultBundleIdentifier;
51+
4652
@end
4753

4854
#endif // FLUTTER_FLUTTERDARTPROJECT_H_

shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,26 @@
1919
static const char* kVMKernelSnapshotFileName = "platform.dill";
2020
static const char* kApplicationKernelSnapshotFileName = "kernel_blob.bin";
2121

22-
static blink::Settings DefaultSettingsForProcess() {
22+
static blink::Settings DefaultSettingsForProcess(NSBundle* bundle = nil) {
2323
auto command_line = shell::CommandLineFromNSProcessInfo();
2424

25-
// Settings passed in explicitly via command line arguments take priority.
25+
// Precedence:
26+
// 1. Settings from the specified NSBundle.
27+
// 2. Settings passed explicitly via command-line arguments.
28+
// 3. Settings from the NSBundle with the default bundle ID.
29+
// 4. Settings from the main NSBundle and default values.
30+
31+
NSBundle* mainBundle = [NSBundle mainBundle];
32+
NSBundle* engineBundle = [NSBundle bundleForClass:[FlutterViewController class]];
33+
34+
bool hasExplicitBundle = bundle != nil;
35+
if (bundle == nil) {
36+
bundle = [NSBundle bundleWithIdentifier:[FlutterDartProject defaultBundleIdentifier]];
37+
}
38+
if (bundle == nil) {
39+
bundle = mainBundle;
40+
}
41+
2642
auto settings = shell::SettingsFromCommandLine(command_line);
2743

2844
settings.task_observer_add = [](intptr_t key, fml::closure callback) {
@@ -38,18 +54,24 @@
3854

3955
// Flutter ships the ICU data file in the the bundle of the engine. Look for it there.
4056
if (settings.icu_data_path.size() == 0) {
41-
NSBundle* bundle = [NSBundle bundleForClass:[FlutterViewController class]];
42-
NSString* icuDataPath = [bundle pathForResource:@"icudtl" ofType:@"dat"];
57+
NSString* icuDataPath = [engineBundle pathForResource:@"icudtl" ofType:@"dat"];
4358
if (icuDataPath.length > 0) {
4459
settings.icu_data_path = icuDataPath.UTF8String;
4560
}
4661
}
4762

4863
if (blink::DartVM::IsRunningPrecompiledCode()) {
49-
// The application bundle could be specified in the Info.plist.
64+
if (hasExplicitBundle) {
65+
NSString* executablePath = bundle.executablePath;
66+
if ([[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
67+
settings.application_library_path = executablePath.UTF8String;
68+
}
69+
}
70+
71+
// No application bundle specified. Try a known location from the main bundle's Info.plist.
5072
if (settings.application_library_path.size() == 0) {
51-
NSString* libraryName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"FLTLibraryPath"];
52-
NSString* libraryPath = [[NSBundle mainBundle] pathForResource:libraryName ofType:nil];
73+
NSString* libraryName = [mainBundle objectForInfoDictionaryKey:@"FLTLibraryPath"];
74+
NSString* libraryPath = [mainBundle pathForResource:libraryName ofType:@""];
5375
if (libraryPath.length > 0) {
5476
settings.application_library_path =
5577
[NSBundle bundleWithPath:libraryPath].executablePath.UTF8String;
@@ -60,7 +82,7 @@
6082
// Frameworks directory.
6183
if (settings.application_library_path.size() == 0) {
6284
NSString* applicationFrameworkPath =
63-
[[NSBundle mainBundle] pathForResource:@"Frameworks/App.framework" ofType:@""];
85+
[mainBundle pathForResource:@"Frameworks/App.framework" ofType:@""];
6486
if (applicationFrameworkPath.length > 0) {
6587
settings.application_library_path =
6688
[NSBundle bundleWithPath:applicationFrameworkPath].executablePath.UTF8String;
@@ -70,11 +92,8 @@
7092

7193
// Checks to see if the flutter assets directory is already present.
7294
if (settings.assets_path.size() == 0) {
73-
// The kernel assets will not be present in the Flutter frameworks bundle since it is not user
74-
// editable. Instead, look inside the main bundle.
75-
NSBundle* bundle = [NSBundle mainBundle];
76-
NSString* assets_directory_name = [FlutterDartProject flutterAssetsName:bundle];
77-
NSString* assetsPath = [bundle pathForResource:assets_directory_name ofType:@""];
95+
NSString* assetsName = [FlutterDartProject flutterAssetsName:bundle];
96+
NSString* assetsPath = [mainBundle pathForResource:assetsName ofType:@""];
7897

7998
if (assetsPath.length > 0) {
8099
settings.assets_path = assetsPath.UTF8String;
@@ -136,15 +155,7 @@ - (instancetype)initWithPrecompiledDartBundle:(NSBundle*)bundle {
136155

137156
if (self) {
138157
_precompiledDartBundle.reset([bundle retain]);
139-
140-
_settings = DefaultSettingsForProcess();
141-
142-
if (bundle != nil) {
143-
NSString* executablePath = _precompiledDartBundle.get().executablePath;
144-
if ([[NSFileManager defaultManager] fileExistsAtPath:executablePath]) {
145-
_settings.application_library_path = executablePath.UTF8String;
146-
}
147-
}
158+
_settings = DefaultSettingsForProcess(bundle);
148159
}
149160

150161
return self;
@@ -218,11 +229,6 @@ + (NSString*)flutterAssetsName:(NSBundle*)bundle {
218229
return flutterAssetsName;
219230
}
220231

221-
+ (NSString*)pathForFlutterAssetsFromBundle:(NSBundle*)bundle {
222-
NSString* flutterAssetsName = [FlutterDartProject flutterAssetsName:bundle];
223-
return [bundle pathForResource:flutterAssetsName ofType:nil];
224-
}
225-
226232
+ (NSString*)lookupKeyForAsset:(NSString*)asset {
227233
NSString* flutterAssetsName = [FlutterDartProject flutterAssetsName:[NSBundle mainBundle]];
228234
return [NSString stringWithFormat:@"%@/%@", flutterAssetsName, asset];
@@ -232,4 +238,8 @@ + (NSString*)lookupKeyForAsset:(NSString*)asset fromPackage:(NSString*)package {
232238
return [self lookupKeyForAsset:[NSString stringWithFormat:@"packages/%@/%@", package, asset]];
233239
}
234240

241+
+ (NSString*)defaultBundleIdentifier {
242+
return @"io.flutter.flutter.app";
243+
}
244+
235245
@end

0 commit comments

Comments
 (0)