I'm not sure if this solution is the best one, since I was struggling with this as you were. What I've done is to listen to changes in the exposure offset and, from them, adjust the ISO until you reach an acceptable exposure level. Most of this code has been taken from the Apple sample code
So, First of all, you listen for changes on the ExposureTargetOffset. Add in your class declaration:
static void *ExposureTargetOffsetContext = &ExposureTargetOffsetContext;
Then, once you have done your device setup properly:
[self addObserver:self forKeyPath:@"captureDevice.exposureTargetOffset" options:NSKeyValueObservingOptionNew context:ExposureTargetOffsetContext];
(Instead of captureDevice, use your property for the device)
Then implement in your class the callback for KVO:
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context{
if (context == ExposureTargetOffsetContext){
float newExposureTargetOffset = [change[NSKeyValueChangeNewKey] floatValue];
NSLog(@"Offset is : %f",newExposureTargetOffset);
if(!self.device) return;
CGFloat currentISO = self.device.ISO;
CGFloat biasISO = 0;
//Assume 0,3 as our limit to correct the ISO
if(newExposureTargetOffset > 0.3f) //decrease ISO
biasISO = -50;
else if(newExposureTargetOffset < -0.3f) //increase ISO
biasISO = 50;
if(biasISO){
//Normalize ISO level for the current device
CGFloat newISO = currentISO+biasISO;
newISO = newISO > self.device.activeFormat.maxISO? self.device.activeFormat.maxISO : newISO;
newISO = newISO < self.device.activeFormat.minISO? self.device.activeFormat.minISO : newISO;
NSError *error = nil;
if ([self.device lockForConfiguration:&error]) {
[self.device setExposureModeCustomWithDuration:AVCaptureExposureDurationCurrent ISO:newISO completionHandler:^(CMTime syncTime) {}];
[self.device unlockForConfiguration];
}
}
}
}
With this code, the Shutter speed will remain constant and the ISO will be adjusted to leave the image not too under or overexposed.
Don't forget to remove the observer whenever is needed. Hope this suits you.
Cheers!