Passing array to watch app with handleWatchKitExtensionRequest - ios

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])
}
}

Related

Adding review[] with google places details

Following the Google API documentation (https://developers.google.com/places/web-service/details) I'm trying to adding for the first time review[] with google places details in my custom table view cell, but it does not work. I already added other parameters like the website and phone number and both working well, but whit review I'm definitely doing something wrong. This is my custom tableViewCell
private let authorKey = "author_name"
private let ratKey = "rating"
private let ctextKey = "text"
class MyTableViewCell: UITableViewCell {
#IBOutlet weak var myCommentsText: UILabel!
var place: EClass?
func update(place:EClass) {
self.place = place
myLabel.text = place.name
myImage.image = UIImage(named: "foto_icon.png")
if let url = place.photos?.first?.getPhotoURL(maxWidth: maxWidht) {
myImage.af_setImage(withURL: url)
}
NearZone.PlaceDetails(place: place) { (place) in
DispatchQueue.main.async {
if let phoneNumber = place.details?["international_phone_number"] as? String {
self.myLabel2.text = place.getDescription() + "\n\(phoneNumber)"
}
else {
self.myLabel2.text = place.getDescription()
}
}
// THIS PART DOES NOT WORK
if let comments = place.details?["reviews[]"] as? [[String:Any]] {
if let au = place.details?[authorKey] as? String, let ra = place.details?[ratKey] as? Float,
let ct = place.details?[ctextKey] as? [String] {
self.myCommentsText.text = "\(comments)"
}
}
}
}
and this is my func PlaceDetails
static func PlaceDetails(place:EClass, completion: #escaping (EClass) -> Void) {
guard place.details == nil else {
completion(place)
return
}
var params : [String : Any]
params = [
"key" : AppDelegate.googlePlacesAPIKey,
"placeid" : place.placeId,
]
Alamofire.request(googlePlaceDetailsHost, parameters: params, encoding: URLEncoding(destination: .queryString)).responseJSON { response in
let value = response.result.value as? [String : Any]
place.details = (value)?["result"] as? [String : Any]
print(((value)?["result"] as? [String : Any] ?? [String : Any]()).debugDescription)
completion(place)
}
}
can someone give me an help with this problem?

REST API call using Swift to recreate App Store

So I have two models, one called AppCategory and App. I've created a function within the AppCategory class that makes an API call that brings me back all categories successfully and within those categories there is an array of dictionaries of apps which I get back in form of dictionaries but i'm not sure on how to set it as an App object.
Here is my AppCategory class:
import UIKit
class AppCategory {
var name: String?
var apps = [App]()
var type: String?
init(dictionary: [String: Any]) {
name = dictionary["name"] as? String
apps = dictionary["apps"] as! [App]
type = dictionary["type"] as? String
}
static func fetchFeaturedApps(completion: #escaping ([AppCategory]) -> Void) {
guard let url = URL(string: "https://api.letsbuildthatapp.com/appstore/featured") else { return }
URLSession.shared.dataTask(with: url) { (data, response, error) in
if error != nil {
print(error!.localizedDescription)
return
}
guard let data = data else { return }
do {
let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String: Any]
var appCategories = [AppCategory]()
for dict in json["categories"] as! [[String: Any]] {
let appCategory = AppCategory(dictionary: dict)
appCategories.append(appCategory)
if dict.index(forKey: "apps") != nil {
}
}
print(appCategories)
DispatchQueue.main.async {
completion(appCategories)
}
} catch {
print("Error in JSON Serialization")
}
}.resume()
}
}
Here is the App model class:
import Foundation
class App {
var id: Int?
var name: String?
var category: String?
var price: Double?
var imageName: String?
init(dictionary: [String: Any]) {
id = dictionary["Id"] as? Int
name = dictionary["Name"] as? String
category = dictionary["Category"] as? String
price = dictionary["Price"] as? Double
imageName = dictionary["ImageName"] as? String
}
}
I've done research and I could make these classes of type NSObject and use the setValue(forKey:) but I don't really want to do that. I've gotten as far as what's highlighted in the AppCategory class by saying if dict.index(forKey: "apps") != nil... Don't know if i'm on the right track but maybe someone can help me with this.

How to fetch exactly the same NSManagedObject I just saved to Core Data?

Simply I do it like this:
var objectID: NSManagedObjectID!
MagicalRecord.save(block: { context in
if let dictionary = (response as? [AnyHashable: Any])?["data"] as? [AnyHashable: Any] {
if let itemInfo = dictionary["item"] as? [AnyHashable: Any] {
objectID = Item.create(with: itemInfo, in: context).objectID //here objectID is NOT nil
}
}
}, completion: { error in
let item = Item.find(with: objectID) //here item is nil
completion(item, Error(error: error))
})
I also created extension:
extension NSManagedObject {
class func find(with objectID: NSManagedObjectID) -> Self? {
return mr_findFirst(with: NSPredicate(format: "SELF = %#", objectID))
}
}

Convert JSON nested objects

I am getting the following JSON from Foursquare API and I have been struggling with extracting the data:
{
"meta":{
"code":200,
"requestId":"58122e59498e5506a1b23580"
},
"response":{
"venues":[
{
"id":"4d56c381a747b60cd4a12c2b",
"name":"Sports Circle",
"contact":{},
"location":{
"lat":31.9,
"lng":35.9,
"labeledLatLngs":[
{
"label":"display",
"lat":31.9,
"lng":35.90
}
],
],
"confident":true
}
}
}
I want to get the name in venues in addition to the lat and lng values. I have tried this so far but it gets out of the second if statement at JVenues because it is nil:
func parseData (JSONData: Data){
do {
var readableJson = try JSONSerialization.jsonObject(with: JSONData, options: .mutableContainers) as! [String:AnyObject]
if let JResponse = readableJson ["response"] as? [String:AnyObject] {
if let JVenues = JResponse["venues"] as? [String:AnyObject]{
if let JName = JVenues["name"] as? String{
NSLog(JName)
}
}
}
} catch {
print(error)
}
}
This is what the other answers are getting at. Will probably make more sense if you can see it all laid out...
if let JResponse = readableJson ["response"] as? [String : AnyObject] {
if let JVenues = JResponse["venues"] as? [[String : AnyObject]] {
if let JName = JVenues.first?["name"] as? String {
NSLog(JName)
}
}
}
Note this only gets the FIRST name in the array of venues.
EDIT:
I prefer something like this. Define a struct and convert your dictionaries to the struct:
struct Venue {
var name: String?
var venueId: String?
init(_ venueDictionary: [String : AnyObject]) {
self.name = venueDictionary["name"] as? String
self.venueId = venueDictionary["id"] as? String
}
}
In your class create a property such as:
var venues = [Venue]()
From your JSON map the dictionaries to the venue array. I renamed variables that start with a capital for convention.
if let response = readableJson ["response"] as? [String : AnyObject] {
if let responseVenues = response["venues"] as? [[String : AnyObject]] {
self.venues = responseVenues.map({ Venue($0)) })
}
}
Use anywhere in your class like:
let venue = self.venues.first
print(venue?.name)
Or:
if let venue = self.venues.find({ $0.name == "Sports Circle" }) {
print("found venue with id \(venue.venueId)")
}

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

Resources