Home > Software engineering >  Issue encoding/decoding file to/from S3 (Realm, Swift)
Issue encoding/decoding file to/from S3 (Realm, Swift)

Time:08-20

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() 
}
  • Related