Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ios] fix asset url not found when loading app extension #46073

Merged
merged 2 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,15 +54,17 @@
}

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];
// 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:@""];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional nit: Is there a reason you're not using nil instead of @"" here and below, given that they do the same thing (according to the docs)? nil is more common as "no value" than an empty string.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just reverted back to the original implementation, unsure why it was @"" instead of nil. I will change it to nil


if (!assets) {
assets = [[NSBundle mainBundle] URLForResource:flutterAssetsPath withExtension:nil];
if (assetsPath.length == 0) {
assetsPath = [[NSBundle mainBundle] pathForResource:flutterAssetsPath ofType:@""];
}
return assets;
return assetsPath;
}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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");
}
}

Expand Down