I am trying to locate a file in a subdirectory of subdirectory of my bundle. I used this code to create an UIImage with init(contentsOfFile:).
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg", inDirectory: "Level1")
let image = UIImage(contentsOfFile: resource!)
What am I doing wrong?
EDIT:
This works because groups you create in xcode editor do not affect the actual path.
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg", inDirectory: nil)
or let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg")
you are get the error fatal error: unexpectedly found nil while unwrapping an Optional value, this means your variable is set to nil, but your code is expecting it to not be nil.
do like check the resource contains value or not.
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg", inDirectory: "Level1")
print (resource) //
then
do like
Choice -1
if let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg", inDirectory: "Level1")
{
let image = UIImage(contentsOfFile: resource!)
}
else
{
print (resource)
}
Choice -2
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg", inDirectory: "Level1")
if resource != nil {
//Do Something
let image = UIImage(contentsOfFile: resource!)
}
for additional information
Ok I figured it out. Based on the path Fatti Khan mentioned I tried
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg",inDirectory: nil)
which is the same as
let resource = NSBundle.mainBundle().pathForResource("1g", ofType: "jpg")
It seems that even though I created groups in xcode editor that had no effect no the actual path, which is: file:///Users/user/Desktop/MattNeuburg/pathFinder/pathFinder/1g.jpg. pathFinder is the name of the project.
Related
I want to load a file from AppBundle. I am able to do this at top level ("/file.txt") with following code:
guard let path = Bundle.main.path(forResource: "file", ofType: "txt") else {
print("file not found")
return
}
But when I put the "file.txt" in a folder ("anyFolder") I do not know how to read the file from "/anyFolder/file.txt".
The shown code does not work with a nested structure.
You should use "url(forResource:withExtension:subdirectory:)"
Check Apple Document
guard let url = Bundle.main.url(forResource: "ios", withExtension: ".ovpn")
else{
print("error")
return
}
print("bundle",url.path)
Create urls of ios.file
I have a folder (untagged-data) in Xcode that consists of a lot of images (100). I am trying to load the images into my application but for some reason the path is not correct and I am not able to load. Here is the URL I get which I am trying to load.
file:///Users/johndoe/Library/Developer/CoreSimulator/Devices/66763907-9153-443A-BA0E-D5CB6CC9280C/data/Containers/Bundle/Application/D3C77C63-CA3D-4238-8EAD-97B1DA15F2C6/MyApp.app/untagged-data/vessey.jpg
Here is the code which populates an array with the paths:
guard let resourceURL = Bundle.main.resourceURL else {
fatalError("Bundle not found")
}
let resourcePath = resourceURL.appendingPathComponent("untagged-data")
let paths = try! FileManager.default.contentsOfDirectory(at: resourcePath, includingPropertiesForKeys: nil, options: .skipsHiddenFiles)
for resourceURL in paths {
let path = resourceURL.absoluteString
self.images.append(path)
print(path)
}
When I try to create an image it simply throws an exception:
//let img = UIImage(named: images[index])
let img = UIImage(contentsOfFile: images[index])
Open the path below path in safari to check whether path exists or not
file:///Users/johndoe/Library/Developer/CoreSimulator/Devices/66763907-9153-443A-BA0E-D5CB6CC9280C/data/Containers/Bundle/Application/D3C77C63-CA3D-4238-8EAD-97B1DA15F2C6/MyApp.app/vessey.jpg
If path exists then comment the below line in code
//let resourcePath = resourceURL.appendingPathComponent("untagged-data")
When I run this code and add a breakpoint:
var pathFor = Bundle.main.path(forResource: imageName, ofType: "png")
print("breakpoint added here")
I see a nil value for the pathFor variable.
However, if I contextually check the file existence in my app Bundle (using XCode -> Device -> Device Name -> Download Container -> Show package content), I can see it inside the Documents directory:
What am I doing wrong?
UPDATE:
I have modified the code, following the suggestion in the answer.
Unfortunately I am unable to instantiate an image based on the path.
Please see here:
You are looking inside the Bundle ( i.e.: files embed on compilation time ) for a file you put in the Documents Folder. that ain't gonna work.
Your file is here :
if let dir = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory, FileManager.SearchPathDomainMask.allDomainsMask, true).first {
if let path = NSURL(fileURLWithPath: dir).appendingPathComponent("file.html") {
print(path as Any)
if let imageData = NSData(contentsOf: path!) {
let image = UIImage(data:imageData as Data)
}
}
Another permutation, but I'd personally do:
let fileURL = try! FileManager.default
.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent(imageName)
.appendingPathExtension("png")
let image = UIImage(contentsOfFile: fileURL.path)
path = Bundle.main.path(forResource: "Owl.jpg", ofType: "jpg")
returns nil, however, using NSHomeDirectory() I'm able to verify that is under Documents/ folder.
First, separate name and extension:
Bundle.main.path(forResource: "Owl", ofType: "jpg")
Second, separate (mentally) your bundle and the Documents folder. They are two completely different things. If this file is the Documents folder, it absolutely is not in your main bundle! You probably want something like this:
let fm = FileManager.default
let docsurl = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
let myurl = docsurl.appendingPathComponent("Owl.jpg")
Third, if Owl is an image asset in the asset catalog, then say
let im = UIImage(named:"Owl") // or whatever its name is
Tested on: xCode 8.3.2 & Swift 3.1
First drag your file (JPG, MP3, ZIP) inside your project folder and make sure Copy items if needed is checked and project/app is selected in Add to targets
Inside relevant ViewController
let fileName = "fileName"
let fileType = "fileType"
if let filePath = Bundle.main.path(forResource: fileName, ofType: fileType) {
print(filePath)
}
If you need to get the file URL you can use NSBundle method
if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileType) {
print(fileURL)
}
Also NSBundle method pathForResource has an initializer that you can specify in which directory your files are located like:
if let filePath = Bundle.main.path(forResource: fileName, ofType: fileType, inDirectory: "filesSubDirectory") {
print(filePath)
}
And for getting file URL:
if let fileURL = Bundle.main.url(forResource: fileName, withExtension: fileType, subdirectory: "filesSubDirectory") {
print(fileURL)
}
enter code here
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
print(documentsDirectory)
I am trying to test something, and need access to the file which is in the same directory as the test class (in fact in sub-directory). I am trying to do it like this:
let fileURL = testBundle.URLForResource("MasterCalendar", withExtension: "ics", subdirectory: "Calendars")
I also tried it like this:
let fileURL = testBundle.URLForResource("MasterCalendar", withExtension: "ics")
My class is called ParserTest. The file I am trying to access is located as shown:
I tried to get the file path:
if let filePath = NSBundle.mainBundle().pathForResource("MasterCalendar", ofType: "ics", inDirectory: "Calendars") {
print("PATH: ", filePath)
}
I tried to remove inDirectory, and put also "CallInTests/Calendar". Nothing worked.
The file itself is added in the Target for tests:
AND for the project:
Regardless of what I do, the fileURL returns always nil.
It is not quite clear to me how your testBundle is defined, but this works for me:
let bundle = Bundle(for: YourClassHere.self)
So in your case that would be:
let bundle = Bundle(for: ParserTest.self)
Which you can then use like so:
if let path = bundle.path(forResource: "MasterCalendar", ofType: "ics") {
//magic goes here
}
Swift 2.3 version
let bundle = NSBundle(forClass: ParserTest.self)
if let path = bundle.pathForResource("MasterCalendar", ofType: "ics") {
//magic still goes here :)
}
Hope that helps you.
try the following way :
let testBundle = NSBundle(forClass: self.dynamicType)
let fileURL = testBundle.URLForResource("MasterCalendar", withExtension: "ics")
XCTAssertNotNil(fileURL)