Try not to laugh or cry -- I'm just getting back into coding after 20 years out...
I've spent more than 4 hours looking at references and trying code snippets to get Bundle.main.path to open my text file so I can read in data for my app (my next step is to appropriately parse it).
if let filepath = Bundle.main.path(forResource: "newTest", ofType: "txt")
{
do
{
let contents = try String(contentsOfFile: filepath)
print(contents)
}
catch
{
print("Contents could not be loaded.")
}
}
else
{
print("newTest.txt not found.")
}
The result is: "newTest.txt not found." regardless of how I try to drag&drop the file into the project, create the file inside Xcode or use the File -> Add Files to... menu item.
The issue is that the file isn't being copied to your app bundle. To fix it:
Double check the Options
in the add files
menu when adding the file. The target in Add to targets
must be ticked to add it to the bundle:
In case you are actually in another bundle (test for instance), use:
guard let fileURL = Bundle(for: type(of: self)).url(forResource: fileName withExtension:"txt") else {
fatalError("File not found")
}
Click on your file on your navigation panel and open the Right Panel/ Property Inspector.
Swift 3.0
let fileNmae = "demo"
let path = Bundle.main.path(forResource: fileName, ofType: "txt")
do {
let content = try String(contentsOfFile:path!, encoding: String.Encoding.utf8)
print(content)
} catch {
print("nil")
}
SWift 2.0
do{
if let path = NSBundle.mainBundle().pathForResource("YOURTXTFILENAME", ofType: "txt"){
let data = try String(contentsOfFile:path, encoding: NSUTF8StringEncoding)
let myStrings = data.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet())
print(myStrings)
}
} catch let err as NSError {
//do sth with Error
print(err)
}
Output :
Hello Hems
Good Morning
I m here for you dude.
Happy Coding.
It's crazy how much time such a simple problem can cost.
Some answers here helped me but I always tried:
Bundle.main.url(forResource: selectedTitle, withExtension: "mp3")
For some reason that doesn't work, but getting the path and translating it to a URL afterwards works:
let path = Bundle.main.path(forResource: selectedTitle, ofType: "mp3")
let url = URL(fileURLWithPath: path!)
Ah, so just found myself dealing with the exact same problem as the OP.
The problem is that the solutions given here and here do not work when the code is being executed in a playground, since the Options
menu of add files
looks different for it does not show the Add to targets
field:
When inside a .playground
file, instead press the Hide or show the Navigator
button on the top-right of your Xcode window (visual impression)-->
Then, once the Navigator folds open on the left-side of the Xcode window, simply drag & drop your file to the Resources
directory of your playground.
If your setup looks anything like the following you should be ok:
This was helpful for me: xcode - copy a folder structure into my app bundle
Mark "create folder references" option when you create assets in nested folders.
Then find path to the file like this:
let path = Bundle(for: type(of : self)).path(forResource: "some_folder_a/some_folder_b/response.json", ofType: nil)
Same problem, slightly different situation & solution. I'm following a tutorial that said to use the following code:
// Start the background music:
if let musicPath = Bundle.main.path(forResource:
"Sound/BackgroundMusic.m4a", ofType: nil) {
print("SHOULD HEAR MUSIC NOW")
let url = URL(fileURLWithPath: musicPath)
do {
musicPlayer = try AVAudioPlayer(contentsOf: url)
musicPlayer.numberOfLoops = -1
musicPlayer.prepareToPlay()
musicPlayer.play()
}
catch { print("Couldn't load music file") }
}
}
I had the same issue as others but none of the solutions fixed the issue. After experimenting, all I did was remove Sound from the path in the following call and everything worked:
Bundle.main.path(forResource: "BackgroundMusic.m4a", ofType: nil)
It would seem that the tutorial was in error by telling me to include Sound in the path.
I added file.txt
to my project and it was automatically added to the Copy Bundle Files
of my project. For me, I had to remove the extension from the forResource
and it worked.
let path = Bundle.main.path(forResource: "file", ofType: "txt") // not forResource: "file.txt"
I think you don't want the inDirectory:
method. Try this instead:
if let filepath = Bundle.main.path(forResource: "newTest", ofType: "txt") {
My problem was in one module, created with Cocoapods. Every pod install/update, the files (json files) were there in the project, but never were find inside the Bundle. After pod install/update, I removed (deleted references) the files and add again to the project.
Always pay attention to target where you add the files.
The answer is simply to not use Assets.xcassets to store your audio file, and add your audio file, ie) BeTheFirstAudio.m4a (made with QuickTime), directly to the PROJECT NAVIGATOR (circled, pink) list of files (photo 1)
WARNING! Be sure to check the "CREATE GROUPS" and "ADD TO TARGETS" checkboxes when the pop-up appears after dragging your audio file from your Finder window.
After that, your code should work to play the audio (including .m4a extensions from QuickTime)
import AVFoundation
class AudioPlayer: NSObject {
private var audioPlayer: AVAudioPlayer!
override init() {
super.init()
// get URL for the default audio
let audioURL = Bundle.main.url(forResource: "BeTheFirstAudio", withExtension: "m4a")
audioPlayer = try! AVAudioPlayer(contentsOf: audioURL!)
}
Apple engineers should be ashamed that this problem is even a question in StackOverflow; developers should be able to add the audio file to Assets.xcassets and Bundle.main.url should be able to find it. The fact that this simple concept is difficult has probably cost a lot of time for developers. Attention @Apple
If you are using R.swift try this:
I was still having issues specially with a plist file that got changed during build times and since my project is using R.swift I changed the code to be
Bundle.main.path(forResource: R.file.myplistfile)
and that worked like a charm.
If you are running unit test or ui test, use their bundle id. Because they are not using main bundle, so you would never find your file by calling Bundle.main.path(forResource: "newTest", ofType: "txt")
.
Use your test target bundle id. In my case I'm trying to read data from a CSV file. Replace TestReadFileUITests
with your class name which extends from XCTestCase
.
Here is the actual bundle id used when I run a UI test case. You could see it is not from main bundle.
(lldb) po testBundle
NSBundle </Users/zhouhaibo/Library/Developer/CoreSimulator/Devices/448D1FCB-8311-4D3F-BEEF-934052C3470F/data/Containers/Bundle/Application/905C2326-8313-410F-9DC2-9D84B9C6D757/TestReadFileUITests-Runner.app/PlugIns/TestReadFileUITests.xctest> (loaded)
(lldb) po filePath
"/Users/zhouhaibo/Library/Developer/CoreSimulator/Devices/448D1FCB-8311-4D3F-BEEF-934052C3470F/data/Containers/Bundle/Application/905C2326-8313-410F-9DC2-9D84B9C6D757/TestReadFileUITests-Runner.app/PlugIns/TestReadFileUITests.xctest/Patients_2022-09-02.csv"
let testBundle = Bundle(for: TestReadFileUITests.self)
guard let filePath = testBundle.path(forResource: fileName, ofType: fileType) else {
print("CSV file not found.")
return [:]
}
class TestReadFileUITests: XCTestCase {
func testDemo() {
let _ = DataManager.readData()
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.