简体   繁体   中英

swift fetch a specific uiimage from core data

I'm pretty new to swift and core data. So if this logic doesn't make sense, please let me know.

I'm trying to save user's images to core data and be able to delete selected one. I have Entity "Media", attribute "photo" type "binary data"

Here I convert UIImage to NSData

let data = UIImagePNGRepresentation(addedImage!) as NSData?

And save it.

let newPhoto = NSEntityDescription.insertNewObject(forEntityName: "Media", into: context)
newPhoto.setValue(imageData, forKey: "photo")

Here I try to retrieve that one selected image from core data using predicate

func deleteImage(imageData: NSData) {

        let context = appDelegate.persistentContainer.viewContext
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Media")
        request.returnsObjectsAsFaults = false
        request.predicate = NSPredicate(format: "photo =%@", imageData)

        do {
            let results = try context.fetch(request)
           ...

And I'm getting this error message.

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[OS_dispatch_data _bytesPtrForStore]: unrecognized selector sent to instance

Saving and getting all images from entity "Media" is working perfectly. I just can't get the specific one.

Any thoughts/suggestions? Thanks.

Saving images like this, with external storage enabled for the property, can be OK. But there are some very unusual things going on here.

The common approach would be to have the image be part of an entity with other information, but not as the primary value of the entity. For example an entity type that represents a person and has name, address, etc, and a picture. Storing just a picture in an entity is kind of weird. You're not getting much of anything from using Core Data over something simpler. If nothing else I'd guess you had a photo ID, or title, or some other data in the entity.

The second thing relates to that-- it's extremely unusual to try to fetch using a predicate based on a binary data property. I guess it might work but only if you can ensure that the predicate value is identical to one in the persistent store all the way through-- not a single bit changed in the binary blob. That might be true but I wouldn't rely on UIKit not doing something along the way that makes it subtly different. I've never seen that particular error message but I'm not surprised that this isn't working.

Finally, it's also unusual (though not quite so strange as the above) to delete an object based on a fetch request. You would have fetched these objects before to get the images. Why fetch the same object again just to delete it? Delete the one you already fetched.

A more reliable approach would be to at least include a unique ID in the entity, which might be an integer or a UUID or whatever else works for you. Fetch this entity and display images using the photo property. When you want to delete one, take the managed object from your fetch and tell the context to delete that one. Or if fetching is necessary for some reason, use the unique ID in the predicate instead of the binary data.

You better stop doing it. Saving heavy data (image, audio, video, ...) to core data will greatly decrease fetching speed when you have more records. Instead, save image to application folder , and then only save its url to core data.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM