1

I have a simple application that needs to read multiple text files. But right now in order to access the files I am giving the address of the file in my laptop.

let path = "/Users/alimashreghi/Desktop/glossories/science.txt"
var text:String = ""

do{

   text = try NSString(contentsOfFile:path, encoding: NSUTF8StringEncoding) as String

}catch{

}

Now, I am concerned about when I want to distribute the app. Where should I put the text files and how should I read them to ensure that it works properly as an app in an iPhone?

Besides, I don't know much about distributing swift apps.

    //
//  ViewController.swift
//  Test
//
//  Created by Ali Mashreghi on 2016-08-29.
//  Copyright © 2016 Ali Mashreghi. All rights reserved.
//

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
    let data = NSData.init(contentsOfFile: "/Users/TestProj/science.txt") //prints Optional(4380)
    let data = NSData.init(contentsOfFile: "science.txt") //prints nil

    print(data?.length)

    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

enter image description here

A. Mashreghi
  • 1,729
  • 2
  • 20
  • 33

2 Answers2

3

Just put them in your application's bundle, then you can read them as:

NSString *filePath = [[NSBundle mainBundle] pathForResource:  "science" ofType:@"txt"];
NSData *data = [NSData dataWithContentsOfFile:filePath];

Or

    if let filepath = Bundle.main.path(forResource: "science", ofType: "txt")
    {
        let data = NSData.init(contentsOfFile: filepath)
        NSLog("\(data)")
    }

You can drag and drop them into Xcode's navigation area, ensure they are included in the bundle in Xcode's Build Phases | Copy Bundles Resources.

Gruntcakes
  • 37,738
  • 44
  • 184
  • 378
  • The file is in the bundle but when I try to get the length, I get nil. print("length = " + String(data?.length)) //gives me nil, How should I properly add to bundle, the file is also in the directory of the project (it is not just a reference) – A. Mashreghi Aug 28 '16 at 22:32
  • And when I put the full address the length is not nil anymore – A. Mashreghi Aug 28 '16 at 22:37
  • Did you do this part of the answer that says " ensure they are included in the bundle in Xcode's Build Phases | Copy Bundles Resources." ? – Gruntcakes Aug 28 '16 at 23:15
  • Yes, when I go to build phase, copy bundle resources, it shows the science.txt file. I'm confused, I assume it should work but it doesn't, is there anything else that I might be missing? – A. Mashreghi Aug 29 '16 at 00:42
  • Post your full code (add it to your question) of what you are doing – Gruntcakes Aug 29 '16 at 01:00
  • @A. Mashreghi I've updated the code in the answer. Try that. The exact syntax for this code depends upon which version of Swift is being used, things like Bundle and data have been constantly changing as swift evolves. This syntax is for the latest version of Swift 3 with iOS Beta 10.7. – Gruntcakes Aug 29 '16 at 21:37
  • Thank you, it works, although the first line should be if let filepath = NSBundle.mainBundle().pathForResource("science", ofType: "txt") – A. Mashreghi Aug 29 '16 at 21:57
  • 1
    As I mentioned it depends on what version of Swift you are using. You are using an older version of Swift and Xcode. Once you upgrade to Xcode 8 and if you migrate to swift 3 then your code will need to change to as I've posted. NSBundle has been renamed to Bundle and mainBundle has been renamed to main – Gruntcakes Aug 29 '16 at 23:01
0

Swift 5 version

func getDataFromBundleFile(_ fileName: String, ofType: String) -> Data? {
    guard let filePath = Bundle.main.path(forResource: fileName, ofType: ofType) else {
        return nil
    }
    return try? Data(contentsOf: URL(fileURLWithPath: filePath))
 }
SafeFastExpressive
  • 3,637
  • 2
  • 32
  • 39