Unable to save UIImage in a SQlite DB as a Blob

I am doing an inline string and everything gets save correctly except for the png image. When I look in the database I see "3344645 bytes" and not all the bytes like I am suppose to. I have manually inserted an image through my db viewer and can see that it is being stored wrong.

is UIImagePNGRepresentation(receiptImage) how I am suppose to enter it? receiptImage is a UIImage()


oneStepDBTable("INSERT INTO receiptInfo (UPLOADED, RECEIPTDATE, PURCHASEDFROM," +

"AMOUNT, ACCOUNTUSED, REASON, RECEIPTIMAGE) VALUES ('0','\(receiptDate!.text!)'" +

",'\(purchasedFrom!.text!)' ,'\(lblReceiptAmount!.text!)' ,'\(accountID)' ," +

"'\(receiptDetails!.text!)' ,'\(UIImagePNGRepresentation(receiptImage)!)')")


Any guidance would be greatly appreciated!

Replies

Have you checked what is the size limit for BLOB in your case ?

h ttps://www.sqlite.org/limits.html states it 2^^31 - 1 (about 2 Billion Bytes), but they advise to limit to a few million. Did you reach the limit ?

Did you try with small images of a few hundred kB ?


When I had to store images, I finally preferred to store them directly as files in a directory and just put the URL in the database.


Can't you do it this way ? Or have you other reasons not to do ?

You kinda shouldn't be using string insertion "\(…)" for a string like this, because the insertion uses String initializer "String(describing:)", which in turn can use any of several methods to get the inserted string, and it's certainly possibly that the inserted string is a description, not the contents.


For example, I did this in a playground:


let image = #imageLiteral(resourceName: <a file name>)
let data = UIImagePNGRepresentation (image)!
print ("\(data)")


and it prints this:


41107 bytes


That is, the "String(describing:)" a Data object is just the length of the string, not its data. You're also using a Data object for the image, and presumably you're getting the same wrong result.


What you should do instead is to convert Data object "UIImagePNGRepresentation(receiptImage)!" explicitly into some kind of non-lossy string. The best choice is probably to use the Data method "base64EncodedString". You'll of course have to decode the base64 string when you read the database record back again later.

My recommendation is to keep the PNG files in a folder on the device's filesystem and using the database to hold only metadata and info about location of the file. Why?


  • It will keep the database from growing very big
  • If will reduce your use of unsafe code (if you are working with SQLite using it's C interface)
  • I suspect that opening PNG from a file is better tested and optimized than opening from blobs
  • Saving to and opening from blob are an extra operations that take some extra battery life

Thank-you for your help. I have decided to go this route.