How to Access File Included in App Bundle in Swift

How to access file included in app bundle in Swift?

Simply by searching in the app bundle for the resource

var filePath = NSBundle.mainBundle().URLForResource("file", withExtension: "txt")

However you can't write to it because it is in the app resources directory and you have to create it in the document directory to write to it

var documentsDirectory: NSURL?
var fileURL: NSURL?

documentsDirectory = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).last!
fileURL = documentsDirectory!.URLByAppendingPathComponent("file.txt")

if (fileURL!.checkResourceIsReachableAndReturnError(nil)) {
print("file exist")
}else{
print("file doesnt exist")
NSData().writeToURL(fileURL!,atomically:true)
}

now you can access it from fileURL

EDIT - 28 August 2018

This is how to do it in Swift 4.2

var filePath = Bundle.main.url(forResource: "file", withExtension: "txt")

To create it in the document directory

if let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last {
let fileURL = documentsDirectory.appendingPathComponent("file.txt")
do {
if try fileURL.checkResourceIsReachable() {
print("file exist")
} else {
print("file doesnt exist")
do {
try Data().write(to: fileURL)
} catch {
print("an error happened while creating the file")
}
}
} catch {
print("an error happened while checking for the file")
}
}

Where to put the text files when I distribute the app?

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.

Read and Update into JSON file in main app bundle

You can't save the file in main bundle again as it's read-only , you need to copy it to say documents/library folder where you can read/write


class ViewController: UIViewController {

override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.

let from = Bundle.main.url(forResource: "data", withExtension: "json")!

let to = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!.appendingPathComponent("result.json")

do {

try FileManager.default.copyItem(at: from, to: to)

print(try FileManager.default.contents(atPath: to.path))

let wer = Data("rerree".utf8 )

try wer.write(to: to)

print(try FileManager.default.contents(atPath: to.path))

}
catch {

print(error)
}

}

}

Trouble adding a Swift file to an app's Resource Bundle

There are a few issues here. Xcode doesn't like putting .swift files in the resource bundle.

The first obvious fix is to go to the "Copy Bundle Resources" section under "Build Phases" for your target and add the .swift file.

This sort of works. But it doesn't copy the raw .swift file, it copies two related files associated with the compiled version of the .swift file.

And there doesn't seem to be a way to prevent Xcode from compiling the Swift file even if it isn't listed under the "Compile Sources" section of "Build Phases".

Here's what I would do:

Rename the .swift file you want in your app bundle to .swiftx for some other similar field extension. Make sure the file is in the list under "Copy Bundle Resources".

Then update your code to something like:

if let fileURL = Bundle.main.url(forResource: "test", withExtension: "swiftx") {
print("# File path loaded.")

if let fileData = Data(contentsOf: fileURL) {
print("File data loaded.")
mail.addAttachmentData(fileData, mimeType: "text/plain", fileName: "test.swift")
}
}

How do you access a file from inside an app directory

You might be looking for NSBundle.mainBundle which returns a reference to the NSBundle for the application. Using this and the various instance methods provided by NSBundle you may then determine the paths/URLs of the files packaged within the application bundle.

How to read data from a file in the App's bundle I macOS?

URL(string is the wrong API. It's only for URL strings starting with a scheme (http://, file://)

For file system paths you have to use URL(fileURLWithPath.

But in this situation there is a much better way

Replace

let path = Bundle.main.path(forResource: "file", ofType: "txt")!
let url = URL(string: path)! // no error

with

let url = Bundle.main.url(forResource: "file", withExtension: "txt")

How can you determine if a file exists within the app bundle?


[[NSFileManager defaultManager] fileExistsAtPath:pathAndFileName];

Getting bundle file references / paths at app launch

You can get the URL of a file in the main bundle using

NSString *path = [[NSBundle mainBundle] pathForResource:@"SomeFile" ofType:@"jpeg"];
NSURL *url = [NSURL fileURLWithPath:path];

You can write this URL to, for example, a property list file in the Documents directory:

NSString *docsDir = [NSSearchForDirectoriesInDomains(NSDocumentsDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *plistPath = [docsDir stringByAppendingPathComponent:@"Files.plist"];
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:[url absoluteString] forKey:@"SomeFile.jpeg"];
[dict writeToFile:plistPath atomically:YES];

If you don't know the names of the files and you just want to list all the files in the bundle, use

NSArray *files = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:[[NSBundle mainBundle] bundlePath] error:NULL];
for (NSString *fileName in files) {
NSString *path = [[NSBundle mainBundle] pathForResource:fileName ofType:nil];
NSURL *url = [NSURL fileURLWithPath:path];
// do something with `url`
}


Related Topics



Leave a reply



Submit