Load image from app's documents folder (iOS 14 widget) - swift

I'd like to know if it's possible (and how!) to load a file saved in my main app's documents sandbox folder from a widget.
My main app (UIKit) saves images to FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]. as a .png. I have a function to load these images from my app but would like to know how to load them in my widget timeline.
Here's my code for loading the images in UIKit:
var documentsUrl: URL {
return FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first!
}
private func loadImage(fileName: String) -> UIImage? {
let fileURL = documentsUrl.appendingPathComponent(fileName)
do {
let imageData = try Data(contentsOf: fileURL)
return UIImage(data: imageData)
} catch {
print("Error loading image : \(error)")
}
return nil
}
I've got app groups working as I'm using UserDefaults between targets fine.
Thanks!

Related

Load GIF from documents directory and convert it to data

guard let imageData = try? Data(contentsOf: bundleURL) else {
print("Cannot turn image named \"\(gifNamed)\" into NSData")
return nil
}
I want to use GIF path in documents directory and extract the data from it not with bundleUrl but with GIF path in : file:///var/mobile/Containers/Data/Application/5615E8E1-F120-4171-A7CE-B2A9F2E8FC19/Documents/test.gif
If I understand correctly you want to get data from gif that is located in you app's Documents directory. Your code may look like that:
func getDataOf(gifNamed: String) -> Data? {
// Get url of Documents directory
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
guard let documentsDirectory = paths.first else { return nil }
// Get url of your gif
guard let gifURL = documentsDirectory.appendingPathComponent(gifNamed) else { return nil }
// Extract the data of your gif
var data: Data?
do {
data = try Data(contentsOf: bundleURL)
} catch {
print(error)
}
return data
}

Use Image in SwiftUI with either URL or Data without UIKit

I have downloaded an image in bytes (Data). I stored it with FileManager in the cache of the user's device. I was wondering if I could create an Image with either Data or a local URL, I am currently using UIImage but I want to support macOS.
Is there a full SwiftUI way of creating an Image with URL or Data without UIKit/UIImage?
if your question is about showing and image in macos, that you already have downloaded (and is in the cachesDirectory), then try something like this, to create an image from your image in bytes: (using NSImage for macos)
struct ContentView: View {
#State var img = NSImage()
var body: some View {
Image(nsImage: img)
.onAppear {
do {
// local file
let url = try FileManager.default
.url(for: .cachesDirectory, in: .userDomainMask, appropriateFor: nil, create: true)
.appendingPathComponent("kat") // <--- your file name here
.appendingPathExtension("png")
print("----> url: \(url)")
// even from the net
// let url = URL(string: "https://upload.wikimedia.org/wikipedia/commons/e/ef/Red-billed_gull%2C_Red_Zone%2C_Christchurch%2C_New_Zealand.jpg")!
if let nsimg = NSImage(contentsOf: url) { img = nsimg }
} catch {
print("\(error)")
}
}
}
}

how to download pdf file in iOS?

I am converting base64 to pdf file in local.
func saveBase64StringToPDF(_ base64String: String)
{
guard
var documentsURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last,
let convertedData = Data(base64Encoded: base64String)
else {
//handle error when getting documents URL
return
}
documentsURL.appendPathComponent("yourFileName.pdf")
do {
try convertedData.write(to: documentsURL)
} catch {
//handle write error here
}
print(documentsURL)
}
From above method I am getting a path pdf file
file:///Users/captivatesoft/Library/Developer/CoreSimulator/Devices/63D1814B-1010-4694-883E-D2EE75C386DD/data/Containers/Data/Application/1F39B567-F470-4B7E-9A9C-4723ADFDC428/Documents/yourFileName.pdf
Is there any way to download this pdf file or to show pdf in safari?
var pdfURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last! as URL
pdfURL = pdfURL.appendingPathComponent( "example.pdf") as URL
let data = try! Data(contentsOf: pdfURL)
let webView = WKWebView(frame: CGRect(x:20,y:20,width:view.frame.size.width-40, height:view.frame.size.height-40))
webView.load(data, mimeType: "application/pdf", characterEncodingName:"", baseURL: pdfURL.deletingLastPathComponent())
view.addSubview(webView)
To open the PDF in Safari you could just do
UIApplication.shared.openURL(URL(string: <the link for the PDF>))
Now to download a PDF or anything from a URL, you could just do
let pdfData = try? Data(contentsOf: URL(string: <the link for the PDF>))
NOTE: try Data(contentsOf: url) will block the thread, so you might want to do it on a different thread like this :
DispatchQueue.global.async { [weak self] in
if let pdfData = try? Data(contentsOf: url) {
// Now you can do anything with the data
}
}
First, you can not download pdf file in iOS, it means you cannot save pdf file in iBook or Album.
You can fetch pdf file data from file URL then you can do follows:
Open in Safari browser from the app.
You can show pdf file in WKWebView within the app.
You can use "QuickLook" framework to show the pdf file.
Using WebView:
if let url = URL(string:string) {
webView.load(URLRequest(url: url))
}

