Access Asset Catalog pathForResource

41,194

Solution 1

Same problem, but I don't think we could access it via pathForResource:, except below:

UIImage* image = [UIImage imageNamed:@"name-in-asset-catalog"];

It has been clearly documented:

Each set in an asset catalog has a name. You can use that name to programmatically load any individual image contained in the set. To load an image, call the UIImage:imageNamed: method, passing the name of the set that contains the image.

I found that in the package of complied app, a file named "Assets.car" came out, and I think it's the entire images sets in my project, and should have been zipped or something.

Refer to Apple's documentation:

Xcode 5 provides different functionality for asset catalogs depending on the deployment target for your project:

  • For all projects, individual images can be loaded using set names.
  • For projects with a deployment target of iOS 7, Xcode compiles your asset catalogs into a runtime binary file format that reduces the download time for your app.

So that's it.

I'm also looking for a way that doesn't use imageNamed:, I don't want runtime to cache my images.

Solution 2

I wanted to access some vector assets for creating UNNotificationAttachment with local resources so I came up with this helper class. It basically just gets image from assets, saves its data to disk and return file URL. I hope that helps someone.

import UIKit

class AssetExtractor {

    static func createLocalUrl(forImageNamed name: String) -> URL? {

        let fileManager = FileManager.default
        let cacheDirectory = fileManager.urls(for: .cachesDirectory, in: .userDomainMask)[0]
        let url = cacheDirectory.appendingPathComponent("\(name).png")

        guard fileManager.fileExists(atPath: url.path) else {
            guard
                let image = UIImage(named: name),
                let data = UIImagePNGRepresentation(image)
            else { return nil }

            fileManager.createFile(atPath: url.path, contents: data, attributes: nil)
            return url
        }

        return url
    }

}

Solution 3

[UIImage imageWithContentsOfFile:[NSString stringWithFormat:@"%@/%@.png", [[NSBundle mainBundle] resourcePath], imgName]];

imgName: the name of Image set, not caring the true name of the image in Image set.

Solution 4

Try using the image name as determined in the "Compile asset catalog" step. You'll find this in the build output. Be sure to expand the transcript - you should see something like this:

/* com.apple.actool.compilation-results */
/path/to/Debug-iphonesimulator/Your.app/[email protected]
/path/to/Debug-iphonesimulator/Your.app/[email protected]
/path/to/Debug-iphonesimulator/Your.app/[email protected]
/path/to/Debug-iphonesimulator/Your.app/[email protected]
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape~ipad.png
/path/to/Debug-iphonesimulator/Your.app/LaunchImage-700-Landscape@2x~ipad.png

Tested using +[UIImage imageNamed:] with Xcode 6.1.1.

Share:
41,194
MobileVet
Author by

MobileVet

I have been building quality mobile applications since 2004. After learning Swift and enjoying the type safety, I fell into a lot of JavaScript work. I have enjoyed some of the newer web libraries, especially React w/ Redux. Throw in the fantastic Ramda library, compile against Typescript and you have a fairly 'functional' setup with the benefits of type safety and enough wiggle room not to overly complicate things.

Updated on July 05, 2022

Comments

  • MobileVet
    MobileVet almost 2 years

    It appears that:

    [[NSBundle mainBundle] pathForResource:@"name" ofType:@"png"];

    Does not return anything for assets that are inside the Images.xcassets asset catalog. I also tried:

    [[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images"];

    [[NSBundle mainBundle] pathForResource:@"name" ofType:@"png" inDirectory:@"Images.xcassets"];

    But neither of those worked either.

    Has anyone had success retrieving paths to assets in the catalog?

  • knl
    knl over 10 years
    I have the same problem about caching images here stackoverflow.com/questions/19919113/…. It appears like imageNamed: caching does not work as expected when using Asset Catalogs, because the memory is never freed up by the system, not even on memory warnings.
  • Alper
    Alper almost 10 years
    I can verify this. Memory is not freed up. This part of iOS is pretty broken.
  • user1010819
    user1010819 over 9 years
    Doesnt work with image in any other bundle apart from main bundle.
  • Arthur Gevorkyan
    Arthur Gevorkyan about 9 years
    Thanks, mate. The way you did it is a good substitution for + (UIImage *)imageNamed:(NSString *)name inBundle:(NSBundle *)bundle compatibleWithTraitCollection:(UITraitCollection *)traitCollection. It was introduced with iOS 8.0 and I need to cover 7.x.x as well.
  • RommelTJ
    RommelTJ over 7 years
    I had the same issue and this worked great. Thanks for sharing.
  • Jon Vogel
    Jon Vogel over 7 years
    Nice! I made it a static function on the UIImage class.
  • Yucel Bayram
    Yucel Bayram almost 7 years
    What if there is a folder in assets and i need only photos in this folder? any help please ?
  • gaskbr
    gaskbr over 6 years
    Same issue here. iOS 11.. XCode 9.1