How to prevent screen lock on my application with swift on iOS - ios

How can I prevent screen lock only when using Navigation?
Waze has the option to do that, how can I do this in my App?

Use this:
Objective-C:
[[UIApplication sharedApplication] setIdleTimerDisabled: YES];
Swift (legacy):
UIApplication.sharedApplication().idleTimerDisabled = true
Swift 3 and above:
UIApplication.shared.isIdleTimerDisabled = true
Make sure to import UIKit.
Here is the link to the documentation from developer.apple.com.

For Swift 3.0 here are two options depending on where you want to invoke the code:
Inside AppDelegate.swift:
application.idleTimerDisabled = true
Outside AppDelegate.swift:
UIApplication.shared().isIdleTimerDisabled = true

Swift 4
in AppDelegate.swift file, add the following line inside application function:
application.isIdleTimerDisabled = true

You can use my little lib Insomnia (Swift 3, iOS 9+) - another nice feature is that you can prevent from sleeping only when charging.
The idleTimerDisabled soultion is okay but you have to remember to set it to false afterwards.

If you have more advanced case you can use our small project: ScreenSleepManager or if it's just about particular ViewControllers - use Insomnia as pointed earlier. Manual dealing with idleTimerDisabled almost always caused me some issues (like forgot to re-set to false or handle multiple (nested) modules trying to set it).

Related

MapBox Route Progress RouteStepProgress variables mostly return nil