Unable to save images in the right directory

I am trying to save images in a directory. Images are correctly saved in the right place, but when I inspect these with the path in the finder, all the images are damaged and unsable.
damaged images
Below the static method:
static func writeImageFile(with data: Data, issue: Issue, page: Int, isThumbnail: Bool) throws -> URL {
let url = MediaFileManager.issueImagesDirectoryURL(issue: issue).ensuringDirectoryExists()
let imageURL = url.appendingPathComponent(imageName(for: page, isThumbnail: isThumbnail))
try data.write(to: imageURL)
return url
}
And the call in the class:
DispatchQueue.main.async {
guard let data = result.data else {
self.downloadDidFail(for: result.page)
return
}
do {
let writeImageFile = try MediaFileManager.writeImageFile(with: data, issue: self.issue, page: result.page, isThumbnail: false)
let writeThumbFile = try MediaFileManager.writeImageFile(with: data, issue: self.issue, page: result.page, isThumbnail: true)
print(writeImageFile)
print(writeThumbFile)
} catch let error as NSError {
print(error.localizedDescription)
}
}
I will assume, since you don't quite specify this, that you have a bunch of UIImage objects.
And I also noticed that you want your images to be saved as JPEG, which is no trouble at all, don't worry.
I would go with something like this:
if let image = UIImage(named: "example.png") {
if let data = UIImageJPEGRepresentation(image, 1.0) {
let filename = getDocumentsDirectory().appendingPathComponent("copy.png")
try? data.write(to: filename)
}
}
Where the func getDocumentsDirectory() is the following:
func getDocumentsDirectory() -> URL {
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return paths[0]
}
You might wonder why I used 1.0 for the second parameter in UIImageJPEGRepresentation, well that's the JPEG quality mapped between 0.0 and 1.0 (it's a float).
If you have any details that I am not aware of, please reply and I will try to help accordingly.
Hope it helps you, cheers!
Source: link
Have you tried to load the image to a UIImageView to see if the images are being properly downloaded? imageView.image = UIImage(data: data).
But I also detect that you're saving Data instead of the image, in order to make sure that you're saving an image I would try the following
static func writeImageFile(with data: Data, issue: Issue, page: Int, isThumbnail: Bool) throws -> URL {
let url = MediaFileManager.issueImagesDirectoryURL(issue: issue).ensuringDirectoryExists()
let imageURL = url.appendingPathComponent(imageName(for: page, isThumbnail: isThumbnail))
let image = UIImage(data: data)
let imgData = UIImageJPEGRepresentation(image, 1)
try imgData.write(to: imageURL)
return url
}
Yes, it might have unnecessary steps, worth trying, this way we're making sure that it's saved as Jpeg. But again, I would check if the images are being properly downloaded first.

Get images from Document Directory not file path Swift 3

This is how I saved the images
let format = DateFormatter()
format.dateFormat="MMMM-dd-yyyy-ss"
let currentFileName = "\(format.string(from: Date())).img"
print(currentFileName)
// Save Images
let fileMgr = FileManager.default
let dirPath = fileMgr.urls(for: .documentDirectory, in: .userDomainMask)[0]
let imageFileUrl = dirPath.appendingPathComponent(currentFileName)
do {
try UIImagePNGRepresentation(returnedImages)!.write(to: imageFileUrl)
print("Image Added Successfully")
} catch {
print(error)
}
Below is code I am using to retrieve images, But I am getting the URL instead of the image file to populate tableview. Any help would be appreciated
let fileManager = FileManager.default
let imageUrl = fileManager.urls(for: .documentDirectory, in: .userDomainMask) [0].appendingPathComponent("img")
print("Your Images:\(imageUrl)")
It's simply because your image's name is invalid. Use the debugger to find the exact value of imageUrl, I bet it's something like this .../Documents/img. What you want is more like .../Documents/Sep-04-2017-12.img
You'd have to store currentFileName in the view controller so you can reference it later.
Also, your naming strategy is pretty fragile. Many images can end up sharing one name.
If you have a folder full of images, you can iterate on that folder to get back the img files:
let fileManager = FileManager.default
let documentDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
let directoryContents = try! fileManager.contentsOfDirectory(at: documentDirectory, includingPropertiesForKeys: nil)
for imageURL in directoryContents where imageURL.pathExtension == "img" {
if let image = UIImage(contentsOfFile; imageURL.path) {
// now do something with your image
} else {
fatalError("Can't create image from file \(imageURL)")
}
}
Try using this
func getImage(){
let fileManager = FileManager.default
let imagePAth = (self.getDirectoryPath() as NSString).appendingPathComponent("apple.jpg") // saved image name apple.jpg
if fileManager.fileExists(atPath: imagePAth){
self.lockbackImageview.image = UIImage(contentsOfFile: imagePAth)
}else{
print("No Image")
self.lockbackImageview.image = UIImage.init(named: "1.jpg")
}
}