Access PNMessageResult in PubNub Swift - ios

See this link
Based on the following function I am able to receive the response,
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
println(message)
But, I am able to access the data only as message.data which is in the format of PNMessageData.
Even that returns the data in following format:
{
message = "{}";
subscribedChannel = 123;
timetoken = 14392105288780634;}
How will I access the value of message inside the message.data(PNMessageData) ?

I have written simple method to parse PNMessageResult
func client(_ client: PubNub, didReceiveMessage message: PNMessageResult) {
//Message Received on Channel:
let channel = message.data.channel
//Message Received:
guard let messageData = message.data.message as? [String : AnyObject] else { return }
//Event:
guard let event:String = messageData["event"] as? String
let data:AnyObject = messageData["data"] else { return }
guard let dict = data as? NSDictionary else { fatalError("Couldn't parse pubnub message") }
//This will be message in dictionary
let mutableDict = dict.mutableCopy() as! NSMutableDictionary
}

You are very close to accessing the data. The SDK serializes the JSON being received and stores the message as a dictionary on message.data.message which should be a dictionary.
Try this:
func client(client: PubNub!, didReceiveMessage message: PNMessageResult!) {
let dictionary: AnyObject = message.data.message
println(dictionary["accelertiony"]);
println(dictionary["accelerationx"]);
}

Related

Trouble parsing Divvy bike data with json

Im trying to parse some data from the following link: https://feeds.divvybikes.com/stations/stations.json.
func getData() {
let url = URL(string:"https://feeds.divvybikes.com/stations/stations.json")
// Submit a request
let task = URLSession.shared.dataTask(with: url!) { (data,response,error) in
// print error if there is one
if error != nil {
print(error!)
self.alert(messageTitle: "Error", messageM: "An error occured")
return
} // end if
// if there is no error, fetch the json
if let content = data {
do {
let json = try JSONSerialization.jsonObject(with: content, options:JSONSerialization.ReadingOptions.mutableContainers ) as AnyObject
if let stationName = json["stationBeanList"] as? [String: AnyObject] {
for station in stationName{
if let lat1 = ["latitude"] as? CGFloat, let long1 = ["longitude"] as? CGFloat{
print(lat1,long1)
}
}
}
}
catch {
print(error)
self.alert(messageTitle: "Error", messageM: "An error occured")
}
}//end if
}//end task
task.resume()
//endqueue
}
I would like to grab the longitude and latitude from the link above and plot them on a mapview embedded in swift but I cant seem to get even the longitude and latitude to print out or store properly. Any help would be much appreciated.
i do call the getData function on load()
and nothing shows up in the debugger when I run the application.
In the code you are considering the latitude and longitude as String. But its value is not type String.
So print(lat1,long1) will never be called.
Solution: Consider it as CGFloat instead of String, it will work I think so
let url = URL(string:"https://feeds.divvybikes.com/stations/stations.json")
// Submit a request to get the JASON data
let task = URLSession.shared.dataTask(with: url!) { (data,response,error) in
// if there is an error, print the error and do not continue
if error != nil {
print(error!)
self.alert(messageTitle: "Error", messageM: "An error occured")
return
} // end if
// if there is no error, fetch the json formatted content
if let content = data {
do {
let jsonObject = try JSONSerialization.jsonObject(with: content, options: [] ) as AnyObject
if let JSON = jsonObject["stationBeanList"] as? [[String:AnyObject]] {
for stationInfo in JSON {
if let longitude = stationInfo["longitude"] as? Float64, let latitude = stationInfo["latitude"] as? Float64 {
print(longitude,latitude)
// self.objects.append(stationInfo(latitude:latitude,longitude:longitude))
}//end if
}//end if let
}//end do
}//end do
catch {
print(error)
self.alert(messageTitle: "Error", messageM: "An error occured")
}
}//end if
}//end task
task.resume()
}//endqueue
}
After going through your code what I found is you made a just minor mistake to get lat-long from the call of web service.
if you want to fetch value you need to go according to this after the for loop of stationName.
Here is sample snippet for more clarification.
for station in stationName{
print(station["latitude"] as! Double)
print(station["longitude"] as! Double)
}
Hope this helps you :)
There are many issues.
The main issue is that the value for stationBeanList is an array not a dictionary.
.mutableContainers is completely useless in Swift, omit the parameter.
A Swift 3+ JSON dictionary is [String:Any], an array is [[String:Any]].
The unspecified JSON type in Swift 3+ is Any, never AnyObject.
A standard JSON floating point value is Double.
Never cast a JSON result to Any if the expected type is more specific.
if let json = try JSONSerialization.jsonObject(with: content) as? [String: Any] {
if let stationBeanList = json["stationBeanList"] as? [[String: Any]] {
for stationInfo in stationBeanList {
let lat = stationInfo["latitude"] as! Double
let lng = stationInfo["longitude"] as! Double
print(lat, lng)
}
}
}

How to return boolean from Cloud Code in Swift

