Writing a Flashlight Application using the iPhone LED

Thu, Dec 16

With the introduction of the iPhone 4, Apple has added an LED alongside the camera. It’s amazing how bright this little bugger is, ideal for a flashlight!

Since the release of the iPhone 4 I’ve been meaning to take a few minutes and write a flashlight application using the LED. My understanding from what I’ve gleaned from the API’s is that in order to turn on the LED, we need to essentially go through the same steps we would to capture video – if you know of a quicker and/or simpler process, please post some code below.

iPhone Flashlight UI

The user interface of this app is about as simple as they get – nothing more than a button to toggle the flashlight on and off.

The code for the UI is equally as trivial, in loadView, check if the device has a torch and if so, add a button to toggle the flashlight state.

- (void)loadView
{
  [self setView:[[[UIView alloc] initWithFrame:[[UIScreen mainScreen] applicationFrame]] autorelease]];
 
  AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 
  // If torch supported, add button to toggle flashlight on/off
  if ([device hasTorch] == YES)
  {
    flashlightButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 120, 320, 98)];
    [flashlightButton setBackgroundImage:[UIImage imageNamed:@"TorchOn.png"] forState:UIControlStateNormal];
     [flashlightButton addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];      
 
    [[self view] addSubview:flashlightButton];
  }
}
Toggling the Flashlight On and Off

The event management code for this app is nothing more than swapping the button background image to reflect the current state of the flashlight followed by a call to the code that will toggle the LED on and off.

- (void)buttonPressed:(UIButton *)button
{
  if (button == flashlightButton)
  {
    if (flashlightOn == NO)
    {
      flashlightOn = YES;
      [flashlightButton setBackgroundImage:[UIImage imageNamed:@"TorchOff.png"] forState:UIControlStateNormal];
    }
    else
    {
      flashlightOn = NO;
      [flashlightButton setBackgroundImage:[UIImage imageNamed:@"TorchOn.png"] forState:UIControlStateNormal];
    }
 
    [self toggleFlashlight];
  }
}
AVCaptureSession Configuration

There are a few objects that we’ll need to interact with to get everything working. AVCaptureDevice is the object we’ll use to represent the physical video device. An AVCaptureSession object will manage the flow of data. And finally, AVCaptureDeviceInput will represent the video data.

With the objects above defined, we configure the AV session to set the torch on and start the session running…

- (void)toggleFlashlight
{
  AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
 
  if (device.torchMode == AVCaptureTorchModeOff)
  {
    // Create an AV session
    AVCaptureSession *session = [[AVCaptureSession alloc] init];
 
    // Create device input and add to current session
    AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error: nil];
    [session addInput:input];
 
    // Create video output and add to current session
    AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
    [session addOutput:output];
 
    // Start session configuration
    [session beginConfiguration];
    [device lockForConfiguration:nil];
 
    // Set torch to on
    [device setTorchMode:AVCaptureTorchModeOn];
 
    [device unlockForConfiguration];
    [session commitConfiguration];
 
    // Start the session
    [session startRunning];
 
    // Keep the session around
    [self setAVSession:session];
 
    [output release];
  }
  else
  {
    [AVSession stopRunning];
    [AVSession release], AVSession = nil;
  }
}
Caveats

Stating the obvious, this application will only work on iPhone 4+ devices. Also, this application works on only on a device – you will receive compile time errors regarding AVCaptureSession if you attempt to build the app for the simulator.

One last thought – chances are running the LED for any length of time may give your battery a pretty intense workout. It may be worthwhile to keep an eye on your battery indicator if you plan to turn the light on for more than a few minutes.

iPhone LED Flashlight- Xcode Project

Here is the link to download the source code for the iPhone LED Flashlight application.

32 comments

Hi John, thank you for this application, this has been very helpful!

by Poko on Dec 17, 2010. Reply #

Rock on! I’ve tried to get this to work before and didn’t know all the steps necessary.

by wz on Dec 18, 2010. Reply #

Great tutorial!!!
Is there a way to start the torch on app launch?

by Mk on Jan 22, 2011. Reply #

Mk, if you update the loadView method so it run the same code as button pressed, that should start the torch when the app loads.

by John Muchow on Jan 24, 2011. Reply #

Hi,

Is it possible to adjust the brightness?

by HB on Feb 2, 2011. Reply #

I am not aware of a means through the API to change the brightness.

by John Muchow on Feb 2, 2011. Reply #

Does anybody know if there is a “legal” way to adjust the brightness?

by Bax on May 1, 2011. Reply #

Very helpfull, thx john

by shahid on May 3, 2011. Reply #

i know this sounds dumb, but where in XCode4 would I paste the above code?

thanks!

by kev on Jun 9, 2011. Reply #

You can download the entire Xcode project and view the code as it is written.

by John Muchow on Jun 9, 2011. Reply #

Thanks! I missed that earlier.

by Kev on Jun 9, 2011. Reply #

Hi there,

Thanks for posting. I am currently learning and this has helped me immensely. I have made some modification and streamlined it for iOS5 however the light seems to flash on for split second then go off and then comes on again? this is using mainly the code you have posted above. Anyone else come across this?

Hope some one can help.

Cheers
Camo

by Ben Camilleri on Jun 27, 2011. Reply #

hey Ben Camilleri, i am using iOS5 beta 5 and same thing happens. I do not have a iOS4 iPhone4 now, so cannot test

by chance on Aug 10, 2011. Reply #

Hi Chance,

I got around this issue by initiating the AV Session in the Application Delegate and the then just calling the switch light on function when the user hits in the ON/OFF button. (I used an if statement to look at the current state of the light and then switch the light on or off depending on that state).

