How to trigger an Apple Watch haptic feedback (or notification) from an active app after the screen just turns off? - swiftui

I'm working on a standalone countdown App for Apple Watch. When the timer is over, the watch rings or vibrate.
There are three different situations where this can happen:
The app screen is active on the user's wrist: that's the easiest part; when the timer is over, the app runs a sound/haptic feedback, no need for anything running in the background. No problem with that.
The app is in the background: Using notifications seems to be the obvious choice, and it already works very well.
The app is in the foreground, but the screen turns off either because it reached the maximum wake duration (15 or 70 seconds) or because the user rotated his wrist back in rest position, which automatically turns the apple watch's screen off.
This third and last situation is where I'm confused. Neither the first nor the second situation works here: when the app is active, but the screen turns off, the app stops running, but the notifications are still not triggered since the app is technically not in the background.
Are there any straightforward ways around this problem?

Use Extended Runtime Sessions to create smart alarms
like this:
func notifyUser(hapticType type: WKHapticType,
repeatHandler: ((UnsafeMutablePointer<WKHapticType>) -> Time
Interval)? = nil)
Apple Documentation
For schedulable sessions such as smart alarms, call this method during the session to alert the user. When you call the method, the system plays repeating haptic feedback. If the app isn’t active, the system also displays a system alarm alert on the watch.
The haptic feedback repeats at the interval specified by the repeatHandler, and continues to repeat until the application or system alert invalidates the session.
If the app isn’t active, the user can tap the Stop button to invalidate the session or tap the Open button to activate the app.
If the app is active, the app must invalidate the session by calling its invalidate method.
Only call this method on a schedulable session that’s running: you must schedule the session using the startAtDate: method, and the session’s state must equal WKExtendedRuntimeSessionStateRunning. During a smart alarm session, your app must call this method before the session expires.
Also you should check out the life cycle of watchOS app

Related

How create alarm on SwiftUI watchOS

I want create alarm app for my apple watch but I don't know how to wake a person. There is an app - Sleep Cycle and they trigger something that looks like on picture:
Watch vibrates constantly like default timer app on apple watch. The question is what's the name of this interface element? This not a notification, not an Alert (https://developer.apple.com/documentation/swiftui/alert), not a WKInterfaceDevice play function. I just want reproduce that behavior. Thanks for help!
What you need is notifyUserWithHaptic, it gives a repeating haptic and also displays this notification style screen with Open and Stop buttons if the app isn't active.
As per Apple Docs
For schedulable sessions such as smart alarms, call this method during
the session to alert the user. When you call the method, the system
plays repeating haptic feedback. If the app isn’t active, the system
also displays a system alarm alert on the watch.
Link to Apple Documentation

How to send a "you haven't used your app in a while " push notification in React Native using AWS?

Just wanted to know from a high level how I would accomplish this.
I thought that when a user opens the application, I will keep track of the last opened time in a Dynamo DB table.
Then I could have a background worker constantly check and see if anybody hasn't used their app in 3 or 4 days and then send a push notification, ie, "you haven't used your app in a while, why don't you open it up and do XYZ."
From a very high level, there are two possible ways:
1.) Local notifications (you don't need AWS for this):
You can schedule a local notification, every time the user opens up the app (or better - every time the user brings the app to foreground). It works like: User opens app -> cancel old scheduled notification if existing -> schedule new notification for "in 3 or 4 days" -> ready :-)
You can use something like this: https://github.com/zo0r/react-native-push-notification (see section Sheduled Notifications).
2.) You could do it with remote notifications (https://aws.amazon.com/sns/):
You can go the way you proposed. Then you have to store an entry in your db with the push notification token of the device and the last time the app was opened. Your worker then has to check and send the push message to the device using a service like SNS.
I would recommend 1.) over 2.) because you are independent from the users internet connection when getting the app opening info. In 2.) you can miss the opening info, when the user opens the app without internet connection. Also 2.) is more expensive then 1.) when you scale your app.
An advantage of 2.) would be, that you are more flexible when and what you send in your notification, since you can edit it on server side. 1.) would mean that it is coded in your app (at least until you build a synchronization mechanism for the variables) :-)

How to save data at time an application gets killed via the Task Manager?

