Two methods of reading a small text file work in Playground but fail in a MacOS App. Some permissions thing or ? Any clues would be appreciated.
this simple one errors with: Operation not permitted
In case the simple example wasn't enough, this longer one errors with: File expected at “…<path>...” is missing
this simple one errors with: Operation not permitted
Code Block import Cocoa var path = "/Users/jeff/Documents/DateDisplayData.txt" //read text file line by line func readFile(_ path: String) -> Int { errno = 0 if freopen(path, "r", stdin) == nil { perror(path) return 1 } while let line = readLine() { //do something with lines.. print(line) } return 0 } readFile(path)
In case the simple example wasn't enough, this longer one errors with: File expected at “…<path>...” is missing
Code Block import Cocoa // get URL to the the documents directory in the sandbox let home = FileManager.default.homeDirectoryForCurrentUser // add a filename let fileUrl = home .appendingPathComponent("Documents") .appendingPathComponent("DateDisplayData") .appendingPathExtension("txt") // make sure the file exists guard FileManager.default.fileExists(atPath: fileUrl.path) else { preconditionFailure("file expected at \(fileUrl.absoluteString) is missing") } // open the file for reading // note: user should be prompted the first time to allow reading from this location guard let filePointer:UnsafeMutablePointer<FILE> = fopen(fileUrl.path,"r") else { preconditionFailure("Could not open file at \(fileUrl.absoluteString)") } // a pointer to a null-terminated, UTF-8 encoded sequence of bytes var lineByteArrayPointer: UnsafeMutablePointer<CChar>? = nil // the smallest multiple of 16 that will fit the byte array for this line var lineCap: Int = 0 // initial iteration var bytesRead = getline(&lineByteArrayPointer, &lineCap, filePointer) defer { // remember to close the file when done fclose(filePointer) } while (bytesRead > 0) { // note: this translates the sequence of bytes to a string using UTF-8 interpretation let lineAsString = String.init(cString:lineByteArrayPointer!) // do whatever you need to do with this single line of text print(lineAsString, terminator: "") // updates number of bytes read, for the next iteration bytesRead = getline(&lineByteArrayPointer, &lineCap, filePointer) }
I found my answer (enough for now) in this post https://developer.apple.com/forums/thread/96062
It's a sandbox setting that I had a hard time finding because the menu navigation doesn't look like what the Xcode help shows, although I could pick out hints from that and figure it out.
So for my use I disabled Sandboxing for my app, good enough for now.
I hope this helps someone else.
It's a sandbox setting that I had a hard time finding because the menu navigation doesn't look like what the Xcode help shows, although I could pick out hints from that and figure it out.
So for my use I disabled Sandboxing for my app, good enough for now.
I hope this helps someone else.