From e32218f392c0b30ed60110b104d8496cb5747308 Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 19 Sep 2023 13:47:40 -0700 Subject: [PATCH 1/2] fix asset url not found --- .../framework/Source/FlutterNSBundleUtils.h | 2 +- .../framework/Source/FlutterNSBundleUtils.mm | 12 ++++---- .../framework/Source/FlutterDartProject.mm | 9 +++--- .../Source/FlutterDartProjectTest.mm | 29 +++++++------------ 4 files changed, 23 insertions(+), 29 deletions(-) diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h index e9c9f323ccb6a..9e0ea22e5fadc 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h @@ -48,7 +48,7 @@ NSString* FLTAssetPath(NSBundle* bundle); // If the key is not set, `flutter_assets` is used as the raw path value. // // If no valid asset is found under the raw path, returns nil. -NSURL* FLTAssetsURLFromBundle(NSBundle* bundle); +NSString* FLTAssetsPathFromBundle(NSBundle* bundle); NS_ASSUME_NONNULL_END diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm index bf0002d9ade34..8f46b37f32a86 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -54,15 +54,15 @@ } NSString* FLTAssetPath(NSBundle* bundle) { - return [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"] ?: kDefaultAssetPath; + return [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"] ?: @"flutter_assets"; } -NSURL* FLTAssetsURLFromBundle(NSBundle* bundle) { +NSString* FLTAssetsPathFromBundle(NSBundle* bundle) { NSString* flutterAssetsPath = FLTAssetPath(bundle); - NSURL* assets = [bundle URLForResource:flutterAssetsPath withExtension:nil]; + NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:@""]; - if (!assets) { - assets = [[NSBundle mainBundle] URLForResource:flutterAssetsPath withExtension:nil]; + if (assetsPath.length == 0) { + assetsPath = [[NSBundle mainBundle] pathForResource:flutterAssetsPath ofType:@""]; } - return assets; + return assetsPath; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm index 3d434eb2179f2..8a79af3a35742 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProject.mm @@ -119,19 +119,20 @@ // Checks to see if the flutter assets directory is already present. if (settings.assets_path.empty()) { - NSURL* assetsURL = FLTAssetsURLFromBundle(bundle); + NSString* assetsPath = FLTAssetsPathFromBundle(bundle); - if (!assetsURL) { + if (assetsPath.length == 0) { NSLog(@"Failed to find assets path for \"%@\"", bundle); } else { - settings.assets_path = assetsURL.path.UTF8String; + settings.assets_path = assetsPath.UTF8String; // Check if there is an application kernel snapshot in the assets directory we could // potentially use. Looking for the snapshot makes sense only if we have a VM that can use // it. if (!flutter::DartVM::IsRunningPrecompiledCode()) { NSURL* applicationKernelSnapshotURL = - [assetsURL URLByAppendingPathComponent:@(kApplicationKernelSnapshotFileName)]; + [NSURL URLWithString:@(kApplicationKernelSnapshotFileName) + relativeToURL:[NSURL fileURLWithPath:assetsPath]]; NSError* error; if ([applicationKernelSnapshotURL checkResourceIsReachableAndReturnError:&error]) { settings.application_kernel_asset = applicationKernelSnapshotURL.path.UTF8String; diff --git a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm index a28aaf8beeab9..19774d21bc52c 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterDartProjectTest.mm @@ -89,31 +89,24 @@ - (void)testFLTGetApplicationBundleWhenCurrentTargetIsExtension { - (void)testFLTAssetsURLFromBundle { { - // Found asset path in info.plist (even not reachable) + // Found asset path in info.plist id mockBundle = OCMClassMock([NSBundle class]); OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets"); - NSURL* mockAssetsURL = OCMClassMock([NSURL class]); - OCMStub([mockBundle URLForResource:@"foo/assets" withExtension:nil]).andReturn(mockAssetsURL); - OCMStub([mockAssetsURL checkResourceIsReachableAndReturnError:NULL]).andReturn(NO); - OCMStub([mockAssetsURL path]).andReturn(@"foo/assets"); - NSURL* url = FLTAssetsURLFromBundle(mockBundle); - XCTAssertEqualObjects(url.path, @"foo/assets"); + NSString* resultAssetsPath = @"path/to/foo/assets"; + OCMStub([mockBundle pathForResource:@"foo/assets" ofType:@""]).andReturn(resultAssetsPath); + NSString* path = FLTAssetsPathFromBundle(mockBundle); + XCTAssertEqualObjects(path, @"path/to/foo/assets"); } { // No asset path in info.plist, defaults to main bundle id mockBundle = OCMClassMock([NSBundle class]); id mockMainBundle = OCMPartialMock([NSBundle mainBundle]); - NSURL* mockAssetsURL = OCMClassMock([NSURL class]); - OCMStub([mockBundle URLForResource:@"Frameworks/App.framework/flutter_assets" - withExtension:nil]) - .andReturn(nil); - OCMStub([mockAssetsURL checkResourceIsReachableAndReturnError:NULL]).andReturn(NO); - OCMStub([mockAssetsURL path]).andReturn(@"path/to/foo/assets"); - OCMStub([mockMainBundle URLForResource:@"Frameworks/App.framework/flutter_assets" - withExtension:nil]) - .andReturn(mockAssetsURL); - NSURL* url = FLTAssetsURLFromBundle(mockBundle); - XCTAssertEqualObjects(url.path, @"path/to/foo/assets"); + NSString* resultAssetsPath = @"path/to/foo/assets"; + OCMStub([mockBundle pathForResource:@"flutter_assets" ofType:@""]).andReturn(nil); + OCMStub([mockMainBundle pathForResource:@"flutter_assets" ofType:@""]) + .andReturn(resultAssetsPath); + NSString* path = FLTAssetsPathFromBundle(mockBundle); + XCTAssertEqualObjects(path, @"path/to/foo/assets"); } } From 50b1ab1893d3dfdbb08aa92a48cb761c71a3b49c Mon Sep 17 00:00:00 2001 From: Chris Yang Date: Tue, 19 Sep 2023 13:57:28 -0700 Subject: [PATCH 2/2] add comments --- .../darwin/common/framework/Source/FlutterNSBundleUtils.mm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm index 8f46b37f32a86..4198fd33e0209 100644 --- a/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm +++ b/shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm @@ -59,6 +59,8 @@ NSString* FLTAssetsPathFromBundle(NSBundle* bundle) { NSString* flutterAssetsPath = FLTAssetPath(bundle); + // Use the raw path solution so that asset path can be returned from unloaded bundles. + // See https://github.com/flutter/engine/pull/46073 NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:@""]; if (assetsPath.length == 0) {