I used to use the userDistanceToManeuverLocation variable from the RouteStepProgress Class but this seems to just return nil recently.
Just in case I was doing something wrong I tried following the MapBox iOS nav tutorial (https://docs.mapbox.com/help/tutorials/ios-navigation-sdk/) but this had the same result.
Going by the MapBox tutorial I would do the following to get the variable:
let navigationViewController = NavigationViewController(for: directionsRoute!)
let distance = navigationViewController.navigationService.routeProgress.currentLegProgress.currentStepProgress.userDistanceToManeuverLocation
I don't seem to see any error messages or other concerns. I would get this variable on every tick of the users location but now just returns nil. Thanks for any help
So after some testing I figured out the issue is to do with the newer versions of MapBox Navigation (SDK MapboxNavigation). Anything from version 0.29.0 onwards causes issues. For now I'm sticking with version 0.28.0 and will have to report this to MapBox
Edit:
It looks like the latest version (MapboxNavigation 0.38.0 at the time of writing this edit) appears to provide a solution. I now use distanceRemaining found in the RouteProgress class which does the same thing.

ApplePay 'requiredShippingAddressFields' was deprecated in iOS 11.0

What is the latest way to set/activate email, phone, or postalAddress in IOS > 11?
I tried scrolling through the methods and attributes and came up with the following: paymentRequest.shippingType
Here is the old way:
paymentRequest.requiredShippingAddressFields = [.phone, .email, .postalAddress]
I would like to understand if there is a way to write the code that is easier than the old way and doesn't cause a warning.
It’s been replaced by requiredShippingContactFields.
https://developer.apple.com/documentation/passkit/pkpaymentrequest/2865927-requiredshippingcontactfields
requiredShippingAddressFields is deprecated, use requiredBillingContactFields instead.
For more info: documentation.

Does AudioKit 4+ support AKFrequencyTracker with Objective C?

I'm trying to incorporate AudioKit 4.0.3 (latest) into an existing iOS ViewController that's written in Objective C. I am having trouble initializing and using the AKFrequencyTracker class, even though other classes work fine (e.g. AKOscillator and AKMicrophone).
I added the following code to the ViewController viewDidLoad method in the Objective C example that came with it:
AKMicrophone *mic;
mic = [[AKMicrophone alloc] init];
AKFrequencyTracker *tracker;
tracker = [[AKFrequencyTracker alloc] init:mic hopSize:512.0 peakCount:20.0];
But I see an "No visible #interface for 'AKFrequencyTracker'" error in Xcode next to the last line.
It doesn't appear there are any init methods for AKFrequencyTracker. Any help would be greatly appreciated!
Due to a change with Swift 4 we need to explicitly add #objc to the init methods and forgot to do so with AKFrequencyTracker. I just fixed it in this commit:
https://github.com/AudioKit/AudioKit/commit/e9328d4aa8d76d0cae31eeb33b232abebd571d6e

Possible to bring the app from background to foreground?

When running an XCT UI test it is possible to put the application under test in the background with:
XCUIDevice().pressButton(XCUIDeviceButton.Home)
It it possible in some way to bring the app back to foreground (active state) without relaunching the application?
Update for Xcode 9: Starting in Xcode 9, you can now simply call activate() on any XCUIApplication.
let myApp = XCUIApplication()
myApp.activate() // bring to foreground
https://developer.apple.com/documentation/xctest/xcuiapplication/2873317-activate
Yes, it is. But, you'll need XCUIElement's private headers (which are available via header dump from Facebook here). In order to foreground the app, you need to call resolve which I believe resolves the element's query (which for applications means foregrounding the app).
For Swift, you'll have to import the XCUIElement.h into your bridging header. For Objective-C you'll just need to import XCUIElement.h.
With the app backgrounded:
Swift:
XCUIApplication().resolve()
Objective-C
[[XCUIApplication new] resolve];
If this is the only functionality you need, you could just write a quick ObjC category.
#interface XCUIElement (Tests)
- (void) resolve;
#end
If you need to launch / resolve another app. Facebook has an example of that here by going through the Springboard.
As of Xcode 8.3 and iOS 10.3, you can accomplish this with Siri:
XCUIDevice.shared().press(XCUIDeviceButton.home)
XCUIDevice.shared().siriService.activate(voiceRecognitionText: "Open {appName}")
Include #available(iOS 10.3, *) at the top of your test suite file and you should be good to go!
This is what I have in my XCUITest and it works like a charm (xcode 10.1 and test device is iPhone X 11.0)
func testWhatever() {
// You test steps go here until you need the background foreground to run
XCUIDevice.shared.press(XCUIDevice.Button.home) // To background the app
XCUIApplication().activate() // To bring the app back
// You test continues after background foreground has been done.
}
If somebody needs just move app back from background i have written (based on answer above) category that really works(great thanks to pointing to FB git)
#implementation XCUIApplication(SpringBoard)
+ (instancetype)springBoard
{
XCUIApplication * springboard = [[XCUIApplication alloc] performSelector:#selector(initPrivateWithPath:bundleID:)
withObject:nil
withObject:#"com.apple.springboard"];
[springboard performSelector:#selector(resolve) ];
return springboard;
}
- (void)tapApplicationWithIdentifier:(NSString *)identifier
{
XCUIElement *appElement = [[self descendantsMatchingType:XCUIElementTypeAny]
elementMatchingPredicate:[NSPredicate predicateWithFormat:#"identifier = %#", identifier]
];
[appElement tap];
}
#end
For Swift, you need to declare the XCUIApplication private methods interface in Bridging-Header.h like this:
#interface XCUIApplication (Private)
- (id)initPrivateWithPath:(NSString *)path bundleID:(NSString *)bundleID;
- (void)resolve;
#end
Then call resolve() in your test cases to bring the app back:
XCUIApplication().resolve()
Since Xcode 13 we got several errors that the app was not in foreground state after returning to the app.
applying this code to our "goToSpringboardAndBack()" works
XCUIDevice.shared.press(XCUIDevice.Button.home)
if XCUIApplication().wait(for: .runningBackground, timeout: 5.0) {
XCUIApplication().activate()
}
_ = XCUIApplication().wait(for: .runningForeground, timeout: 5.0)
´´´

App stuck in splash screen on iOS 9 with no error

My app gets stuck on splash screen in iOS 9 both on iPhone and simulator. I can run it on iOS 8 or lower on device and simulator with no problem. My colleague working on the same app has exactly the same problem.
There is no error or anything, just hangs on splash screen. If I stop it on xcode and try to run it from the phone or simulator directly, it would run without any problem.
By the way, I don't see didFinishLaunchingWithOptions or willFinishLaunchingWithOptions getting called!
In your "answer" you include the code:
+(void)initialize
{
titles = #[NSLocalizedString(#"CODE", nil), NSLocalizedString(#"ERROR", nil), NSLocalizedString(#"TROUBLESHOOTING", nil)];
}
This is indeed the source of your issue. It's wise to be very careful when implementing +load or +initialize. #bbum has a great article on exactly that topic.
+initialize is invoked the first time the class (or category) is touched - when the class is initialized +initialize is called by the class loading mechanism. There is no guarantee of when in the class loading process this may happen, which is part of your problem.
In your case you are using NSLocalizedString - which under the hood can be fairly heavy. It has dependancies on several other classes (NSString, etc) and can potentially access the file system. As #bbum points out in his article, that can lead to serious trouble. In your case, this may be a nasty deadlock.
Move your titles = #[NSLocalizedString... line to a more appropriate place in your object, like an initializer, awakeAfterUsingCoder:, etc. and your immediate problem should be solved. After doing so you should check your entire codebase for instances where +initialize and +load are implemented and audit them to make sure those uses are in line with #bbum 's recommendations.
OK I found the problem. It sounds ridiculous though!!
I am using UITabBarController and inside the first controller I have a UITableViewController with a customised datasource class which would initiate a hard code table header and these headers are localised!!
+ (void)initialize {
titles = #[NSLocalizedString(#"CODE", nil), NSLocalizedString(#"ERROR", nil), NSLocalizedString(#"TROUBLESHOOTING", nil)];
}
After I traced the stacks, I realised the process gets stuck right there with no trace and error! I still don't know why!
So I came up with a workaround:
+ (void)initialize {
titles = #[#"Code",#"Error",#"Troubleshooting"];
}
And only retrieve the localised value when returning the text:
- (NSString *)titleAt:(NSInteger)index {
return NSLocalizedString(titles[index],nil);
}
I have both debug and release set to NO
You sure "any SDK" also has arm64?
Ok, I think I found the answer.
You have to specify arm64 in all "Valid Architectures".
If you don't specify arm64 or forget one the app won't start and stays on the splashscreen.
Just verified this.
Is this an Xcode 7 bug?

Resources