I am using call_number plugin to make a call from my app. I am tracking the AppLifecycleState to take actions. This is the order in which states are changing-
AppLifecycleState.inactive
AppLifecycleState.resumed
AppLifecycleState.inactive
AppLifecycleState.paused
AppLifecycleState.inactive
AppLifecycleState.resumed
Last 4-I understand the flow, but I am unable to understand why is state changing to resumed the first time. According to the documentation - "The application is visible and responding to user input." when it is in resumed state but when I press button, call is directly placed.
I wonder if it is being done by the plugin in background but I don't see my app coming up even for a split second.
Related
To give more clarity on the issue, i am developing this for IOS using expo push notifications and react-navigation v6 along with expo sdk44 in my current project.
I am having an issue when the user interacts with the notification while the app is in a killed state (the notificatiosn arrives succesfully with all of the data), what im having trouble with is, i want to navigate the user to a specific screen. The problem is because my navigationRef is null. Here i need to mention i did not create a seperate RootNavigator. Like it is shown here https://reactnavigation.org/docs/navigating-without-navigation-prop/ .
What would be the "proper" way of handling this? So far i've tried putting all of the relevant push notification listener code inside NavigatonContainer's onReady callback ( this worked).
I also tried making a seperate useEffect and changing the state of a isReady variable and setting its new value in <NavigationContainer ref={navigationRef} onReady={() => {setNavigatorReady(true)}}> to force a rerender and thus running the code inside useEffect again. (this approach did not work)
Just to sum up my current problem. When the user interacts with a notification while the app is in a killed state i want them to be navigated to a specific screen.
Thanks in advance.
I too am using react-navigation 6.x and expo. To tackle this problem I pretty much followed this section on expo's docs: https://docs.expo.dev/versions/latest/sdk/notifications/#addnotificationresponsereceivedlistenerlistener-event-notificationresponse--void-void.
It shows you how to implement addNotificationResponseReceivedListener which is called whenever a user interacts with a notification. It works in all situations, even when the app is killed, which is the specific situation you are interested in.
The docs also show you how to integrate this listener with react-navigation. Link: https://docs.expo.dev/versions/latest/sdk/notifications/#handling-push-notifications-with-react-navigation
I'm implementing GADRewardedInterstitialAd into a game.
https://developers.google.com/admob/ios/api/reference/Classes/GADRewardedInterstitialAd
I'm using presentFromRootViewController:userDidEarnRewardHandler to react to the user finishing the ad.
Now I'd also like to know how to react to the user cancelling the ad.
If I continue directly after calling presentFromRootViewController, the callback handler will not have been called yet, because the systems works asynchonous, as is to be expected. So any game animations (e.g. screen fade, dialog close) will have to be stalled.
If I rely only on the handler, I won't get a callback when the ad was cancelled.
My solution would be to build in a timer that waits 30+1s to give the handler a chance to get called (hopefully on the next main thread dispatch cycle), and then react to it not being called yet (assuming a cancellation by the user).
I really hate that plan.
It's not deterministic.
It doesn't use callbacks/delegates/handlers (which are great exactly for this kind of thing)
I have to write the timer code and keep a boolean flag somewhere... it's messy.
It adds an arbitrary delay to the user experience (30+1s) when they close the ad!!
Am I thinking the wrong way about this or is this just the way Google has made it and I'll have to live with it?
Edit: please note that I'm talking about the new GADRewardedInterstitialAd API, not GADRewardedAd.
I've figured it out; it works by setting GADFullScreenContentDelegate fullScreenContentDelegate and implementing adDidDismissFullScreenContent.
In there you can check if this particular instance of GADRewardedInterstitialAd did not get a reward yet (as notified by userDidEarnRewardHandler...)
This all hinges on the assertion that adDidDismissFullScreenContent gets called AFTER the userDidEarnRewardHandler, else I will already have assumed there was no reward. Let's hope that is always the case.
https://developers.google.com/ad-manager/mobile-ads-sdk/ios/api/reference/Protocols/GADFullScreenContentDelegate
Some background
I am currently writing a UI Test for a settings pane, and click on buttons to enable certain permissions such as push notifications and location services.
However, if the alert for the permission has been displayed before (regardless of the user allowing or denying access to the permission), the alert will not display again, and will just take the user to the settings app. Unfortunately, these settings do not reset, meaning the first time I run the UI tests, alerts will show; and on all subsequent UI test runs, the buttons will take me to the settings app unless I reset the device before the tests begin.
My issue
Thus, my test needs to know if the app went into the background, and attempt to foreground it to continue the testing:
if app.state == background {
foregroundApp()
}
// continue with other tests
Is there any way to determine if the app is in the background?
What I tried
I researched methods to determine the state of the application (running/background/etc) from a UI test, and was not able to find much. I tried to check whether certain elements exist:
if (app.navigationBars.element.exists) ...
but this gives me runtime errors[1] if the user is taken to the settings page because the app under test is in the background, and the test cannot lookup the navigationBars (or other elements).
I tried using some of the methods from Facebook's private headers for XCUIApplication() and XCUIElement().
XCUIApplication().state always returns 3 no matter what state the app is currently in, and any attempts to call XCUIApplication().resolve() to foreground the app give me the same errors as before[1]
I tried to rewrite the logic to foreground the app before resuming the tests, but methods such as XCUIApplication().launch() kill the app before restarting, which I cannot do. Only siri service seems to work for me, but I cannot access the siri service through the corporate proxy, and modifying proxy permissions is not possible.
Is there any other way to check the app state?
Errors
[1] This error is printed every time I try to do something involving state. I do not call snapshotView anywhere, and thus the suggestion to use afterScreenUpdates is useless.
Failure to get snapshot within 15.0s
Cannot snapshot view (<UIKeyboardImpl: 0x7febcc75d000; frame = (0 0;
414 226); layer = <CALayer: 0x608000625720>>) with
afterScreenUpdates:NO, because the view is not in a window. Use
afterScreenUpdates:YES.`
tl;dr
I need to check whether the app I am UI testing has entered the background (i.e. user pressed the home button). Checking for existence of particular elements such as navigation bars doesn't work, neither do most methods from Facebook's private headers for XCUIApplication/XCUIElement. Foregrounding the app also causes issues, and relaunching the app is not an option; neither is siri service.
You can do this in Swift 4, using XCUIApplication.state, which will give you information about the state of the app - whether it's in the foreground or background etc. however, it's not possible to find this information in Swift 3 and below. Essentially, UI testing in Swift 3 doesn't support leaving the app.
I followed the hello world example on this page to set up lua-lgi and libnotify, successfully getting a notification that looks and acts the samea s if using os.execute("notify-send..."). Notify-send does not allow user actions, from what I've gathered, so I am attempting to directly use the libnotify library to display a notification with a button. When clicked in the notification, it should open a file. I am able to call the function described here with lua, using (building from the hello world example):
Hello:add_action("button", "Open", function(notification, action, user_data) os.open("gedit tmp") end)
which successfully displays a button with the label "Open" in the notification. However, the callback function is not called, so the file does not open. I also noticed when running the script, it actually finishes executing before the notification has fully appeared, so if the program is not running anymore when the button in the notification is clicked, then that's one reason why the callback isn't being called, if it's working correctly up until that point. This is my first experience with lua-lgi, so I'm not sure how these types of callback functions translate into lua, or if they're even supported, which is probably what I'm really trying to understand here. Any help is appreciated regarding this issue, or insight into an alternative to displaying a notification with a button and callback via other means.
I have an app. In this app, a user can like/unlike something. If the user tap the button like, it would change text to unlike, vice versa.
To make the like/unlike event run seamlessly to user, i change the text first, and then make request to my API, saying that the user like/unlike this. The API decides whether the action is liking or unliking depends on value at database. The API then returns a message stating the action made ("liked"/"unliked"). The app receives it, and then update the UI according to the result, in case the action intended by user fails.
If all runs smoothly, the user won't detect the changes made by API result.
This is the flow of liking something
user like -> button text changes to "unlike"
-> app make a request -> request is queued to operation queue
-> request run -> API decides whether that something is liked/unliked by the user
-> API returns action (in this case, "liked") -> app updates button text ("unlike")
Now my question are:
How do I handle rapid button tap by user?
How do I handle failed requests (internet disconnected, or no signal) while handling the problem no. 1?
nb: I don't want to disable the button (the app has to run seamlessly. Facebook app don't do it either, i just checked). Oh, and I use AFHTTPRequestOperationManager and set its maxConcurrentOperationCount to 1.
I resolved my problem using this answer
with a bit modification. The first time user click the button, I set a request flag to false, so that even if the user click the button many times, request won't be made before the first request is done.