33

I am saving files in a document directory in swift 3 with this code:

fileManager = FileManager.default
// let documentDirectory = fileManager?.urls(for: .documentDirectory, in: .userDomainMask).first as String
var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
path = path + name

let image = #imageLiteral(resourceName: "Notifications")
let imageData = UIImageJPEGRepresentation(image, 0.5)
let bool = fileManager?.createFile(atPath: path, contents: imageData, attributes: nil)

print("bool is \(bool)")
return true

But as you can see, I am not using filemanager to get document directory path as filemanager gives only URL not string.

Questions:

  • How to get string from file manager?
  • Is there any chance of crash in my code?
Honey
  • 24,125
  • 14
  • 123
  • 212
TechChain
  • 7,104
  • 20
  • 81
  • 193
  • `let fileManager = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first?.path` – Willjay Jun 20 '17 at 07:26

4 Answers4

89

Please think the other way round.

URL is the recommended way to handle file paths because it contains all convenience methods for appending and deleting path components and extensions – rather than String which Apple has removed those methods from.

You are discouraged from concatenating paths like path = path + name. It's error-prone because you are responsible for all slash path separators.

Further you don't need to create a file with FileManager. Data has a method to write data to disk.

let fileManager = FileManager.default
do {
    let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:false)
    let fileURL = documentDirectory.appendingPathComponent(name)
    let image = #imageLiteral(resourceName: "Notifications")
    if let imageData = image.jpegData(compressionQuality: 0.5) {
        try imageData.write(to: fileURL)
        return true
    }
} catch {
    print(error)
}
return false
vadian
  • 232,468
  • 27
  • 273
  • 287
4

following the above example given by vadian the only line you need to save a (Data)file in Document Directory is:

try imageData.write(to: fileURL)

Getting the file path is the interesting part

ex: create the file path

 func createNewDirPath( )->URL{ 

let dirPathNoScheme = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String

    //add directory path file Scheme;  some operations fail w/out it
    let dirPath = "file://\(dirPathNoScheme)"
    //name your file, make sure you get the ext right .mp3/.wav/.m4a/.mov/.whatever
    let fileName = "thisIsYourFileName.mov"
    let pathArray = [dirPath, fileName]
    let path = URL(string: pathArray.joined(separator: "/"))

    //use a guard since the result is an optional
    guard let filePath = path else {
        //if it fails do this stuff:
        return URL(string: "choose how to handle error here")!
    }
    //if it works return the filePath
    return filePath
}

call the function:

let shinnyNewURLpath = createNewDirPath( ) 


//write data to file using one line in do/catch operation
do {
   try yourDataObject?.write(to: shinnyNewURLpath)
    } 
catch {
       print("catch error",error.localizedDescription)
 }
subCipher
  • 61
  • 3
4

I use the following method for creating "Test.txt" file. Hope it helps you.

func createFile() {
    let fileName = "Test"
    let documentDirURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
    let fileURL = documentDirURL.appendingPathComponent(fileName).appendingPathExtension("txt")
    print("File PAth: \(fileURL.path)")
}
LinusGeffarth
  • 21,607
  • 24
  • 100
  • 152
Mahyar
  • 735
  • 6
  • 12
-13
func copyandpaste() {
   var path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)
   let dbpath: NSString = path[0] as NSString
        
   let strdbpath =  dbpath.strings(byAppendingPaths: ["mydb.db"])[0]
   print(strdbpath)
   let fmnager  =  FileManager.default
        
   if !fmnager.fileExists(atPath: strdbpath) {
      let local  = Bundle.main.path(forResource: "mydb", ofType: "db")
      do {
         try fmnager.copyItem(atPath: local!, toPath: strdbpath)
      } catch {
      }
   }        
}
koen
  • 4,535
  • 6
  • 38
  • 77
Neeraj IOS
  • 37
  • 4