Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit d2dde39

Browse files
author
Chris Yang
authored
[ios] fix asset url not found when loading app extension (#46073)
In 9446392, I refactored the assetsPath to use NSURL. It turns out that when the app bundle is not loaded (during launching app exgtension), the assetURL will return nil using the `URLForResource`, but the `pathForResource` successfully returns the raw path. This PR reverts back to the raw path solution. part of flutter/flutter#124287 [C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
1 parent 4f8a300 commit d2dde39

File tree

4 files changed

+25
-29
lines changed

4 files changed

+25
-29
lines changed

shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ NSString* FLTAssetPath(NSBundle* bundle);
4848
// If the key is not set, `flutter_assets` is used as the raw path value.
4949
//
5050
// If no valid asset is found under the raw path, returns nil.
51-
NSURL* FLTAssetsURLFromBundle(NSBundle* bundle);
51+
NSString* FLTAssetsPathFromBundle(NSBundle* bundle);
5252

5353
NS_ASSUME_NONNULL_END
5454

shell/platform/darwin/common/framework/Source/FlutterNSBundleUtils.mm

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,15 +54,17 @@
5454
}
5555

5656
NSString* FLTAssetPath(NSBundle* bundle) {
57-
return [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"] ?: kDefaultAssetPath;
57+
return [bundle objectForInfoDictionaryKey:@"FLTAssetsPath"] ?: @"flutter_assets";
5858
}
5959

60-
NSURL* FLTAssetsURLFromBundle(NSBundle* bundle) {
60+
NSString* FLTAssetsPathFromBundle(NSBundle* bundle) {
6161
NSString* flutterAssetsPath = FLTAssetPath(bundle);
62-
NSURL* assets = [bundle URLForResource:flutterAssetsPath withExtension:nil];
62+
// Use the raw path solution so that asset path can be returned from unloaded bundles.
63+
// See https://github.com/flutter/engine/pull/46073
64+
NSString* assetsPath = [bundle pathForResource:flutterAssetsPath ofType:@""];
6365

64-
if (!assets) {
65-
assets = [[NSBundle mainBundle] URLForResource:flutterAssetsPath withExtension:nil];
66+
if (assetsPath.length == 0) {
67+
assetsPath = [[NSBundle mainBundle] pathForResource:flutterAssetsPath ofType:@""];
6668
}
67-
return assets;
69+
return assetsPath;
6870
}

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

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -139,19 +139,20 @@ static BOOL DoesHardwareSupportWideGamut() {
139139

140140
// Checks to see if the flutter assets directory is already present.
141141
if (settings.assets_path.empty()) {
142-
NSURL* assetsURL = FLTAssetsURLFromBundle(bundle);
142+
NSString* assetsPath = FLTAssetsPathFromBundle(bundle);
143143

144-
if (!assetsURL) {
144+
if (assetsPath.length == 0) {
145145
NSLog(@"Failed to find assets path for \"%@\"", bundle);
146146
} else {
147-
settings.assets_path = assetsURL.path.UTF8String;
147+
settings.assets_path = assetsPath.UTF8String;
148148

149149
// Check if there is an application kernel snapshot in the assets directory we could
150150
// potentially use. Looking for the snapshot makes sense only if we have a VM that can use
151151
// it.
152152
if (!flutter::DartVM::IsRunningPrecompiledCode()) {
153153
NSURL* applicationKernelSnapshotURL =
154-
[assetsURL URLByAppendingPathComponent:@(kApplicationKernelSnapshotFileName)];
154+
[NSURL URLWithString:@(kApplicationKernelSnapshotFileName)
155+
relativeToURL:[NSURL fileURLWithPath:assetsPath]];
155156
NSError* error;
156157
if ([applicationKernelSnapshotURL checkResourceIsReachableAndReturnError:&error]) {
157158
settings.application_kernel_asset = applicationKernelSnapshotURL.path.UTF8String;

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

Lines changed: 11 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -89,31 +89,24 @@ - (void)testFLTGetApplicationBundleWhenCurrentTargetIsExtension {
8989

9090
- (void)testFLTAssetsURLFromBundle {
9191
{
92-
// Found asset path in info.plist (even not reachable)
92+
// Found asset path in info.plist
9393
id mockBundle = OCMClassMock([NSBundle class]);
9494
OCMStub([mockBundle objectForInfoDictionaryKey:@"FLTAssetsPath"]).andReturn(@"foo/assets");
95-
NSURL* mockAssetsURL = OCMClassMock([NSURL class]);
96-
OCMStub([mockBundle URLForResource:@"foo/assets" withExtension:nil]).andReturn(mockAssetsURL);
97-
OCMStub([mockAssetsURL checkResourceIsReachableAndReturnError:NULL]).andReturn(NO);
98-
OCMStub([mockAssetsURL path]).andReturn(@"foo/assets");
99-
NSURL* url = FLTAssetsURLFromBundle(mockBundle);
100-
XCTAssertEqualObjects(url.path, @"foo/assets");
95+
NSString* resultAssetsPath = @"path/to/foo/assets";
96+
OCMStub([mockBundle pathForResource:@"foo/assets" ofType:@""]).andReturn(resultAssetsPath);
97+
NSString* path = FLTAssetsPathFromBundle(mockBundle);
98+
XCTAssertEqualObjects(path, @"path/to/foo/assets");
10199
}
102100
{
103101
// No asset path in info.plist, defaults to main bundle
104102
id mockBundle = OCMClassMock([NSBundle class]);
105103
id mockMainBundle = OCMPartialMock([NSBundle mainBundle]);
106-
NSURL* mockAssetsURL = OCMClassMock([NSURL class]);
107-
OCMStub([mockBundle URLForResource:@"Frameworks/App.framework/flutter_assets"
108-
withExtension:nil])
109-
.andReturn(nil);
110-
OCMStub([mockAssetsURL checkResourceIsReachableAndReturnError:NULL]).andReturn(NO);
111-
OCMStub([mockAssetsURL path]).andReturn(@"path/to/foo/assets");
112-
OCMStub([mockMainBundle URLForResource:@"Frameworks/App.framework/flutter_assets"
113-
withExtension:nil])
114-
.andReturn(mockAssetsURL);
115-
NSURL* url = FLTAssetsURLFromBundle(mockBundle);
116-
XCTAssertEqualObjects(url.path, @"path/to/foo/assets");
104+
NSString* resultAssetsPath = @"path/to/foo/assets";
105+
OCMStub([mockBundle pathForResource:@"flutter_assets" ofType:@""]).andReturn(nil);
106+
OCMStub([mockMainBundle pathForResource:@"flutter_assets" ofType:@""])
107+
.andReturn(resultAssetsPath);
108+
NSString* path = FLTAssetsPathFromBundle(mockBundle);
109+
XCTAssertEqualObjects(path, @"path/to/foo/assets");
117110
}
118111
}
119112

0 commit comments

Comments
 (0)