Yet another torch – using AVFoundation to light things up

Very small example this time. Let’s build our own flashlight application. We’ll see how AVFoundation framework could help us in this task.

Again, we’ll not focus on UI in this example. So, we’ll have simple layout: torch selector (with the help of UISegmentedControl), torch level selector (that would be UISlider) and “off” button.

torchStoryboard
Well. First of all, when I typed this topic iOS devices had only one flash, but we’ll make future-proof application. Another interesting thing – you can select how bright flash should shine.

Let’s start with looking for flashes on physical device (actually, we’ll look for torches). AVFoundation offers us AVCaptureDevice class, which could expose all cameras (including those who have torch).

NSArray *devices = [AVCaptureDevice devices];
NSMutableArray *torchDevices = [NSMutableArray array];
[self.torches removeAllSegments];
for (AVCaptureDevice *device in devices)
{
    if ((device.hasTorch) && ([device isTorchModeSupported:AVCaptureTorchModeOn]))
    {
        [torchDevices addObject:device];
        [self.torches insertSegmentWithTitle:device.localizedName 
                                     atIndex:NSIntegerMax 
                                    animated:NO];
    }
}

We’re enumerating all devices and checking if they have torch and that torch could be switched on. Also we’re adding device localized name to our UISegmentedControl.
We also have selectedTorch property with setter being overridden.

@property (weak, nonatomic) AVCaptureDevice *selectedTorch;

-(void)setSelectedTorch:(AVCaptureDevice *)selectedTorch
{
    [_selectedTorch unlockForConfiguration];
    _selectedTorch = selectedTorch;
    NSError * __autoreleasing error;
    if (![self.selectedTorch lockForConfiguration:&error])
    {
        // signal error
    }
}

This code locks selected torch. -lockForConfiguration: method is required to make any modifications to device’s configuration. And enabling/disabling torch is considered to be configuration activity. Also, this method releases this lock for previously selected torch (by using -unlockForConfiguration method).

The rest is simple, as we now have only devices which have torch and that torch could be switched on, we’re implementing tartget/actions for slider and button.

- (IBAction)torchOff
{
    self.selectedTorch.torchMode = AVCaptureTorchModeOff;
    self.torchLevel.value = 0;
}

- (IBAction)torchLevelChanged
{
    NSError * __autoreleasing error;
    BOOL torchMode;
    if (self.torchLevel.value)
    {
        torchMode = [self.selectedTorch setTorchModeOnWithLevel:self.torchLevel.value
                                                          error:&error];
    }
    else
    {
        self.selectedTorch.torchMode = AVCaptureTorchModeOff;
        torchMode = YES;
    }
    if (!torchMode)
    {
        // signal error
    }
}

Our UISlider is set to return values from 0 to 1 and that range is expected by -setTorchModeOnWithLevel:error: method. Level of 0 is not valid though, instead we set torchMode property to AVCaptureTorchModeOff to disable flashlight.

That’s it. With this small app we can get some light in the dark.

As always, consult Apple documentation on AVFoundation framework, and AVCaptureDevice class reference.
Source code is available on GitHub.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s