I want to programmatically load a couple of images into arrays from my xcassets. I don't know how many images there are in the asset, but the images are named in order, like this: "img1_1", "img1_2", "img2_1", "img2_2", ...
I put the images in folders inside the asset, so folder "images1" contains all images with names starting with "img1_" and the folder called "images2" contains all images starting with "img2_". Does that help?
How do I get the number of images in the asset that are named like that so I can iterate through them and add them to my array?
There isn't a real easy way to go about it since the files are placed in the app at compile time. You can, though, create a RunScript in the Build Phases to be ran before compiling that creates a text file of the images. Then you can read in that text file and populate an array of images. You can use that array to get the details you need.
RunScript in the Build Phases:
#!/bin/sh
>./your_app_folder/fileNames.txt
for FILE in ./your_app_folder/Images.xcassets/actions/*; do
echo $FILE >> ./your_app_folder/fileNames.txt
done
Also, here's a link to an accepted answer that a previous poster asked with more details.
Another option if you do not want to deal with Build Phases, and one I'd probably choose, is not to use the Assets.xcassets file. Just place the images in a folder within your app bundle. It's much easier to read from the bundle.
UPDATE:
For the second option, you can drag your images (or folder of images) to your project, but be sure copy as a folder reference rather than group. Then in your code, you can read that folder using the FileManager.
let fileManager = FileManager.default
let imagePath = Bundle.main.resourcePath! + "/your_new_folder"
let imageNames = try! fileManager.contentsOfDirectory(atPath: imagePath)
imageNames in this case will be an array of file names within that url path. If go this route, you probably have to load the images by contentsOfFile too.
if let imagePath = bundle.path(forResource: fileName, ofType: nil) {
myImage = UIImage(contentsOfFile: imagePath)
}
Related
After hours of hard work I could implement iCloud storage to my macOS app.
My container is displayed in iCloud. The name of the folder is correct. I can store generated pdf to all folders, but...
... I can't get a list of files of a certain folder inside this iCloud container.
I use this little snippet of code
let manager = FileManager.default
let driveURL = manager.url(forUbiquityContainerIdentifier: nil)?.appending(path: "Documents").appending(path:"Import")
try? manager.createDirectory(at: driveURL!, withIntermediateDirectories: true, attributes: [:])
let files = manager.enumerator(atPath: driveURL!.absoluteString)
files ist always empty (nil), because the folder Import doesn't exist (what's wrong, because it's there). And it should be created, if not exists.
Do I miss some settings to my project, to get access to my own folders? Or is there another, different way to get reading access?
I'm creating a Commandline tool that will get an input from a user to search for a specific application that supports a certain file extension. For example, if I enter mp4, it will probably show me QuickTime. I'm looking for the specific FileManager manipulation to achieve this in Swift.
I think you are looking for NSWorkspace.urlForApplication(toOpen:). It finds the application that would be opened if you had double clicked on a file, and returns its URL. Since it requires a file to work, you need to first create a temporary empty file somewhere, with the desired extension, then call this method.
let tempFileURL = FileManager.default.temporaryDirectory.appendingPathComponent("foo.mp4")
FileManager.default.createFile(atPath: tempFileURL.path, contents: nil, attributes: nil)
// this gives me the URL for QuickTime Player:
// file:///System/Applications/QuickTime%20Player.app/
let url = NSWorkspace.shared.urlForApplication(toOpen: tempFileURL)
I am making a screensaver in Swift using SpriteKit.
While testing screensaver in app, all the textures load properly. As soon as I make .saver and load it in System Preferences, SpriteKit shows that images are not found.
I used (imageNamed: ""), so I tried using
var imageURL = Bundle.main.url(forResource: "gradient", withExtension: "png")
let imageGradient = NSImage(contentsOf: imageURL!)!
,but I got the same result.
SpriteKit can't access images when built into .saver file, but works perfectly when ran through the app.
I have included images in bundle, in assets, in Target's Copy Bundle Resources/Development Assets/Resource Tags.
You can clone the project from here: https://github.com/Nazar-Bibik/SavePortal
I have looked into this project: https://github.com/leebradley/nyan-screensaver
And I found how to properly do it:
You need to put images into bundle, not xcassets ( put it with .swift files )
Instead of using image name use the following
let sourceBundle = Bundle(for: MainSwiftFile.self)
let imagePath = sourceBundle.path(forResource: "picture-name", ofType: "png")!
neededTextures = SKTexture(imageNamed: imagePath)
You need to provide the name of the .swift file with your principal class ( principle class in info.plist file ).
The rest is simple - forResource is a file name, ofType is a file extension and instead of passing usual name in imageNamed: you provide String of path to file.
"imagePath" is of a String type.
I am using the latest XCode / Swift 3.0 and facing some problems:
I created a folder in /MyProject/MyProject/Assets/Subfolder1 and stored a few hundred .txt files in it to iterate over the files inside the Subfolder1 with the following code:
let fm = FileManager.default
fm.enumerator(atPath: "/MyProject/Assets/Subfolder1")?.forEach({ (e) in
if let e = e as? String, let url = URL(string: e) {
doSomethingWith(url.pathExtension)
}
})
But I cannot find any files. I tried some variations ("/Assets/Subfolder1/" and "/MyProject/MyProject/Assets/Subfolder1"), all are not working.
What is the correct path that I have to specify?
Best
Chris
First off, make sure you have added the actual folder to the Xcode project. You can do this simply by dragging and dropping the folder into your project. After you drag and drop, this window should appear
Make sure you select Create folder references and Copy items if needed. This will make sure that the entire folder is constantly synced inside your Xcode project. Then to verify that the assets will be transferred to your device when building the project, go into Build Phases and then to Copy Bundle Resources and you should see the name of the folder, in my case, I have named it TextFiles.
Now because you have added your folder into the application's Main Bundle, you can access it by doing this:
let fm = FileManager.default
let path = Bundle.main.resourcePath?.appending("/TextFiles")
fm.enumerator(atPath: path!)?.forEach({ (e) in
if let e = e as? String, let url = URL(string: e) {
doSomethingWith(url.pathExtension)
}
})
The reason we need to do the Bundle.main.resourcePath before it and can't simply say /TextFiles is because if we say /TextFiles it looks for that folder starting from the system root, which is why it wasn't working before. It would be like having a folder in C:/Users/Abc123/Documents/TextFiles but the system is looking for it in C:/TextFiles.
I'm trying to save some images into my bundle. The images reads just fine when I save them in the main bundle.
in main bundle
However, if I place them into the asset catalog, they can no longer be read.
In asset catelog
Below are the codes I use to access them. If I save the pictures inside the asset catalog, the for item in items loop doesn't pick up any of the pictures.
override func viewDidLoad() {
super.viewDidLoad()
let fm = FileManager.default
let path = Bundle.main.resourcePath!
let items = try! fm.contentsOfDirectory(atPath: path)
for item in items {
if item.hasPrefix("nssl") {
pictures.append(item)
}
}
}
There's no documented way to iterate through the images contained in an xcasset file. At build time the assets get compiled to a .car file, but the only way to read images out of the asset is through UIImaged(named:).
If you need to be able to iterate through some resources in this way, it's best to store them in a simple folder inside your bundle.