I\'m new to iOS. I\'ve been trying to make an application that will store an image captured from the camera into CoreData
. I now know how to store data like
In xcdatamodelId subclass declare image entity as NSData
... you can't use UIImage
format because image data is in binary format.
@property (nonatomic, retain) NSData *imag;
In Implementation file.. convert UIImage
to NSData
UIImage *sampleimage = [UIImage imageNamed:@"sampleImage.jpg"];
NSData *dataImage = UIImageJPEGRepresentation(sampleimage, 0.0);
Then finally save it
[obj setValue:dataImage forKey:@"imageEntity"]; // obj refers to NSManagedObject
You can store images in Core Data using the Binary Data attribute type. However you should be aware of a few things:
Always convert your UIImage to a portable data format like png or jpg For example:
NSData *imageData = UIImagePNGRepresentation(image);
Enable "Allows external storage" on this attribute Core Data will move the data to an external file if it hits a certain threshold. This file is also completely managed by Core Data, so you don't have to worry about it.
If you run into performance issues, try moving the Binary Data attribute to a separate entity.
You should abstract the conversion to NSData behind the interface of your NSManagedObject subclass, so you don't have to worry about conversions from UIImage to NSData or vice versa.
If your images are not strongly related to the entities in your model, I would suggest storing them outside of Core Data.
I don't know why you want to store image in core data, while there is other persistent storage available in iOS. If you just want to store image for cache purpose, you can store it in document directory or cache directory. Happy Coding...
Please refer below URL, How to store and retrieve images in document directory.
http://www.wmdeveloper.com/2010/09/save-and-load-uiimage-in-documents.html
Saving image to Documents directory and retrieving for email attachment
How do I create a temporary file with Cocoa?
It is possible to store images in Core Data as UIImage. Although this is not considered to be good practice as Databases are not meant for storing files. We don't use core data to store the images directly instead we use the file path to where the image data is stored on your phone.
Anyways, the best method I found out while developing a side-project is demonstrated below
Set the entity codeGen to Manual/None
Select the attribute you want to be of Image type and choose transformable as it's type
Enter Custom class identifier as UIImage
Go to editor and select Create NSManagedObject Subclass
The Process will create 2 swift files depending on the number of your entities(I only had 1 entity). Now, select the <EntityName> + CoreDataProperties.swift
file and import UIKit
If, on clicking Jump to Definition for the @NSManaged public var UIImage definition
your work is done.
Perform actions on the entities just like you would and you will be able to fetch, save, edit the image attribute by down-casting <EntityName>?.value(forKey: "<attributeName>") as? UIImage
.
I had to use the entity as NSManagedObject
type and was for some reason not able to access the image directly from the created subclass.
For Swift 5 and Swift 4.2
convert UIImage
to Data
:
let imageData = image.jpegData(compressionQuality: 1.0)
save to CoreData
:
let object = MyEntity(context: managedContext) //create object of type MyEntity
object.image = imageData //add image to object
do {
try managedContext.save() //save object to CoreData
} catch let error as NSError {
print("\(error), \(error.userInfo)")
}
- (void)imageChanged:(UIImage*)image{
if (self.detailItem) {
[self.detailItem setValue:UIImagePNGRepresentation(image) forKey:kSignatureImage];
}
}
In this a very brief example. self
is a view controller using core data and self.detailItem is the usual NSManagedObject. In that project I did not create model classes for the entities but strictly use the KVC pattern to access the attributes. As you might guess, the attribute is named "signatureImage"
which I had defined in an #define constant kSignatureImage
.
This is where the image is restored from core data:
self.signatureCanvas.image = [UIImage imageWithData:[self.detailItem valueForKey:kSignatureImage]];
Again, self
is a view controller, signatureCanvas
is a UIImageView
subclass and .image
is its regular image
property inherited from UIImageView
. detailItem
, again, is the usual NSManagedObject
.
The example is taken from a project I am currently working on.
There are pros and cons for storing large data objects like images in core data or having them separated in files. Storing them in files means that you are responsible for deleting them when the related data objects are deleted. That provides coding overhead and may be volatile for programming errors. On the other hand, it may slow down the underlying database. I have not yet enough experience with this approach that I could share with respect to performance. In the end, the disk storage occupied is about the same size in total.