How can I read a file in a swift playground

Im trying to read a text file using a Swift playground with the following

let dirs : String[]? =    NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? String[]

if (dirs != nil) {
    let directories:String[] = dirs!;
    let dir = directories[0]; //documents directory
    let path = dir.stringByAppendingPathComponent(file);

    //read
    let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)
}

However this fails with no error. It seems the first line stops the playground from outputting anything below

  • How to save Array to CoreData?
  • Swift : How $0 works in Array.forEach?
  • Swift - Second section in tableview not visible
  • How can you provide default implementations for UIPageViewControllerDataSource?
  • Create an UIImage from Uibezierpath Array in Swift
  • Detect if Swift app is being run from Xcode
  • 8 Solutions Collect From Internet About “How can I read a file in a swift playground”

    This works for me. The only thing I changed was to be explicit about the file name (which is implied in your example) – perhaps you have a typo in the off-screen definition of the “file” variable?

    let dirs = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? [String]
    
    let file = "trial.txt" // My change to your code - yours is presumably set off-screen
    if let directories = dirs {
      let dir = directories[0]; //documents directory
      let path = dir.stringByAppendingPathComponent(file);
    
      //read
      let content = NSString(contentsOfFile: path, usedEncoding: nil, error: nil)
      // works...
    }
    

    You can also put your file into your playground’s resources. To do this: show Project Navigator with CMD + 1. Drag and drop your file into the resources folder. Then read the file:

    On XCode 6.4 and Swift 1.2:

    var error: NSError?
    let fileURL = NSBundle.mainBundle().URLForResource("Input", withExtension: "txt")
    let content = String(contentsOfURL: fileURL!, encoding: NSUTF8StringEncoding, error: &error)
    

    On XCode 7 and Swift 2:

    let fileURL = NSBundle.mainBundle().URLForResource("Input", withExtension: "txt")
    let content = try String(contentsOfURL: fileURL!, encoding: NSUTF8StringEncoding)
    

    On XCode 8 and Swift 3:

    let fileURL = Bundle.main.url(forResource: "Input", withExtension: "txt")
    let content = try String(contentsOf: fileURL!, encoding: String.Encoding.utf8)
    

    If the file has binary data, you can use NSData(contentsOfURL: fileURL!) or Data(contentsOf: fileURL!) (for Swift 3).

    While the answer has been supplied for a quick fix, there is a better solution.

    Each time the playground is opened it will be assigned a new container. This means using the normal directory structure you would have to copy the file you want into the new container every time.

    Instead, inside the container there is a symbolic link to a Shared Playground Data directory (/Users//Documents/Shared Playground Data) which remains when reopening the playground, and can be accessed from multiple playgrounds.

    You can use XCPlayground to access this shared folder.

    import XCPlayground
    
    //String Constant
    XCPSharedDataDirectoryPath
    
    let filePath = XCPSharedDataDirectoryPath.stringByAppendingPathComponent("<fileName>")
    

    The official documentation can be found here: XCPlayground Module Reference

    Cool post on how to organize this directory per-playground: Swift, Playgrounds, and XCPlayground

    Swift 3 (Xcode 8)

    The code below works in both iOS and macOS playgrounds. The text file (“MyText.txt” in this example) must be in the Resources directory of the playground. (Note: You may need to open the navigator window to see the directory structure of your playground.)

    import Foundation
    
    if let fileURL = Bundle.main.url(forResource:"MyText", withExtension: "txt")
    {
        do {
            let contents = try String(contentsOf: fileURL, encoding: String.Encoding.utf8)
            print(contents)
        } catch {
            print("Error: \(error.localizedDescription)")
        }
    } else {
        print("No such file URL.")
    }
    

    1. Access a file that is located in the Resources folder of your Playground

    With Swift 3, Bundle has a method called url(forResource:withExtension:). url(forResource:withExtension:) has the following declaration:

    func url(forResource name: String?, withExtension ext: String?) -> URL?
    

    Returns the file URL for the resource identified by the specified name and file extension.


    You can use url(forResource:withExtension:) in order to read the content of a json file located in the Resources folder of an iOS or Mac Playground:

    import Foundation
    
    do {
        guard let fileUrl = Bundle.main.url(forResource: "Data", withExtension: "json") else { fatalError() }
        let data = try Data(contentsOf: fileUrl)
        let json = try JSONSerialization.jsonObject(with: data, options: [])
        print(json)
    } catch {
        print(error)
    }    
    

    You can use url(forResource:withExtension:) in order to read the content of a text file located in the Resources folder of an iOS or Mac Playground:

    import Foundation
    
    do {
        guard let fileUrl = Bundle.main.url(forResource: "Text", withExtension: "txt") else { fatalError() }
        let text = try String(contentsOf: fileUrl, encoding: String.Encoding.utf8)
        print(text)
    } catch {
        print(error)
    }
    

    As an alternative to let image = UIImage(named: "image"), you can use url(forResource:withExtension:) in order to access an image located in the Resources folder of an iOS Playground:

    import UIKit
    
    do {
        guard let fileUrl = Bundle.main.url(forResource: "Image", withExtension: "png") else { fatalError() }
        let data = try Data(contentsOf: fileUrl)
        let image = UIImage(data: data)
    } catch {
        print(error)
    }
    

    2. Access a file that is located in the ~/Documents/Shared Playground Data folder of your computer

    With Swift 3, PlaygroundSupport module provides a global constant called playgroundSharedDataDirectory. playgroundSharedDataDirectory has the following declaration:

    let playgroundSharedDataDirectory: URL
    

    The path to the directory containing data shared between all playgrounds.


    You can use playgroundSharedDataDirectory in order to read the content of a json file located in the ~/Documents/Shared Playground Data folder of your computer from an iOS or Mac Playground:

    import Foundation
    import PlaygroundSupport
    
    do {
        let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Data.json")        
        let data = try Data(contentsOf: fileUrl)
        let json = try JSONSerialization.jsonObject(with: data, options: [])
        print(json)
    } catch {
        print(error)
    }
    

    You can use playgroundSharedDataDirectory in order to read the content of a text file located in the ~/Documents/Shared Playground Data folder of your computer from an iOS or Mac Playground:

    import Foundation
    import PlaygroundSupport
    
    do {
        let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Text.txt")
        let text = try String(contentsOf: fileUrl, encoding: String.Encoding.utf8)
        print(text)
    } catch {
        print(error)
    }
    

    You can use playgroundSharedDataDirectory in order to access an image located in the ~/Documents/Shared Playground Data folder of your computer from an iOS Playground:

    import UIKit
    import PlaygroundSupport
    
    do {
        let fileUrl = PlaygroundSupport.playgroundSharedDataDirectory.appendingPathComponent("Image.png")
        let data = try Data(contentsOf: fileUrl)
        let image = UIImage(data: data)
    } catch {
        print(error)
    }
    
    1. Select the .playground file.

    2. Open Utility inspector, In the playground press opt-cmd-1 to open the File Inspector. You should see the playground on the right. If you don’t have it selected, press cmd-1 to open the Project Navigator and click on the playground file.

    3. Under ‘Resource Path’ in Playground Settings choose ‘Relative To Playground’ and platform as OSX.

    On Mavericks with Xcode 6.0.1 you can read using iOS platform too.

    import UIKit
    let dirs : [String]? =    NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true) as? [String]
    let myDir = "/Shared Playground Data"
    
    let file = "README.md" // My change to your code - yours is presumably set off-screen
    if (dirs != nil) {
      let directories:[String] = dirs!;
      let dir = directories[0] + myDir; // iOS playground documents directory
      let path = dir.stringByAppendingPathComponent(file);
    
      //read
      let content = String.stringWithContentsOfFile(path, encoding: NSUTF8StringEncoding, error: nil)
      // works...
      println(content!)
    }
    

    Remember, you need to create a directory called "Shared Playground Data" in your Documents directory. Im my case I used this command: mkdir "/Users/joao_parana/Documents/Shared Playground Data" and put there my file README.md

    String.stringWithContentsOfFile is DEPRECATED and doesn’t work anymore with Xcode 6.1.1

    Create your documentDirectoryUrl

    let documentDirectoryUrl = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask).first! as NSURL
    

    To make sure the file is located there you can use the finder command Go To Folder e copy paste the printed documentDirectoryUrl.path there

    println(documentDirectoryUrl.path!)
    // should look like this: /Users/userName/Library/Containers/com.apple.dt.playground.stub.OSX.PLAYGROUNDFILENAME-5AF5B25D-D0D1-4B51-A297-00015EE97F13/Data/Documents
    

    Just append the file name to the folder url as a path component

    let fileNameUrl = documentDirectoryUrl.URLByAppendingPathComponent("ReadMe.txt")
    var fileOpenError:NSError?
    

    Check if the file exists before attempting to open it

    if NSFileManager.defaultManager().fileExistsAtPath(fileNameUrl.path!) {
    
        if let fileContent = String(contentsOfURL: fileNameUrl, encoding: NSUTF8StringEncoding, error: &fileOpenError) {
            println(fileContent)        // prints ReadMe.txt contents if successful
        } else {
            if let fileOpenError = fileOpenError {
                println(fileOpenError)  // Error Domain=NSCocoaErrorDomain Code=XXX "The file “ReadMe.txt” couldn’t be opened because...."
            }
        }
    } else {
        println("file not found")
    }