Strange WatchKit WKInterfaceController and WKExtensionDelegate lifecycle calls - watchkit

I have added logs on both WKExtensionDelegate and WKInterfaceController.
Here is what i get when playing around with starting and exiting the app in
Watch OS Simulator. (Simulator is running watchOS 4.2)
Step 1: Upon first start of the app here are the logs i see:
Init ExtensionDelegate
applicationDidFinishLaunching
applicationDidBecomeActive
awake withContext
willActivate
didAppear
Step 2: While I am in-app, after pressing home button (Cmd-Shift-h), I geth the following logs:
applicationWillResignActive
didDeactivate
willActivate
didAppear
didDeactivate
Step 3: I start my app again from app screen (the same goes when starting it from a complication)
applicationDidBecomeActive
willActivate
Question 1: in Step 2, didDeactivate is called 2 times, also willActivate and didAppear are called for some reason. I would expect just didDeactivate to be called one time. Has anyone got the answer for why this happens?
Question 2: in Step 3, after willActivate i would expect didAppear to be called. Why is it not called?

I am experiencing the same behaviour on both the simulator and the Apple Watch. I have no idea what is the problem there (bad documentation or bugs in the SDK) but from my experience it is much better (and time saving) to try workaround the issues for such weird cases instead of trying to figure out what is wrong with the SDK.

Related

ProgressNotification callback not triggered without an initial download in Realm 10

We are using MongoDB Realm in our app.
The first time the user is connected to the app, the ProgressNotifcation callback is triggered correctly, and it will work and trigger whenever a new download is coming.
Even if no download is pending, the ProgressNotification callback will be triggered (the Progress object pass in the callback will contain values from the last download) at least once(when creating it). I supposed this is due to the fact that we are downloading the first data set of the user.
But after killing the app and launching it again, the ProgressNotification callback is not triggered anymore until new data are received by the app. And from this point, the callback will be called every time we need it.
It seems that now, the framework needs a first download since the app is launch to make ProgressNotification callback to be triggered every time we need it.
This was working in the previous version of Realm (5.X.X). We just finished the migration to Realm 10 and discover this issue.
I am a bit stuck here, do not know if this is an intended change or a bug on my part. But I am pretty sure this was working in the previous version of the SDK.
Can anyone help me with this? Thanks
Note: this is no more working in both mode : .forCurrentlyOutstandingWork and .reportIndefinitely
Example
self.token = syncSession.addProgressNotification(for: .download, mode: .forCurrentlyOutstandingWork) { progress in
.......Some code........ <- this part of the code is not triggered anymore
}
EDIT - 21/12/2020
For clarification, the token returned contains a value and the .invalidate is not being called.
There is no error in the session and any new download is triggering the callback. After an initial download, everything works as expected. This means that when I add a progressNotifcation later on, the callback is triggered immediately with the progress of the previous download. But if there is not an initial download, the callback is never called.
For the scope, this method is actually in the custom publisher that I created and it is not deallocated.
Realm 10.5.0
iOS 14.3

Why the activity under google assistant go onPause in Android TV?

