Passing Data between interface controllers in WatchKit

How would I pass data stored in a label from my Interface Controller to another interface controller in WatchKit using Swift? I can’t seem to find an answer anywhere, hope someone here can help me. I’ve included the section of my code that deals with calculating the value I need passed. I basically want to show the same value that was calculated by the user and elaborate more on it in the next Interface Controller named ResultsController. Any help is greatly appreciated 😀

class InterfaceController: WKInterfaceController {
     var currentValue: String = "0"

     func setDisplayValue(value: Double)
    {
        var percent = value
        //  check if value is an integer
        if value % 1 == 0
        {
            // our value is an integer
            currentValue = "\(Int(value))"// new value %
        }
        else
        {
            // our value is a float
            currentValue = "\(value)"
        }
        // Display 2 decimal places in final amount
       var round =  NSString(format:"%.2f", value)
        displayLabel.setText("$\(round)") // Display final value
        // This value is what I want to be passed to another label in another IC.
    }

    // Answer Tapped
    @IBAction func totalTapped() {
        if command != nil
        {
            let answer = command!.executeWithNewValue((currentValue as NSString).doubleValue)
            setDisplayValue(answer)
            command = nil
            calculationExecuted = true
        }
    }
}

This is the second Interface controller that I want the value from the first one to be displayed in using a label.

  • Migrating NSPersistentStore from application sandbox to shared group container
  • Notify WatchKit app of an update without the watch app requesting it
  • Reading NSUserDefaults in watchOS 2 (I know App Groups doesn't work)
  • WKImage always return nil
  • watchOS - Complication shows previous entry
  • Apple Watch pre-build action to change storyboard customModule references
  • import WatchKit
    import Foundation
    
    
    class ResultsController: WKInterfaceController {
    
        @IBOutlet weak var totalLabel: WKInterfaceLabel!
    
        override func awakeWithContext(context: AnyObject?) {
            super.awakeWithContext(context)
    
            // Label to hold the same value as in previous Interface Controller
            totalLabel.setText("")
        }
    
        override func willActivate() {
            // This method is called when watch view controller is about to be visible to user
            super.willActivate()
        }
    
        override func didDeactivate() {
            // This method is called when watch view controller is no longer visible
            super.didDeactivate()
        }
    
    }
    

    Edit: Here is the tutorial I followed, I manipulated it a bit to be essentially a tip cal. I added in ResultsController to hold the information inputted by the user using the calculator from InterfaceController but I can’t seem to pass the data over to my labels in RC, in the Command I removed subtract and divide since I wouldn’t be needing those. So the only calculation buttons I have are multiply and addition. Example of how it should work: Enter in an amount 12.58 tap multiply and enter in 15 tap add and it displays the final amount of 14.46
    I need to pass over all of those values to RC in separate labels.

    Github Tutorial – Apple Watch

    Here is what I am trying to accomplish:
    Passing the initial amount to a label, and the tip amount, as well as the final cost to separate labels to resemble a bill.

    2 Solutions Collect From Internet About “Passing Data between interface controllers in WatchKit”

    The best way to do this is to override the contextForSegueWithIdentifier method that is called when you segue from one view to the next.

    The method of passing data between WKInterfaceControllers is a bit different than the method for doing so with UIViewControllers in a traditional iOS app.

    Normally, you’d do something like this:

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "showDetail" {
            let controller: DetailViewController = (segue.destinationViewController as UINavigationController).topViewController as DetailViewController
            controller.myVariable = myValue
        }
    }
    

    However, there is no prepareForSegue method in WatchKit. The contextForSegueWithIdentifier WKInterfaceController method is similar, but it has a glaring difference: it doesn’t provide you with an instance of the destination view controller.

    Instead, you return data from the method, and access that data within your target class.

    So, in your case, it would look like this:

    // In InterfaceController
    override func contextForSegueWithIdentifier(segueIdentifier: String) -> AnyObject? {
        // You may want to set the context's identifier in Interface Builder and check it here to make sure you're returning data at the proper times
    
        // Return data to be accessed in ResultsController
        return self.currentValue
    }
    
    // In ResultsController
    override func awakeWithContext(context: AnyObject?) {
        super.awakeWithContext(context)
    
        // Make sure data was passed properly and update the label accordingly
        if let val: String = context as? String {
            self.totalLabel.setText(val)
        } else {
            self.totalLabel.setText("")
        }
    }
    

    Use pushControllerWithName:context: or presentControllerWithName:context:

    NSDictionary *exampleObj = @{@"key":@"value"};
    [self pushControllerWithName:@"YourInterfaceControllerName" context:exampleObj];
    

    On the receiving end, use awakeWithContext:context

    - (void)awakeWithContext:(id)context
    {
        [super awakeWithContext:context];
        NSString *value = context[@"key"];
    }
    

    As context is an (id), you can pass anything, not just NSDictionary.