How to Load an Image from Documents Directory on MACos Swift

How to load an image from documents directory on macOS Swift?

First click on your app target > signing & capabilities and remove the App Sandbox as shown in the following picture:

Sample Image

Now you can access files that are not located inside your app bundle.

struct ContentView: View {
let image = NSImage(contentsOf: URL(fileURLWithPath: "/Users/codegrinder/Documents/turtlerock.jpg"))!
var body: some View {
Image(nsImage: image)
.frame(maxWidth: .infinity, maxHeight: .infinity, alignment:.center)
}
}

Loading an Image from documents directory

You should use [NSURL fileURLWithPath:imgPath] instead of [NSURL URLWithString:imgPath]. Image path is not a valid url, it needs a file:// prefix.

Get image from documents directory swift

You are finding the document directory path at runtime for writing the image, for reading it back, you can use the exact logic:

Swift 3 and Swift 4.2

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("Image2.png")
let image = UIImage(contentsOfFile: imageURL.path)
// Do whatever you want with the image
}

Swift 2

let nsDocumentDirectory = NSSearchPathDirectory.DocumentDirectory
let nsUserDomainMask = NSSearchPathDomainMask.UserDomainMask
if let paths = NSSearchPathForDirectoriesInDomains(nsDocumentDirectory, nsUserDomainMask, true)
{
if paths.count > 0
{
if let dirPath = paths[0] as? String
{
let readPath = dirPath.stringByAppendingPathComponent("Image2.png")
let image = UIImage(contentsOfFile: readPath)
// Do whatever you want with the image
}
}
}

How do I load this image data from disk and present it in my SwiftUI List?

Try the following

VStack(alignment: .leading, spacing: 10) {
//Populate text with info from notification.
Text(notification.content.title)

if let image = loadImageFromDiskWith(fileName: notification.identifier) {
Image(uiImage: image)
.resizable()
.scaledToFit()
} else {
// Put some placeholder image here
}
}

How to display an image from documents directory to UIImageView in Swift 3?

Apple is trying to move everyone off the path-as-string paradigm to URL (i.e. file:///path/to/file.text). The Swift API pretty much removes all path in favor of URL.

You can still find it in Objective-C (NSString):

let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let getImagePath = NSString.path(withComponents: [paths, "fileName"])

The more Swifty way:

let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let url = URL(fileURLWithPath: paths).appendingPathComponent("fileName")

Can not load images from `Documents` directory on device

Solved

For some reason, images in Documents weren't accessible this way with loading html from string. I needed to create a html file in Documents folder to be able to read images from that folder.

So, html and images(resources) need to be in the same folder.

Code that didn't work:

webView.loadHTMLString(html, baseURL: URL(fileURLWithPath: Bundle.main.bundlePath))
//html is a string.

Code that works:

 let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let documentsDirectory = paths[0]
let filename = documentsDirectory.appendingPathComponent("index.html")

do {
//html is a string
try html.write(to: filename, atomically: true, encoding: String.Encoding.utf8)
} catch {
//...
}
webView.loadFileURL(filename, allowingReadAccessTo: documentsDirectory)

how to use writeToFile to save image in document directory?

The problem there is that you are checking if the folder not exists but you should check if the file exists. Another issue in your code is that you need to use url.path instead of url.absoluteString. You are also saving a jpeg image using a "png" file extension. You should use "jpg".

edit/update:

Swift 4.2 or later

do {
// get the documents directory url
let documentsDirectory = try FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
print("documentsDirectory:", documentsDirectory.path)
// choose a name for your image
let fileName = "image.jpg"
// create the destination file url to save your image
let fileURL = documentsDirectory.appendingPathComponent(fileName)
// get your UIImage jpeg data representation and check if the destination file url already exists
if let data = image.jpegData(compressionQuality: 1),
!FileManager.default.fileExists(atPath: fileURL.path) {
// writes the image data to disk
try data.write(to: fileURL)
print("file saved")
}
} catch {
print("error:", error)
}

To write the image at the destination regardless if the image already exists or not you can use .atomic options, if you would like to avoid overwriting an existing image you can use withoutOverwriting instead:

try data.write(to: fileURL, options: [.atomic])


Related Topics



Leave a reply



Submit