I am working an app on android tv.
We are discussing about the reason why activity go onPause when Google Assistant is active.
We found this problem happened suddenly in one day.
After tracing this problem for many days, we found that Assistant page cover on our app as a activity.
That's the reason why my app go onPause.
But I want to know the reason why it could suddenly become an activity.
Here is my observation of activity.
I use "adb shell dumpsys activity" to check activity status.
Without going to onPause situation
Running activities (most recent first):
Run #0: ActivityRecord{2d9fe0 u0 com.google.android.katniss/com.google.android.apps.tvsearch.app.launch.trampoline.SearchActivityTrampoline t12 f}
Running activities (most recent first):
Run #0: ActivityRecord{32ee7d7 u0 com.sv.n973796_home/.atv.ui.HomeActivity t5}
Running activities (most recent first):
Run #0: ActivityRecord{f0c9842 u0 com.sv.n973796_home/.LauncherMainActivity t3}
Going to onPause situation
Running activities (most recent first):
Run #0: ActivityRecord{bdce69a u0 com.google.android.katniss/com.google.android.apps.tvsearch.results.activity.SearchResultActivity t825}
Running activities (most recent first):
Run #2: ActivityRecord{87c5fd1 u0 com.sv.n973796_home/.common.ui.HomeActivity t817}
Run #1: ActivityRecord{28d1d6c u0 com.sv.n973796_home/.LauncherMainActivity t817}
My questions here:
Is there any document about this changing?(between "com.google.android.apps.tvsearch.app.launch.trampoline.SearchActivityTrampoline" and "com.google.android.apps.tvsearch.results.activity.SearchResultActivity")
Does this problem relate to my SDK version?(sdk version in gradle or SDK manager?)
Is there any way to check the version of com.google.android.katniss? and could I choose it?
There is no specific documentation about this changing. It's due to a change with how ATV Assistant is implemented.
No. It is entirely based on which version of ATV Assistant is on the device.
You can manually check the ATV Assistant version in system settings (Apps -> All Apps -> Show system apps, Google). You may be able to programmatically determine the version on the device by checking package manager (I don't recall if that requires a permission), but you don't want to do that. You can't guarantee that the behavior will be the same in different versions and updates are being regularly released.
I'd ask what specific issue you have with onPause being triggered (or not triggered) and start from there because ATV Assistant isn't the only reason that onPause could be called. For example, if your app handles video playback you would want to stop the player in onPause() in Android 6.0 and earlier and then in onResume() you would check if it was playing when onPause() was invoked and trigger playback again if it was. You shouldn't care about whether onPause() was invoked due to the Assistant coming to the foreground or the OS displaying an alert dialog. In versions of Android after that, you can simply have that logic in onStop/onStart, since the onStop() lifecycle method is guaranteed to be called quickly when the activity is no longer visible.

When is sessionReachabilityDidChange(_:) called on a watch WCSessionDelegate?

Apple's documentation says this in the discussion section of the method description:
This method is called to let the
current process know that its counterpart session’s reachability
changed.
The description of the isReachable property says this: WatchKit
extension. The iOS device is within range, so communication can occur
and the WatchKit extension is running in the foreground, or is running
with a high priority in the background (for example, during a workout
session or when a complication is loading its initial timeline data).
I am assuming this would mean that if the watch moves out of or into range of the iOS device, the WatchKit extension would be launched and the WCSessionDelegate's sessionReachabilityDidChange() method would be called, and the WCSession's isReachable would be true if the iOS device just came into range and false if it just when out of range.
I have not found a way to verify this in xcode. For example I put a log message in sessionReachabilityDidChange(_:) and walked out of range, but xcode simply says the app lost connection with the iphone and can no longer debug it. Can someone verify this or point me to some documentation that better describes this?
I think you cannot verify this in Xcode.
I have an app on iOS and watchOS. To check this kind of situation, I can enable debug alerts on iOS and watchOS. When func sessionReachabilityDidChange(session: WCSession) is triggered, I display a debug alert.
Now, if I run (not under Xcode) my watch extension, and then switch off the paired iPhone, the debug alert is shown on the watch.
This shows that sessionReachabilityDidChange is actually called as expected.
Apparently, under Xcode a connected iOS device is always reachable.
EDIT:
To check the situation when the watch extension is not in foreground, I did the following:
Instead of showing a debug alert, I set now the complication to a unique value that is not possible otherwise. I launched the watch extension and put it into background by showing the watch face with the complication.
When I now switch off the iPhone, the complication is not updated.
This indicates to me that sessionReachabilityDidChange is not called in background.

HKWorkoutSession isn't keeping app at front of Apple Watch

It has been stated that an app running a HKWorkoutSession will have special privileges over other watchOS 2 apps, so when a user looks at their Apple Watch, it will go to the view showing running a workout rather than the watch face.
Currently, on both my device and simulator, this is not the case. If I start a HKWorkoutSession and then leave for 5 minutes and then interact with either the Apple Watch, or the Watch Simulator, it presents the watch face.
If I then open my app, it appears to have been frozen, rather than terminated (which is what I imagine happens to other apps). As the UI will update when I need receive a response in my query.updateHandler. Also if I set it to provide haptic feedback every time my query.updateHandler receives a new HKQuantitySample it will do so, so the app must be running in the background in some form.
Has anyone else noticed this behaviour, and am I doing anything wrong, or expecting something I shouldn't?
Here is how I start my HKWorkoutSession:
self.workoutSession = HKWorkoutSession(activityType: HKWorkoutActivityType.Other, locationType: HKWorkoutSessionLocationType.Indoor)
self.healthStore.startWorkoutSession(self.workoutSession) {
success, error in
if error != nil {
print("startWorkoutSession \(error)\n")
self.printLabel.setText("startWorkoutSession \(error)")
self.printLabel.setTextColor(UIColor.redColor())
}
We're seeing that too, for the moment we've made sure 'opens last activity' is configured.
When the UI is active we start a dispatch_timer to request and process data in 1 second intervals.
Make sure you do any significant processing using the NSUserProcessInfo method though and pause the dispatch_timers whenever you are no longer active. You'll get crashes otherwise.

Loadrunner Test Scenario Controller doesn't want to start and throws this : "Failed to start/stop Service Virtualization"

I have a Loadrunner Test Scenario, here is the snapshot for it:
after opening my Test Scenario with Loadrunner Controller, I click then the "Start Scenario" button, the Scenario must run for 2 Hours, but it stops after 1 minute, and get the following Error:
Failed to stop Service Virtualization.
Failed to start Service Virtualization.
here you can see the error snapshot:
to increase the size of the snapshot please: Ctrl++
It seems that you have unwittingly activated an integration with HP Service Virtualization (or SV for short), without having SV installed on the same machine. In order to remove it, open the SV configuration dialog and uncheck all the entries.
I solved the problem with a lot of effort.
the problem is, when you have test scenario, which worked before, and you try to remove some script (groups) of the scenario,after that the test scenario will not work, what I've done, is I created from scratch a new scenario with the same test scripts, and voila it worked, I hope everyone will pay attention at that in the future

Resources