How can I read a file in a swift playground

Solution 1:

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).

Solution 2:

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/UserName/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

let path = XCPlaygroundSharedDataDirectoryURL.appendingPathComponent("foo.txt")

The official documentation can be found here: XCPlayground Module Reference

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


UPDATE: For swift 4.2 use playgroundSharedDataDirectory. Don't need to import anything. Looks like:

let path = playgroundSharedDataDirectory.appendingPathComponent("file")

Solution 3:

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)
}

Solution 4:

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.")
}