How do I use a converted jpgData image in SwiftUI? - ios

When the user selects an item from their photo library, the app saves the UIImage to the app's directory using the following code:
let imageUUID = UUID()
let filename = getDocumentsDirectory().appendingPathComponent("\(imageUUID)")
guard let uiImage = newImage else { return}
if let jpegData = uiImage.jpegData(compressionQuality: 0.8) {
try? jpegData.write(to: filename, options: [.atomicWrite, .completeFileProtection])
}
How can I use the saved image in a view?
Thanks!

First, you should save the UUID somewhere so that you can read the file later. This could be in UserDefaults, a JSON file, CoreData, or whatever, depending on your needs.
Suppose you have the path to the file stored in filePath, you can create an Image like this:
Image(uiImage: UIImage(contentsOfFile: filePath) ?? UIImage())
This will use an empty image as fallback if it failed to read the file.

Following code convert UIImage to Image in SwiftUI:
let uiImage = UIImage(contentsOfFile: path) ?? UIImage() // Access it from your storage
let image = Image(uiImage: uiImage)
There are different UIImage initializer methods available, you can use any one of them to get UIImage instance.
https://developer.apple.com/documentation/swiftui/image
You will like this tutorial of Coredata with SwiftUI: https://www.raywenderlich.com/9335365-core-data-with-swiftui-tutorial-getting-started

Related

How to retrieve data from firebase storage

Hey I am trying to retrieve the user image saved in the firebase storage but I am using this storage path (the folder of profile pictures in firebase) as a string(child path) to update the user image. When the user profile updates there are no errors this code just didn't update the user image as I expected what am I missing here that will allow me to successfully my user image and solve my problem ?
var spaceRef = Storage.storage().reference()
let storagePath = "gs://tunnel-vision-bc055.appspot.com/images/space.jpg"
spaceRef = Storage.storage().reference(forURL: storagePath)
let reference = spaceRef.child("profilePic")
// UIImageView in your ViewController
let imageView: UIImageView = self.ProfileImage
// Placeholder image
let placeholderImage = UIImage(named: "image/jpeg")
// Load the image using SDWebImage
imageView.sd_setImage(with: reference, placeholderImage: placeholderImage)
// Uh-oh, an error occurred!
return
}
This will not be the answer to all your issues, but hopefully some of them.
First of all, in Swift, variables and constants starts with a lowercase letter. Classes with uppercase. For example, your ProfileImage should be profileImage. For clarity, when I type profileImage I refer to your ProfileImage.
Now, types. You have a constant profileImage in the code you posted. This is of type String. You set the value of the key "ProfileImageUrl" to it. I would change it's name to profileImageURL.
Then (according to one of your comments) you are calling self.profileImage
let imageView: UIImageView = self.profileImage
Since you're not seeing any errors I assume you also have a class property called profileImage of type UIImageView.
The line
// let user = User(ProfileImage: ProfileImage)
will not help you. As far as I understand from the code you posted - and what you are trying to achieve - you may as well delete it. Or comment it (//) as I did above.
What you want to do is to set an imageView's image.
For this you need to do
imageView.image = image
And to be able to do that you need an imageView and an image. If you don't know how to create an imageView, search for answers here on SO.
You can then create the image from the url you get from Firebase and set it to the imageView. Kind of like this
let profileImageURL = value?["ProfileImageUrl"] as? String ?? ""
let url = URL(string: profileImageURL)
DispatchQueue.global().async {
guard let data = Data(contentsOf: url) else {return} // if url is nil, return block is executed and code below is not
DispatchQueue.main.async {
self.imageView.image = UIImage(data: data)
}
}

Displaying image in Swift

There are many examples on how to use imageWithContentsOfFile in object-c, but how do I use it in Swift. imageView.image = UIImage(imageWithContentsOfFile: imageName)
returns Argument labels '(imageWithContentsOfFile:)' do not match any available overloads
while if I write: imageView.image = UIImage(contentsOfFile:imageName)
It doesn't display the image.
(I have all images stores in Media.xcassets)
I am displaying a lot of images so using UIImage(named:imageName) isn't a viable option. How can I get the functionality of contentsOfFile in swift?
Swift code:
func getImage (named name : String) -> UIImage?
{
if let imgPath = Bundle.main.path(forResource: name, ofType: ".png")
{
return UIImage(contentsOfFile: imgPath)
}
return nil
}
//Image name "MyImage.png"
getImage(named: "MyImage")!

get the URL for NSData saved in CoreData

I'm saving a UIImage to Core Data. So first, I convert it to NSData, then save it.
I need to get the URL for the image after it's saved. I'm doing this because I want to schedule a local notification with an attachment, and the only way to do it, AFAIK, is to with a URL.
Here is my code:
//my image:
var myImage: UIImage?
var imageData: NSData?
if let image = myImage {
imageData = UIImageJPEGRepresentation(image, 0.5)! as NSData
}
myEntity.setValue(imageData, forKey: "image")
And that's how I should add an attachment to the notification:
UNNotificationAttachment.init(identifier: String, url: URL>, options: [AnyHashable : Any]?)
I'm saving the image and scheduling the notification manually when the user taps on a button to save the image.
Please let me know if you need extra info.
You can't get the URL. If you configured this property to use external storage then yes, technically there could be a file URL. Maybe. But there's no documented way to get it, and anyway it might not exist after all-- because the external storage setting doesn't require Core Data to use external storage, it just allows it to do so.
If you didn't use that setting then there's never any URL since the image is saved as part of the SQLIte file.
If you need a file URL for the image, save the image to a file separately from Core Data and save the file name as an entity property. Then the file URL is wherever you saved the file.
And an implementation of how I saved it and then got the URL in practice when I had the same challenge:
Swift 5:
func getImageURL(for image: UIImage?) -> URL {
let documentsDirectoryPath:NSString = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString
let tempImageName = "tempImage.jpg"
var imageURL: URL?
if let image = image {
let imageData:Data = image.jpegData(compressionQuality: 1.0)!
let path:String = documentsDirectoryPath.appendingPathComponent(tempImageName)
try? image.jpegData(compressionQuality: 1.0)!.write(to: URL(fileURLWithPath: path), options: [.atomic])
imageURL = URL(fileURLWithPath: path)
try? imageData.write(to: imageURL!, options: [.atomic])
}
return imageURL!
}

How to get image complete data while sharing it with the help of share extension?

I am using share extension in my application and I want to show image taken time while I am sharing image with share extension.Is there any way to get the time of image when we use share extension.
The timestamp is available in EXIF data stored with the images. You can get it using UIImagePickerController like this:
https://stackoverflow.com/a/33672661/4042468
On the other hand, if you have image file url, you can use import ImageIO and the below code to get all the properties of the image of which date time is one.
if let imagePath = Bundle.main.path(forResource: "test", ofType: "jpg") {
let imageURL = NSURL(fileURLWithPath: imagePath)
if let imageSource = CGImageSourceCreateWithURL(imageURL, nil) {
if let imageProperties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, nil) as? [String: AnyObject] {
}
}
}
Note that there is a Exif key in which you can find timestamp.

