Error when reading in txt file to iOS app - ios

Im currently working on an iOS app that requires the parsing of a dictionary of words.
When I attempt to import the file and convert the contents to Strings I get an error on the let path:String = Bundle.main.path(forResource: "words", ofType: "txt")! line. The error is Thread 1: "EXC_BREAKPOINT(code=1,subcode=0x1002e11ec)"
Any help would be greatly appreciated.
NOTE: Screen shot of assets attached
let path:String = Bundle.main.path(forResource: "words", ofType: "txt")!
text = try! String(contentsOfFile: path, encoding: String.Encoding.utf8)
words = text.components(separatedBy: ("\n"))

Bundle path(forResource:ofType:) returns an optional String. You are force unwrapping the options. This crashes when the return value is nil.
It returns nil when there is actually no such file in your app's resource bundle.
You need to actually have a file named words.txt in your app's bundle. Make sure the filename case matches and make sure the file is selected for your target.
Generally you shouldn't force-unwrap optionals. It causes crashes. However, one can argue that the two force-unwraps in the code you posted will never crash once your app is working properly. The first one is only crashing because you have not yet properly put the file in your resource bundle. And the 2nd (try!) won't crash once your file is correct because you know it will be a valid text file in the given encoding.

Don't use a dataset. Just drag your txt file right into the file navigator.
To explain further, the error you're seeing is that you're using ! which says you're guaranteeing that a path for that resource exists in the bundle. Which it doesn't.

Related

Bundle.main.path(forResource:ofType:inDirectory:) returns nil when app name contains "space"

Why the Bundle.main.path(forResource: "testFile", ofType: "rtf") returns nil when the app's name has space? anyone encounter this? and perhaps able to fixed? The error doesn't occur if I remove the "space" in the app's name.
When I print the path the result is this /Users/<user>/Library/Developer/CoreSimulator/Devices/915D4A93-D812-4180-A49E-6BFA3BD77986/data/Containers/Bundle/Application/8623072B-7528-463C-971F-ECD1FB89BDDB/Test Application.app/testFile.rtf as you may notice the app's name "Test Application.app" has space on it. this causes the Bundle.main.path to return nil
It's highly recommended to use the URL related API anyway
Bundle.main.url(forResource: "testFile", withExtension: "rtf")
Swift 4.1
Its work with me to read the mp3 files in my app
Bundle.main.paths(forResourcesOfType: "mp3", inDirectory: "")

iOS reading from a file

I'm trying to get my iPhone app to load text from a file into a string array, with 1 line from the file per array element.
I've created an input file as a text file using sublime text. I dragged the file (which is located inside of a folder inside of my project directory) into xCode into a folder in the same location in the project heirarchy.
I also tried adding it as a bundle (by copying the folder and renaming it with the .bundle extension), to no avail. Currently, my app has the file in 2 places (Obviously I plan to delete the unneeded version, but I'm not sure how this will work so I've left it for now).
I've written a function that I want to read my file, and assemble its contents into an array:
func readFromFile(filename: String) -> [String]? {
guard let theFile = Bundle.main.path( forResource: fileName, ofType: "txt") else {
return nil // ALWAYS returns nil here: Seems 'filename' can't be found?????
}
do { // Extract the file contents, and return them as a split string array
let fileContents = try String(contentsOfFile: theFile)
return fileContents.components(separatedBy: "\n")
} catch _ as NSError {
return nil
}
}
As it stands, the function always returns nil at the location commented in the code.
I've been working on this for ~6hrs (and tried every suggestion I could find on StackOverflow, google etc) and I'm just getting more and more confused by the differences between the various versions of Swift and intricacies of iOS development. I can't seem to find a consistent answer anywhere. I've checked the apple documentation but it's too high level with no example code for me to understand at my swift beginner level.
I also tried naming the file with a ".txt" extension but that didn't help either.
The file must certainly be named alert01.txt if you are going to refer to it as forResource: "alert01", ofType: "txt".
Loading from a bundle will not work. The file needs to be part of your project as shown in the first entry.
However, your code is not going to work because you have created a folder reference. That means the folder PanicAlertFiles is being copied with all its contents into your bundle. Your code will need to dive into that folder in order to retrieve your file. Use path(forResource:ofType:inDirectory:) to do that, or (if you don't want to have to code the file name explicitly) get the folder and then use the FileManager to examine its contents.

Error called trying to get Bundle URL

I am getting an error when I try to get a path of an audio file I have.
let path = Bundle.main.path(forResource: "SaveALife", ofType: "mp3")!
In the console I receive this:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
Any help? Thanks.
I will go with #Rob, You must have spelled the resource name incorrectly or the file is not there in the bundle.
And by providing "!" you are forcing to get string path, but as the file is not there Or due to spelling mismatch the file is not found in bundle, the return path would be nil, and due to "!" it tries to unwrap the nil which results the crash.
So the solution is remove the "!" like below
let path = Bundle.main.path(forResource: "SaveALife", ofType: "mp3")
Or else if you definitely want to use "!", You must have to give correct resource path and confirm that the resource must be there in the bundle.
Hope it helps.
Happy coding ...
Make sure SaveALife.mp3 should be in your bundle. Also when you drag and drop the file please check copy bundle resources.

Does using a path from system, while calling a file, cause crashes?

I've a text file that stores my app's data for me.
If I use system path (/Users/username/Desktop/ProjectFile/data.txt), can it cause errors when application compiled into .ipa file?
open the file in your project, and check the target membership, as shown in following image. If target membership icon is checked for your corresponding target, then it will not make any problem during compilation(creating ipa). But if target membership is unchecked for your target build, then it will make the problem.
Using path form system like in the question causes crash when tested on a real iOS device.
Instead of using system path, using the code below will be more advantageous. It prevents crashes on real device.
let path = NSBundle.mainBundle().pathForResource("file", ofType: "txt")
let fileMgr = NSFileManager.defaultManager()
var array: [String] = []
if fileMgr.fileExistsAtPath(path!) {
do {
let text = try! String(contentsOfFile: path!, encoding: NSASCIIStringEncoding)
array = text.componentsSeparatedByString("|#|")
}
}

Swift Array size limit and Xcode compile limits

I have extracted OSX English language dictionary and want to use it in my Swift iPhone app. It has about 236,000 words which I have added to a swift string array.
When I try to run the build, it takes a long time to compile and then throws Segmentation Fault 11
Is this because the array is too big?
Am I going the correct path trying to add english dictionary in my project?
You should probably not store this as a single string. There are more efficient data structures that you can use, such as a trie. You should also consider not loading the entire content into memory at one point but be able to navigate it from the filesystem.
I was able to solve this problem by adding the actual dictionary text file into my xcode project. then utilize below code to fill words from the file to an array. it was pretty fast.
let path = NSBundle.mainBundle().pathForResource("dict2", ofType: "txt")
let dico = String(contentsOfFile: path!, encoding: NSUTF8StringEncoding, error: nil)
let dict = dico!.componentsSeparatedByString("\n")
Hope it helps someone.

Resources