Confused with quasar documentation. Not sure what that means
From docs: Notifications are meant to be dismissed only by the user, however for exceptional cases you can do it programmatically. Especially useful when you set indefinite timeout (0).
const dismiss = $q.notify({...})
...
dismiss()
For those who got confused with documentation as much as i did
$q.notify(...) returns you another function, you can leave it as is, call it with no parameters to hide the said notification, or call with some parameters to update the said notification
$q.notify({ message: 'I am a regular notification, will open and close as usual' })
const dismiss = $q.notify({ message: 'I will hide programmatically', timeout: 0 // Optionally set timeout to 0 to fully control the dismissing })
setTimeout(() => {
dismiss() // will hide the notification above
}, Math.random() * 5000)
Related
Unlike tracking a user's session via them logging in, I need to find a way to timeout the user going through a multi-page registration process after x amount of time of inactivity.
The registration process uses an observable class to store the various entered values in memory as the user is going through the process. Each page of the registration is within a NavigationView, with navigation links on each page that takes the user to the next screen.
I can't just timeout the entire registration if they are actively going through it because for some it may take a few minutes, whereas for someone who has a disability, it might take a lot longer. As long as there is some sort of activity I want to ensure no timeout.
However, if the user is on page 2 for example, and then gets a phone call (sending the app into the background), forgets about it until the next day (again, just an example), and then comes back to the app to keep going, I want to show an alert that upon the user tapping OK would clear out the values within the observable class and take them back to a certain page of the app.
While there are a lot of suggestions on something like this for UIKit (not really exactly for this, but....) I haven't seen anything to do this using the latest SwiftUI for iOS 15+.
I need the timer to start when the user begins the registration process, and not be interrupted if the app goes into the background. If the user quits the app, there's nothing I can do about that, but if the app remains open, in either the foreground OR the background, I need to time them out of the registration process, after x amount of time of inactivity.
#jnpdx Approach definitely works.
I can add an approach without Timer, using DispatchQueue, which also works when the app goes into background:
// global timer var for every view
var timerWorkItem: DispatchWorkItem?
struct ContentView: View {
#State private var message = "not started"
var body: some View {
VStack {
Text(message)
.font(.title)
Button("Start") {
message = "in process"
// set timer
timerWorkItem = DispatchWorkItem {
message = "timed out!"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 10, execute: timerWorkItem!)
}
.padding()
Button("Do something") {
// cancel old item
timerWorkItem?.cancel()
// set new item
timerWorkItem = DispatchWorkItem {
message = "timed out!"
}
DispatchQueue.main.asyncAfter(deadline: .now() + 10, execute: timerWorkItem!)
}
.padding()
}
.buttonStyle(.bordered)
}
}
In the current implementation, my payment takes a long time in some cases. Often users have an error like "Apple pay not completed". The question says that in iOS 11 this happens after 15-20 seconds, can I increase this time, if so, how ? If the payment has time to process during this time, the payment in apple pay is successful.
Unfortunately this is not possible from what i know and what i found ,
the onpaymentauthorized method has to be called within 30 seconds , if not the payment is declined . Refer to this , in most cases you only have as much as 30 seconds .
https://developer.apple.com/documentation/apple_pay_on_the_web/applepaysession/1778020-onpaymentauthorized
While changing the failure timeout is impossible, there is still a workaround to avoid the "Apple pay not completed" message for cases when, for example, your API call processing the payment has extended timeout. (At the moment of writing this answer, on iOS 13, the ApplePay dialog would timeout itself in around 30 secs).
The trick is to set a one-time timer, which would dismiss the ApplePay dialog just before it decides to give up. Of course your app must always give user proper feedback when the purchase process ends (was it success or failure), 'cause ApplePay dialog won't be able to show anything after you dismiss it.
Example timer:
_ = Timer.scheduledTimer(withTimeInterval: 25, repeats: false) { _ in
guard self.applePayBeingProcessed == true else { return }
if let applePayVC = AppUtil.shared.topMostController() as? PKPaymentAuthorizationViewController {
self.applePayHasTimeouted = true
applePayVC.dismiss(animated: true)
}
}
*applePayBeingProcessed is set to true in paymentAuthorizationViewController(_:didAuthorizePayment:handler:) and set back to false right after calling handler(PKPaymentAuthorizationResult(status: paymentStatus, errors: [error])) - so that the routine called by timer would be skipped when ApplePay dismissed in a normal way via paymentAuthorizationViewControllerDidFinish(_:)
** applePayHasTimeouted is later checked inside a completion of your payment processing API call, if true it means we need to perform actions, that are normally supposed to be performed inside paymentAuthorizationViewControllerDidFinish(_:) (because the latter will never be called after manually closing ApplePay dialog)
*** topMostController() method finds the controller from the top of hierarchy. How to do this is out of scope of current question, there lots of ways to do this, my favorite one is in this answer.
I have a requirement where I want to perform an action inside the electron app only when it is in foreground.
It is an electron-react application. On mounting of a component, I want to schedule a periodic task which only runs when the app is in focus or is being used by the user. And pause the task when the app goes in background.
How can we detect the Electron app being in foreground?
You can use the isFocused method from BrowserWindow. To get your own BrowserWindow, you can do this :
remote.BrowserWindow.getAllWindows();
This will return all your app's windows. So to get the first / primary window, you could deconstruct the array like this :
const [yourBrowserWindow] = remote.BrowserWindow.getAllWindows();
console.log(yourBrowserWindow.isFocused());
You can use the focus / blur events on your BrowserWindow to be notified when the app is focused / unfocused.
mainWindow = new BrowserWindow({})
mainWindow.on('focus', () => {
console.log('window got focus')
})
mainWindow.on('blur', () => {
console.log('window blur')
})
You may want to update the component's state within these event handlers or use any other method to keep track of the current focus status.
This assumes that you have a single application window. If you have multiple, you'll need to extend the check to cover all of your windows.
This question already has answers here:
Escaping Closures in Swift
(8 answers)
Closed 5 years ago.
I was reading the apple developer documentation's definition of escaping closures. It says "a closure is said to escape a function when the closure is passed as an argument to the function, but is called after the function returns"
I am not sure what the last part is supposed to mean, what does it mean by "after the function returns"? Does it mean "after the function returns a value"?
Take for example a call to an API. This call is going to take time, but we are going to want to do something after the call is completed. For example, say we want to refresh a UITableView with the new data that we pull. If we were to do it immediately, the data wouldn't have been received yet:
ApiObject.getObjects(completion: { (error, objects) in })
tableView.reloadData()
If we were to reload the data here, the table view will refresh immediately (before we actually have received the data). By doing it in the completion block, we are saying, run the code when we have completed the function, not when the function actually returns:
ApiObject.getObjects(completion: {(error, objects) in
self.tableView.reloadData()
})
Here we are running it once the objects have been fetched, not once the function itself has reached the end.
Edit
Maybe this will make it easier; I have the following code:
let comeInAnimation = POPBasicAnimation(propertyNamed: kPOPLayoutConstraintConstant)!
comeInAnimation.toValue = 0
comeInAnimation.completionBlock = { (anim, success) -> Void in
self.loginButton.enabled = true
self.signupButton.enabled = true
}
signUpContainingViewLeftConstraint.pop_add(comeInAnimation, forKey: AnimationString.EnterExit.identifier)
This is using the POP animation framework. In this case, I have a login and signup button, but I also have an animation for them to appear. I dont want the buttons to be clicked while they are appearing so i have their enabled set to false originally. Now you can see they get set to enabled in the completionBlock. This means, when the animation is completed, the completion block gets called and I know now is the time to set them to be enabled. Had I done it like so:
let comeInAnimation = POPBasicAnimation(propertyNamed: kPOPLayoutConstraintConstant)!
comeInAnimation.toValue = 0
signUpContainingViewLeftConstraint.pop_add(comeInAnimation, forKey: AnimationString.EnterExit.identifier)
self.loginButton.enabled = true
self.signupButton.enabled = true
Even though the enabled properties are set after the animation is called, the properties are actually being set before the animation is complete. Because the program runs line by line, the animation gets added and then immediately the properties are set (this is too early).
Note: This is an issue because these functions run asynchronously. That is, it allows the program to keep running while it is doing its thing. If this line of code blocked (stopped the program until it was compete) then putting the code in a completion block and putting it immediately after would be the same thing. In real life though, we dont want to block because it gives the appearance that the program has frozen.
I have a notifications setup which perodically retrieves notifications from a database via an AJAX call.
If notifications are new, then I want to add a jQuery UI "highlight" effect to the notification containing element.
There are lots of these for different notification types.
as the notifications are loaded in, the elements containing the notification data is giving a new class "flashAlert" where required. The function below is then triggered.
function startAlert() { // this function makes alerts flash
setInterval(function () {
$('.flashAlert').effect("highlight", {}, 2500);
}, 2500);
};
This works, however, if the class "flashAlert" is removed from the element (done by a 'clear notifications' function), the effect is still applied.
I know that I could call clearInterval in my "clear notifications" function, but then I have to set up a separate Interval function for every notification rather than a single function like this.
I've seen other questions on here with users finding difficulties having the effect working on elements which are added by jQuery, but nothing about removing the effect!
Doing a page reload clears it, but that's not what I want!
function startAlert(){
$('.flashAlert').effect("highlight", {}, 2500, startAlert);
}
And when you want it to stop in your clear notifications, simply do:
$('.flashAlert').removeClass("flashalert").stop();