"contentsOfFile" returning nil, possible cause - swift

The following returns nil when getting the content of a csv file. However, reducing the csv table to 10 rows will work properly, outputting the content of the csv file.
The original csv has about 400,000 characters arranged in 500 rows and 11 columns. What could be causing it to return nil with the original csv?
let dbPath = "/Volumes/Gios2TWD/myDB.csv"
var error: NSError?
let csvContent = NSString(contentsOfFile: dbPath, encoding:NSUTF8StringEncoding, error: &error) as String!
println(csvContent)
println(error)
I'm running XCode Version 6.1 (6A1030)
error:
Optional(Error Domain=NSCocoaErrorDomain Code=261 "The file “myDB.csv” couldn’t be opened using text encoding Unicode (UTF-8)." UserInfo=0x10050c5b0 {NSFilePath=/Volumes/Gios2TWD/myDB.csv, NSStringEncoding=4})

You need code that tests for errors something like this:
let dbPath = "/Volumes/Gios2TWD/myDB.csv"
var error: NSError?
let csvContent = NSString(contentsOfFile: dbPath, encoding:NSUTF8StringEncoding, error: &error)
if csvContent != nil {
// do something with the string
}
else {
println("error: \(error)")
}
Then try to understand any error message. Post the code and full error message to SO if you need help.
With an error message like: "couldn’t be opened using text encoding Unicode (UTF-8)" it is not a UTF-8 file. There may be corruption in the file or it many be another format. Try NSMacOSRomanStringEncoding, it is an 8-bit ASCII encoding that is very forgiving. It also might be another 8-bit ASCII encoding.
Note: Do not explicitly unwrap things unless you are 100% certain that under no circumstances they can never be nil.

Just stumbled upon this question and Zaph's answer with the recommendation to use NSMacOSRomanStringEnconding as the enconding does fix alot of issues indeed - in my case it were umlauts which caused the issue with NSUTF8StringEnconding.
Nevertheless I just wanted to add the latest Swift syntax in case you wanna catch the error and handle it properly
let csvContent: String?
do{
csvContent = try String(contentsOfFile: path!, encoding: NSUTF8StringEncoding)
// file could be read properly - do something with the content ...
} catch {
let nsError = error as NSError
print(nsError.localizedDescription)
}

Related

How do I read a file from the filesystem in a Swift command line app?

