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?
Asked
Active
Viewed 3,493 times
3

rawbee
- 2,946
- 3
- 18
- 22
3 Answers
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
-
1No, it may or may not be String. It depends on the javascript code which sent the message. – Hai Feng Kao May 22 '23 at 21:38