title: iOS 13 error: Inconsistent state from AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection
body: <p>I'm developing command line tool that will take photo from camera (programmatically, without modal views or controls) and save it locally on device. So I'm trying to implement <code>[AVCaptureStillImageOutput]</code>.
  (Yes, I'm aware this has been deprecated since iOS 10, but my goal is to target also previous system version, starting iOS 9.)</p>
  
  <p>So the problem I'm facing is fatal exception in function <strong><code>[captureStillImageAsynchronouslyFromConnection]</code></strong> that states <strong><code>Inconsistent state</code></strong>:</p>
  
  <pre><code>*** -[AVCaptureStillImageOutput captureStillImageAsynchronouslyFromConnection:completionHandler:] Inconsistent state
  </code></pre>
  
  <p>I've seen other SO threads and I think I implemented all the possible solutions to bypass this error but none worked that's why I'm posting this question with my code.</p>
  
  <p><strong>I've tested this code on iOS 9 and it works fine, but error rises on iOS 13. May the deprecation cause the error?</strong>
  Anyway program compiles fine and works fine up until this specific function. All seems fine, front camera is found, session is started, videoConnection is active and enabled.. Still <code>captureStillImageAsynchronouslyFromConnection</code> returns exception. </p>
  
  <p>Please find my code attached below. Any help much appreciated!</p>
  
  <p>Header:</p>
  
  <pre><code>#import &lt;AVFoundation/AVFoundation.h&gt;
  #import &lt;Foundation/Foundation.h&gt;
  
  @interface CameraManager : NSObject
  @property (retain) AVCaptureStillImageOutput *stillImageOutput;
  @property (retain) AVCaptureConnection *videoConnection;
  @property (retain) AVCaptureSession *session;
  
  
  + (instancetype)sharedInstance;
  - (void) takePhoto;
  
  @end
  </code></pre>
  
  <p>Class implementation:</p>
  
  <pre><code>#import "CameraManager.h"
  
  @interface CameraManager()
  @end
  
  @implementation CameraManager
  
  + (instancetype)sharedInstance {
  
      static CameraManager *sharedInstance = nil;
      static dispatch_once_t onceToken;
      dispatch_once(&amp;onceToken, ^{
          sharedInstance = [[CameraManager alloc] init];
      });
  
      return sharedInstance;
  }
  
  
  -(AVCaptureDevice *) frontFacingCameraIfAvailable{
  
      NSArray *videoDevices = [AVCaptureDevice devicesWithMediaType:AVMediaTypeVideo];
      AVCaptureDevice *captureDevice = nil;
  
      for (AVCaptureDevice *device in videoDevices){
  
          if (device.position == AVCaptureDevicePositionFront){
  
              captureDevice = device;
              break;
          }
      }
  
      if (!captureDevice){
  
          captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
      }
  
      return captureDevice;
  }
  
  -(void) setupCaptureSession {
  
      self.session = [[AVCaptureSession alloc] init];
      self.session.sessionPreset = AVCaptureSessionPresetMedium;
  
      AVCaptureVideoPreviewLayer *captureVideoPreviewLayer = [[AVCaptureVideoPreviewLayer    alloc] initWithSession:self.session];
  
      NSError *error = nil;
      AVCaptureDevice *device = [self frontFacingCameraIfAvailable];
      AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:&amp;error];
      if (!input) {
          NSLog(@"ERROR: trying to open camera: %@", error);
      }
      [self.session addInput:input];
  
      self.stillImageOutput = [[AVCaptureStillImageOutput alloc] init];
      NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys: AVVideoCodecJPEG, AVVideoCodecKey, nil];
      [self.stillImageOutput setOutputSettings:outputSettings];
  
      [self.session addOutput:self.stillImageOutput];
  
      [self.session startRunning];
  
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionWasInterrupted:) name:AVCaptureSessionWasInterruptedNotification object:self.session];
      [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(sessionInterruptionEnded:) name:AVCaptureSessionInterruptionEndedNotification object:self.session];
  
  }
  
  - (void) sessionWasInterrupted:(NSNotification*)notification
  {
      AVCaptureSessionInterruptionReason reason = [notification.userInfo[AVCaptureSessionInterruptionReasonKey] integerValue];
      NSLog(@"Capture session was interrupted with reason %ld", (long)reason);
  
  }
  
  - (void) sessionInterruptionEnded:(NSNotification*)notification
  {
      NSLog(@"sessionInterruptionEnded");
  }
  
  -(void) takePhoto {    
      [self setupCaptureSession];
  
      self.videoConnection = nil;
      for (AVCaptureConnection *connection in self.stillImageOutput.connections) {
          for (AVCaptureInputPort *port in [connection inputPorts]) {
              if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
                  self.videoConnection = connection;
                  break;
              }
          }
          if (self.videoConnection) { break; }
      }
  
      NSLog(@"about to request a capture from: %@", self.stillImageOutput);
      [self.videoConnection setVideoOrientation:AVCaptureVideoOrientationPortrait];
  
      if (!self.videoConnection || !self.videoConnection.enabled || !self.videoConnection.active) {
          NSLog(@"videoConnection not enabled or not active"); 
          return;
      } else {
          NSLog(@"videoConnection enabled: %hhd, active: %hhd", (char)self.videoConnection.enabled, (char)self.videoConnection.active);
      }
  
      // NSLog(@"videoConnection: %@", self.videoConnection);
  
      NSError *error;
      if (error) {
          NSLog(@"Error %@", error);
      }
  
      @try {
          // here captureStillImageAsynchronouslyFromConnection crash with:
          // *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '*** -[AVCaptureStillImageOutput 
  captureStillImageAsynchronouslyFromConnection:completionHandler:] Inconsistent state'
          [self.stillImageOutput captureStillImageAsynchronouslyFromConnection:self.videoConnection completionHandler: ^(CMSampleBufferRef imageSampleBuffer, NSError *error) {
  
              NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];
  
              NSLog(@"Here should have imageData %@", imageData);
          }];
      }
      @catch (NSException *exception) {
          NSLog(@"EXCEPTION %@", exception.reason);
      }
      @finally {
          NSLog(@"Continue..");
      }
  
  }
  
  
  @end
  </code></pre>