Steffen L.
Steffen L.

Reputation: 149

Swift 3 - save and fetch image from core data

Yes I realize there are other questions like this, but no answers has seemed to work for me yet...

I have an api call that returns a base64 string. This I try to save to core data and then return as a picture. I can't figure out where I go wrong though and maybe some of you bright minds can help me out.

This is where I recieve data from my api call:

let image = data?.base64EncodedString()
saveImageToDB(brandName: imageBrandName, image: image!)

The brandName simply being a string, ex: "Baresso".

My saveImageToDB:

  func saveImageToDB(brandName: String, image: String) {
        let managedContext = getContext()
        let entity = NSEntityDescription.entity(forEntityName: "CoffeeShopImage", in: managedContext)!
        let CSI = NSManagedObject(entity: entity, insertInto: managedContext)


        let image = UIImage(named: image)

        //this is the line that appears to be wrong
        let imageData = NSData(data: (UIImagePNGRepresentation(image!)?.base64EncodedData())!) 

        CSI.setValue(imageData, forKey: brandName)

        do {
            try managedContext.save()
            print("saved!")
        } catch let error as NSError {
            print("Could not save. \(error), \(error.userInfo)")
        }
    }

My fetch func:

func getImageFromDB(callback: @escaping (_ image: UIImage)-> ()) {

    var imageFromDB: UIImage?

    let fetchRequest: NSFetchRequest<NSManagedObject> = NSFetchRequest(entityName: "CoffeeShopImage")

    do {
        let searchResults = try getContext().fetch(fetchRequest)

        for images in searchResults {
            let image = images.value(forKey: "Baresso") as! NSData
            imageFromDB = UIImage(data: image as Data)!
            callback(imageFromDB!)
        }

    } catch {
        print("Error with request: \(error)")
    }
}

My error log:

fatal error: unexpectedly found nil while unwrapping an Optional value
(lldb) 

So it seems I am not saving my image which kinda makes sense, however I can't figure out what I am doing wrong?

EDIT:

I messed up my types. The corrected code is as follows:

func saveImageToDB(brandName: String, image: NSData) {
    let managedContext = getContext()
    let entity = NSEntityDescription.entity(forEntityName: "CoffeeShopImage", in: managedContext)!
    let CSI = NSManagedObject(entity: entity, insertInto: managedContext)

    CSI.setValue(image, forKey: "image")
    CSI.setValue(brandName, forKey: "brandName")

    do {
        try managedContext.save()
        print("saved!")
    } catch let error as NSError {
        print("Could not save. \(error), \(error.userInfo)")
    }
}

Upvotes: 0

Views: 1651

Answers (1)

Jon Rose
Jon Rose

Reputation: 8563

Your types are all messed up.

You start with data which I assume is data and convert it to a string called image. Then in saveImageToDB you treat the string image like it was a UIImage and try to convert it first to data using UIImagePNGRepresentation (which will fail because it is a string) then you try to convert that data to a string, and then try to convert that string back into data which is also wrong.

If you are storing data in the database just pass the data into saveImageToDB. Change image in saveImageToDB to imageData and cut out all you converting from string to data to image and back. You start with data and want to save data so there is no reason to do any of that.

Upvotes: 1

Related Questions