I am working on a SwiftUI app on iOS using Realm (Sync) as back-end. I have been following the article on o-fish (Realm Data and Partitioning Strategy Behind the WildAid O-FISH Mobile Apps | MongoDB) to enable users to attach pictures while offline.
My Photo model:
class Photo: Object, ObjectKeyIdentifiable {
@Persisted(primaryKey: true ) var _id: ObjectId
@Persisted var picture: Data?
@Persisted var pictureUrl: String
convenience init (pictureUrl: String = "", picture: Data? = Data()) {
self .init()
self .pictureUrl = pictureUrl
self .picture = picture
}
For testing purpose, in my iOS app code, I am writing in the realm like the following:
.onChange(of: image) { _ in
if(image != nil) {
if let newData = image!.jpegData(compressionQuality: 0.5) {
try! realm.write {
realm.add(Photo(picture: newData))
}
}
}
}
Which as explained in the article, will trigger functions on App Services to (1) upload to S3 and (2) replace the field ID by S3’s generated link.
I created my AWS S3 bucket and managed to upload some blob on it through the upload function.
exports = async function(imageName, file) {
const AWS = require('aws-sdk');
AWS.config.update({
accessKeyId : <key>
secretAccessKey : <key>,
region: <region>
});
const s3 = new AWS.S3({apiVersion: '2006-03-01'})
const bucketName = <bucket name>
return s3.upload({
"Bucket": bucketName,
"Key" : imageName,
"Body": file.toBase64(),
"ACL": "public-read",
"ContentType": "image/jpeg",
}).promise()
}
Regarding my issue: from what I understand, the file saved on S3 is in base64 format. Thus it is impossible to download the file from S3 and open it in an image viewer, is that correct? Furthermore, I am now trying to display the base64 image on the iOS app but I only get decoding errors… :
let (data, _) = try await URLSession.shared.data(from: URL) // URL is the new S3 image link
If let image = UIImage(data: Data(base64Encoded: data.base64EncodedString())!) {
...
}
Doing a curl on the image link gives a long string looking like
/9j/4AAQSkZJRgABAQAASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAGhKADAAQAAAABAAAJxAAAAAD/wAARCAnEBoQDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/…
Is there something I am missing either in the S3 upload or in the Swift/SwiftUI decoding?
CodePudding user response:
try this example code, where you turn the data
you receive into a String
, then base64 decode it, for use into a UIImage
:
if let str = String(data: data, encoding: .utf8), let imageData = Data(base64Encoded: str) {
let img = UIImage(data: imageData) ?? UIImage()
}