Swift Codable - how to encode and decode stringified JSON values?

JBlake

The server I'm talking to expects a message in the format:

{
  "command": "subscribe",
  "identifier": "{\"channel\": \"UserChannel\"}",
  "data": "{\"key\": \"value\"}"
}

Where the identifier and data values is an escaped json string.

I have this so far:

struct ActionCableMessage<Message: Encodable>: Encodable {
    let command: Command
    let identifier: CableChannel
    let data: Message?

    func encode(to encoder: Encoder) throws {
        var container = encoder.container(keyedBy: CodingKeys.self)
        try container.encode(command, forKey: .command)

        try container.encode(identifier, forKey: .identifier) // ????
    }

    private enum CodingKeys: String, CodingKey {
        case command, identifier, data
    }
}

But I don't know what to do from here. I think I need a protocol that CableChannel and Message can conform to, with a provided extension func that implements encode (to encoder: Encoder), which ensures Encoder must be a JSONEncoder, and if so, uses that to rewrite it's own value as a escaped json string.

I also need to decode this back to the ActionCableMessage struct, but I haven't gotten that far yet.

Sweeper

I think I need a protocol that CableChannel and Message can conform to

Well, that protocol is Encodable (or Codable if you prefer).

// just implement these as you normally would
extension CableChannel : Encodable { ... }
extension Message : Encodable { ... }

Then in ActionCableMessage, you use another encoder to encode the inner objects to JSON data, then convert that to string, then encode that string:

func encode(to encoder: Encoder) throws {
    var container = encoder.container(keyedBy: CodingKeys.self)
    try container.encode(command, forKey: .command)

    let subencoder = JSONEncoder()
    let identifierString = try String(data: subencoder.encode(identifer), encoding: .utf8)

    try container.encode(identifierString, forKey: .identifier)

    // do the same for "data"
}

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

How can I use Swift’s Codable to encode into a dictionary?

Swift Codable: How to encode top-level data into nested container

How to encode and decode struct to NSData in swift?

How to encode/decode Timestamp for json in circe?

How to manually decode an an array in swift 4 Codable?

Swift Codable - decode nested dictionary

Decode an array inside JSON data only using Swift 4 Codable

How do I decode a JSON using codable with a mutating key?

How to decode JSON with codable in Swift 4?

How to make a swift Codable struct that will decode and encode a MongoDB _id ObjectId() in JSON

swift 4 Codable - how to decode if there is string or dictionary?

Use swift Codable to decode JSON with values as keys

How to ignore nil json values in codable

Swift Codable decode changing JSON and ignoring some fields

How to decode JSON Array with different objects with Codable in Swift?

Swift Codable - How to encode custom array

Encode/decode JSON keys?

How to encode / decode scalar values

Swift decode and encode string

In Swift 4, how can you use Codable to decode JSON and create references between the decoded objects?

How to decode JSON in swift

How to implement a context controllable Swift Codable Encode function?

How to decode JSON dictionary (with varying keys) of dictionaries, using Codable?

JSON decode to and encode from recursive enum in Swift

How to decode json into a Codable to use in a SwiftUI Preview?

Decode a dictionary in json using Swift 5 and Codable

Swift: How to pass a codable type as a function input to encode or decode json

How to decode an invalid stringified JSON - Flutter

How to decode JSON in Swift?