How can I store an Image to Realm database?

I'm writing an iOS application using Swift 2.2 and I want to save profile picture of an account locally in a Realm database according to resize the picked image. I googled and also saw here but not clear well. If images are small in size or less in numbers or if I have more images or large size what can be done?
another confusion is what I will use either NSData or NSString ?
my model is
class IndividualContact: Object {
dynamic var photoDataString = ""
var photoData: NSData? = nil
dynamic var isPhotoAvailable = false
}
and I already picked image from gallery
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
if let pickedImage = info[UIImagePickerControllerOriginalImage] as? UIImage {
imageView.contentMode = .ScaleAspectFit
imageView.image = pickedImage
}
now how can I store it according to resize it as (120*110 size)?
You can not save directly image into Realm, convert it into NSData and the store it.
if your image is of type JPEG then use,
let data = NSData(data: UIImageJPEGRepresentation(yourImage,0.9))
and if your image is of PNG type then use,
let data = NSData(data: UIImagePNGRepresentation(yourImage))
after that write you file in realm like,
let realm = Realm()
realm.write{
realm.add(data)
}
Hope this helps.
You can't save directly image into Realm, convert it into Data and
the store it.
Convert your image to Data
let data = NSData(data: UIImageJPEGRepresentation(yourImage,0.9))
Convert data to PNG format if any
let imgPNG = UIImage.imageWithData(data)
Convert PNG image to Data
let dataPNGImg = NSData(data: UIImagePNGRepresentation(imgPNG))
Store your data into Realm DB...
let realm = Realm()
realm.write{
realm.add(dataPNGImg)
}
IMPORTANT!!!
It is not a good idea to store an image in the database. It will increase database load and processing time. You can store the image path instead of the image.

Resources