How can I open a txt file in local directory in swift2? - ios

I've put a "restaurants.txt" file in the same directory with MenuViewController.swift.
Then I put this code in viewDidLoad() of MenuViewController to read the file.
if let path = NSBundle.mainBundle().pathForResource("restaurants", ofType: "txt") {
if let content = try? String(contentsOfFile: path, encoding: NSUTF8StringEncoding) {
print(content)
} else {
print("error1")
}
} else {
print("error")
}
Then I get "error1" in my console.
How can I read the file in the same directory of the swift file?
Or do I have to put my "restaurants.txt" file somewhere else?

Add the file to the target:
Select the file
In the Project Navigator command1 select the file icon
Under "Target Membership" click the checkbox for the file.

1) If you wish to read content of a text file, even without inserting it to your project, you may also use NSFileMananger. The following code works, the only drawback - you need to state full path.
let fullPath = "/your/full/path/restaurants.txt"
if NSFileManager.defaultManager().fileExistsAtPath(fullPath){
do
{
let content = try String(contentsOfFile: fullPath, encoding: NSUTF8StringEncoding)
print("\(content)")
}
catch let error as NSError
{
print("error reading file: \(error)")
}
}
2) If you do mind the hardcode, and want it more generic - you will have to change Settings in the Build in Xcode. See here:
Locate source project directory in Swift

Related

Saving to xml document Swift

I'm using this code to save a string to an xml file in my project
let saveTo = statisticsI.toXMLString()
let filepath = Bundle.main.url(forResource: "statistics", withExtension: "xml")
let filepathAlt = Bundle.main.path(forResource: "statistics", ofType: "xml")
print(filepathAlt!)
do {
try saveTo.write(to: filepath!, atomically: false, encoding: String.Encoding.utf8)
let contents = try String(contentsOfFile: filepathAlt!)
print("FILE CONTENTS \(contents)")
}
catch let error as NSError {
print("Error writing values \(error)")
}
Printing the file contents returns the xml correctly, but when I stop running the application, the file hasn't been updated
When the above code is run, the file has already been read by a seperate function. Is the fact that the file has already been accessed (and its path still stored in a variable) the issue?
when I stop running the application, the file hasn't been updated
You can't write into the application bundle in iOS. Try using a path into the Documents folder or some other place within the app's sandbox.

Swift File Download Issue

I am trying to download a plist file from a remote location and use it in the iOS app I am creating. The file is going to be used for calendar details within the app's calendar. The goal is obviously that I can update the remote file instead of having to push updates to the app itself every time we need to make changes to calendar details.
I started with the code used in this example: Download File From A Remote URL
Here is my modified version:
// Create destination URL
let documentsUrl:URL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first as URL!
let destinationFileUrl = documentsUrl.appendingPathComponent("2017.plist")
//let destinationFileUrl = URL(string: Bundle.main.path(forResource: String(currentYear), ofType: "plist")!)
//Create URL to the source file you want to download
let fileURL = URL(string: "https://drive.google.com/open?id=0BwHDQFwaL9DuLThNYWwtQ1VXblk")
let sessionConfig = URLSessionConfiguration.default
let session = URLSession(configuration: sessionConfig)
let request = URLRequest(url:fileURL!)
let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in
if let tempLocalUrl = tempLocalUrl, error == nil {
// Success
if let statusCode = (response as? HTTPURLResponse)?.statusCode {
print("Successfully downloaded. Status code: \(statusCode)")
}
do {
try FileManager.default.removeItem(at: destinationFileUrl)
try FileManager.default.moveItem(at: tempLocalUrl, to: destinationFileUrl)
print("File was replaced")
print(NSArray(contentsOf: tempLocalUrl))
//print(tempLocalUrl)
} catch (let writeError) {
print("Error creating a file \(String(describing: destinationFileUrl)) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription as Any);
}
}
task.resume()
I originally tried to overwrite the file that is bundled with the app to being with, that resulted in errors. So I instead tried to just save it in the app's documents folder and that removed that error. I had to make sure and remove any previous version of the file because it was giving me a file already exists error after the first run.
While it says everything is working (The outputs for both successful download and replaced file happen) when I print the contents of the array from the downloaded URL it just gives me nil.
This is my first attempt to use any kind of external resources in an app. Before I have always kept everything internal, so I am sure there is something glaringly obvious I am missing.
Update 1:
I realized I didn't have the correct URL to use to download a file from a Google drive. That line of code has been changed to:
let fileURL = URL(string: "https://drive.google.com/uc?export=download&id=0BwHDQFwaL9DuLThNYWwtQ1VXblk")
So now I actually am downloading the plist like I originally thought I was. Even removing the deletion issue mentioned in the first comment, I still can't get the downloaded file to actually replace the existing one.
Update 2:
I have reduced the actual file manipulation down to the following:
do {
try FileManager.default.replaceItemAt(destinationFileUrl, withItemAt: tempLocalUrl)
print("File was replaced")
print(NSArray(contentsOf: destinationFileUrl))
} catch (let writeError) {
print("Error creating a file \(String(describing: destinationFileUrl)) : \(writeError)")
}
} else {
print("Error took place while downloading a file. Error description: %#", error?.localizedDescription as Any);
}
After the replacement is performed the output of the file shows the correct new contents that were downloaded from the internet.
Later in the code when I try and access the file it seems to be nil in content again.
Look at your download completion code. You:
Delete the file at the destination URL (in case there was one
leftover)
MOVE the temp file to the destination URL (removing it from the temp
URL)
Try to load the file from the temp URL.
What's wrong with this picture?
You are trying to get the contents of the moved file. You already moved the file to destination url and then you are trying to get the contents of the file from temporary location.
For getting file data, Please try the following :
let fileData = try! String(contentsOf: destinationFileUrl, encoding: String.Encoding.utf8)
print(fileData)

