What is the lifecycle of Watch App? - watchkit

There are two subclasses of WKInterfaceController in my Apple Watch app.
The first one is the entrance of another one, their relationships is nextPage with the Interface Builder.
For the awakeWithContext, willActivate and didDeactivate method in each InterfaceController, I printed them all out while watch app launching.
And I got this output:
awakeWithcontext -> First
awakeWithContext -> Second
willActivate -> First
willActivate -> Second
didDeactivate -> Second
and I swipe to the next InterfaceController:
willActivate -> Second
didDeactivate -> First
So now the question is:
Will all the awakeWithContext method of all InterfaceControllers in Watch App be fired as long as launched?
What about the willActivate method?

The life cycle of watchOS apps is as described below.
awakeWithContext
When initializing the page, awakeWithContext will be called. This is the first method to be called, and no UI is displayed yet.
You should do something like updating model arrays for table views, setting properties, etc in awakeWithContext. This method has a very similar job to initializers in simple classes (init()), but this time in WKInterfaceControllers.
The answer of your first question:
awakeWithContext will be called on ALL PAGES as soon as the watchOS
app launches.
willActivate
When the interface controller is about to be displayed, willActivate will be called.
You should update label values, actions and anything else related to view elements there.
The answer of your second question:
willActivate will be called on ALL PAGES as soon as the watchOS app
launches, but in contrast with awakeWithContext, this will be called
again as soon as you view the controller (in other words, when you
navigate to that desired interface).
For the first time you launch the app, all controllers' didDeactivate will be called, except the current, and when going to another, its willActivate will be called prior to didDeactivate being called on first one.
So the life cycle is:
1- awakeWithContext of all views
2- willActivate of all views
3- didDeactivate of all views, except the first one (the current one)
And when swiping to the second:
1- willActivate of the second view
2- didDeactivate of the first view

awakeWithContext is called on initialization. This method will be called on all your pages in your watch app on launch.
willActivate is called when the interface controller is about to be displayed. The reason your second interface controller's willActivate followed by didDeactivate is called, is because it's the next page that can be onscreen. This happens in order to help load the next interface controller with relevant data since it may come on screen soon.
Therefore, if you had a 3rd page interface controller its willActivate followed by didDeactivate would be called when the 2nd interface controller is onscreen.
Apple Doc on willActivate. Page-based navigation on the watch may not explicitly say this, but they always help to read.

Related

Is there any destroy method in JavaFX we must call before leaving the page/controller

In my JavaFX application, at a specific page I have to initialize (when loading the page) some devices such as iris scanner, fingerprint scanner, cameras etc. Before leaving the page/controller it is necessary to deinitialize the devices. There are two buttons in that page. If the user leaves this page by clicking one of these two buttons I can easily deinitialize them. But if the user leaves the page by clicking any menu/sub menu (there are more than 30 menu and sub menu in this application), how can I deinitialize these devices?
There is no destructor in java and I also tried using finalize but nothing comes out.
You cannot rely only on the finalize() method. An answer to this request seems to show that this method is used by the garbage collector to check data loss references. So you need to destroy objects by-hand in a custom method, then finalize() will be automatically applied.
You must create a deinitialize() method (public or package-private, depends on the location of your MenuBar controller) then call it inside your sub-menu item.

Xamarin.Mac -- AppDelegate DidFinishLaunching -- Is the "Main Interface" specified in Info.plist already supposed to be loaded?

