XCode 9 (currently in beta) has a method called activate that can be used to bring an application to the foreground:
https://developer.apple.com/documentation/xctest/xcuiapplication/2873317-activate
Using the following code, I put the application into the background using the home button and then bring the application back to the foreground:
XCUIDevice.shared().press(XCUIDeviceButton.home)
let app = XCUIApplication(bundleIdentifier:"com.aaa.abc.xyz")
app.activate()
When the application is brought to the foreground, the user is taken back to the login screen. It behaves as if it does not have access to the token anymore which the tokens are currently stored in NSUserdefaults. Does activate not check here for tokens or clear it?
Using app.launch() again does work but curious why activate() does not?
Related
I've just implemented the ATT request in my applications. It appears at the app first opening but I would like to show it again if the user wants to change his preferences from the app settings (internal).
I tried to call the requestTrackingAuthorization method again but it enters immediately to the completion handler. Is there a way to reset the status?
I know how to put app into Single app mode programmatically, provided that Autonomous single app mode persimmon is granted by MDM server to App.
This link have detail description about how to lock app in single app mode too.
Code to Apply single app mode as below -
UIAccessibilityRequestGuidedAccessSession(true){
success in
completionBlock(success)
}
My Question/Requirement is, detect if app is running in Autonomous single single app mode or UIAccessibilityRequestGuidedAccessSession is enabled, if it's enabled then only show alert to user and ask if he wish to disable Single App mode.
I Tried to detect using UIAccessibilityIsGuidedAccessEnabled() but it's of no use, as return value is always false.
You can use BOOL UIAccessibilityIsGuidedAccessEnabled(void); to get that information.
Source#AppleDocs
You could also try to add UIGuidedAccessRestrictionDelegate and then react to
func UIGuidedAccessRestrictionStateForIdentifier(_ restrictionIdentifier: String) -> UIGuidedAccessRestrictionState
Remember though, guided access needs to be enabled by the user (triple tap home button). Not from the settings!
So #Akaino answer is right, but UIAccessibilityIsGuidedAccessEnabled method wasn't working as expected due to i used to apply code below on didFinishLaunchingWithOptions hence it wasn't working properly
UIAccessibilityRequestGuidedAccessSession(true){
success in
completionBlock(success)
}
When i applied same code above on viewDidLoad() method, UIAccessibilityIsGuidedAccessEnabled is working as expected.
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.
When i delete the app from Iphone and Run my project again The app is installed and Location Permission is asked even before the app is launched after that it disappears too quickly before user can interact with it. In this scenario the breakpoints in didFinishLaunchingWithOptions and main.m is not working at all but the app is Loading the first screen And Notification permission is Loading .I cannot forward the app to signup screen since the app requires Location for finding the nearest counties users can register But when I stop the project and run again everything is working as it should be I cannot find the reason for this problem How is the app asking for permission without even entering didFinishLaunchingWithOptions? And proceeding to first page in storyboard without even entering viewdidLoad of that particular class
If you once allow or granted the permission then it will not ask second time. So your flow is normal. Location service asks for permission with high priority so it will shown little bit earlier. If you want this on sign up screen then you should implement that code in your viewDidload of signup screen.
Update : (In response to comment)
If you uninstall or delete app from device or simulator that means you are deleting it's all data and configuration or settings(include your location permission). So, if you install it again then there is no permissions set in your device's setting app for your app. So, you got asked again for permission. that's it.
I override my app's openURL-method to know when we're about to leave the app from an ABPersonViewController, the reason being that that class doesn't notify its delegate on all of the actions it presents to the user. If it did everything would be fine.
This worked flawlessly in iOS 7, but when trying this in iOS 8.1 it turns out that the ABPersonViewController doesn't call openURL for all its actions anymore. For instance, tapping a phone number gets me to the phone app without calling openURL. Tapping the SMS bubble on the other hand will call openURL.
When tapping the facebook profile entry (with the URL "fb://profile/1234567890") the log says that "Launch Services" doesn't have a registered handler for the scheme "fb". So I'm assuming that calls to Launch Services have replaced the calls to openURL. I can't find out much more about it other than that it's "a private API".
Is there a way to detect these calls? Or, is it possible to override handlers for known schemes like "tel" and "mailto" internally for my app? I basically just need to know when we're leaving the app and where we're going.