Receiving nil when trying to pass array to watch app

I am trying to receive an array of objects (that are retrieved from Parse within the app) from a parent application to be displayed in the watch application. I have been trying a few different things but with no success.


Here is my code in the extension:


    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
      
        var parkPassed = context as! String
        println(parkPassed)
        openParentAppWithPark(parkPassed)
    }

func openParentAppWithPark(park: String) {
        WKInterfaceController.openParentApplication(["request": park], reply: { (reply, error) -> Void in
            println(reply)
        })
    }

And the code in the parent app:


    func beginBackgroundUpdateTask() -> UIBackgroundTaskIdentifier {
        return UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler({})
    }

    func endBackgroundUpdateTask(taskID: UIBackgroundTaskIdentifier) {
        UIApplication.sharedApplication().endBackgroundTask(taskID)
    }

    func application(application: UIApplication, handleWatchKitExtensionRequest userInfo: [NSObject : AnyObject]?, reply: (([NSObject : AnyObject]!) -> Void)!) {
        println("Test")

        if let userInfo = userInfo, request = userInfo["request"] as? NSArray {
            let taskID = beginBackgroundUpdateTask()
            if request == "Park1" {
                DataManager.sharedInstance.loadRides("Park1")
            } else if request == "Park2" {
                DataManager.sharedInstance.loadRides("Park2")
            } else if request == "Park3" {
                DataManager.sharedInstance.loadRides("Park3")
            } else {
                DataManager.sharedInstance.loadRides("Park4")
            }
   
            let rides = DataManager.sharedInstance.rideArray
            println("Rides: \(rides)")
   
            reply(["rideData": rides])
            endBackgroundUpdateTask(taskID)
            return
        }
    }


At the moment I am just recieving the nil every time. I assume this is because the app doesn't have time to load all of the objects into the array from parse before it tries to pass it back to the watch? In my main app I have added an observer that updates the table view when the array is ready, but I'm not sure how I would do that in this situation.


Anyone have any suggestions?


Thanks!

Nobody have any suggestions?

At the moment I am just recieving the nil every time.

Where are you seeing this nil? I see you have a bunch of println statements; presumably one of these is seeing a nil value.

btw For situations like this, where there are multiple processes in play, I generally recommend NSLog. That way you can see the output of all the processes in one place (the system log displayed in Xcode's Devices window).

I assume this is because the app doesn't have time to load all of the objects into the array from parse before it tries to pass it back to the watch?

You haven't really describes how this asynchronicity fits into your app's structure. Does

DataManager.sharedInstance.loadRides
work asynchronously? If so, then yes, it's clear that the reply going back to your watch app could have stale data because it just sends back the current state of affairs, not the state after the async work has finished.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

Thanks for the responce! Yes, 'DataManager.sharedInstance.loadRides' works asynchronously. I ended up changing my code quite a bit, and I'm definitely much closer to a solution now. There are still a couple of issues though. The first issue is that it only seems to work on a fast internet connection. I have read that I should start a background task to ensure that the request has time to complete. That would probably solve that issue, right?


The other issue is that it is only passing the last object in the loop as individual strings, whereas I need it to pass an array of all of the objects.


Here is my current code:


    func reloadTable() {
        WKInterfaceController.openParentApplication(["pfquery_request": "dummy_val"]) { 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)
                }
            }
        }
    }


App Delegate:


    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: "MagicKingdom")
            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])
            }
        }
    }

There are still a couple of issues though. The first issue is that it only seems to work on a fast internet connection.

Before you start trying to engineer the mechanics of that, you have to think about your user-level behaviour. Imagine that every network request you make takes a minute to come back? What should the watch be showing during that minute? Do you want to show a 'please wait' UI? Do you want to show the last data that was successfully fetched? And so on.

Remember that most watch UI interactions are shorter than a slow network request, so you have to have a plan for handling this case.

Share and Enjoy

Quinn "The Eskimo!"
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"
Receiving nil when trying to pass array to watch app
 
 
Q