-3

I am getting a json from my server. my server json is

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    print(userInfo)
 }

this print result of userInfo

[AnyHashable("smallIcon"): small_icon, AnyHashable("tickerText"): , AnyHashable("message"): {"action":"new_content_notification","msg":{"headline":"iOS REFERRAL BONUS","subhead":"Congratulations. You have unlocked another BDT500 discount on long route trip booking.","brief":"Congratulations. You have unlocked another BDT500 discount on long route trip booking.","content_id":44}}, AnyHashable("subtitle"): www.ezzyr.com, AnyHashable("sound"): 1, AnyHashable("gcm.message_id"): 0:id, AnyHashable("aps"): {
   "content-available" = 1;     
},
AnyHashable("title"): Notification from ezzyr, AnyHashable("vibrate"): 1, AnyHashable("largeIcon"): large_icon]

i am converting this by using swifty json. after converting swity json i am gettng this

let fullInfo = JSON(userInfo)
print(fullInfo)

{
  "gcm.message_id" : "0: some number",
  "subtitle" : "www.someName.com",
  "smallIcon" : "small_icon",
  "largeIcon" : "large_icon",
  "title" : "Notification from ezzyr",
  "vibrate" : "1",
  "message" : "{\"action\":\"new_content_notification\",\"msg\":{\"headline\":\"iOS REFERRAL BONUS\",\"subhead\":\"Congratulations. You have unlocked another BDT500 discount on long route trip booking.\",\"brief\":\"Congratulations. You have unlocked another BDT500 discount on long route trip booking.\",\"content_id\":69}}",
  "sound" : "1",
  "tickerText" : "",
  "aps" : {
    "content-available" : "1"
  }
}

i want only data what i have in my message key. so i try to get message key value this way

let message = fullInfo["message"]
print(message)

after printing message i am getting this result

{"action":"new_content_notification","msg":{"headline":"iOS REFERRAL BONUS","subhead":"Congratulations. You have unlocked another BDT500 discount on long route trip booking.","brief":"Congratulations. You have unlocked another BDT500 discount on long route trip booking.","content_id":94}}

Than i was try to get the key value of "action" in this way.

let action = message["action"]
print(action)

but this time i am getting null value.. How can i fix this issue and get string value and also the key value of msg

Thanks advanced for help

3
  • The value of message is another JSON string. You have to deserialize it with JSONSerialization or Decodable, then you can access the keys and values. Commented Jan 22, 2019 at 9:49
  • how can i do that can please share some example Commented Jan 22, 2019 at 9:56
  • 6
    Please, questions about JSON serialization are one of the most frequently asked questions here on SO. Commented Jan 22, 2019 at 10:01

3 Answers 3

1

I recommend ditching SwiftyJSON and JSONSerialization entirely, use Codable instead.

Use this to parse the inner JSON contained in message:

struct Message: Codable {
    let action: String
    let msg: Msg
}

struct Msg: Codable {
    let headline, subhead, brief: String
    let contentID: Int

    enum CodingKeys: String, CodingKey {
        case headline, subhead, brief
        case contentID = "content_id"
    }
}

if let messageStr = userInfo["message"] as? String {
  let messageData = messageStr.data(using: .utf8 )!
  let message = try JSONDecoder().decode(Message.self, from: messageData)
}
Sign up to request clarification or add additional context in comments.

7 Comments

xcode complain Replace 'decoder' with 'decode .. after auto complete its says Cannot convert value of type '[AnyHashable : Any]' to expected argument type 'Data'
i am getting data from userinfo but when i pass this variable i gatting same error here i what pass, let fullInfo = try JSONDecoder().decode(FullInfo.self, from: userInfo)
it gives error "Cannot convert value of type '[AnyHashable : Any]' to expected argument type 'Data'"
Looks like you're passing the result of an initial JSONSerialization call. Don't do that, pass the raw data to the decoder (ie. whatever you used to get to that dictionary.
i was updated my question hope it will help you to understand my problem..
|
0

Check this : Convert Json string to Json object in Swift 4

Convert message text in json :

let messageStr = message as! String
let data = messageStr.data(using: .utf8)!
do {
    if let jsonArray = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [Dictionary<String,Any>]
    {
       print(jsonArray) // use the json here    

        let action = jsonArray["action"]
        print(action) // your action is here

    } else {
        print("bad json")
    }
} catch let error as NSError {
    print(error)
}

2 Comments

getting this error, Value of type 'JSON' has no member 'data' on first line
Please don't recommend using JSONSerialization when we have Codable
0

As vadian sir have said, the value of the key message is another JSON string, so to get the value of action from message, you need to deserialize it with JSONSerialization like below and get the value of the key action.

let message = fullInfo["message"] as! String
let data = message.data(using: .utf8)!
do {
    if let messageDict = try JSONSerialization.jsonObject(with: data, options : .allowFragments) as? [String : Any] {
        let action = messageDict["action"] as! String
        print(action)
    } else {
        print("bad json")
    }
} catch let error as NSError {
    print(error)
}

Hope this helps.

1 Comment

i getting error in runtime for bad execution in first line

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.