Get Path of a File in a Data Set Located in Assets.Xcassets

How to get Assets.xcassets file names in an Array (or some data structure?)

Assets.xcassets is not a folder but an archive containing all the images using Assets.car as its filename.

If you really want to read the assets file then you need to use some library that can extract the contents of the file like this one.

Or you can create a bundle in your project and drag all the images you have there. In my case, I have Images.bundle in my project. To get the filenames you can do the following:

let fileManager = NSFileManager.defaultManager()
let bundleURL = NSBundle.mainBundle().bundleURL
let assetURL = bundleURL.URLByAppendingPathComponent("Images.bundle")
let contents = try! fileManager.contentsOfDirectoryAtURL(assetURL, includingPropertiesForKeys: [NSURLNameKey, NSURLIsDirectoryKey], options: .SkipsHiddenFiles)

for item in contents
{
print(item.lastPathComponent)
}

SWIFT 3/4 Version:

let fileManager = FileManager.default
let bundleURL = Bundle.main.bundleURL
let assetURL = bundleURL.appendingPathComponent("Images.bundle")

do {
let contents = try fileManager.contentsOfDirectory(at: assetURL, includingPropertiesForKeys: [URLResourceKey.nameKey, URLResourceKey.isDirectoryKey], options: .skipsHiddenFiles)

for item in contents
{
print(item.lastPathComponent)
}
}
catch let error as NSError {
print(error)
}

Get path to assets file in iOS: NSBundle is missing

Many things have changed names in Swift3!

let url = Bundle.main.url(forResource: "Database", withExtension: "txt")
// url.path

Figuring assets.xcassets path programmatically using SWIFT

If you only need the path to the file (and not an instance of UIImage), this will do it:

Swift 2:

if let resourcePath = NSBundle.mainBundle().resourcePath {
let imgName = "dog.png"
let path = resourcePath + "/" + imgName
}

Swift 3/4:

if let resourcePath = Bundle.main.resourcePath {
let imgName = "dog.png"
let path = resourcePath + "/" + imgName
}

Get Data from XCAsset catalog

I am going to answer my own question.

Since iOS 9, the Asset Catalog allows more than just Images. They allow Data sets. In order to get data from the Asset Catalog, you must use the NSDataAsset class.

Example: Assume you have an Data Asset named "CoolJSON"

if let asset = NSDataAsset(name: "CoolJSON") {
let data = asset.data
let d = try? NSJSONSerialization.JSONObjectWithData(data, options: [])
}

In this example I turned an NSData object into a json.

NSDataAsset class reference

Can I access an xcassets directory on the filesystem?

If there are other solutions to this problem, I'm open to that

The problem is that there is no introspection at runtime into an asset catalog: it isn't a "thing" you can "see" as far as Objective-C and Cocoa Touch are concerned.

The usual solution to this kind of problem is to drag a folder full of images into your project at the outset, and when you do, choose "Create folder references for any added folders" in the dialog - not "Create groups for any added folders". The result is that the folder is copied into your app bundle, and now you can use ordinary file system methods to say "every file in this folder".

List the Assets.xcassets contents

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.

Access Asset Catalog pathForResource

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.

Where to place a .txt file and read from it in a IOS project

if let path = Bundle.main.path(forResource: "README", ofType: "txt") {
do {
textView.text = try String(contentsOfFile: path, encoding: .utf8)
} catch let error {
// Handle error here
}
}

Just drop the file anywhere into the project browser and make sure it is added to the right target.

Just to expand on the answer, you can also place them in a folder and use:
+ pathForResource:ofType:inDirectory:.



Related Topics



Leave a reply



Submit