I have an existing .xib that needs to be displayed as the main page in a Xamarin.Mac application. If I set the "Main Interface" as this existing .xib, it does display but it's not done by the time my DidFinishLaunching override gets called. This is where I expect to do some initialization, but the outlets I specified are all null.
I am new to Xamarin and I'm trying to figure out if I need to override a different call that lets me know that the main page is done loading or if the issue lies elsewhere.
I did see that an NSWindowController has a WindowDidLoad override, but if I set the Main Interface in the info.plist, how does it know what the ViewController is for that view so that my override WindowDidLoad gets called?
I'm thinking I probably need to create the main window manually in DidFinishLaunching, but I can't find any documentation on how to create the main window through an .xib. There is documentation on how to get a storyboard from a nib, but I am not seeing anything on loading a .xib. If someone can find a good reference on how the main window gets initialize (with all the plumbing included) in a Xamarin.Mac application, that may be enough.
Thank you in advance for your time.
The chain of events is roughly:
Main invokes NSApplication.Main
Reads Info.plist to determine what xib/storyboard to load.
Storyboard is loaded and inflated. The view controller has a custom class that points to "ViewController"
Your ViewController is spun up, and WindowDidLoad get called.
DidFinishLaunching is not exactly what you are looking for.
May I suggest take a look at the documentation in question to get a better understand of the full process:
https://developer.xamarin.com/guides/mac/getting_started/hello,_mac/#Anatomy_of_a_Xamarin.Mac_Application

Espresso perform click on button located in fragment

I've got the following problem. I want to test my application with Espresso. Therefore I want to click a button which is part of the "Buttons" fragment, this fragment is located in a frame-layout in the MainActivity.
Ofcourse I can check if the frame-layout is displayed but I can not reach the layout of the fragment which is located into the frame-layout.
So my question is, how can I reach the layout of the fragment into the frame-layout, so I can click on a button into the fragment.
The result at the moment is a NoViewMatchException:
android.support.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id:...
Thanks in advance!
Edit: The exception shows the view hierarchy
These are the methods I'm calling:
onView(ViewMatchers.withId(R.id.buttons)).check(matches(isDisplayed()));
This is the frame-layout in the MainActivity for the buttons fragment:
onView(withText("LOCATIONS")).perform(click());
The locations buttons is in the Buttons fragment
withId on the button id in stead of withText doesn't make sense.
The question is not very clear. It does not matter which layout you are using. Espresso can locate the element on the view hierarchy. If your case, you're getting NoViewMatchException. That means the view (R.id.buttons) is not there when you're checking.
For debugging, you can add some wait (SystemClock.sleep(2000)) and check if it works.
If that works, you need to write the idling resource to wait for the buttons fragment to appear.

Fragment Life cycle from onPause to OnResume

In Activity life cycle we can go from OnPause to Onresume directly (this can occur if our activity leaves the foreground but is still visible, i.e. a dialog pop ups). Checking the fragment life cycle diagram: http://developer.android.com/guide/components/fragments.html
When the activity is paused then the fragments respective onPause is called. But at this point when the activity call onResume what state is the fragment in ? What life cycle callback gets called ?
The Fragment lifecycle is tied to the Activity lifecycle. If the Activity is changing the state the Fragment will aswell. Because of that a Fragment has the same major lifecycle components as an Activity like onCreate(), onResume and so on. In addition to these, there are some specific ones like onAttached(), onDetached(), onActivityCreated() etc.
A Fragment is able to draw an UI and is controlled by the Activity. If that wouldn't be the case some strange things could happen. Like the Activity goes into the background but the Fragment is still visible. That's why these two components have to sync their state.
onResume as well, check the official documentation: http://developer.android.com/reference/android/app/Fragment.html#onResume()

Start Activity in a Fragment

I want to start an activity in a fragment and the activity is just like any other installed applications. eg. Email.
I get the intent of that application from PackageManager, now I want to start that activity in my seperate Fragment. Whenever I use startActivityFromFragment is starts the application in whole screen, but I want to start that activity limited in only that fragment.
What should I do?
Drop the idea as it doesn't really make sense and I can't see that it can be done anyway.
For example if you have a dual-pane layout and want to invoke the contacts app into the right fragment which itself uses a dual-pane layout along with making use of the application bar how would you expect it to look? It's the contacts app that is making the call to setContentView and deciding how to layout itself out, not your app. If I'm mistaken in what you mean and it's your activity then of course you can create a fragment from it and load into your required view.

Resources