Issue with loading file from disk - swift

Ok so this one has had me scratching my head for a while.
I have a png file that I write out to disk. I get the data by:
let data = UIImagePNGRepresentation(scaledImage!)
let filename = getDocumentsDirectory().appendingPathComponent("\(record.uid!).png")
I do a try catch and everything seems to work. The resulting filename is:
file:///var/mobile/Containers/Data/Application/C6B796E8-2DB6-45A4-9B18-EF808B8CA3CA/Documents/580420d51800cd826a7e217c.png
The problem comes when I try to load that image back from the disk.
When I get a list of all files in the documents directory I get:
[file:///private/var/mobile/Containers/Data/Application/C6B796E8-2DB6-45A4-9B18-EF808B8CA3CA/Documents/580420d51800cd826a7e217c.png]
The only difference I can see is the 'private' part of the filepath. When I try to check to see if the file exists using the filepath I get back from appending the filename (the one without the private part) I get false.
What am I missing?

Swift 3/4 code
Let us assume the method getDocumentsDirectory() is defined as follows
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
return documentsDirectory
}
In order to save the image
let data = UIImagePNGRepresentation(scaledImage!)
let filename = getDocumentsDirectory().appendingPathComponent("\(record.uid!).png")
try? data?.write(to: filename)
And your image is saved in Documents Directory
Now in order to load it back
let imagePath = getDocumentsDirectory().appendingPathComponent("\(record.uid!).png").path
let fileManager = FileManager.default
if fileManager.fileExists(atPath: imagePath){
print("Image Present")
//load it in some imageView
}else {
print("No Image")
}

Related

Swift deleting file from folder in documents directory

I appreciate some assistance. I created a folder inside my documents directory named "MyPhotos". I added three image files to the folder. No issues.
Next I'm attempting to construct some code that will delete the files when needed but can't get it right. I can append the MyPhotos folder to the search path but can't subsequently append the file name to the path after multiple tries. tempPhotoTitle is a variable. Thank you for helping.
let fileManager = FileManager.default
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory,.userDomainMask,true)[0] as NSString
let destinationPath = documentsPath.appendingPathComponent("MyPhotos")
let finalPath = destinationPath.appending(tempPhotoTitle)
do {
try fileManager.removeItem(atPath: finalPath)
}
catch {
print(error)
}
The issue there is that you are working with strings (paths) and not adding the slash. I recommend always working with URLs this way you dont need to worry about adding the slash to your path.
do {
let tempPhotoTitle = "filename.jpg"
let documents = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
let photos = documents.appendingPathComponent("MyPhotos")
let fileURL = photos.appendingPathComponent(tempPhotoTitle)
try FileManager.default.removeItem(at: fileURL)
} catch {
print(error)
}
Leo Dabus's answer of working with URLs is the better one. However, it's worth mentioning that when working with Strings, if you bridge to NSString again, appendingPathComponent is available:
let finalPath = (destinationPath as NSString).appendingPathComponent(tempPhotoTitle)

swift save file after download Alamofire

download and save file
let destination: DownloadRequest.DownloadFileDestination = { _, _ in
// var fileURL = self.createFolder(folderName: downloadFolderName)
var fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let fileName = URL(string : currentFile.link )
fileURL = fileURL.appendingPathComponent((fileName?.lastPathComponent)!)
return (fileURL, [.removePreviousFile, .createIntermediateDirectories])
}
Alamofire.download(currentDownloadedFile.link , to: destination).response(completionHandler: { (DefaultDownloadResponse) in
print("res ",DefaultDownloadResponse.destinationURL!);
completion(true)
})
but when i wont to check file in this dirrectory i get nil
let filemanager:FileManager = FileManager()
let fileURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
let files = filemanager.enumerator(atPath: fileURL.absoluteString) // = nil
while let file = files?.nextObject() {
print(file)
}
if i save local path to file and after reload app wont to share it -> "share" app cant send file (mb cant found it)
can u pls help me. how it works ? why when i print all files he didnt find it? how to save file who after reboot app it will be saved in same link
You are using the wrong API
For file system URLs use always path, absoluteString returns the full string including the scheme (e. g. file:// or http://)
let files = filemanager.enumerator(atPath: fileURL.path)

How to save video data to document directory in swift?

I want to save video data to document directory.
I know how to create document directory my folder.
But how to save data that document directory??
let fileManager = FileManager.default
if let tDocumentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask).first {
let filePath = tDocumentDirectory.appendingPathComponent("\(FOLDER_NAME)")
if !fileManager.fileExists(atPath: filePath.path) {
do {
try fileManager.createDirectory(atPath: filePath.path, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Couldn't create document directory")
}
}
print("Document directory is \(filePath)")
}
Now, I have (FOLDER_NAME) folder. But How to save video data to (FOLDER_NAME) folder??
And How to I get saved video file path?
I apologize for my stupidity.
In your Info.plist, add the following permissions:
Supports opening documents in place: YES
Application supports iTunes file sharing: YES
let videoFilename = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] + "/" + getFileName() //return your filename from the getFileName function
videoNSData.write(toFile: videoFilename, atomically: true)
Then, inside Files, you can get a folder named with your app name, where you can access your saved video file (with the specified filename).

