Why can't Swift recognize the array sent by JS?

I am communicating with JS using Webview. I transfer into parameter api the received data again. But when Swift get an array from JS, Swift don't recognize it properly.



Where to Send Data from JS

var jsonData = {
  data,
  type : "fromjs"
};
alert(jsonData)
webkit.messageHandlers.sendFromJS.postMessage(jsonData);



Data Viewed by Alerts


{

"type" = "fromjs",

"data" = {

"num": "one",

"arr_data" : [{ "title": "test1", "val" : "testval1" },

{ "title": "test2" , "val" : "testval2"}]

}

}




I check the data received by Swift.


@available(iOS 8.0, *)
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
   if message.name == "sendFromJS" {
        let getdata = message.body as! NSDictionary
        print(getdata)



But Swift doesn't recognize the array properly.


{

type = "fromjs",

data = {

"num": "one",

"arr_data" : ({ "title": "test1", "val" : "testval1" },

{ "title": "test2" , "val" : "testval2"})

}

}




Swift recognizes square brackets as parentheses.



How can you solve this problem? I have to send the data that I received by putting it in the parameters as it is.



func apiCall(_ param: NSDictionary){
   let parameters: [String: AnyObject] = param["data"] as! [String : AnyObject]
Alamofire.request(url, method: .post, parameters: parameters, encoding: URLEncoding.default, headers: headers)



I've changed the type of data. But it's equally unrecognizable.


let getdata = message.body as! [String : Any]
print(getdata)


//log From Swift

[

type = "fromjs",

data = {

"num": "one",

"arr_data" : ({ "title": "test1", "val" : "testval1" },

{ "title": "test2" , "val" : "testval2"})

}

]




To create json data in js

var data = {
  num: "one"
};
var data_arr = [];
data_arr.push({"title": "test1", "val" : "testval1"});
data_arr.push({"title": "test2" , "val" : "testval2"});
data.arr_data = data_arr;
var jsonData = {
  data,
  type : "fromjs"
};
alert(jsonData)
webkit.messageHandlers.sendFromJS.postMessage(jsonData);

Accepted Reply

Swift recognizes square brackets as parentheses.

This is just a difference in the way that JSON and traditional NeXT property lists represent arrays. Consider this:

let json = """
    { "a": [1, 2, 3] }
    """
let d = try! JSONSerialization.jsonObject(with: Data(json.utf8), options: [])
print("plist:", d)
let d2 = try! JSONSerialization.data(withJSONObject: d, options: [.prettyPrinted])
print("json:", String(data: d2, encoding: .utf8)!)

It prints:

plist: {
    a =     (
        1,
        2,
        3
    );
}
json: {
  "a" : [
    1,
    2,
    3
  ]
}

The property list renders the array using

( … )
but that’s just a rendering oddity. The actual objects are correct, as witnessed by the fact that you can turn them back into the some JSON you started with.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Replies

Did you try replacing

func apiCall(_ param: NSDictionary) {

by

func apiCall(_ param: Dictionary) {

I tried change value But get error


func apiCall(_ param: Dictionary) { 

Reference to generic type 'Dictionary' requires arguments in

Insert '<<#Key: Hashable#>, Any>'

Where exactly in code do you get the error ?

Just like the code you wrote in your answer, I changed my code the same way, and I got the following error.


Reference to generic type 'Dictionary' requires arguments in

Insert '<<#Key: Hashable#>, Any>'


Click the fix button to change:

Dictionary<<#Key: Hashable#>, Any>



When creating a Dictionary, it appears that I must specify a type by default.


Dictionary Example

var dic : [Int : String] = [:]
var dic2 = [Int : String]()
var dic3 : Dictionary = [Int:String]()
var dic4 : Dictionary<int, string=""> = Dictionary<int, string="">()


But as you can see from my question, this is how I've already tried.

let getdata = message.body as! [String : Any]
print(getdata)

Swift recognizes square brackets as parentheses.

This is just a difference in the way that JSON and traditional NeXT property lists represent arrays. Consider this:

let json = """
    { "a": [1, 2, 3] }
    """
let d = try! JSONSerialization.jsonObject(with: Data(json.utf8), options: [])
print("plist:", d)
let d2 = try! JSONSerialization.data(withJSONObject: d, options: [.prettyPrinted])
print("json:", String(data: d2, encoding: .utf8)!)

It prints:

plist: {
    a =     (
        1,
        2,
        3
    );
}
json: {
  "a" : [
    1,
    2,
    3
  ]
}

The property list renders the array using

( … )
but that’s just a rendering oddity. The actual objects are correct, as witnessed by the fact that you can turn them back into the some JSON you started with.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"