watchOS1 - When notification arrives, first InterfaceController loads too - watchkit

Every time the Watch receives a notification (let's say local), either the static long look or the dynamic long look interface is loaded.
However, what I am observing is that every time the corresponding watch app's first interface controller is also getting loaded.
Is it something that other people have also observed?
Every time the Watch receives a notification, the watch app's first interface controller also gets run behind the scenes.
If it really does, how to distinguish when the watch app ran because user opened it and when it ran because there was a notification that came? context in awakeWithContext: is null in both cases.

Yes, I noticed too. It also seems it is in charge to handle the action methods for for local and remote Notification when tap on a button:
handleActionWithIdentifier:forLocalNotification:
I think you can use:
didReceiveRemoteNotification:withCompletion:
or
didReceiveLocalNotification::withCompletion:
to detect when your app is populated from a remote or local notification

As of watchOS 3 you can out exit of awake(withContext:) early in this scenario by inspecting the applicationState of your extension:
override func awake(withContext context: Any?) {
if #available(watchOS 3.0, *) {
if WKExtension.shared().applicationState == .background {
print("Awake with Context in background. Not processing.")
return
}
}
// otherwise, load normally
}

Related

Does firebase guarantee all events will be received, or just that state will be consistent? [duplicate]

Do event listeners guarantee that all data ever written to a path will be delivered to the client eventually?
For instance if I have a game client that pushes moves to the same path one after the other will the listening client receive all updates?
What would happen in this situation: client A pushes move 1 to game1/user1/move_data which client B is listening on; client A then immediately pushes another move updating the value at game1/user1/move_data.
Will the listening client be guaranteed to receive all moves pushed?
Currently I have a system that creates a new path per move and then I am calling single listeners on each move as each client reaches that move in it's state. It doesn't seem efficient as if the client A receives the most recent move that client B has made then client A begins listening on a path that doesn't exist yet.
The below quotes are from this link: https://firebase.google.com/docs/database/admin/retrieve-data
"The value event is used to read a static snapshot of the contents at a given database path, as they existed at the time of the read event. It is triggered once with the initial data and again every time the data changes. The event callback is passed a snapshot containing all data at that location, including child data. In the code example above, value returned all of the blog posts in your app. Everytime a new blog post is added, the callback function will return all of the posts."
The part about as they existed at the time of the read event causes me to think that if a listener is on a path then the client will receive all values ever on that path eventually.
There is also this line from the guarantees section which I am struggling to decipher:
"Value events are always triggered last and are guaranteed to contain updates from any other events which occurred before that snapshot was taken."
I am working with a language that does not have a Google based sdk and am asking this question, so I can further assess Firebases' suitability for my uses.
Firebase Realtime Database performs state synchronization. If a client is listening to data in a location, it will receive the state of that data. If there are changes in the data, it will receive the latest state of that data.
...if I have a game client that pushes moves to the same path one after the other will the listening client receive all updates?
If there are multiple updates before the Firebase server has a chance to send the state to a listener, it may skip some intermediate values. So there is no guarantee that your client will see every state change, there is just a guarantee that it will eventually see the latest state.
If you want to ensure that all clients (can) see all state changes, you should store the state changes themselves in the database.
try to this code to get update value from firebase database:-
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseDatabase = mFirebaseInstance.getReference();
mFirebaseDatabase.child("new_title").setValue("Realtime Database");
mFirebaseDatabase.child("new_title").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String appTitle = dataSnapshot.getValue().toString();
Log.e("Hey", appTitle);
title.setText(appTitle);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e("Hey", "Failed to read app title value.", error.toException());
}
});

what is the Function that takes place upon reopening app

