Life Cycle of Watch app & Glance

For LifeCycle in Watch OS2: check this Apple Documentation on WKExtensionDelegate.

Screen Shot 2015-07-07 at 3.26.25 pm

Firsly, in Glance Controller in Watch OS2, you see awakeWithContext, willActivate and didDeactivate. 

There is no init in Glance. 

1. AwakeWithContext (used to load data to display)

AwakeWithContext will be called once, then willActivate called every time the Glance appears.

(If this is a page-based app, awakeWithContext will be called first on all controllers before the willActivate is called on the first page. And never called again.

If this is a hierarchical app, awakeWithContext will be called for the first level only, the next levels will be created on-fly. Once we go back to original level, deeper-level controllers are deallocated -> so if you go down a level: then controller is created, init & awakeWithContext will be called again for it. Same for MODAL controllers.)

- (void)awakeWithContext:(id)context {
    [super awakeWithContext:context];
   // context is NSExtensionContext class

An NSExtensionContext is the host app’s context from which the app extension is invoked.

The most important part of this Context is the inputItems array.

New changes in Watch 1.0.1: page-based now will have willActivate & didDeactivate called on the next page, to prepare for that page to be ready.


2. WillActivate (used to update the changes of data to display)

We can only update the UI when it’s on screen (active), so any code to update UI must be called after willActivate and before didDeactivate.

3. Notifications

On lowering wrist: 

NSExtensionHostWillResignActiveNotification and NSExtensionHostDidEnterBackgroundNotification are delivered. Then didDeactivate (of the current visible controller)  is called before the app goes to SUSPENDED mode.

To kill the app, you have to use the Force-Quit mechanism (2 long press on Power button).

On raising wrist: 

In 1.0.1 willActivate is called first.

NSExtensionHostWillEnterForegroundNotification and  NSExtensionHostDidBecomeActiveNotification are delivered. Then willActivate (of the will-be-visible controller) is called before the app goes to ACTIVE mode. (1.0.0)

GLANCE Networking

1. Use Default NSURLSession – The DataTask

2. Request background (async.queue): NSProcessInfo.processInfo().performExpiring …

3. Use dispatch_semaphore to time out.

Communicating with WCSession

” The WCSession class facilitates communication between a WatchKit extension and its companion iOS app. Both processes must create and configure an instance of this class at some point during their execution. When both session objects are active, the two processes can communicate immediately by sending messages back and forth. When only one session is active, the active session may still send updates and transfer files, but those transfers happen opportunistically in the background.

To configure the session, assign a delegate to the default session object and call that object’sactivateSession method. Your WatchKit extension and iOS app each must configure their own session object. Activating the session opens a channel that allows each app to communicate with its counterpart.

For more information about implementing the delegate object, see WCSessionDelegate Protocol Reference. ” – Quoted from Apple

Application Context (link)

Application Context is the dictionary that is sent to counter-part app, can be read later when the counter-part app wakes up.

1. Updating: updateApplicationContext:

We use applicationContext to see what we have sent, and use receivedApplicationContext for what we have received from counter-part.

Important Tips

1. Always debug when Watch is on charger !

2. Each app has 5MB image cache:  addCachedImage:name: will cache encode image as PNG and cache it. If we want JPG, use addCachedImageWithData:name: -> save a lot more space.

3. We can cache image on a background thread (but then the oldest image is undetermined, we will need to manage that ourself).

4. Turn off Wrist-detection (Watch Settings) to test notifications.

5. Improve loading time by doing less in willActivate. 

6. Users can run the Watch app before the iPhone app, so always test it.

7. Use KVO to update the labels -> better than timers (only update when changed -> save battery). Check out JBInterfaceController.

8. Syncing between the iPhone app and the Watch app: when things changed on iPhone app, we need to update the Watch and vice-versa if needed.

9. While we can’t create controllers programmatically, we can hide/unhide them to have different look.

10. Watch elements only have setters, not getters, so keep the current values in a property.

11. Always use asset and store on Watch app (not extension).

12. Local notifications require soundName property!