In Swift 3, how to display images from link to local file directory in tableviewcell

I want to save images in local file not on server and displays those images in UItableviewcell via link to that file\folder.
I am not sure what path i used to save in database. I am saving imagefolder in desktop.But that path: /desktop/imagefolder/image.jpg not working.
iOS apps have access only to sandbox , that mean you write only in the folder Document , Temp and Library . See the documentation.
Here an exemple how to write and read an image in documents directory.
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = "\(documentsDirectory)/image.png"
let image = UIImage(contentsOfFile: path)
And now how to save:
let image = ...
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
let path = "\(documentsDirectory)/image.png"
if let data = UIImagePNGRepresentation(image!) {
try? data.write(to: URL(fileURLWithPath: path))
}

Issue setting UIImageView from local image in documents directory

I am trying to load images that I have downloaded using Alamofire to the documents directory. I store the filenames in a Realm database. Once it is time to display the image I take the path to the documents directory and append the filename. This path doesn't seem to work for building a UIImage though.
if let name = playlist.RLMsongs[indexPath.row].name, let imageURL = playlist.RLMsongs[indexPath.row].album?.image?.getImageURL(.SmallImage), let fileName = playlist.RLMsongs[indexPath.row].album?.image?.smallLocalFileName {
cell.songName.text = name
let range = imageURL.rangeOfString("http")
if let theRange = range where theRange.startIndex == imageURL.startIndex { // imageURL starts with "http" (remote url)
cell.albumImage.sd_setImageWithURL(NSURL(string: imageURL), placeholderImage: UIColor.imageFromColor(UIColor.grayColor())) {
_ in
cell.albumImage.fadeIn(completion: nil)
}
} else {
cell.albumImage.image = UIImage(named: fileName) // images still do not load
// tried this first -> cell.albumImage.sd_setImageWithURL(NSURL(fileURLWithPath: imageURL), placeholderImage: UIColor.imageFromColor(UIColor.grayColor()))
}
}
Here is the bit that builds the path (imageURL above):
let documentsDir = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0]
let path = documentsDir.URLByAppendingPathComponent(localFile).path
return path
As per TiM's recommendation I checked the value of imageURL on a breakpoint and it looks just fine:
imageURL: "/Users/danielnall/Library/Developer/CoreSimulator/Devices/0B8D64B5-9593-4F86-BBD3-E408682C5C0F/data/Containers/Data/Application/011E4805-40EB-4221-9D7D-1C1D64660186/Documents/75.9226ecd6893cb01a306c974d9d8ffd62803109c1.png"
This is the full path on the simulator and is only missing the file schema (file://) which for the use of NSURL fileURLWithPath should be just fine I think.
If you already have the PNG file in Documents then all you need to do is this.
(Assuming that cell.albumImage is UIImageView)
let imageFileName = "75.9226ecd6893cb01a306c974d9d8ffd62803109c1.png"
cell.albumImage.image = UIImage(named: imageFileName)
Check if file exists:
func fileExists(filePath: String) -> Bool {
let filemanager = NSFileManager.defaultManager()
if filemanager.fileExistsAtPath(filePath) {
return true
}
return false
}
I ended up finding the solution to the problem which was unrelated to the direction of this question. Turned out that the issue was in my override of the prepareForReuse method in my UITableViewCell class. Thank you for everyone's suggestions though.