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
Access Class Property from Instance
Flipping The Positions of Items in a UIstackview
Xcodebuild Commands Failed to Generate Ipa
Passing in Variable Number of Args from One Function to Another in Swift
Swift - Measurement Convert(To:) Miles to Feet Gives Wrong Result
Detecting Swipes on All Four Directions on Watchkit Using The Storyboard
Facebook Graphrequest for Swift 5 and Facebook Sdk 5
Passing Parameters with #Selector
+' Is Deprecated: Mixed-Type Addition Is Deprecated in Swift 3.1
How to Specify Japanese Encoding for a UIlabel
When How to Start Submitting Apps to The iOS App Store Written Using The Swift Programming Language
Variable with Getter/Setter Cannot Have Initial Value, on Overridden Stored Property
Performseguewithidentifier Not Working If Called from Viewdidload
Apple Watch and iPhone Are Not Connected When The App in Phone Goes to Background
How to Get Reliable Timing for My Audio App
Inner Didset Protection Bizarrely Extends to The Whole Class