I'm just starting learning Swift and to teach myself I'm making a simple command line app. It will eventually connect to an online data source but initially I want to load data from a file. I've seen various guides on reading the contents of a file in Swift but none of them seem to work for me. Here is my app so far:
import Foundation
// Set the file path
let path = "/Users⁩/username/workspace⁩/⁨Swift⁩/sis⁩/sis/data.json⁩"
do {
// Get the contents
let contents = try String(contentsOfFile: path, encoding: .utf8)
print(contents)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
Running it outputs:
Ooops! Something went wrong: Error Domain=NSCocoaErrorDomain Code=260 "The file “data.json⁩” couldn’t be opened because there is no such file." UserInfo={NSFilePath=/Users⁩/username/workspace⁩/⁨Swift⁩/sis⁩/sis/data.json⁩, NSUnderlyingError=0x100e19a50 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
However on the terminal:
$ ls -l /Users/username/workspace/Swift/sis/sis/data.json
-rwxrwxrwx# 1 username staff 165563 16 Jan 17:14 /Users/username/workspace/Swift/sis/sis/data.json
(yeah I relaxed the permissions somewhat just in case that was the problem)
The only slightly anomalous thing I noticed (aside from the inaccurate assertion that the file doesn't exist) was that when I copy and past the path from the XCode output into iTerm2 it puts spaces between each path component:
(pasted as an image as copying it and pasting it back into this form seems to hide the spaces - this is probably irrelevant anyway)
Any help figuring this out would be really appreciated!
I copied your code, downloaded a sample json file to my desktop, and renamed it to example_ 1.json (I included a space inside the file name).
import Foundation
// Set the file path
let path = "/Users⁩/username/Desktop/example_ 1.json⁩"
do {
// Get the contents
let contents = try String(contentsOfFile: path, encoding: .utf8)
print(contents)
}
catch let error as NSError {
print("Ooops! Something went wrong: \(error)")
}
It successfully printed the file. It also worked when I defined contents as a NSString.
let contents = try NSString(contentsOfFile: path,
encoding: String.Encoding.ascii.rawValue)
I am using Swift 4.2.1
you can not read if your command line app is sandboxed. what you can do is to add this file in your project and set path of file by looking the full path of file in identity inspector.
let path = "/Users/snx/EmailReplacer/EmailReplacer/shared_domains_staging.json"
do {
let data = try Data(contentsOf: URL(fileURLWithPath: path), options: .mappedIfSafe)
let jsonResult = try JSONSerialization.jsonObject(with: data, options: .mutableLeaves)
if let jsonResult = jsonResult as? Dictionary<String, AnyObject> {
print(jsonResult)
}
} catch {
print(error)
}

How do I use String(contentsOfFile: ) in Swift? [duplicate]

This question already has answers here:
Read and write a String from text file
(21 answers)
Xcode 7.1 beta: Content Of File Error
(1 answer)
Closed 4 years ago.
Edit: I do not believe this question is a duplicate of Read and write a String from text file. I linked that exact question in this one explaining that it did not work!
I want to be able to read a .txt file I am including within my Xcode project in an iOS app. I have the following code:
let bundle = Bundle.main
override func sceneDidLoad() {
let path = bundle.path(forResource: "data", ofType: "txt")
let string = try String(contentsOfFile: path!) else throw Error
}
All the lines up until let string = ... are fine. However, everything I have found in questions such as this one are unable to read the data.txt file as they are incorrect/outdated syntax.
How do I read from it?
Edit: I've got the let string to be this:
do {
let string = try String(contentsOfFile: path!)
print(string) // prints the content of data.txt
}
catch {
throw Error
}
But I still have two errors:
Thrown expression type 'Error.Protocol' does not conform to 'Error'
and
Error is not handled because the enclosing function is not declared 'throws'
How do I fix the errors?
You need to handle the possible error thrown by encapsulating the throwable function in a do-catch block. In the catch block you shouldn't throw an error, but rather parse the error thrown and decide what to do with it.
let path = bundle.path(forResource: "data", ofType: "txt")!
do {
let string = try String(contentsOfFile: path)
} catch {
print(error)
// Handle the error
}

Parsing large XML files fails--ERROR:Error Domain=DDXMLErrorDomain Code=1 "(null)"

I'm parsing XML using KissXML. I can successfully parse small XML but have problem with large XML. Here's my code
let url = URL(fileURLWithPath: xmlPath!)
let xmlData = try! Data(contentsOf: url)
do {
let doc = try DDXMLDocument(data: xmlData, options:0)// This is not working if xml is large (6MB)
let project = try! doc.nodes(forXPath: "//Project") as! [DDXMLElement]
for user in project {
let ProjectName = user.attribute(forName: "ProjectName")!.stringValue
let userTime = user.attribute(forName: "UseTime")!.stringValue
print("ProjectName:\(ProjectName!),userTime:\(userTime!)")
}
}
catch {
print("\(error)") //Get some idea from this error
}
When parsing 12k XML was successful, but 6M XML was a failure. When parsing large XML(6M),doc equal to nil.
I try to use NSXMLParser,the same problem arises,small file can work, big files can't.ERROR:NSXMLParserErrorDomain error 4.
You should not ignore the error using try?, always enclose it in do - catch construct. Use below code and see what error are you getting and then try to resolve it. Don't shoot in the dark, get some idea from the error and if nothing works post your error message in the question.
do {
let doc = try DDXMLDocument(data: xmlData, options:0)
// Your next line of code
}
catch {
print("\(error)") //Get some idea from this error
}

SWIFT: Reading file: NSData successful, String fails. Why?

I'm trying to read large data from file. It is a text file. The following line is successful, data is read into memory:
if let data = NSData(contentsOfFile: path, options: NSDataReadingOptions(), error: &error)
This line return an error:
if let data = String(contentsOfFile:path, encoding: NSUTF8StringEncoding, error: &error)
But why? File is there, only Function is different. And I like to use second one, because I want to split all rows into separate strings in an array:
var array = data.componentsSeparatedByString("\n")
Any hint what to do?
Additional information: There are german umlauts, so code is larger than 127. But the file was saved as UTF-8. How could I load/use non ascii text?
I tried out every option and found the solution I didn't expect:
NSMacOSRomanStringEncoding
This setting accepts also german umlauts!

unable to print the data after encoding in swift

I'm getting below error when i try to encode the data. If i print directly without encoding its printing properly
fatal error: unexpectedly found nil while unwrapping an Optional value
// get the NSURLRequestSession and get the data
let task = NSURLSession.sharedSession().dataTaskWithRequest(nsurlReq){
(data,response,error) in
// check whether there is no error
if(error==nil)
{
// println("Data \(data) ");
var encodedData = NSString(data: data, encoding: NSUTF8StringEncoding)!;
println(encodedData);
}
} //
// you need to resume the task
task.resume();
I would expect that your data has invalid encoding and that is why you're not able to print out the parsed data.