P-Rod
P-Rod

Reputation: 471

xCode playground and writing files to Documents

I'm trying to test some sqlite database calls through XCode's playground. I start with a database in my Playground's Resources folder and try to move it to the Playgrounds Documents folder, however what happens is that a symbolic link is generated pointing back to the file within the Resources folder so I am unable to write to that file. However, If I figure out where the Documents folder is and then copy the file there by hand from the terminal everything works just fine.

So why does the file manager copy command actually create a sym link to rather than copy? And is there any way to actually make this happen? It seems to only be a problem with the Playground. copy from Resource to Documents works fine in the app itself.

some code to test within the playground...

let dirPaths =     NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask, true)
let docsDir = dirPaths[0]
let destPath = (docsDir as NSString).appendingPathComponent("/data.sqlite")
print(destPath)

let fileMgr = FileManager.default


let srcPath = Bundle.main.path(forResource: "data", ofType:"sqlite")
// This copies the data.sqlite file from Resources to Documents
//    ** However in the playground, only a symlink is generated
do {
    try fileMgr.copyItem(atPath: srcPath!, toPath: destPath)
} catch let error {
    print("Error (during copy): \(error.localizedDescription)")
}

Upvotes: 0

Views: 573

Answers (1)

Takeshi Kajino
Takeshi Kajino

Reputation: 21

Rod, It's too late but, I figure this out.

Context:

  • I add one playground to my project in the same workspace
  • To make the playground works with my project, I create a framework
  • I added the Store.db file to the framework target
  • I haven't added the Store.db to the Playground as a Resource
  • Swift 3

Playground

@testable import MyAppAsFramework

func copyMockDBToDocumentsFolder(dbPath: String) {
    let localDBName = "Store.db"
    let documentPath = dbPath / localDBName
    let dbFile = Bundle(for: MyAppAsFrameworkSomeClass.self).path(forResource: localDBName.deletingPathExtension, ofType: localDBName.pathExtension)

    FileManager.copyFile(dbFile, toFolderPath: documentPath)
}

copyMockDBToDocumentsFolder(dbPath: "The documents path")

Things like / copyFile(x) and the others are operator overloads and extensions

extension String {

    public var pathExtension: String {
        get {
            return (self as NSString).pathExtension
        }
    }

    public var deletingPathExtension: String {
        get {
            return (self as NSString).deletingPathExtension
        }
    }

    public func appendingPath(_ path: String) -> String {
        let nsSt = self as NSString
        return nsSt.appendingPathComponent(path)
    }

}


infix operator / : MultiplicationPrecedence

public func / (left: String, right: String) -> String {
    return left.appendingPath(right)
}


extension FileManager { 

    class func copyFile(_ filePath: String?, toFolderPath: String?) -> Bool {

        guard let file = filePath else { return false }
        guard let toFolder = toFolderPath else { return false }

        var posibleError: NSError?

        do {
            try FileManager.default.copyItem(atPath: file, toPath:toFolder)
        } catch let error as NSError {
            posibleError = error
            print("CAN'T COPY \(error.localizedDescription)")
        }

        return posibleError == nil
    }

}

Upvotes: 1

Related Questions