Hi i am using a location based app and wants to use iphone camera flashlight while in background.Unfortunately flashlight is working only in foreground ,it automatically turns off the flash in background even though the code is executing .
The code i used is working only in foreground
#import <AVFoundation/AVFoundation.h>
//flashcode
Class captureDeviceClass = NSClassFromString(#"AVCaptureDevice");
if (captureDeviceClass != nil) {
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
if ([device hasTorch] && [device hasFlash]){
[device lockForConfiguration:nil];
if (device.torchMode == AVCaptureTorchModeOff)
{
[device setTorchMode:AVCaptureTorchModeOn];
[device setFlashMode:AVCaptureFlashModeOn];
//torchIsOn = YES;
}
else
{
[device setTorchMode:AVCaptureTorchModeOff];
[device setFlashMode:AVCaptureFlashModeOff];
// torchIsOn = NO;
}
[device unlockForConfiguration];
}
}
This is a normal behavior.
Apple's sandboxing will not allow you to keep the flash on while your app is in the background.
There is no workaround unless we are talking about a jailbroken app.
Edit:
Apple is very strict on it's system's APIs usage. Especially when it comes to:
- User privacy
- Battery life
- User experience
In the case of the flashlight, the last two items are relevant. Apple will not let an app drain the battery when not in the foreground and iOS users are used to the fact that flashlight, camera, microphone... are immediately disabled when going to the background (with an exception for the microphone in some background modes cases).
To answer the comment on your initial post, iOS controls your hardware. So since Apple decided they don't want the light to stay on when the user closes the app, iOS will just power off the flash when your app goes in the background. Your app has no authority to prevent it.
Related
I have a universal application running both on iPads and iPhones. The application starts with a .xib file, built in interface builder, which acts as the launch image. Once the app launched, it switches to the appropriate view controller based on device size set in the app delegate:
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if (screenSize.height <= 568.0f) {
// iPhone 4, 4S, 5, 5C, 5S, SE
self.viewController = [[iPhoneSmallViewController alloc] init];
} else {
// All other iPhones
self.viewController = [[iPhoneLargeViewController alloc] init];
}
} else {
// All iPad models
self.viewController = [[iPadViewController alloc] init];
}
The iPad view controller supports all interface orientations (set in app targets/main setup page), but on iPhones I only allow portrait mode restricted in the view controller as such:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations
{
return (UIInterfaceOrientationMaskPortrait | UIInterfaceOrientationMaskPortraitUpsideDown);
}
I have two problems with this method:
If the iPhone is held horizontally, the app still loads in portrait mode (as per the restrictions, which is all good) but all measurements are in landscape upon initialization. UI elements stick out on the side because they were measured for a landscape view but placed on a portrait.
I use the window's size to set up everything inside the view by initializing the following variable in the ViewDidLoad method:
windowSize = [[UIScreen mainScreen] bounds].size;
Tt gives me landscape dimensions in phone is held horizontally, even though landscape mode is not allowed.
If the app loads with landscape measurements initially, all my sorting of screen sizes in the app delegate are off since I identify iPhone models by measuring screen width that is only good in portrait mode.
Question: does anyone have a way to handle this complex problem in an elegant and simple way?
Some additional info: I use Xcode 10, support all the way back to iOS9 and do everything programmatically in Objective C.
p.s: I think this method worked before but not any more in iOS 12. But I could be wrong...
Edit: I provide an image of what I want to accomplish, and all help would be greatly appreciated. As I said, this has worked before (the app is quite old), but in recent iOS releases got increasingly buggy and desperately needs a cleanup, which is what I need help with.
One thing that might solve my problem, is if I could somehow restrict interface orientations based on device type in the launchScreen.xib, as I believe that is what causes the faulty behavior on iPhones.
Maybe this SO will be helpful,
They are detecting the device orientation and then rotating the view, look at first answer:
Change orientation programmatically with button - iOS
UIInterfaceOrientation currentOrientation = [UIApplication sharedApplication].statusBarOrientation;
NSNumber *value = [NSNumber numberWithInt:UIInterfaceOrientationPortrait];
[[UIDevice currentDevice] setValue:value forKey:#"orientation"];
[UIViewController attemptRotationToDeviceOrientation];
A better way to detect device is explained here:
iOS detect if user is on an iPad
if ( UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad )
{
return YES; /* Device is iPad */
}
I've been experimenting with this for days, and worked out a solution. Although this is probably not the most elegant way to do it, so if anyone has a better solution, please feel free to post it.
It is important to allow all interface orientations in the info.plist because I was unable to restrict them based on device size in the launchScreen.xib.
Create the universal launch screen that supports both iPads and iPhones. Because all interface orientations are allowed in the info.plist, this will have no restrictions.
Below is my current method in the app delegate. This is not the best way to do identifying the smaller iPhones (which I need for reasons... :), but because of the size differences, this works quite well.
At this point, the phone can be in any of the four interface orientations set in the info.plist, but because only the small handsets have a 320-width it is easy to catch it:
// Get screen size
CGSize screenSize = [[UIScreen mainScreen] bounds].size;
// Determine device based on screen dimensions
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
if ( (screenSize.height == 320.0f) || (screenSize.width == 320.0f) ){
// iPhone 4, 4S, 5, 5C, 5S, SE
self.viewController = [[iPhoneSmallViewController alloc] init];
} else {
// iPhone 6, 6S, 6P, 6SP, 7, 7P, 8, 8P X, XS, XM, XR
self.viewController = [[iPhoneLargeViewController alloc] init]; //Same as previous
}
} else {
// All iPad models
self.viewController = [[iPadViewController alloc] init];
}
Restrict interface orientations in the iPhone view controllers (all other view controllers will inherit the ones we set in the info.plist).
Do it like so:
- (UIInterfaceOrientationMask)supportedInterfaceOrientations {
return (UIInterfaceOrientationMaskPortrait);
}
There is another trick we need to do for the above to work though. When the window loads for the first time, it will not take into consideration the restriction we added to the view controller. That means, if we do our setup in the viewDidLoad method, we will receive landscape screen dimensions if the device is held horizontally (even though this orientation is not allowed). Restriction will be applied once the viewDidLoad method has concluded.
Therefore, to prevent buggy behavior, you need to create a separate method in which you do your setup (such as postViewDidLoad) and call it once the real viewDidLoad had concluded:
- (void) viewDidLoad
{
[super viewDidLoad];
[self performSelector:#selector(postViewDidLoad) withObject:nil afterDelay:0.0f];
}
In this method, you will get access the real screen size based on your restrictions you set in the supportedInterfaceOrientations method.
And that is basically it. If you have multiple views, all with different restrictions, just follow steps 4 and 5 in each of them to properly setup your workflow.
My application uses the camera.
In iOS8 they include a new privacy setting, Camera, where the user can manage
use of camera rights for each application.
Problem:
If the user didn't allow my application to use camera then how can i know that
My application have no access for camera.
like i can use ALAssetsLibrary authorizationStatus to discover the status of the photolibrary
or ABAddressBookGetAuthorizationStatus to know status of phonebook access.
Question:
How i can know whether my application has camera access or not in iOS8,
so that I may prompt the user to allow camera access for my application?
I have below print screen of Photo booth which having same problem
as my application have.
When there is no camera access it will only show black screen no message nothing.
Check AVAuthorizationStatus for camera availability and then handle cases accordingly
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(status == AVAuthorizationStatusAuthorized) {
// authorized
} else if(status == AVAuthorizationStatusDenied){
// denied
} else if(status == AVAuthorizationStatusRestricted){
// restricted
} else if(status == AVAuthorizationStatusNotDetermined){
// not determined
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if(granted){
NSLog(#"Granted access");
} else {
NSLog(#"Not granted access");
}
}];
}
I'm trying to test to play a song in with silence mode activate.
I have this code which I picked up from the answers in this web:
if(CFStringGetLength(state) == 0) {
//SILENT
NSLog(#"Silent switch is on");
//create vibrate
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
//this 2 line below use to play audio even in silent/vibrator mode too
UInt32 audioCategory = kAudioSessionCategory_MediaPlayback;
AudioSessionSetProperty( kAudioSessionProperty_AudioCategory, sizeof(UInt32), &audioCategory);
NSError *error;
AVAudioPlayer *player = [[AVAudioPlayer alloc]initWithContentsOfURL:[NSURL URLWithString:soundPath] error:&error];
[player play];
NSLog(#"error %#",error);
}
else {
//NOT SILENT
NSLog(#"Silent switch is off");
AudioServicesPlaySystemSound(finishedSound);
}
I'm testing in a iPod touch 4 generation ios 6 the sound sounds when the app is in background and foreground (with volume to a minimum).
But with iPad one with iOS 5.1.1 it doesn't sound none of two situations.
The sound sounds with the silence mode off in both devices.
Do you know what can I change to achieve that the app sounds in both situations ?
I just published an application on the App Store with an iAd banner. When I downloaded it to check for the advertisement, I just saw a plain white horizontal rectangle even though it says "Live: This app is receiving live ads." in development.
adView = [[ADBannerView alloc] initWithFrame:CGRectZero];
[adView setCurrentContentSizeIdentifier:ADBannerContentSizeIdentifierLandscape];
[adView setDelegate:self];
[self.view addSubview:adView];
[self.view bringSubviewToFront:adView];
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
return YES;
}
Everything in my performance chart is zero, except for the 715 requests. What does this mean?
Also, is it possible for iAd to determine the user's location so that apple can put ads from local companies? For example, the user is in Japan, will iAd only show ads from Japan?
Does it work in the simulator, i don't think it's a programming error but rather a technical error from apples side. Manny developers is experiencing this:
Can not see iAd in program?
I think there is no ad available so your app receives a nil value. I don't see any check for that, so regardless if it's nil or not, your app tries to display what it got, which may be nil. So you end up with a blank ad with no link what you see there.
I suggest in the next version to check for that and/or use some fallback method like AdMob or something.
You need to check if your ADBannerView received an ad or not and then display or hide it accordingly.
-(void)bannerViewDidLoadAd:(ADBannerView *)banner {
// Display banner
adView.alpha = 1.0;
}
-(void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error {
// Hide banner
adView.alpha = 0.0;
}
So I have a universal app and I'm setting up the content size of a UIScrollView. Obviously the content size is going to be different on iPhones and iPads. How can I set a certain size for iPads and another size for iPhones and iPod touches?
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
// The device is an iPad running iOS 3.2 or later.
}
else
{
// The device is an iPhone or iPod touch.
}
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone)
and
if(UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
The macros UI_USER_INTERFACE_IDIOM() also works on older iOS versions like iOS 3.0 without crashing.
UI_USER_INTERFACE_IDIOM() is the best solution in your case since your app is universal. But if you are running an iPhone app on iPad than UI_USER_INTERFACE_IDIOM() will return UIUserInterfaceIdiomPhone, regardless of the device. For such purposes as that, you can use the UIDevice.model property:
if ([[UIDevice currentDevice].model rangeOfString:#"iPad"].location != NSNotFound) {
//Device is iPad
}
In Swift 2.x you can use the following equalities to determine the kind of device:
UIDevice.currentDevice().userInterfaceIdiom == .Phone
or
UIDevice.currentDevice().userInterfaceIdiom == .Pad
In Swift 3 for new people coming here.
if UIDevice.current.userInterfaceIdiom == .pad {
\\ Available Idioms - .pad, .phone, .tv, .carPlay, .unspecified
\\ Implement your awesome logic here
}
The UIDevice class will tell you everything you need to know about the device. The model property, for instance, will tell you the model of the device. You can use this to determine which view to use for the current device.
Use the UIScreen class to determine the application's frame.
CGRect usableSpace = [[UIScreen mainScreen] applicationFrame];
The returned rectangle is the screen's size minus the status bar. Don't use the UI idioms for determining available space as they're not future-proof.
By the way, UIViewController can resize content views (including scroll views) automatically, as well as provide you with other goodies, such as auto-rotation. Consider it if it's appropriate in your situation.
if you are using swift,
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiom.Pad)
{
// device is ipad
}
else
{
//device is iPhone
}
You can also check the UIUSerInterfaceIdiom and choose the device you want to UIUserInterfaceIdiom.Pad or UIUserInterfaceIdiom.Phone or UIUserInterfaceIdiom.TV or UIUserInterfaceIdiom.CarPlay