简体   繁体   中英

Can`t copy file from bundle to documents directory in iOS

I am trying to copy a file from my bundle to the documents directory in iOS with the following code.

let bundlePath = NSBundle.mainBundle().pathForResource("information", ofType: ".png")
print(bundlePath, "\n") //prints the correct path
let destPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
let fileManager = NSFileManager.defaultManager()
let fullDestPath = NSURL(fileURLWithPath: destPath).URLByAppendingPathComponent("information.png")
let fullDestPathString = String(fullDestPath)
print(fileManager.fileExistsAtPath(bundlePath!)) // prints true

do{
try fileManager.copyItemAtPath(bundlePath!, toPath: fullDestPathString)
}catch{
    print("\n")
    print(error)
}

Error Domain=NSCocoaErrorDomain Code=4 "The file “information.png” doesn't exist." UserInfo={NSSourceFilePathErrorKey=/Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Bundle/Application/EFA83E02-5F24-4BB3-B32A-7E755081A730/AutoLayout tuts.app/information.png, NSUserStringVariant=( Copy ), NSDestinationFilePath=file:///Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Data/Application/86A1BDD5-FAF2-486E-85A9-CF72A547C6CD/Documents/information.png, NSFilePath=/Users/macbookpro/Library/Developer/CoreSimulator/Devices/E58CA1C6-C6F1-4D72-9572-3925675E78A5/data/Containers/Bundle/Application/EFA83E02-5F24-4BB3-B32A-7E755081A730/AutoLayout tuts.app/information.png, NSUnderlyingError=0x7fb53251cd80 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}

According to the fileManager.fileExistsAtPath() the file does indeed exist. What am I doing wrong?

The problem is this line:

let fullDestPathString = String(fullDestPath)

It should be:

let fullDestPathString = fullDestPath.path

Look at the error. The problem is the destination. Notice the file:/// . Your code is not properly converting the URL to a file path. You need to use the path property of NSURL to get the path as a string.

In all of your debugging and checking, you never verified the value of fullDestPathString .

Swift 3

func copyfileToDocs()
    {
        let bundlePath = Bundle.main.path(forResource: "db", ofType: ".sqlite")
        print(bundlePath!, "\n") //prints the correct path
        let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let fileManager = FileManager.default
        let fullDestPath = NSURL(fileURLWithPath: destPath).appendingPathComponent("db.sqlite")
        let fullDestPathString = fullDestPath?.path
        print(fileManager.fileExists(atPath: bundlePath!)) // prints true
        do
        {
            try fileManager.copyItem(atPath: bundlePath!, toPath: fullDestPathString!)
            print("DB Copied")
        }
        catch
        {
            print("\n")
            print(error)
        }
    }

Swift 4

Misleading in some answers:

print(fileManager.fileExists(atPath: bundlePath!))

hence proposing this extension version:

extension FileManager {
    func copyfileToUserDocumentDirectory(forResource name: String,
                                         ofType ext: String) throws
    {
        if let bundlePath = Bundle.main.path(forResource: name, ofType: ext),
            let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,
                                .userDomainMask,
                                true).first {
            let fileName = "\(name).\(ext)"
            let fullDestPath = URL(fileURLWithPath: destPath)
                                   .appendingPathComponent(fileName)
            let fullDestPathString = fullDestPath.path

            if !self.fileExists(atPath: fullDestPathString) {
                try self.copyItem(atPath: bundlePath, toPath: fullDestPathString)
            }
        }
    }
}

Usage

try fileManager.copyfileToUserDocumentDirectory(forResource: "information",
                                                ofType: "png")
...

Please find Code Below.i have taken reference from @rmaddy's answer.

func CheckDataBaseOnPathorNot() -> Void {
        let bundlePath = Bundle.main.path(forResource: "Project_Expert", ofType: ".db")
        print(bundlePath ?? "", "\n") //prints the correct path
        let destPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).first!
        let fileManager = FileManager.default
        let fullDestPath = NSURL(fileURLWithPath: destPath).appendingPathComponent("Project_Expert.db")
        let fullDestPathString = fullDestPath!.path
        print(fileManager.fileExists(atPath: bundlePath!)) // prints true
        if fileManager.fileExists(atPath: fullDestPathString) {
            print("File is available")
        }else{
            do{
                try fileManager.copyItem(atPath: bundlePath!, toPath: fullDestPathString)
            }catch{
                print("\n")
                print(error)

            }
        }

    }

Check this code for if the file is not available on the path, then copy the file.

Thank you.

to get the string path you should use this

let path = fullDestPath.path

On side note

fileManager.fileExistsAtPath(bundlePath!) == true 

is the way to check if the value if true

fileManager.fileExistsAtPath(bundlePath!)

just this can have some problems

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM