Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift 3 - Saving images to Core Data

For some reason I can't figure out how to save images to core data and fetch them again. I have a feeling it's something about my types but have a look:

Image is saved as Binary Data and stored in External Record File

I get my data from an api call to my server. It returns a base64 string. Here is where I get the data:

updateAccessTokenOnly(newAccessToken: aToken!)
saveImageToDB(brandName: imageBrandName, image: data! )

Here I save it to my DB:

func saveImageToDB(brandName: String, image: Data) {
    dropImages(){tableDropped in
        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)")
        }
    }
}

then to fetch it:

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

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

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

        for images in searchResults {
            print("vi når her ned i get image")
            if (images.value(forKey: "brandName")! as! String == "Baresso"){
                print(images.value(forKey: "brandName")! as! String)

                let image: Data = images.value(forKey: "image")! as! Data
                let decodedimage = UIImage(data: image)

                callback(decodedimage!)

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

Full error log:

https://docs.google.com/document/d/1gSXE64Sxtzo81eBSjv4bnBjBnnmG4MX2tuvNtnuJDIM/edit?usp=sharing

Hope someone can help. Thanks in advance!

UPDATED

So I uninstalled the app and then the code above worked. However the pictures come out blue? (yes I've checked that the pictures sent from the database are correct).

Any solution?

Pictures fetched from CoreData

like image 247
Steffen L. Avatar asked Feb 27 '17 11:02

Steffen L.


People also ask

How do I save an image in Core Data in Swift?

Creating the Model In that entity , create one attribute . Name it img and make sure the attribute type is Binary Data, then click on the img attribute and go to Data Model Inspector. Check the box Allows External Storage. By checking this box, Core Data saves a reference to the data which will make for faster access.

Can you save images in Core Data?

Yes, we can store the images with the core data but not directly as UIImage. This can be achieved by converting UIImage to Data. Because UIImage is not a valid attribute type in Core Data. If you are new to the core data and want to learn from the basics then refer to this post.

How do I add Core Data to an existing project in Swift?

Add a Core Data Model to an Existing ProjectChoose File > New > File and select the iOS platform tab. Scroll down to the Core Data section, select Data Model, and click Next. Name your model file, select its group and targets, and click Create.

What is Core Data in Swift iOS?

Overview. Use Core Data to save your application's permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device. To sync data across multiple devices in a single iCloud account, Core Data automatically mirrors your schema to a CloudKit container.


1 Answers

replace

let image: Data = images.value(forKey: "image")! as! Data
let dataDecoded : Data = Data(base64Encoded: image, options: [])!
let decodedimage = UIImage(data: dataDecoded)

with

let image: Data = images.value(forKey: "image")! as! Data
let decodedimage = UIImage(data: image)

Base64 is a way to to convert data to a string. There is no reason to use it here. You already have the data from the database you just want to convert it to a UIImage.

also change

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

to

saveImageToDB(brandName: imageBrandName, image: data!)

base64EncodedData is turning the data from image data into a utf-8 encoded based64encoded string. There is no reason for that.

You should get the base64 encoded string from server, convert it to data and then you never need base64 again. Read and write data to your database, and after you read it convert it to a UIImage. Base64 is an encoding method to transfer data. If you are not talking to the server there is no reason to use base64.

like image 70
Jon Rose Avatar answered Sep 30 '22 18:09

Jon Rose