0

I have to send a URLRequest containing a JSON object as its http-body (which needs to be of type Data).

My JSON looks like this:

let json: [String : Any] = [
        "to" : toDeviceToken,       // String
            "notification" : [
                "title" : title,    // String
                "body" : body,      // String
                "icon" : icon       // UIImage
            ],
            "data" : {
                // Add optional data here.
            }
        ]

And I would like to convert this to type Data in order to put it into a URLRequest.

This

try JSONSerialization.data(withJSONObject: json, options: .prettyPrinted)

always fails for some reason, maybe because it is a nested JSON object? In addition, JSONSerialization.isValidJSONObject(json) returns false.

When turning the UIImage object into a String object like this UIImagePNGRepresentation(UIImage.appIcon!)?.base64EncodedString(), I get an error saying 'Invalid type in JSON write (_SwiftValue)'

How would I do that?

j3141592653589793238
  • 1,810
  • 2
  • 16
  • 38
  • Possible duplicate of [Convert Dictionary to JSON in Swift](https://stackoverflow.com/questions/29625133/convert-dictionary-to-json-in-swift) – Lou Franco Jan 20 '18 at 22:47
  • `try JSONSerialization.data(withJSONObject: ...` – Lou Franco Jan 20 '18 at 22:47
  • @LouFranco This does not work for me, maybe because it's a nested JSOn object? – j3141592653589793238 Jan 20 '18 at 22:51
  • The `UIImage` is the problem. The problem with your string conversion is that you used `?`, which means it's an `Optional` and cannot be represented either. You have to unwrap that optional which is the base64 string representation of the PNG. – Rob Jan 20 '18 at 23:51
  • 1
    FYI, people often use multipart/form-data requests when uploading an image, as the base64 string representation introduces 33% overhead. If it's a small image, that's inconsequential. But if it's a large image or if you're uploading many, it can start to become material. Tools like Alamofire make uploading multipart/form-data requests really easy. But if doing it manually, the code is a little more tedious. – Rob Jan 20 '18 at 23:53
  • 1
    I would also suggest using JPEG representation which will reduce considerably the data size – Leo Dabus Jan 21 '18 at 00:10
  • Uh...Did nobody see this or was is too obvious? After replacing the curly braces with the angular braces (see "data"), everything works. I also had to convert the image to a base64-encoded string, as you told me. – j3141592653589793238 Jan 21 '18 at 10:01

1 Answers1

1

Your code fails because it contains data that can't be converted to JSON.

See the documentation for JSONSerialization for a list of support data types. Note that UIImage is not one of the supported types.

You will need to convert the UIImage to a string using a base64 encoding of its JPG or PNG representation.

rmaddy
  • 314,917
  • 42
  • 532
  • 579
  • UIImagePNGRepresentation(UIImage.appIcon!)?.base64EncodedString() So this code should work, but it always throws a very long error 'Invalid type in JSON write (_SwiftValue)' – j3141592653589793238 Jan 20 '18 at 23:03