I created an app using Xamarin.Forms. I am trying to detect if there is a change in phone's language each time the app is reopened after being closed using the back button. Tried to Debug.WriteLine on each of onStart, onSleep and onResume to see which one occurs when I open the app again but none of them worked. This is what i tried:
App.xaml.cs
protected override void OnStart()
{
Debug.WriteLine("onresume");
//CultureInfo language = CultureInfo.InstalledUICulture;
//Thread.CurrentThread.CurrentUICulture = language;
//ApplicationResource.Culture = language;
//Application.Current.MainPage = new NavigationPage(new MainPage());
}
protected override void OnSleep()
{
Debug.WriteLine("onsleep");
}
protected override void OnResume()
{
Debug.WriteLine("onresume");
}
How do I know when the app is reopened so I could try the language change code?
If i understand your concern correctly two things can help you:
On android you can have a very wierd behavour if you do not specify SingleTask for your mainactivty. Basically if you "close" the app using Back button and then click on app icon, the app is launched from start recreating App but keeps static variables and the debugger is still connected too. You can detect it setting a static variable, then checking it with a breakpoint inside App.cs constructor. So the avoid such just use LaunchMode = LaunchMode.SingleTask inside the MainActivity.cs [Activity] attribute. This way after you return to the app after the Back button + click on icon you'll get a fresh new app with OnStart invoked.
Some could say to use LaunchMode.SingleInstance but it will kill your app if you click on push notification whie app is active so better use SingleTask, it will open smoothly the running app.
To store and retrieve data between app launches use local persistent storage, full docs: https://learn.microsoft.com/en-us/xamarin/essentials/preferences?tabs=android. So when you got your language store it, then at app start (App.cs constructor) check values.
I had done a simple to test your code with the Android simulator. And I use the Console.WriteLine instead of the Debug.WriteLine.
I had found that:
When the app exited with the back button, it will call the OnSleep method and if you get into the app in the recent task, it will call the OnStart method.
When the app go to background with the home button, it will call the OnSleep methed too, but if you get into the app in the recent task, it will call the OnResume method.
So if you add a break point in the OnStart method, when you exit with the back button and get into the app again, it will hit the break point.

How does the value event work on updates with Firebase listeners?

Do event listeners guarantee that all data ever written to a path will be delivered to the client eventually?
For instance if I have a game client that pushes moves to the same path one after the other will the listening client receive all updates?
What would happen in this situation: client A pushes move 1 to game1/user1/move_data which client B is listening on; client A then immediately pushes another move updating the value at game1/user1/move_data.
Will the listening client be guaranteed to receive all moves pushed?
Currently I have a system that creates a new path per move and then I am calling single listeners on each move as each client reaches that move in it's state. It doesn't seem efficient as if the client A receives the most recent move that client B has made then client A begins listening on a path that doesn't exist yet.
The below quotes are from this link: https://firebase.google.com/docs/database/admin/retrieve-data
"The value event is used to read a static snapshot of the contents at a given database path, as they existed at the time of the read event. It is triggered once with the initial data and again every time the data changes. The event callback is passed a snapshot containing all data at that location, including child data. In the code example above, value returned all of the blog posts in your app. Everytime a new blog post is added, the callback function will return all of the posts."
The part about as they existed at the time of the read event causes me to think that if a listener is on a path then the client will receive all values ever on that path eventually.
There is also this line from the guarantees section which I am struggling to decipher:
"Value events are always triggered last and are guaranteed to contain updates from any other events which occurred before that snapshot was taken."
I am working with a language that does not have a Google based sdk and am asking this question, so I can further assess Firebases' suitability for my uses.
Firebase Realtime Database performs state synchronization. If a client is listening to data in a location, it will receive the state of that data. If there are changes in the data, it will receive the latest state of that data.
...if I have a game client that pushes moves to the same path one after the other will the listening client receive all updates?
If there are multiple updates before the Firebase server has a chance to send the state to a listener, it may skip some intermediate values. So there is no guarantee that your client will see every state change, there is just a guarantee that it will eventually see the latest state.
If you want to ensure that all clients (can) see all state changes, you should store the state changes themselves in the database.
try to this code to get update value from firebase database:-
mFirebaseInstance = FirebaseDatabase.getInstance();
mFirebaseDatabase = mFirebaseInstance.getReference();
mFirebaseDatabase.child("new_title").setValue("Realtime Database");
mFirebaseDatabase.child("new_title").addValueEventListener(new ValueEventListener() {
#Override
public void onDataChange(DataSnapshot dataSnapshot) {
String appTitle = dataSnapshot.getValue().toString();
Log.e("Hey", appTitle);
title.setText(appTitle);
}
#Override
public void onCancelled(DatabaseError error) {
// Failed to read value
Log.e("Hey", "Failed to read app title value.", error.toException());
}
});

