-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
Use asset catalog for ios images #30129
base: main
Are you sure you want to change the base?
Conversation
Base commit: 950ea91 |
Base commit: c27e9e6 |
a39cb37
to
072c071
Compare
@janicduplessis I haven't dived deep into assets stuff on the CLI side and here, but maybe you have a better overview on this. Now that assets logic is scoped under |
@thymikee This already uses the shared code in the assets package and updates it (just rename a method since it is now used on iOS too). |
@sota000 Any interest on landing this? I've been using this in my fork for a long time and is stable. |
It would be great to have a status on this one, there's an outstanding PR in the CLI too. |
One think I'd guess would be fixing the conflicts, but yeah also would be great to get some internal 👍/👎 if it's even worth |
@janicduplessis can we rebase + fix the conflicts here? |
050a242
to
f527b5e
Compare
Ok I rebased this and tested again in RN tester. I added instructions on how to do so in the Test Plan. It does require the CLI patched with react-native-community/cli#1290 to work. I think the main part that is tricky with this is if the app template is not properly updated or for some reason an older version of the cli is used it will break. For the old cli version case it is actually not that bad since the build will error because of invalid parameter --asset-catalog-dest. If the template project is not properly configured then assets won't show in release mode only. I think it is still fine to move forward, but might want to make sure to document the change to make sure templates are updated properly. The main 2 things that need updating is to create the RNAssets.xcassets catalog and to reorder build scripts so that JS bundle is built before Copy Bundle Resources. For new projects and automated updates that should be fine, but might not be obvious for someone updating manually. |
/rebase |
f527b5e
to
58b1917
Compare
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Weird, this PR makes the template tests fail... Basically, the CLI is not able to create a RN app... Is it expected because it requires react-native-community/cli#1290 ? |
Oh I see the problem, the template yarn install fails because of error Couldn't find any versions for "@react-native/assets" that matches "1.1.0". Not sure what would be best to handle updating the @react-native/assets package. It is basically just renaming a function since we use it on iOS too now. |
We might also have build issue later for ios release build since it does require the cli patch |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a packages/react-native-codegen/react-native-codegen-0.0.5.tgz
that needs to go 👍
packages/assets/package.json
Outdated
@@ -1,6 +1,6 @@ | |||
{ | |||
"name": "@react-native/assets", | |||
"version": "1.0.0", | |||
"version": "1.1.0", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This would require a npm publish
of this package OR the use of Verdaccio (which we already have for template tests).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might also conflict with #34572. Maybe not all template tests use verdaccio currently? Do I need to make some changes for it to pickup the assets package?
Maybe the simplest way would be to just revert the change to the assets package and can land it later as it is not really needed as all it does is rename a function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe the simplest way would be to just revert the change to the assets package and can land it later as it is not really needed as all it does is rename a function.
If possible, let's revert it. We're in the process of migrating our repo to be a proper monorepo and let's try to limit the changes to those packages to only the necessary ones 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok I reverted the change, let's see how CI goes.
b7608e4
to
64f025a
Compare
@javache Thanks for reviewing this. I've reimplemented the logic to convert from the file url to the asset catalog name in objc and made it so it falls back to using the current bundle url logic if the image doesn't exist in the catalog. It will also log a warning. I've tested that the Image example works with and without an asset catalog (by not passing the asset catalog arg to the CLI). This also makes sure old way to include assets work too and doesn't log a warning. |
PR build artifact for 64f025a is ready. |
PR build artifact for 64f025a is ready. |
64f025a
to
3894a46
Compare
3894a46
to
6a1a87a
Compare
PR build artifact for 6a1a87a is ready. |
PR build artifact for 6a1a87a is ready. |
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
React/Base/RCTUtils.m
Outdated
// Remove extension | ||
path = [path stringByDeletingPathExtension]; | ||
|
||
// Remove scale suffix | ||
path = [RCTAssetURLScaleRegex() stringByReplacingMatchesInString:path | ||
options:0 | ||
range:NSMakeRange(0, [path length]) | ||
withTemplate:@""]; | ||
|
||
path = [path lowercaseString]; | ||
|
||
// Encode folder structure in file name | ||
path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; | ||
|
||
// Remove illegal chars | ||
path = [RCTAssetURLCharactersRegex() stringByReplacingMatchesInString:path | ||
options:0 | ||
range:NSMakeRange(0, [path length]) | ||
withTemplate:@""]; | ||
|
||
// Remove "assets_" prefix | ||
if ([path hasPrefix:@"assets_"]) { | ||
path = [path substringFromIndex:@"assets_".length]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a really important code path that will be used by any image loaded in RN. Can we optimize it further?
E.g. rather than mutating the string multiple times, could you have a single regular expression that captures in a subgroup the relevant information so we don't have to write it multiple times, like this https://regex101.com/r/6Lqxoc/1
React/Base/RCTUtils.m
Outdated
NSString *__nullable RCTAssetCatalogNameForURL(NSURL *__nullable URL) | ||
{ | ||
NSString *path = RCTBundlePathForURL(URL); | ||
// Packager assets always start with assets/ | ||
if (path == nil || ![path hasPrefix:@"assets/"]) { | ||
return nil; | ||
} | ||
|
||
// Remove extension | ||
path = [path stringByDeletingPathExtension]; | ||
|
||
// Remove scale suffix | ||
path = [RCTAssetURLScaleRegex() stringByReplacingMatchesInString:path | ||
options:0 | ||
range:NSMakeRange(0, [path length]) | ||
withTemplate:@""]; | ||
|
||
path = [path lowercaseString]; | ||
|
||
// Encode folder structure in file name | ||
path = [path stringByReplacingOccurrencesOfString:@"/" withString:@"_"]; | ||
|
||
// Remove illegal chars | ||
path = [RCTAssetURLCharactersRegex() stringByReplacingMatchesInString:path | ||
options:0 | ||
range:NSMakeRange(0, [path length]) | ||
withTemplate:@""]; | ||
|
||
// Remove "assets_" prefix | ||
if ([path hasPrefix:@"assets_"]) { | ||
path = [path substringFromIndex:@"assets_".length]; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any documentation by Apple on how asset catalog assets are named that we could reference here as a comment?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This logic is based on how we name the assets when we create the catalog in the rn cli (https://github.com/react-native-community/cli/blob/main/packages/cli-plugin-metro/src/commands/bundle/assetPathUtils.ts#L67). The logic is the same as we use for android, which i know has a lot of limitations about how assets have to be named.
React/Base/RCTUtils.m
Outdated
regex = [NSRegularExpression regularExpressionWithPattern:@"[^a-z0-9_]" options:0 error:nil]; | ||
}); | ||
return regex; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of a regular expression, could you use a NSCharacterSet for this?
React/Base/RCTUtils.m
Outdated
return image; | ||
} else { | ||
RCTLogWarn( | ||
@"Image %@ not found in the asset catalog. Make sure your app template is updated correctly.", catalogName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a link to documentation we could provide here?
I'm worried that this warns and then just continues executing, so the warning will likely be ignored.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we could provide a link to the release notes where it explains this change. However this doesn’t exists yet so I guess it could be added later?
@janicduplessis, there are a couple of comments by @javache that should be addressed. Could you take care of it, please? 🙏 |
Yes, haven’t had the time to address those yet. I should be able to in the next week or so. |
6a1a87a
to
0ccbecb
Compare
/rebase |
/rebase |
@cipolleschi has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
Summary: There is currently an error when building in release on iOS when using asset catalogs (experimental feature that is partially merged #30129) This was probably incorrectly migrated from the community cli repo. `.imageset` is actually folders so it needs to be removed with `{recursive: true, force: true}`. I also renamed the variable `files` which is confusing since its folders. ## Changelog: [IOS] [FIXED] - Fix cleanAssetCatalog error Pull Request resolved: #41865 Test Plan: Tested in an app that uses asset catalogs Reviewed By: NickGerleman Differential Revision: D52032258 Pulled By: huntie fbshipit-source-id: 1dc0ca09e0da0d514b03d7d72707bdcaef03301d
Summary: There is currently an error when building in release on iOS when using asset catalogs (experimental feature that is partially merged facebook#30129) This was probably incorrectly migrated from the community cli repo. `.imageset` is actually folders so it needs to be removed with `{recursive: true, force: true}`. I also renamed the variable `files` which is confusing since its folders. ## Changelog: [IOS] [FIXED] - Fix cleanAssetCatalog error Pull Request resolved: facebook#41865 Test Plan: Tested in an app that uses asset catalogs Reviewed By: NickGerleman Differential Revision: D52032258 Pulled By: huntie fbshipit-source-id: 1dc0ca09e0da0d514b03d7d72707bdcaef03301d
This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days. |
I will one day find time to finish this :) |
Summary
Use an asset catalog for images on iOS. See related PR in the CLI for the code that generates it react-native-community/cli#1290.
Changelog:
[iOS] [Added] - Use asset catalog for ios images
Test Plan
See react-native-community/cli#1290
Test on RN Tester
PRODUCTION=1 yarn setup-ios-jsc
in packages/rn-testerIn Xcode, product -> scheme -> edit scheme -> change Build Configuration to Release.
Build and check that local images are working.