How can I read a file in a swift playground

后端 未结 9 1834
时光说笑
时光说笑 2020-12-12 22:37

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

let dirs : String[]? =    NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory         


        
相关标签:
9条回答
  • 2020-12-12 22:44

    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")
    }
    
    0 讨论(0)
  • 2020-12-12 22:46

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

    0 讨论(0)
  • 2020-12-12 22:49

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

    Update Swift 4.2

    As @raistlin points out, this would now be

    let dirs = NSSearchPathForDirectoriesInDomains(
                  FileManager.SearchPathDirectory.documentDirectory,
                  FileManager.SearchPathDomainMask.userDomainMask,
                  true)
    

    or, more tersely:

    let dirs = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                    .userDomainMask, true)
    
    0 讨论(0)
  • 2020-12-12 22:55

    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

    0 讨论(0)
  • 2020-12-12 22:55

    I was unable to read a file with ease in playground and ended up just creating a command line app in Xcode. This seemed to work for me very well.

    0 讨论(0)
  • 2020-12-12 22:59

    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")
    
    0 讨论(0)
提交回复
热议问题