I have a Cloud Code function that returns several objects, with some of them being Booleans. I would like to do something in my Swift code, based on the boolean values of the returned objects, as seen below. However, I keep getting multiple errors in my implementation.
Cloud Code
Parse.Cloud.define("checkCharge", function(request, response){
stripe.charges.retrieve(request.params.charge, function(err, charge) {
if(err){
console.log(err);
response.error(err);
}else{
console.log("Successfully checked the charge");
response.success(charge);
}
});
});
Swift Code
PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { (success: AnyObject?, error: NSError?) -> Void in
// if let responseJSON: [String: Bool] = success as? [String: Bool] {
if error == nil{
// let responseString = response as? String
// let chargeCaptured: Bool = success["captured"]
let objects = success as! NSArray
for object in objects {
let chargeCaptured = object["captured"] as! Bool
let chargeRefunded: Bool = success["refunded"]
let chargePaid: Bool = success["paid"]
if chargeCaptured == true || chargeRefunded == true || chargePaid == true{
print("charge already processed charge")
object.deleteInBackground()
}else{
self.storyboard
}
I get errors such as ambiguous use of subscript and type AnyObject has no subscript members, whenever I try to set a constant. I also get the error cannot convert type Bool to Bool.
Problem:
After casting into an NSArray you were trying to use it like a dictionary.
Code:
See if this fixes the issues for you:
PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { data, error in
//If there is an error, code will not proceed, it will exit
guard error == nil else {
print("error = \(error!)")
return
}
//If data is not a dictionary of the type [String : Any] it will exit
guard let objects = data as? [String : Any] else {
print("data is not of the type [String : Any]")
print("actual data type of data = \(type(of: data))")
return
}
if let chargeCaptured = objects["captured"] as? Bool,
let chargeRefunded = objects["refunded"] as? Bool,
let chargePaid = objects["paid"] as? Bool,
chargeCaptured == true || chargeRefunded == true || chargePaid == true {
print("charge already processed charge")
object.deleteInBackground()
}
else {
print("Else condition")
}
}
Suggestion:
Please use Swift native types where ever possible
Use guard, if let to conditionally unwrap optionals
It would help if you learn the Swift basics.
Use Control + I shortcut to format your code in Xcode
It turned out the cloud code returned values as NSDictionary. So this is what I did in Swift.
PFCloud.callFunctionInBackground("checkCharge", withParameters: ["charge": orderCharge]) { (success: AnyObject?, error: NSError?) -> Void in
if error == nil{
let objects2 = success as! NSDictionary
let chargeCaptured = objects2.objectForKey("captured") as! Bool
let chargeRefunded = objects2.objectForKey("refunded") as! Bool
let chargePaid = objects2.objectForKey("paid") as! Bool
}
}

PayPal Integration with IOS swift

How to get created_time and id after payment success?
i can get confirmation only "completedPayment.confirmation"
Chek this PayPal delegate method
func payPalPaymentViewController(_ paymentViewController: PayPalPaymentViewController, didComplete completedPayment: PayPalPayment)
{
print("PayPal Payment Success !")
paymentViewController.dismiss(animated: true, completion: { () -> Void in
// send completed confirmaion to your server
print("Here is your proof of payment:\n\n\(completedPayment.confirmation)\n\nSend this to your server for confirmation and fulfillment.")
let dict = completedPayment.confirmation
print("dict data is ====%#", dict)
let paymentResultDic = completedPayment.confirmation as NSDictionary
let dicResponse: AnyObject? = paymentResultDic.object(forKey: "response") as AnyObject?
let paycreatetime:String = dicResponse!["create_time"] as! String
let payauid:String = dicResponse!["id"] as! String
let paystate:String = dicResponse!["state"] as! String
let payintent:String = dicResponse!["intent"] as! String
print("id is --->%#",payauid)
print("created time ---%#",paycreatetime)
print("paystate is ----->%#",paystate)
print("payintent is ----->%#",payintent)
})
}

Ios Swift decode json data sent from GCM notification

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"].

Getting an error when trying to parse data from a json in Swift 2.0?

I'm having issues trying to parse data from a json.
This is the error I'm getting
Could not cast value of type '__NSArrayI' (0x10e7eb8b0) to 'NSDictionary' (0x10e7ebd60)
let jsonResult: AnyObject?
do {
jsonResult = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
print(jsonResult, terminator: "");
let channel: NSDictionary! = jsonResult!.valueForKey("CATEGORY_NAME") as! NSDictionary;
print(channel, terminator: "");
let result: NSNumber! = channel.valueForKey("EVENT_NAME") as! NSNumber;
print(result, terminator: "");
if (result == 0)
{
let alertController = UIAlertController(title: "", message: "There is no live stream right now", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default,handler: nil))
self.presentViewController(alertController, animated: true, completion: nil)
}
}
catch
{
// TODO: handle
}
}
task.resume()
The line I'm getting the error on is
let channel: NSDictionary! = jsonResult!.valueForKey("CATEGORY_NAME")
as! NSDictionary;
I agree with the comment above that you're trying to force the wrong type (a reason why ! should be avoided), but it's hard to give you working code without knowing the structure of your data.
JSON typically arrives as a top level array or a top level dictionary. You can use NSDictionary and NSArray, or even plain Swift Dictionaries and Arrays. The code below will parse either a top level dictionary or array. You would pass it your the result of your NSJSONSerialization call.
func parse (jsonResult: AnyObject?) {
// If our payload is a dictionary
if let dictionary = jsonResult as? NSDictionary {
// Tried to figure out the keys from your question
if let channel = dictionary["CATEGORY_NAME"] as? NSDictionary {
print("Channel is \(channel)")
if let eventName = channel["EVENT_NAME"] as? NSNumber {
print ("Event name is \(eventName)")
}
}
// Same parsing with native Swift Dictionary, assuming the dictionary keys are Strings
if let channel = dictionary["CATEGORY_NAME"] as? [String: AnyObject] {
print("Channel is \(channel)")
if let eventName = channel["EVENT_NAME"] as? NSNumber {
print ("Event name is \(eventName)")
}
}
// Or perhaps our payload is an array?
} else {
if let array = jsonResult as? NSArray {
for element in array {
print(element)
}
}
// Again, same parsing with native Swift Array
if let array = jsonResult as? [AnyObject] {
for element in array {
print(element)
}
}
}
}
parse (["CATEGORY_NAME":["EVENT_NAME" : 22]])
parse (["FOO", "BAR", ["EVENT_NAME" : 22]])

Resources