In order to prevent application's data from losing caused by "End Task" from Task Manager, I am trying to save data at the function handler of WM_CLOSE event.
The app saves data successfully in case I closed my app via Alt+F4 or "close" button. But when I killed it via the Task Manager, the saving data process couldn't be done properly. It seems that the saving progress was terminated in middle.
I tried to debug it via VS2015 IDE, the debugger intercepted a break point in the WM_CLOSE handler successfully but it could not go further, hitting F10 to step over caused my app closes immediately.
Is there any way to delay the termination progress until my application saves data completely?
I found two links below but they didn't help.
How to handle "End Task" from Windows Task Manager on a background process?
How does task manager kill my program?
The task manager might decide that your application isn't responding, and terminate it. You can do nothing against it.
If you want to ensure that your data is always saved, you should save constantly (with some heuristics, like at least once every minute, preferrably after no change happened in a few seconds) in the background. It's more complex but has the advantage of working even when you won't receive WM_CLOSE at all, for example in the case of power loss.

Gracefully terminate a request based service on server

In our web application, for each http-request there is a lot of computation that happens on back end. Output can vary from 10 sec - 1 Hour. In the mean time when it is computed, "Waiting.." is shown on the website for the respective user.
But it so happens, that a user might cut down the service in between. So what all can be done on the back end so that the computation can be stopped in between to save resources? What different tactics can be applied here?
And if better (instead of killing the thread directly), then a graceful termination policy should make wonders.
I'm not sure if this fits your scenario but here is how I have tackled this issue in the past. We were generating pdf reports for a web-app. Most reports could be generated in under 5 seconds but some would take up to an hour.
When the User clicks on generate button we redirect them to a "Generating..." dialog screen which has a sort of progress bar and a Cancel button. This also launches the generate process on the server in a separate thread (we have a worker pool). The browser then polls the server regularly via ajax to check on the progress (either update the progress bar or redirect to the display page when finished).
The synchronization at the server between the generating process and the ajax process was done via a process synchronization object. The sync-obj was a very simple class instance which could be retrieved quickly from any thread at any time via some unique string.
Both processes could update this shared sync-obj. As the report generated the repgen thread would update the sync-obj which the ajax thread would inform the browser. If the User clicked the Cancel button then the ajax thread would set the "cancel" flag in the sync-ob and the repgen thread would pick that up and break out of the generate loop.
Clearly the responsiveness of the whole process depends a lot on how frequently the repgen thread checks the sync-obj and that often comes down to how the individual report was coded.
Finally, to answer your question, if the User gets bored and goes "back" and clicks the generate button again we do not cancel the first report and start a second but rather realise that it is the same report (and the same sync-obj id) and so just let the report continue. However if that does not suit your scenario then starting a generate process could cancel the first in the same manner that the User could via the Cancel button.

implementing a timer in a django app

In my Django app, I need to implement this "timer-based" functionality:
User creates some jobs and for each one defines when (in the same unit the timer works, probably seconds) it will take place.
User starts the timer.
User may pause and resume the timer whenever he wants.
A job is executed when its time is due.
This does not fit a typical cron scenario as time of execution is tied to a timer that the user can start, pause and resume.
What is the preferred way of doing this?
This isn't a Django question. It is a system architecture problem. The http is stateless, so there is no notion of times.
My suggestion is to use Message Queues such as RabbitMQ and use Carrot to interface with it. You can put the jobs on the queue, then create a seperate consumer daemon which will process jobs from the queue. The consumer has the logic about when to process.
If that it too complex a system, perhaps look at implementing the timer in JS and having it call a url mapped to a view that processes a unit of work. The JS would be the timer.
Have a look at Pinax, especially the notifications.
Once created they are pushed to the DB (queue), and processed by the cron-jobbed email-sending (2. consumer).
In this senario you won't stop it once it get fired.
That could be managed by som (ajax-)views, that call system process....
edit
instead of cron-jobs you could use a twisted-based consumer:
write jobs to db with time-information to the db
send a request for consuming (or resuming, pausing, ...) to the twisted server via socket
do the rest in twisted
You're going to end up with separate (from the web server) processes to monitor the queue and execute jobs. Consider how you would build that without Django using command-line tools to drive it. Use Django models to access the the database.
When you have that working, layer on on a web-based interface (using full Django) to manipulate the queue and report on job status.
I think that if you approach it this way the problem becomes much easier.
I used the probably simplest (crudest is more appropriate, I'm afraid) approach possible: 1. Wrote a model featuring the current position and the state of the counter (active, paused, etc), 2. A django job that increments the counter if its state is active, 3. An entry to the cron that executes the job every minute.
Thanks everyone for the answers.
You can always use a client based jquery timer, but remember to initialize the timer with a value which is passed from your backend application, also make sure that the end user didn't edit the time (edit by inspecting).
So place a timer start time (initial value of the timer) and timer end time or timer pause time in the backend (DB itself).
Monitor the duration in the backend and trigger the job ( in you case ).
Hope this is clear.