Reputation: 1105
I am trying to save and load images to and from the file directory, however my writeImageToPath
function prints the following error to the console and says the file does not exist.
Console
Write image to directory
File exists Write image
Error Write image to directory File does NOT exist -- file:///Users/user/Library/Developer/CoreSimulator/Devices/70EAC77D-9F3C-4AFC-8CCA-A7B9B895BDE6/data/Containers/Data/Application/DDAF2EBD-5DDA-4EA6-95D3-6785B74A0B09/Documents/upload/http://i.annihil.us/u/prod/marvel/i/mg/a/f0/5202887448860 -- is available for use Write image Error Writing Image: Error Domain=NSCocoaErrorDomain Code=4 "The file “5202887448860” doesn’t exist." UserInfo={NSFilePath=/Users/user/Library/Developer/CoreSimulator/Devices/70EAC77D-9F3C-4AFC-8CCA-A7B9B895BDE6/data/Containers/Data/Application/DDAF2EBD-5DDA-4EA6-95D3-6785B74A0B09/Documents/upload/http://i.annihil.us/u/prod/marvel/i/mg/a/f0/5202887448860, NSUnderlyingError=0x600003b04ab0 {Error Domain=NSPOSIXErrorDomain Code=2 "No such file or directory"}}
Here's my code, I am not sure where I am going wrong
// The images are loaded from the web and displayed in the cell.imageView.image
if let thumbnail = product["thumbnail"] as? [String: Any],
let path = thumbnail["path"] as? String,
let fileExtension = thumbnail["extension"] as? String {
//Save image to directory
if image != nil {
writeImageToPath(path, image: image!)
}
}
// Write image to directory
func writeImageToPath(_ path: String, image: UIImage) {
print("Write image to directory")
let uploadURL = URL.createFolder(folderName: "upload")!.appendingPathComponent(path)
if !FileManager.default.fileExists(atPath: uploadURL.path) {
print("File does NOT exist -- \(uploadURL) -- is available for use")
let uploadURL = URL.createFolder(folderName: "upload")!.appendingPathComponent(path)
if let data = UIImageJPEGRepresentation(image, 0.9) {
do {
print("Write image")
try data.write(to: uploadURL)
}
catch {
print("Error Writing Image: \(error)")
}
} else {
print("Image is nil")
}
} else {
print("This file exists -- something is already placed at this location")
}
}
// load image from directory
func loadImageFromPath(_ path: String) -> UIImage? {
let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let folderURL = documentsURL.appendingPathComponent("upload")
let fileURL = folderURL.appendingPathComponent(path)
if FileManager.default.fileExists(atPath: fileURL.path) {
//Get Image And upload in server
print("fileURL.path \(fileURL.path)")
do{
let data = try Data.init(contentsOf: fileURL)
let image = UIImage(data: data)
return image
}catch{
print("error getting image")
}
} else {
print("No image in directory")
}
return nil
}
extension URL {
static func createFolder(folderName: String) -> URL? {
let fileManager = FileManager.default
// Get document directory for device, this should succeed
if let documentDirectory = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first {
// Construct a URL with desired folder name
let folderURL = documentDirectory.appendingPathComponent(folderName)
// If folder URL does not exist, create it
if !fileManager.fileExists(atPath: folderURL.path) {
do {
// Attempt to create folder
try fileManager.createDirectory(atPath: folderURL.path,
withIntermediateDirectories: true,
attributes: nil)
} catch {
// Creation failed. Print error & return nil
print(error.localizedDescription)
return nil
}
}
// Folder either exists, or was created. Return URL
return folderURL
}
// Will only be called if document directory not found
return nil
}
}
How can I correctly save and load images from the directory ?
Upvotes: 0
Views: 11025
Reputation: 707
The path name is wrong to replace this function call with the correct path name
writeImageToPath("http://i.annihil.us/u/prod/marvel/i/mg/b/70/4c0035adc7d3a", image: image)
To
writeImageToPath("4c0035adc7d3a", image: image)
Upvotes: 0
Reputation: 4015
Below is how I save images to a folder named "Screenshots". I tried to keep it as clear as I could.
func saveImageToDocumentDirectory(image: UIImage) {
var objCBool: ObjCBool = true
let mainPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
let folderPath = mainPath + "/Screenshots/"
let isExist = FileManager.default.fileExists(atPath: folderPath, isDirectory: &objCBool)
if !isExist {
do {
try FileManager.default.createDirectory(atPath: folderPath, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error)
}
}
let documentDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
let imageName = "\(fileName).png"
let imageUrl = documentDirectory.appendingPathComponent("Screenshots/\(imageName)")
if let data = image.jpegData(compressionQuality: 1.0){
do {
try data.write(to: imageUrl)
} catch {
print("error saving", error)
}
}
}
This is how I load images stored in the folder
func loadImageFromDocumentDirectory(nameOfImage : String) -> UIImage {
let nsDocumentDirectory = FileManager.SearchPathDirectory.documentDirectory
let nsUserDomainMask = FileManager.SearchPathDomainMask.userDomainMask
let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
if let dirPath = paths.first{
let imageURL = URL(fileURLWithPath: dirPath).appendingPathComponent("Screenshots/\(nameOfImage)")
guard let image = UIImage(contentsOfFile: imageURL.path) else { return UIImage.init(named: "fulcrumPlaceholder")!}
return image
}
return UIImage.init(named: "imageDefaultPlaceholder")!
}
Upvotes: 2
Reputation: 1873
class MyImageClass {
func writeImageToPath(_ path:String, image:UIImage) {
let uploadURL = URL.createFolder(folderName: "upload")!.appendingPathComponent(path)
if !FileManager.default.fileExists(atPath: uploadURL.path) {
print("File does NOT exist -- \(uploadURL) -- is available for use")
let data = image.jpegData(compressionQuality: 0.9)
do {
print("Write image")
try data!.write(to: uploadURL)
}
catch {
print("Error Writing Image: \(error)")
}
}
else {
print("This file exists -- something is already placed at this location")
}
}
}
extension URL {
static func createFolder(folderName: String) -> URL? {
let fileManager = FileManager.default
// Get document directory for device, this should succeed
if let documentDirectory = fileManager.urls(for: .documentDirectory,
in: .userDomainMask).first {
// Construct a URL with desired folder name
let folderURL = documentDirectory.appendingPathComponent(folderName)
// If folder URL does not exist, create it
if !fileManager.fileExists(atPath: folderURL.path) {
do {
// Attempt to create folder
try fileManager.createDirectory(atPath: folderURL.path,
withIntermediateDirectories: true,
attributes: nil)
} catch {
// Creation failed. Print error & return nil
print(error.localizedDescription)
return nil
}
}
// Folder either exists, or was created. Return URL
return folderURL
}
// Will only be called if document directory not found
return nil
}
}
var saving = MyImageClass()
saving.writeImageToPath("whereIWantToSaveTheImageTo", image: UIImage(named: "myImage"))
Reference Create Directory in Swift 3.0
I didn't test if the imaging worked, however, this does create a folder called "Upload" and you can call it every time. The extension has a method called createFolder
that returns a folder for whatever you call and creates it if it is not already there. We can just check for the specified path within the folder, then if it is available, we can write to it. I also only rewrote the writeImageToPath
portion.
NOTE:
Tested this in playground...
Results were:
File does NOT exist -- file:///var/folders/vs/nlj__xh93vs0f8wzcgksh_zh0000gn/T/com.apple.dt.Xcode.pg/containers/com.apple.dt.playground.stub.iOS_Simulator.MyPlayground-67A67A07-51FF-4DF4-BE80-02E7FDAFA1CA/Documents/upload/whereIWantToSaveTheImageTo -- is available for use
Write image
Upvotes: 2