3

I set up the WKScriptMessageHandler function userContentController(WKUserContentController, didReceive: WKScriptMessage) to handle JavaScript messages sent to the native app. I know ahead of time that the message body will always come back with the same fields. How do I convert the WKScriptMessage.body, which is declared as Any to a struct?

rawbee
  • 2,946
  • 3
  • 18
  • 22

3 Answers3

4

What about safe type casting to, for example, dictionary?

let body = WKScriptMessage.body
guard let dictionary = body as? [String: String] else { return }

Or as an option, you can send body as json string and serialise it using codable.

struct SomeStruct: Codable {
    let id: String
}

guard let bodyString = WKScriptMessage.body as? String,
      let bodyData = bodyString.data(using: .utf8) else { fatalError() }

let bodyStruct = try? JSONDecoder().decode(SomeStruct.self, from: bodyData)
Andrew
  • 331
  • 1
  • 6
  • that second approach with a struct saved me: probably the issue was that String value had escapes in it, so just conditional unwrapping as? String neven worked. Thanks! – Async- Apr 29 '21 at 09:53
  • The body is not a always string. It can be a nested json object, including arrays, other objects, numbers, etc. – florieger Aug 15 '23 at 13:31
1

Your defined struct

struct EventType:Codable{
    let status: Int!
    let message: String!
}

WKScriptMessageHandler protocol method

func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
    do {
        let jsonData = try JSONSerialization.data(withJSONObject: message.body)
        let eventType = try JSONDecoder().decode(EventType.self, from: jsonData)
    } catch {
        print("fatalError")
    }
}
Piyush
  • 1,156
  • 12
  • 20
0

In SwiftUI message.body is String object. You can convert the body in dictionary like this:

            if let bodyString = message.body as? String {
            let data = Data(bodyString.utf8)
            do {
                if let json = try JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] {
                    guard let body = json["body"] as? [String: Any] else {
                        return
                    }
                    //use body object
                }
            } catch let error as NSError {
                print("Failed to load: \(error.localizedDescription)")
            }
        }
Muzammil
  • 1,529
  • 1
  • 15
  • 24