-
Notifications
You must be signed in to change notification settings - Fork 728
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
Inconvenient access to Assets of type color & image #603
Comments
The very major difference is that assets can be quite memory heavy. In your example templates, all images are stored in memory, which is absolutely not the way to go. If someone has a few MBs of image or data assets, they'd all be at all times in memory. Something you can do in your codebase is to add extensions to for example extension UIImageView {
func set(asset: ImageAsset) {
image = asset.image
}
} |
Note, there is a typealias at the start: typealias AssetColorTypeAlias = UIColor
typealias AssetImageTypeAlias = UIImage The reason they have a somewhat long name, is to avoid conflicts with the other templates' output (or other modules). You can always customise these using the template parameters, see the documentation for more information (https://github.com/SwiftGen/SwiftGen/blob/master/Documentation/templates/xcassets/swift4.md#customization). |
I agree that there's some inconsistency with Assets exposing a @djbe I thought about the memory-heavy problem, but thinking back about it, global constants are lazy by default, so that might not actually be a problem after all? (See the PR where we discuss the -- As for the So in your case @Dschee just un-checking the "provides namespace" on your "Colors" and "Images" groups you might have created in your Asset Catalog would solve that second point… |
The problem still remains that those assets would, once loaded, remain in memory, so that'd still be a very bad idea. |
Another note: the |
@Dschee Another reason why you might have those The cases when we create sub-enums under
Otherwise, we don't create subenums and colors and images should be directly accessible under |
@AliSoftware We separate colors from images, so we have a |
So, if I get this right then we should add the above typealiases to our project tempalte since it's a result of our setup. That's okay with me, but I still think the Thanks for the quick answers by the way @djbe & @AliSoftware! 👍 |
@Dschee So that's where your sub-enum is coming from, that's because you use separate asset catalogs so we create one sub-enum per catalog, because people separating assets in separate catalogs usually do it for semantic reasons, and expected that separation to be re-transcrived in the generated constants. That's the expected behaviour, at least for 95% of our users. -- So only question that remains from that issue is your first point: would it be possible to remove the need for |
@AliSoftware Exactly. That would be interesting to know. |
If you want to avoid that sub-enum in your case, you can either:
I think the most appropriate solution for you should be solution 2 (only have one asset catalog, and use folders to organise them), but YMMV. |
The other major reason we have these Now, we could use computed |
Last note: image assets can have trait variations (so they can change with the horizontal/vertical size classes). |
Good point. Example where it makes it useful to have an class MyVC: UIViewController {
let asset: ImageAsset!
@IBOutlet let imageView: UIImageView!
static func instantiate(asset: ImageAsset) {
let vc = MyVC()
vc.asset = asset
return vc
}
override func traitCollectionDidChange(_ previousTraitCollection: UITraitCollection?) {
self.imageView.image = asset.image // recompute with new traitCollection
}
} And even if it's not the case yet, in the future we could imagine adding a |
Okay, I can see now why you would want to keep the default template this way. But I still can't convince my colleagues to simply use the default template for reasons of wider community knowledge and community maintenance. Since they have never used trait collections (trait collections are not particularly useful if you're developing mainly iPhone apps, they can't even differentiate between a tiny iPhone SE screen and a huge iPhone Xs Max screen which has 5 times the pixels amount) it's hard to understand the need for the last part of the call. The last hope for me really is an alternative template now: What do you think about an |
Well, for these cases custom templates is what we usually recommend. TBH I tend to avoid shortcuts like these, just in case I need to add iPad support (for example) to an existing app. Any built-in template we provide should protect the user against their own "mistakes". It'd be unfortunate if our users would have to switch templates and modify their whole codebase if at some point they need trait variations in their apps. Like @AliSoftware mentioned, we maybe should add the |
iPad support doesn't make us want to use trait collections. But even if it would, we still wouldn't provide different images for trait collections and even if that was the case, why should we ever want to provide different colors for different traits? To me, the correct naming for the current template would be How many people are using trait-specific images and would need that API, honestly? My gut feeling formed from my personal experience tells me that 95% of the users won't ever need that feature. You guys may live in a world where things are different, but in my world this is just unnecessary API clutter. Having that said, I don't much care about still using a custom template like we already do in our projects. I just wanted to discuss here if the current templates APIs couldn't be improved. If you're fine with even the |
I've just created a simplified template which I'm suggesting to add to the project in #605. Even if you decide not to merge it, maybe someone will come across this thread and wants to use the simplified template rather than the default one. |
Doesn't UIImage handle this internally? Otherwise just storing an image in a variable like in a view model would mean the image doesn't change when the trait collection changes. Also doesn't UIImage handle caching etc itself, that along with static variables being lazy loaded, should mean that the ImageAsset struct isn't needed |
Yep UIImage handles caching itself when using the UIImage(named:) init. https://developer.apple.com/documentation/uikit/uiimage/1624154-init So if the memory gets low it will purge unused images. I think ImageAsset is basically implementing UIImage which is just a wrapper around the image itself and the details. So if you put a UIImage in a UIImageView and the traitCollection changes, UIImageView will ask UIImage for the relevant image. |
Currently, when I use the default
swift4
template forxcassets
I need to access my colors like so:When accessing images it looks like so:
In my opinion this is unnecessarily long. It should rather be like these calls:
Note that I'm aware that we can use our own custom templates (actually we're doing this, see here and there). But I think the default template could be improved in this perspective.
I mean, the Strings call also doesn't look like
Asset.Strings.Onboarding.Header.title.string
. It'sL10n.Onboarding.Header.title
which is to the point. The contextL10n
makes clear the last component is aString
and I'm not able to get thekey
name either so why do I need it for images and colors, but not for Strings? Also why isn't there at least a typealias for the start like:I don't seem to understand these points. I'd be glad to hear the rationale.
The text was updated successfully, but these errors were encountered: