title: Can't start iPhone X flash in touch mode
body: <p>I have problems with running iPhone X flash in torch mode.</p>
  
  <p>Back AVCaptureDeviceTypeBuiltInTelephotoCamera selected as capture device:</p>
  
  <pre><code>com.apple.avfoundation.avcapturedevice.built-in_video:2' -
  AVCaptureDeviceTypeBuiltInTelephotoCamera
  </code></pre>
  
  <p>After checking touch mode availability with:</p>
  
  <pre><code>[self.captureDevice isTorchModeSupported:AVCaptureTorchModeOn]
  </code></pre>
  
  <p>I'm trying to switch flash light into torch mode with</p>
  
  <pre><code>[self.captureDevice lockForConfiguration:nil];
  BOOL result = [self.captureDevice setTorchModeOnWithLevel:1 error:&amp;error];
  [self.captureDevice unlockForConfiguration];
  </code></pre>
  
  <p>This call is successful. result == YES and error == nil. But flash light blinks once then turns off.</p>
  
  <p>I saw this behaviour on iPhone X myself and there is a reports of the same behaviour from iPhone 8 and iPhone 8 Plus owners. Some users say that this problem appeared after update to iOS 11.1. But I couldn't reproduce it with iPhone 8 myself.</p>
  
  <p>Is there any ideas how to fix or debug this problem?</p>
  
  <p>Full code snippet from my app listed below:</p>
  
  <pre><code>// Retrieve the back camera
      if ([AVCaptureDeviceDiscoverySession class]) {
          DDLogDebug(@"Search camera with AVCaptureDeviceDiscoverySession");
          AVCaptureDevice* camera =
          [AVCaptureDeviceDiscoverySession
           discoverySessionWithDeviceTypes: @[AVCaptureDeviceTypeBuiltInTelephotoCamera]
           mediaType:AVMediaTypeVideo
           position:AVCaptureDevicePositionBack].devices.firstObject;
  
          if (!camera) {
              camera = [AVCaptureDeviceDiscoverySession
                        discoverySessionWithDeviceTypes: @[AVCaptureDeviceTypeBuiltInTelephotoCamera]
                        mediaType:AVMediaTypeVideo
                        position:AVCaptureDevicePositionBack].devices.firstObject;
          }
          DDLogDebug(@"Did find %@ camera", camera);
          self.captureDevice = camera;
      } else {
          DDLogDebug(@"Haven't found camera device with AVCaptureDeviceDiscoverySession");
      }
  
      if (!self.captureDevice) {
          DDLogDebug(@"Searching at [AVCaptureDevice devices], where %lu devices available", (unsigned long)AVCaptureDevice.devices.count);
          for (AVCaptureDevice *device in [AVCaptureDevice devices]) {
              if ([device hasMediaType:AVMediaTypeVideo] &amp;&amp; [device hasTorch]) {
                  self.captureDevice = device;
                  break;
              }
          }
      }
  
      if (!self.captureDevice) {
          NSError* error = [NSError buildError:^(MRErrorBuilder *builder) {
              builder.localizedDescription = NSLocalizedString(@"There is no camera devices able to measure heart rate", nil);
              builder.domain               = kWTCameraHeartRateMonitorError;
              builder.code                 = 27172;
          }];
          DDLogError(@"%@", error);
          self.session = nil;
          self.handler(0, 0, error);
          return NO;
      }
  
      NSError *error;
      AVCaptureDeviceInput *input = [[AVCaptureDeviceInput alloc] initWithDevice:self.captureDevice
                                                                           error:&amp;error];
      if (error) {
          DDLogError(@"%@", error);
          self.session = nil;
          self.handler(0, 0, error);
          return NO;
      }
  
  
      NSString* deviceType = [self.captureDevice respondsToSelector:@selector(deviceType)] ? self.captureDevice.deviceType : @"Unknown";
  
      DDLogDebug(@"Configurating camera '%@'/'%@' - %@ id %@ at %ld connected: %@", self.captureDevice.localizedName, self.captureDevice.modelID, deviceType, self.captureDevice.uniqueID, (long)self.captureDevice.position, self.captureDevice.connected?@"YES":@"NO");
  
      self.session               = [[AVCaptureSession alloc] init];
      NSString* preset = [self.session canSetSessionPreset:AVCaptureSessionPresetLow] ? AVCaptureSessionPresetLow : nil;
      if (preset) {
          self.session.sessionPreset = preset;
      }
  
      [self.session beginConfiguration];
      [self.session addInput:input];
  
      // Find the max frame rate we can get from the given device
      AVCaptureDeviceFormat *currentFormat;
      for (AVCaptureDeviceFormat *format in self.captureDevice.formats)
      {
          NSArray *ranges = format.videoSupportedFrameRateRanges;
          AVFrameRateRange *frameRates = ranges[0];
  
          // Find the lowest resolution format at the frame rate we want.
          if (frameRates.maxFrameRate == FRAMES_PER_SECOND &amp;&amp; (!currentFormat || (CMVideoFormatDescriptionGetDimensions(format.formatDescription).width &lt; CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).width &amp;&amp; CMVideoFormatDescriptionGetDimensions(format.formatDescription).height &lt; CMVideoFormatDescriptionGetDimensions(currentFormat.formatDescription).height)))
          {
              currentFormat = format;
          }
      }
  
      if (![self.captureDevice isTorchModeSupported:AVCaptureTorchModeOn]) {
          NSError* error = [NSError buildError:^(MRErrorBuilder *builder) {
              builder.localizedDescription = NSLocalizedString(@"Torch mode is not supported for your camera", nil);
              builder.domain               = kWTCameraHeartRateMonitorError;
              builder.code                 = 28633;
          }];
          self.session = nil;
          DDLogError(@"%@", error);
          self.session = nil;
          self.handler(0, 0, error);
          return NO;
      }
  
      // Tell the device to use the max frame rate.
      [self.captureDevice lockForConfiguration:nil];
      DDLogVerbose(@"Turn on tourch mode with level 0.5");
      self.captureDevice.flashMode = AVCaptureFlashModeOff;
      BOOL result = [self.captureDevice setTorchModeOnWithLevel:0.5 error:&amp;error];
      if (!result) {
          DDLogError(@"%@", error);
          self.session = nil;
          self.handler(0, 0, error);
          return NO;
      }
      [self.captureDevice setFocusMode:AVCaptureFocusModeLocked];
      [self.captureDevice setFocusModeLockedWithLensPosition:1.0
                                           completionHandler:nil];
      self.captureDevice.activeFormat = currentFormat;
      self.captureDevice.activeVideoMinFrameDuration = CMTimeMake(1, FRAMES_PER_SECOND);
      self.captureDevice.activeVideoMaxFrameDuration = CMTimeMake(1, FRAMES_PER_SECOND);
      [self.captureDevice unlockForConfiguration];
  
      // Set the output
      AVCaptureVideoDataOutput* videoOutput = [AVCaptureVideoDataOutput new];
  
      // create a queue to run the capture on
      dispatch_queue_t captureQueue=dispatch_queue_create("catpureQueue", DISPATCH_QUEUE_SERIAL);
  
      // setup our delegate
      [videoOutput setSampleBufferDelegate:self queue:captureQueue];
  
      // configure the pixel format
  
      videoOutput.videoSettings = @{(id)kCVPixelBufferPixelFormatTypeKey: @(kCVPixelFormatType_32BGRA)};
      videoOutput.alwaysDiscardsLateVideoFrames = NO;
  
      [self.session addOutput:videoOutput];
  
      if (debugPath) {
          NSError* error;
          [[NSFileManager defaultManager] removeItemAtPath:debugPath
                                                     error:nil];
  
          BOOL result =
          [[NSFileManager defaultManager] createDirectoryAtPath:debugPath
                                    withIntermediateDirectories:YES
                                                     attributes:nil
                                                          error:&amp;error];
          if (result) {
              [self setupDebugRecordAt:debugPath withFormat:currentFormat];
          } else {
              DDLogError(@"%@", error);
          }
  
          const char* path = [debugPath cStringUsingEncoding:NSUTF8StringEncoding];
          self.filter-&gt;setDebugPath(path);
      }
  
  
      // Start the video session
      [self.session commitConfiguration];
  
      self.frameNumber = 0;
      [self.assetWriter startWriting];
      [self.assetWriter startSessionAtSourceTime:kCMTimeZero];
      [self.session startRunning];
  </code></pre>