SWIFT 3 access JSON that is within a folder

I have a lot of JSON files that all of them are in a new folder called assets. How can I access some of the JSON files that are in a folder within the assets folder. Here is a screenshot of the file I want to work with. http://prntscr.com/eiv7p4
UPDATE:
here is the code with which I access the file "mc-summer-0.json"
if let path = Bundle.main.path(forResource: "mc-summer-0", ofType: "json") {
do {
let jsonData = try NSData(contentsOfFile: path, options: NSData.ReadingOptions.mappedIfSafe)
do {
let jsonResult: NSDictionary = try JSONSerialization.jsonObject(with: jsonData as Data, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary
if let times_to : [String] = jsonResult["times_to"] as? [String] {
for (value) in times_to {
print("\(value)")
}
}
} catch {}
} catch {}
}
but if I want to access a file that is in the "assets" folder I change the line into if let path = Bundle.main.path(forResource: "assets/mc-summer-1", ofType: "json") {
but unfortunately it doesnt work.
Those files are in groups in your project, not in separate folders. Very likely they will be in the root level of your app bundle, but we can't be sure based on what you've shown. I suggest building your app for the simulator and then opening the resulting bundle in the Finder and examining it.
alright, in case somebody get stuck just like me the real solution is to remove the assets "folder" and re add it and select to add them as reference instead as a group

swift 2 - file not found error when reading text file from app main bundle

I added a simple text file (savedinfo.txt) to my project containing just 1 line of text. I need to read the text from within my app. I did that as below. However, for some reasons, it cannot find the file when reading it, even though sFilePath shows the file path. See debug msg below. I am using the latest Xcode 7.2.
Thanks
let sFilePath = String(NSBundle.mainBundle().pathForResource("savedinfo", ofType: "txt")
let sText = try NSString(contentsOfFile: sFilePath, encoding: NSUTF8StringEncoding)
sFilePath: Optional("/Users/user115387/Library/Developer/CoreSimulator/Devices/F3866C2A-869A-4CE5-9936-C8BC0CC5CE0D/data/Containers/Bundle/Application/A98B6D45-1C9A-4049-86F1-9502D45836B0/TableViewDemo.app/savedinfo.txt")
error in reading file Error Domain=NSCocoaErrorDomain Code=260 "The file “savedinfo.txt")” couldn’t be opened because there is no such file."
This code works for me:
if let sFilePath = NSBundle.mainBundle().pathForResource("savedinfo", ofType: "txt") {
do {
let sText = try NSString(contentsOfFile: sFilePath, encoding: NSUTF8StringEncoding)
print(sText)
}catch {
}
}

How can i use existing DB.sqlite from folder in swift project?

I know about FMdb and use it to my project, but I don't know how use existing DB file and where can I add my DB.sqlite in my project?
In your case:
drop "DB.sqlite" to your project folder (in navigation window)
add following code to your AppDelegate.swift file
func checkDataBase(){
print("check database...")//log
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("DB.sqlite")
// Load the existing database
if !NSFileManager.defaultManager().fileExistsAtPath(url.path!) {
print("Not found, copy one!!!")//log
let sourceSqliteURL = NSBundle.mainBundle().URLForResource("DB", withExtension: "sqlite")!
let destSqliteURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("DB.sqlite")
do {
try NSFileManager.defaultManager().copyItemAtURL(sourceSqliteURL, toURL: destSqliteURL)
} catch {
print(error)
}
}else{
print("DB file exist")//log
}}
3.Function is ready to use, just call "checkDataBase()" function in "func application" maybe..

Resources