Cheers
Ben

by Ben Camilleri on Aug 11, 2011. Reply #

I just realised this tutorial has the if statement on the on/off button lol

by Ben Camilleri on Aug 11, 2011. Reply #

Cool! Thanks for code

by Atul on Jul 4, 2011. Reply #

Hi everyone

@John: Thank you for this great post

@Ben: I’ve read your answer and tried to put it into practice, but i failed…

Could you post your code please? I can’t figure out how you managed, that the app doesn’t flash
and turns on after a short brake.

I tried to start the session in the AppDelegate and to switch on/off the light with a button. But if I start
the app, there is still an initial flash before the actual torch.

Cheers
Florian

by florian on Aug 21, 2011. Reply #

I got the same issue here. When I start the session in AppDelegate, there is still an initial flash before led is on.

And there is another problem, when I turn of the torch and turn it on again, the app crash with the following error message: “Multiple audio/video AVCaptureInputs are not currently supported.”

I think it basically mean the session can’t be shared. (I don’t understand why the [session stopRunning] didn’t remove the input and output.

I’m wondering what is the best solution to remove the initial flashing before the torch is really on.

Thanks

by Bagusflyer on Nov 9, 2011. Reply #

Hey,

Previous iOS releases require AVCaptureSession to be running before a client may turn on the LED torch. Consequently, the full capture stack is allocated and running, resulting in unnecessary power consumption for applications using the LED torch as a flashlight. In iOS 5, it is no longer necessary to run an AVCaptureSession to turn the torch on. Flashlight applications may now simply call:

AVCaptureDevice *backCamera = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];

if ( [backCamera isTorchAvailable] && [backCamera isTorchModeSupported:AVCaptureTorchModeOn] )

{

BOOL success = [backCamera lockForConfiguration:nil];

if ( success )

{

[backCamera setTorchMode:AVCaptureTorchModeOn];

[backCamera unlockForConfiguration];

}

}

by Ujjwal Shrestha on Jan 18, 2012. Reply #

Hi everyone,
does anyone knows how to make a S.O.S signal flashlight. I m new to IOS development so if u could help ne out.

Thanks,
Ujwal

by Ujjwal on Aug 29, 2011. Reply #

This is a very clear explanation on how to access the flashlight except for one line.
line 52 [output release]; Xcode gives me a reminder “potential leak of an object allocated on line 24 and stored into ‘session’”

Does any one know?

by Rich12345 on Sep 11, 2011. Reply #

I have this same problem regarding the potential leak. Has anyone found a fix?

Thanks,

by Tom on Nov 16, 2011. Reply #

When the torch is turned off, the AVSession is released. This should free the session object (line 55).

by John Muchow on Nov 16, 2011. Reply #

Actually, no. There is a leak. In the project you posted, in line 24 of TestViewController.m, you create a local variable “session” of type AVCaptureSession, using alloc/init. That returns an object that you own, and must release.

At line 48, you set your (retained) property AVSession to this session object. That causes the property to retain the object again. It’s retain count is now 2.

Later, in the else clause that turns the torch off, you release AVSession. That drops the retain count to 1. You then set AVSession to nil, thus losing track of it and losing any chance to ever release it.

You need to add an extra line right after the line

[self setAVSession:session];

It should read

[session release];

If you do that, the AVSession property will retain the object, and your release in the else clause will deallocate the AVCaptureSession object like it should.

Without that extra line, your code will leak an AVCaptureSession object each time you turn the flashlight on and off. (Actually, it’s possible that the system might treat the rear camera as a singleton and return the same instance each time. I doubt it, since the code uses alloc/init rather than a convenience class method, but it is possible. NSNumber init methods actually return the same object each time if you use the same value, so it MIGHT…)

One other style note:

Cocoa has a strong convention of naming variables and properties beginning with lower-case letters. Only class names should start with upper-case letters. (Core Foundation classes break this rule, but that’s a different subject.)

Aside from those fairly minor issues, this is a handy project.

by Duncan C on Jul 13, 2012. Reply #

Thanks Duncan for the thorough review and updates.

by John Muchow on Jul 13, 2012. Reply #

Does anyone have any ideas on how to create a strobe effect? I know we can loop with a pause in the code, but there’s gotta be a better way. Any ideas? Thanks!

by Coder12398 on Sep 14, 2011. Reply #

Thank you so much, this was an awesome post.

by LittlePeculiar on Sep 16, 2011. Reply #

Thank you for this example

This application has been very helpful to me!

Thanks you again.

by Billy G on Oct 22, 2011. Reply #

Wy do you need the session stuff.
If you only switch the flashlight,on/off this code is enough

AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[device lockForConfiguration:nil];
[device setTorchMode:AVCaptureTorchModeOn];
[device unlockForConfiguration];

best regards, ralf

by Ralf on Dec 4, 2011. Reply #

Hi there i might seem to be a complete idiot when it comes to this; but i need some help on this?
Ive been trying for hours with no luck. I have set up my UI with custom buttons but i need to know how to:

1) Link a button to turn the flash on/off
2) Learn how to put the buttons in
3) know where to put the different bits of code

If someone could mock up a beginners tut id appreciate it a lot

Cheers

Adam

by AdamB on Jan 10, 2012. Reply #

Hi.. just wondering,

Am i allowed to use this code in my app ?

Do I have permission to?

Thanks,

Nick

by Nick M on Jan 31, 2012. Reply #

You can use the code in your app. If you could reference iOSDeveloperTips.com in a comment header, that would be greatly appreciated.

by John Muchow on Feb 1, 2012. Reply #

Leave a Comment