Ios Swift decode json data sent from GCM notification - ios

I am receiving the GCM Json encoded data as AnyObject as below
[MsgKey: {"NamKey":"Bdy","MobKey":"9964120147","UidKey":"Uid31"}, collapse_key: do_not_collapse, from: 925652137353]
I want to decode the above and pass it to local notication screen
I tried below :
func application(appPsgVar: UIApplication,
didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
{
print("Notification: ",userInfo["MsgKey"]!)
let MsgVar = userInfo["MsgKey"]
var GotVar = MsgVar?.objectAtIndex(2)
|Or|
var GotVar = MsgVar?.objectForKey("UidKey")
|Or|
var GotVar = MsgVar?.valueForKey("UidKey")
and
if let MsgVar = userInfo["MsgKey"] as? [String:AnyObject]
{
GetNfnFnc(MsgVar["NamKey"] as! String)
}
and
if let MsgVar = userInfo["MsgKey"] as? NSData
{
var JsnAryVar: AnyObject!
do
{
JsnAryVar = try NSJSONSerialization.JSONObjectWithData(MsgVar, options: [])
print(JsnAryVar)
}
catch
{
print("ErrVar")
}
GetNfnFnc(JsnAryVar["NamKey"] as! String)
}
}
userInfo["MsgKey"] gives me below data and not able understand how to decode further
{"NamKey":"Bdy","MobKey":"9964120147","UidKey":"Uid31"}

Actu the problem was Json encoded data from server was coming as String
Method 1: Suggested by Eric D giving the solution link
Retrieving values from 2D array in JSON string
do
{
if let MsgCodVar = MsgSrgVar.dataUsingEncoding(NSUTF8StringEncoding),
let MsgJsnVar = try! NSJSONSerialization.JSONObjectWithData(MsgCodVar, options: []) as? [String:AnyObject]
{
print(MsgJsnVar)
}
}
Method 2 : My own hard workaround :-(
Create own function to convert String data to array[String:AnyObject]
func CnvJsnSrgTooAryFnc(JsnSrgPsgVar: String) -> [String:AnyObject]
{
var JsnSrgVar = JsnSrgPsgVar
JsnSrgVar = JsnSrgVar.stringByReplacingOccurrencesOfString("\"", withString: "")
JsnSrgVar = JsnSrgVar.stringByReplacingOccurrencesOfString("{", withString: "")
JsnSrgVar = JsnSrgVar.stringByReplacingOccurrencesOfString("}", withString: "")
let SrgAryVar = JsnSrgVar.componentsSeparatedByString(",")
var JsnAryVar = [String:AnyObject]()
for SrgIdxVar in SrgAryVar
{
let SrgIdxAryVar = SrgIdxVar.componentsSeparatedByString(":")
JsnAryVar[SrgIdxAryVar[0]] = SrgIdxAryVar[1]
}
return JsnAryVar
}
let MsgAryVar = CnvJsnSrgTooAryFnc(MsgSrgVar)
MsgAryVar["UidKey"]
Got output :
print(MsgSrgVar) :
{"NamKey":"Bdy","MobKey":"9964120147","UidKey":"Uid99"}
print(MsgAryVar)
["NamKey": Bdy, "MobKey": 9964120147, "UidKey": Uid99]

In your third approach, set the JsnAryVar type to a Dictionary ([String: AnyObject]) and cast the result of JSONObjectWithData to a Dictionary.
Follows:
var JsnAryVar: [String: AnyObject]!
JsnAryVar = try NSJSONSerialization.JSONObjectWithData(MsgVar, options: []) as! [String: AnyObject]
Now, you can access the elements inside MsgKey as a Dictionary, like JsnAryVar["NamKey"].

Related

GET request on new Alamofire Swift 3

So I decided to migrate my App to Swift 3.0 but now I am seeing myself unable to solve a problem I´m facing with a .GET request with the new Alamofire. This is the request right now:
func getAlbums(_ ID: String, ANN: String, completed: #escaping DownloadComplete) {
let searchFT = ID.replacingOccurrences(of: " ", with: "+", options: NSString.CompareOptions.literal, range: nil)
let urlPath = ""
let url = URL(string: urlPath)
Alamofire.request(url!, method: .get).responseJSON { response in
if let JSON = response.result.value as! [String: AnyObject]! {
if let dict = JSON["results"] as! NSArray! {
AlbumsArtist.removeAll()
AlbumsArtist = [String]()
ImagesArtist.removeAll()
ImagesArtist = [String]()
for items in dict {
if let AT = items["artistName"] as? String {
if AT == ANN {
if let TN = items["collectionName"] as? String {
AlbumsArtist.append(TN)
} else {
AlbumsArtist.append("")
}
if let IM = items["artworkUrl100"] as? String {
let newString = IM.stringByReplacingOccurrencesOfString("100", withString: "600", options: NSStringCompareOptions.LiteralSearch, range: nil)
ImagesArtist.append(newString)
} else {
ImagesArtist.append("")
}
}
}
}
completed()
}
}
}
}
The problem that I am getting is with if let AT = items["artistName"] as? String the error says this: Type 'NSFastEnumerationIterator.Element (aka: 'Any') has no subscript members
Thank you very much!
As mentioned in the comment you should change your code to:
if let AT = items["artistName"] as? [[String:Any]]
But to make your code more safe you should use the following:
if let AT = items["artistName"] as? [[String:Any]] {
if AT == ANN {
guard let TN = items["collectionName"] as? String,
let IM = items["artworkUrl100"] as? String else { // Some error occurred }
AlbumsArtist.append(TN);
let newString = IM.stringByReplacingOccurrencesOfString("100", withString: "600", options: NSStringCompareOptions.LiteralSearch, range: nil)
ImagesArtist.append(newString)
}
}

When i am printing an array in Swift its type(<__NSArrayM 0x60800024a1a0>) is also coming with it. Why?

{let doctorId: NSNumber = (self.selectedDoctor["id"] as? NSNumber)!
let referredTo:Dictionary = ["id":doctorId]
var postParams = [String : Any]()
postParams["referredTo"] = referredTo as AnyObject?
if self.mCase != nil{
if let patient:Patient = self.mCase.patient {
postParams["patient"] = ["id":patient.id!]
}
if let mCaseId:NSNumber = self.mCase.id{
postParams["medicalCase"] = ["id":mCaseId]
}
postParams["completeCase"] = self.completeCase as AnyObject?
postParams["includeAttachments"] = self.includeAttachment as AnyObject?
let visitDict = NSMutableDictionary ()
//let array = NSMutableArray()
for dict in self.visitIds {
let indx : Int! = (dict["visitID"] as? Int)!
visitDict["visit"] = ["id":indx!]
self.visitArray.add(visitDict)
}
if self.completeCase {
for visit in self.mCase.visits{
var id = (visit as AnyObject).id!
visitDict["visit"] = ["id": id!]
self.visitArray.add(visitDict)
}
}
postParams["referredVisits"] = self.visitArray
print(postParams["referredVisits"])
}
else{
let patient:Dictionary = ["id":self.patientId]
postParams["patient"] = patient as AnyObject?
}
marseResponse = MARSRequest.SendRequest("POST", postParams: postParams as [String : AnyObject]?,getParams: nil, service:.postpatientrererral)
}
This is how i am setting the parameters
Error Xcode is showing <__NSArrayM > while printing the array and please guide me for how to remove this. Please refer the below image. It was working fine in swift 2 but when I updated my code to swift 3 this issue appears. This is happening when I am sending the parameters in POST Method. And May be because of this I am not able to parse the data.
Data Parsing this is how i am parsing the data
How about converting your data to JSON?
For example, using standard class JSONSerialization:
let array = [
[
"visit": [
"id": 2625
]
]
]
let data = try JSONSerialization.data(withJSONObject: array, options: [])
let string = String(data: data, encoding: .utf8)
And then send string value?

How to get all keys and values into separate String arrays from NSDictionary in Swift?

let urlAsString = "https://drive.google.com/uc?export=download&id=0B2bvUUCDODywWTV2Q2IwVjFaLW8"
let url = NSURL(string: urlAsString)!
let urlSession = NSURLSession.sharedSession()
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
do {
if let jsonDate = data, let jsonResult = try NSJSONSerialization.JSONObjectWithData(jsonDate, options: []) as? NSDictionary {
print(jsonResult)
}
} catch let error as NSError {
print(error)
}
})
jsonQuery.resume()
Okay so here i am receiving data from online json then storing it as NSDictionary in jsonresult . I need to get all keys and values as into two separate arrays ?
Basically i want this
jsonresult.allkeys --> String array
jsonresult.allvalues --> String array
You can use:
let keys = jsonResult.flatMap(){ $0.0 as? String }
let values = jsonResult.flatMap(){ $0.1 }
It is quite simple because you are using jsonResult as NSDictionary.
let dict: NSDictionary = ["Key1" : "Value1", "Key2" : "Value2"]
let keys = dict.allKeys
let values = dict.allValues
In you're case
let keys:[String] = dict.allKeys as! [String]
var values:[String]
if let valuesSting = dict.allValues as? [String] {
values = valuesSting
}
For anyone trying it with newer version Swift please use compactMap()instead of flatMap()
let keys = jsonResult.compactMap(){ $0.0 as? String }
let values = jsonResult.compactMap(){ $0.1 }

parse nested JSON attributes in swift

Having trouble which is probably so minor but my searches turn up nothing. I have a json model as follows :
//quick syntax to give you an idea of the model
{user:
{"name": "",
"password": "",
"medium" : {
{"title":"",
{"description":""}}}
I'm getting the above data model from a GET request to user and it returns all the info above but when i try to parse the "medium" information such as "title" & "description" I'm having no luck. I get these responses in Xcode that say
"Value of object 'AnyObject' not unwrapped, did you mean to use ! or ?"
and then when i click on the round red Xcode message to fix it it places !s and ?s everywhere but the error remains. Here is my parse method which worked perfectly fine when I was parsing only from the "medium". Any idea what I'm doing wrong?
a portion of the parse method where i get the same error for each attribute:
all lines with the same error indicated by *
// Parse JSON data
let jsonMedium = jsonResult?["user"] as! [AnyObject] //media where user is
for jsonMedia in jsonMedium {
let media = Media()
*media.title = jsonMedia["medium"]["title"] as! String
*media.description = jsonMedia["medium"]["description"] as! String
*media.category = jsonMedia["medium"]["category"] as! String
*media.image = jsonMedia["medium"]["image"] as! String
*if let IDer = jsonMedia["medium"]["id"] as? Int{
var stringIder = String(IDer)
media.identifierString = stringIder
}
Still no luck with anything. I don't understand why it works with regular JSON but Xcode won't accept anything when I try to obtain nested. All of your help has been appreciated. In the meantime here's the full method if it helps any further
func parseJsonData(data: NSData) -> [Media] {
var medium = [Media]()
do {
let jsonResult = try NSJSONSerialization.JSONObjectWithData(data,
options: NSJSONReadingOptions.MutableContainers) as? NSDictionary
// Parse JSON data
let jsonMedium = jsonResult?["media"] as! [AnyObject]
for jsonMedia in jsonMedium {
let media = Media()
media.title = jsonMedia["medium"]["title"] as! String
media.description = jsonMedia["medium"]["description"] as! String
media.category = jsonMedia["medium"]["category"] as! String
media.image = jsonMedia["medium"]["image"] as! String
if let IDer = jsonMedia["medium"]["id"] as? Int{
var stringIder = String(IDer)
media.identifierString = stringIder
}
medium.append(media)
}
} catch {
print(error)
}
return medium
}
let json = [
"user" : [
"name" : "My Name",
"password" : "My Password",
"medium" : [
"title" : "My Title",
"description" : "My Description"
]
]
]
if let userJson = json["user"] as? [String : AnyObject] {
if let name = userJson["name"] as? String {
print("name: \(name)")
}
if let password = userJson["password"] as? String {
print("password: \(password)")
}
if let mediumJson = userJson["medium"] as? [String : AnyObject] {
if let title = mediumJson["title"] as? String {
print("title: \(title)")
}
if let description = mediumJson["description"] as? String {
print("description: \(description)")
}
}
}
Maybe it helps
let request : ASIFormDataRequest = ...your request
if request.responseString() != nil {
var jsonResponse : Dictionary<String, AnyObject>?
do{
jsonResponse = try NSJSONSerialization.JSONObjectWithData(request.responseData(), options: NSJSONReadingOptions.AllowFragments) as? Dictionary<String, AnyObject>
} catch _ {
//some error
}
}
FIXED IT! Took an entire day of deep thought and google/youtube/stack/brainstorming and your help but it was one changed line that got the whole thing going
// Parse JSON data
let jsonMedium = jsonResult?["user"]!["medium"] as? [AnyObject]
for jsonMedia in jsonMedium! {
let media = Media()
media.title = jsonMedia["title"] as! String
media.description = jsonMedia["description"] as! String
instead of :
let jsonMedium = jsonResult?["user"] as! [AnyObject] //media where user is
for jsonMedia in jsonMedium {
let media = Media()
*media.title = jsonMedia["medium"]["title"] as! String
*media.description = jsonMedia["medium"]["description"] as! String

Passing array to watch app with handleWatchKitExtensionRequest

I have finally managed to get some data to pass to my Apple Watch app from the parent application, however I am now looking to pass an array. At the moment I have it working with a 2 separate strings, however I cannot figure out how to get it to work with 2 arrays.
Here is my current code in the watch app:
func reloadTable() {
WKInterfaceController.openParentApplication(["pfquery_request": "pfquery_request"]) { userInfo, error in
println("User Info: \(userInfo)")
println("Error: \(error)")
var data = (userInfo as NSDictionary)
if let success = data["success"] as? NSNumber {
if success.boolValue == true {
var name = data.objectForKey("Name") as! String
var waitTime = data.objectForKey("WaitTime") as! String
println(name)
}
}
}
}
And in the parent app:
func application(application: UIApplication, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?, reply: (([NSObject : AnyObject]!) -> Void)!) {
if let pfqueryRequest: AnyObject = (userInfo as? [String: AnyObject])?["pfquery_request"] {
var name = ""
var waitTime = ""
var query = PFQuery(className: "Park")
var objects = query.findObjects()
if let objects = objects as? [PFObject] {
for object in objects {
name = (object.objectForKey("Name") as? String)!
waitTime = (object.objectForKey("WaitTime") as? String)!
}
reply(["success": true, "name": name, "waitTime": waitTime])
}
}
}
Can anyone point me in the right direction or provide some example code? I'm looking to pass an array of all of the object names, and waitTimes.
Thanks!
This should work, though not tested!
if let pfqueryRequest: AnyObject = (userInfo as? [String: AnyObject])?["pfquery_request"] {
var name : [String] = []
var waitTime : [String] = []
var query = PFQuery(className: "Park")
var objects = query.findObjects()
if let objects = objects as? [PFObject] {
for object in objects {
name += (object.objectForKey("Name") as? String)!
waitTime += (object.objectForKey("WaitTime") as? String)!
}
reply(["success": true, "name": name, "waitTime": waitTime])
}
}

Resources