authWithCustomToken not firing callback

When a user registers on my system, I create the user internally, and then allow the user to register with Firebase using the firebase client lib. This generates a session token for the user. Later, when a user starts the app again, the app automatically logs the user in like this:
ref.authWithCustomToken(sessionToken, function(error, authData) {...
debugger
I have verified that the sessionToken is available when the function is executed, but debugger is never reached, and no error is ever emitted.
Any help is appreciated!
I know it's a bit late, but I experienced a similar problem and it had me scratching my head for a while, so just in case it helps somebody else, here's what I found.
If I run authWithCustomToken with a token generated with one uid (uid1) and then run it again on the same ref with a different uid (uid2), the callback doesn't get fired the second time around.
In my case, I had declared the same ref in different modules that were used in the same node process and was trying to authenticate them with different uids. Although I had declared the ref twice, Firebase still saw it as the same ref because it was in the same process and referred to the same Firebase location. By declaring and authorising the ref in a parent module, I was then able to use onAuth in the child modules and the onAuth callbacks all fired as expected.
I had a similar problem with iOS, authWithCustomToken callback was never called right after install.
All consecutive launches worked fine.
My findings might be related so I thought I share them.
Problem was I called
func applicationWillResignActive(application: UIApplication) {
Firebase.goOffline()
}
func applicationWillEnterForeground(application: UIApplication) {
Firebase.goOnline()
}
in AppDelegate. Turns out if you call Firebase.goOnline() without logging in first it messes up the callback. Once I removed those two lines everything worked fine.

Stoping web service in flex?

is it possible to stop a web service from executing?
I have a flex web application that searches clients with both full name and client id, when searching by name sometimes the usuer just types the last name and it takes a long time.
Since the app is used when clients are waiting in line, I would like to be able to stop the search and use their full name or id instead, and avoid waiting for the results and then having to search the user manually within the results.
thanks
edit: Sorry, I didn't explain myself correctly, when I meant "web service" I actually meant mx.rpc.soap.mxml.WebService, I want to stop it from waiting for the result event and the fault event. thanks.
There is actually a cancel(..) method explicitly for this purpose, though it is a little burried. Using the cancel method will cause the result and fault handlers not to be called and will also remove the busy cursor etc.
Depending on how you run your searches (ie. separate worker process etc), it is also possible to extend this by added in a cancelSearch() web service method to kill these worker processes and free up server resources etc.
private var _searchToken:AsyncToken;
public function doSearch(query:String):void
{
_searchToken = this.searchService.doSearch(query);
}
protected function doSearch_resultHandler(event:ResultEvent):void
{
trace("doSearch result");
trace("TODO: Do stuff with results");
_searchToken = null;
}
protected function doSearch_faultHandler(event:FaultEvent):void
{
trace("doSearch fault: " + event.fault);
_searchToken = null;
}
public function cancelSearch():void
{
var searchMessageId:String = _searchToken.message.messageId;
// Cancels the last service invocation or an invokation with the
// specified ID. Even though the network operation may still
// continue, no result or fault event is dispatched.
searchService.getOperation("doSearch").cancel(searchMessageId);
_searchToken = null;
trace("The search was cancelled, result/fault handlers not called");
// TODO: If your web service search method is using worker processes
// to do a search and is likely to continue processing for some time,
// you may want to implement a 'cancel()' method on the web service
// to stop any search threads that may be running.
}
Update
You could use disconnect() to remove any pending request responders, but it also disconnects the service's connection. Then call initialize().
/Update
You cannot stop the web service from executing, because that's beyond the Flex app's control, but you can limit the processing of the web service's response. For instance on the app, have a button like Cancel Search which sets a boolean bSearchCanceled to true.
The result handler for the web service call checks bSearchCanceled; if true just return.

Resources