-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

Ratnesh Jain
  • 671
  • 7
  • 14
behtito
  • 3
  • 6
  • 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. – vadian Jan 22 '19 at 09:49
  • how can i do that can please share some example – behtito Jan 22 '19 at 09:56
  • 6
    Please, questions about JSON serialization are one of the most frequently asked questions here on SO. – vadian Jan 22 '19 at 10:01

3 Answers3

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)
}
Gereon
  • 17,258
  • 4
  • 42
  • 73
  • xcode complain Replace 'decoder' with 'decode .. after auto complete its says Cannot convert value of type '[AnyHashable : Any]' to expected argument type 'Data' – behtito Jan 22 '19 at 10:21
  • 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) – behtito Jan 22 '19 at 10:29
  • it gives error "Cannot convert value of type '[AnyHashable : Any]' to expected argument type 'Data'" – behtito Jan 22 '19 at 10:31
  • 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. – Gereon Jan 22 '19 at 10:39
  • i was updated my question hope it will help you to understand my problem.. – behtito Jan 22 '19 at 10:52
  • So you're not getting JSON (except in the `message`), but rather a push notification. Updated my answer. – Gereon Jan 22 '19 at 11:10
  • now getting this error Value of type '[AnyHashable : Any]' has no member 'message' – behtito Jan 22 '19 at 11:21
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.

Ratnesh Jain
  • 671
  • 7
  • 14
iPeter
  • 1,330
  • 10
  • 26
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)
}
Mahesh Shahane
  • 489
  • 5
  • 16