Getting asset catalog path for image using UIImage(contentsOfFile:) - ios

When you drag an image from the desktop into the asset catalog in Xcode, you can access that image in a project using:
UIImage(named: "somePNG")
But how do you access that image using UIImage(contentsOfFile:)?
if let path = Bundle.main.path(forResource: "somePNG", ofType: "png") {
someImageView.image = UIImage(contentsOfFile: path)
}
The above code doesn't work. The image in the file inspector is added to the target. What am I missing?

Why would you want to use UIImage(contentsOfFile:) instead of UIImage(named:)? The reason is probably that you are wishing you could load your image from the asset catalog without automatically caching it. You can't. (I regard this as a major bug in the way asset catalogs work.) You will have to store the image at the root level of your app bundle instead, just as we used to do before asset catalogs existed.
If you name your resolution-dependent files according to the naming convention, e.g. myFile.png, myFile#2x.png, myFile#3x.png, then the right thing will happen when you use the code you've shown along with the name "myFile.png".

You can't access the image through contentsOfFile if it exists in xcassets , you need to add it to the project files , with copy option enabled

Related

Calling an Asset from the Assets.xcassets folder

It seems that an asset within my Assets.xcassets folder cannot be found. I'm getting the error [Use of unresolved identifier]. Am I calling it the right way?
if buttonName.currentImage == imageName { // etc…
The file names in your assets folder are not variables too. If you want to get the image from a file, you must say UIImage(named: "moreOff").
Instead of directly comparing the current image, you should add a boolean state variable to your class. For example, var isMoreOff: Bool. Whenever you change the image, you must update isMoreOff accordingly.

List the Assets.xcassets contents [duplicate]

This question already has an answer here:
Load array of images using group in xcassets [duplicate]
(1 answer)
Closed 2 years ago.
I'm trying to list all files in the Assets.xcassets catalogue but I can't find a way to do it...
There are some images inside and I'm looking for a way to insert these filenames into an array.
If I try this code:
let fm = FileManager.default
let path = Bundle.main.resourcePath!
let items = try! fm.contentsOfDirectory(atPath: path)
I can list items outside the Assets.xcassets
I know that I can put the images outside but I'm wondering if there's a way to list the files inside the Assets.xcassets catalogue.
Is there a special path to that "folder" or a text list somewhere?
Files from your Assets.xcassets are not simply copied into you app bundle.
Instead, Xcode compiles them into a special file called a car file - think of it as a sort of ZIP archive of all your assets.
The .car file format has been reverse engineered, e.g. at https://blog.timac.org/2018/1018-reverse-engineering-the-car-file-format/ but reading its content is quite a lot of hassle.

Get image name list from assets catalogue in xcode [duplicate]

This question already has an answer here:
Get list of folder and files within Assets.xcassets
(1 answer)
Closed 5 years ago.
I am new to xCode. I want to create an array of UIImage from the folder in Assets Catalogue - see screenshot ("Brands" folder).
To load it in a UITableView like this:
private func loadLocalBrands() {
// Load images names from assets and add them to array
let names : [String] = ["Avon","Dove","Faberlic","Grand","GreenLight","Loreal",
"Loreal", "MaxFactor", "Nivea", "Olay", "Oriflame",
"Rexona","Schwarzkopf","Spaquatoria","Wella"]
for name in names{
brands.append(Brand.init(name: name, photo:
UIImage(named: name), rating: Int(arc4random_uniform(5) + 1))!)
}
}
and it works properly - see screenshot
But if I will add sooner more images, I will need to expand "names" array too.
So I want to get list of files that located in "Brands" folder within the Assets catalogue.
You are over-engineering this, its best to maintain a list of your assets that you want to display to the user. You will have to add assets to the project and repackage which is a good time to add new items to the list.
Also this is why things like this are manged from server in case you didn't think of it.
Another issue is that the asset catalogue is a product of Xcode whereas its not available when the IPA file of the app is created in the same format (in my understanding). So this approach will fail even if you were to work around and read the file list somehow.

How to name images in XCode Asset Catalog in the right manner?

I try to organise the images in XCode Asset Catalog, but I am kind of confused:
(1) I try to create new folders for different group of images. However, I can access an image without specifying the folder name, such as:
let image = UIImage(named: "btn_tabsetting")
Should I give each image a different name even I already have put them in different folders?
(2) As shown below, in test folder, I create an image btn_tabsetting which has the same name as the one in the other folder. Why does XCode allow me to do this? When I call
let image = UIImage(named: "btn_tabsetting")
it actually loads the the one in Tab Setting View folder instead of the one in test folder, why is it so? What is the rule here?
I think maybe I misunderstand some important concepts in using the Asset Catalog, please help me to correct them.
According to docs
For any target in an Xcode project, the fully qualified name of an asset must be unique across all the asset catalogs and across all asset types. For example, it is an error to have an image set folder in one asset catalog called Llama.imageset and an image set with the same name in the same catalog or in a different catalog that is part of the same target. Similarly, it is an error to have both an image set folder called Llama.imageset and an app icon folder called Llama.appiconset in the same catalog or in a different catalog that is part of the same target.
So asset names should be unique. What I recommend is organize assets in logical groups and than prefixing each asset inside group with group name.
For an example:
- Icons (group)
- icon_gear
- icon_heart
- icon_edit
- TabBar (group)
- icon_tabbar_profile
- icon_tabbar_settings
- Settings (group)
- icon_settings_age
- icon_settings_name
- Streachables (group)
- streachable_profile_background
- streachable_product_background
Xcode Automatically set different image name, if you have placed same name of images in Asset Catlog.
Suppose i have drop one image as xyz.png and then i again drop xyz.png in it, the xcode will rename it with xyz_1.png

How to localize the images in Images.xcassets?

We can localize an image in the File Inspector using Localize... like this:
Then we can get this:
But now, I use Images.xcassets to manage my images in my iOS project, how should I localize these images in Images.xcassets?
If you are using an Asset Catalog:
Asset catalog elements are now localizable. In the information panel for an asset, there is a "Localization" section that lists all the languages you've set up for your project in the project settings. If you don't select any of them, your images will be deemed "universal" (i.e., they will adopt the default behavior). If you select one or more of them, you will be able to select different images for "universal" and any alternate language.
For example, if your base language is English, and you want Spanish-language alternates, select only "Spanish" and drag in the alternate versions in the Spanish wells, and leave the English versions as the Universal. Then, at run-time, if the chosen language is Spanish, then the Spanish-language image will be pulled. Otherwise, it will pull the English version. (Or, if you want specific English and Spanish versions that are both different from "everything else", also check English and drag in the corresponding English and Universal images.)
If you need to determine localized images at run time without using the Asset Catalog:
While there's (apparently) not currently a way to explicitly localize the xcassets file directly, you could instead localize the name of the asset to pull using your Localizable.strings file. For instance, say you have a graphic logo treatment for the main menu of a game that needs to be localized. You could put the localized logo treatments in the assets file with different names, add the names to your Localizable.strings file, and then fetch the appropriate image with code like this:
UIImage *img = [UIImage imageNamed:NSLocalizedString(#"MAIN_MENU_IMAGE", nil)];
That "Localize..." button is back in Xcode 11! So now you can localize your images and assets in the Asset catalog as you expect:
When Apple gives you lemons, make lemonade, or in this case, lemonade_en, lemonade_es or whatever suits your needs.
First, I create an entry for each desired language in my assets file like so:
Next, you will need to get a language code for the device. The important thing to remember here is that the user may have an unsupported language, so if that is the case, return your default (I use English).
The following extension of UIApplication will handle all of this for you:
extension UIApplication {
var languageCode: String {
let supportedLanguageCodes = ["en", "es", "fr"]
let languageCode = Locale.current.languageCode ?? "en"
return supportedLanguageCodes.contains(languageCode) ? languageCode : "en"
}
}
This extension does the following:
Creates an array of the languages my app supports
Obtains the current device's language code, or returns a default value if this is nil
Finally, it checks to see if the current code is in my supported list. If it is, it returns it, otherwise it returns my default code
Now, we combine the two to get the proper image:
let languageCode = UIApplication.shared.languageCode
let image = UIImage(named: "access_\(languageCode)")
After some search on the Internet, I think this feature is not provide by xcassets right now. Therefore, just don't use xcassets to manage your localization images.
I found another way:
add in you asset.xcassets a folder for each language (for instance: en,it,de)
set the flag "Provides Namespace" to each folder
copy all images and assets in that folder
In your code load the assets by calling
let languageCode = UIApplication.shared.languageCode
let image = UIImage(named: "\(languageCode)\assetname")
At the moment, I pull out the images that needs localization from Images.xcassets and put it in the standard project folder. I leave the non-localized images in the .xcassets. I use your method for the images that need to be localized.

Resources