Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 2.0 code works in Xcode but not in Playground

I'm learning Swift and have been frustrated trying to figure out how I'm unable to load files. It turns out that the code works in Xcode but does not work in a playground. What is the reason for this?

Here's the code:

func testFileLoad(){
    let myFilePath: String = "/Users/clay/Desktop/test.txt"
    let t: Bool = NSFileManager.defaultManager().fileExistsAtPath(myFilePath)
    print(t)

    let s: String = try! String(contentsOfFile: myFilePath, encoding: NSUTF8StringEncoding)
    print(s)

    do {
        let p: String = try String(contentsOfFile: myFilePath, encoding: NSUTF8StringEncoding)
        print(p)
    } catch {
        print("nope")
    }
}

Running in a test module in Xcode, it works properly and prints what I would hope for to the console.

Test Suite 'Selected tests' started at 2015-08-05 14:24:15.977 
Test Suite 'swiftgraphTests' started at 2015-08-05 14:24:15.978 
Test Case '-[swiftgraphTests.swiftgraphTests testFileLoad]' started. 
true 
this is a test 
this is a test 
Test Case '-[swiftgraphTests.swiftgraphTests testFileLoad]' passed (0.001 seconds). 
Test Suite 'swiftgraphTests' passed at 2015-08-05 14:24:15.979.      
    Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds 
Test Suite 'Selected tests' passed at 2015-08-05 14:24:15.979.   
    Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds

In a playground, I get this:

enter image description here

What am I doing wrong here? Am I using the playground improperly?

like image 468
Clay Avatar asked Aug 05 '15 18:08

Clay


1 Answers

If you go to the menu

"View" -> "Debug Area" -> "Show Debug Area"

you will see the full error: "you don't have permissions to access the filesystem from the Playground*."

The workaround is to include the file in the Playground using its Project Navigator.

Go to the menu

"View" -> "Navigators" -> "Show Project Navigator"

then drag and drop your file into the "Resources" folder.

Then use NSBundle to get the path.

func testFileLoad() {

    // get the file path for the file from the Playground's Resources folder
    guard let path = NSBundle.mainBundle().pathForResource("test", ofType: "txt") else {
            print("Oops, the file is not in the Playground")
            return
    }

    // keeping the examples from your question
    let s: String = try! String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
    print(s)

    do {
        let p: String = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
        print(p)
    } catch {
        print("nope")
    }

}

testFileLoad()

*Actually you have only access to the /var/ folder containing your Playground shared data, and the Playground is just offering a shortcut. This folder in the Playground's navigator actually represents the /var/ folder, and is unique for each Playground. You can see its address with NSBundle:

NSBundle.mainBundle().resourcePath
like image 177
Eric Aya Avatar answered Sep 21 '22 11:09

Eric Aya