title: Toggle camera using AVFoundation iOS 6
body: <p>I want to toggle camera using AVFoundation. Here is my code
  I have subclass of NSObject as </p>
  
  <p><code>@interface CaptureSessionManager : NSObject</code></p>
  
  <pre><code>@property (retain) AVCaptureVideoPreviewLayer *previewLayer;
  @property (retain) AVCaptureSession *captureSession;
  @property (retain) AVCaptureStillImageOutput *stillImageOutput;
  @property (nonatomic, retain) UIImage *stillImage;
  </code></pre>
  
  <p>In <code>@implementation CaptureSessionManager</code></p>
  
  <pre><code>    - (id)init {
      if ((self = [super init])) {
          [self setCaptureSession:[[AVCaptureSession alloc] init]];
      }
      return self;
  }
  
  - (void)addVideoPreviewLayer {
      [self setPreviewLayer:[[[AVCaptureVideoPreviewLayer alloc] initWithSession:[self captureSession]] autorelease]];
      [[self previewLayer] setVideoGravity:AVLayerVideoGravityResizeAspectFill];
  
  }
  
  - (void)addVideoInputFrontCamera:(BOOL)front {
      NSArray *devices = [AVCaptureDevice devices];
      AVCaptureDevice *frontCamera;
      AVCaptureDevice *backCamera;
  
      for (AVCaptureDevice *device in devices) {
  
          NSLog(@"Device name: %@", [device localizedName]);
  
          if ([device hasMediaType:AVMediaTypeVideo]) {
  
              if ([device position] == AVCaptureDevicePositionBack) {
                  NSLog(@"Device position : back");
                  backCamera = device;
              }
              else {
                  NSLog(@"Device position : front");
                  frontCamera = device;
              }
          }
      }
  
      NSError *error = nil;
  
      if (front) {
          AVCaptureDeviceInput *frontFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&amp;error];
          if (!error) {
              if ([[self captureSession] canAddInput:frontFacingCameraDeviceInput]) {
                  [[self captureSession] addInput:frontFacingCameraDeviceInput];
              } else {
                  NSLog(@"Couldn't add front facing video input");
              }
          }
      } else {
          AVCaptureDeviceInput *backFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&amp;error];
          if (!error) {
              if ([[self captureSession] canAddInput:backFacingCameraDeviceInput]) {
                  [[self captureSession] addInput:backFacingCameraDeviceInput];
              } else {
                  NSLog(@"Couldn't add back facing video input");
              }
          }
      }
  }
  
  - (void)addStillImageOutput 
  {
    [self setStillImageOutput:[[[AVCaptureStillImageOutput alloc] init] autorelease]];
    NSDictionary *outputSettings = [[NSDictionary alloc] initWithObjectsAndKeys:AVVideoCodecJPEG,AVVideoCodecKey,nil];
    [[self stillImageOutput] setOutputSettings:outputSettings];
  
    AVCaptureConnection *videoConnection = nil;
    for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
      for (AVCaptureInputPort *port in [connection inputPorts]) {
        if ([[port mediaType] isEqual:AVMediaTypeVideo] ) {
          videoConnection = connection;
          break;
        }
      }
      if (videoConnection) { 
        break; 
      }
    }
  
    [[self captureSession] addOutput:[self stillImageOutput]];
  }
  
  - (void)captureStillImage
  {  
      AVCaptureConnection *videoConnection = nil;
      for (AVCaptureConnection *connection in [[self stillImageOutput] connections]) {
          for (AVCaptureInputPort *port in [connection inputPorts]) {
              if ([[port mediaType] isEqual:AVMediaTypeVideo]) {
                  videoConnection = connection;
                  break;
              }
          }
          if (videoConnection) { 
        break; 
      }
      }
  
      NSLog(@"about to request a capture from: %@", [self stillImageOutput]);
      [[self stillImageOutput] captureStillImageAsynchronouslyFromConnection:videoConnection 
                                                         completionHandler:^(CMSampleBufferRef imageSampleBuffer, NSError *error) { 
                                                           CFDictionaryRef exifAttachments = CMGetAttachment(imageSampleBuffer, kCGImagePropertyExifDictionary, NULL);
                                                           if (exifAttachments) {
                                                             NSLog(@"attachements: %@", exifAttachments);
                                                           } else { 
                                                             NSLog(@"no attachments");
                                                           }
                                                           NSData *imageData = [AVCaptureStillImageOutput jpegStillImageNSDataRepresentation:imageSampleBuffer];    
                                                           UIImage *image = [[UIImage alloc] initWithData:imageData];
                                                           [self setStillImage:image];
                                                           [image release];
                                                           [[NSNotificationCenter defaultCenter] postNotificationName:kImageCapturedSuccessfully object:nil];
                                                         }];
  }
  
  - (void)dealloc {
  
      [[self captureSession] stopRunning];
  
      [previewLayer release], previewLayer = nil;
      [captureSession release], captureSession = nil;
    [stillImageOutput release], stillImageOutput = nil;
    [stillImage release], stillImage = nil;
  
      [super dealloc];
  }
  
  -(void)toggleCamera:(BOOL)front
  {
      NSArray *devices = [AVCaptureDevice devices];
      AVCaptureDevice *frontCamera;
      AVCaptureDevice *backCamera;
  
      for (AVCaptureDevice *device in devices) {
  
          NSLog(@"Device name: %@", [device localizedName]);
  
          if ([device hasMediaType:AVMediaTypeVideo]) {
  
              if ([device position] == AVCaptureDevicePositionBack) {
                  NSLog(@"Device position : back");
                  backCamera = device;
              }
              else {
                  NSLog(@"Device position : front");
                  frontCamera = device;
              }
          }
      }
      [[self captureSession] beginConfiguration];
      NSError *error = nil;
      AVCaptureDeviceInput *frontFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:frontCamera error:&amp;error];
      AVCaptureDeviceInput *backFacingCameraDeviceInput = [AVCaptureDeviceInput deviceInputWithDevice:backCamera error:&amp;error];
      if (front)
      {
          [[self captureSession] removeInput:backFacingCameraDeviceInput];
          if (!error) {
              if ([[self captureSession] canAddInput:frontFacingCameraDeviceInput]) {
                  [[self captureSession] addInput:frontFacingCameraDeviceInput];
              } else {
                  NSLog(@"Couldn't add front facing video input");
              }
              [[self captureSession] addInput:frontFacingCameraDeviceInput];
          }
      } else
      {
          [[self captureSession] removeInput:frontFacingCameraDeviceInput];
          if (!error) {
              if ([[self captureSession] canAddInput:backFacingCameraDeviceInput]) {
                  [[self captureSession] addInput:backFacingCameraDeviceInput];
              } else {
                  NSLog(@"Couldn't add back facing video input");
              }
              [[self captureSession] addInput:backFacingCameraDeviceInput];
          }
      }
  
      [[self captureSession] commitConfiguration];
  }
  </code></pre>
  
  <p>In my ViewController , I have </p>
  
  <pre><code>@property (retain) CaptureSessionManager *captureManager;
  @property (nonatomic,readwrite) BOOL isFrontCameraSelected;
  
      - (void)viewDidLoad
  {
      self.isFrontCameraSelected = NO;
  
      [self setCaptureManager:[[[CaptureSessionManager alloc] init] autorelease]];
  
      [[self captureManager] addVideoInputFrontCamera:self.isFrontCameraSelected]; // set to YES for Front Camera, No for Back camera
  
      [[self captureManager] addStillImageOutput];
  
      [[self captureManager] addVideoPreviewLayer];
      CGRect layerRect = [[[self innerview] layer] bounds];
      [[[self captureManager] previewLayer] setBounds:layerRect];
      [[[self captureManager] previewLayer] setPosition:CGPointMake(CGRectGetMidX(layerRect),CGRectGetMidY(layerRect))];
      [[[self innerview] layer] addSublayer:[[self captureManager] previewLayer]];
  
      UIImageView *overlayImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"overlaygraphic.png"]];
      [overlayImageView setFrame:CGRectMake(30, 60, 260, 260)];
      [[self innerview] addSubview:overlayImageView];
      [overlayImageView release];
  
      UIButton *overlayButton3 = [UIButton buttonWithType:UIButtonTypeCustom];
      [overlayButton3 setImage:[UIImage imageNamed:@"camera.png"] forState:UIControlStateNormal];
      [overlayButton3 setFrame:CGRectMake(130, 330, 60, 30)];
      [overlayButton3 addTarget:self action:@selector(innerscanButtonPressed) forControlEvents:UIControlEventTouchUpInside];
      [[self innerview] addSubview:overlayButton3];
  
      UIButton *cameraSelection = [UIButton buttonWithType:UIButtonTypeCustom];
      [cameraSelection setImage:[UIImage imageNamed:@"camera.png"] forState:UIControlStateNormal];
      [cameraSelection setFrame:CGRectMake(260, 30, 60, 30)];
      [cameraSelection addTarget:self action:@selector(cameraSelectionTapped:) forControlEvents:UIControlEventTouchUpInside];
      [[self innerview] addSubview:cameraSelection];
  
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(saveImageToPhotoAlbum) name:kImageCapturedSuccessfully object:nil];
  
      [[captureManager captureSession] startRunning];
  }
  
  - (void)innerscanButtonPressed {
  
      [[self scanningLabel] setHidden:NO];
      [[self captureManager] captureStillImage];
  
  }
  
  -(void)cameraSelectionTapped:(id)sender
  {
      [[self captureManager] toggleCamera:self.isFrontCameraSelected];
  }
  </code></pre>
  
  <p>When I click on toggleCamera button , it crashes with below error</p>
  
  <pre><code>Couldn't add back facing video input
  *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** Multiple audio/video AVCaptureInputs are not currently supported.'
  *** First throw call stack:
  (0x38f2f2a3 0x3725997f 0x39aff977 0x39aff091 0xe943d 0xe7875 0x3a4de0a5 0x3a4de057 0x3a4de035 0x3a4dd8eb 0x3a4ddde1 0x3a4065f1 0x3a3f3801 0x3a3f311b 0x37cad5a3 0x37cad1d3 0x38f04173 0x38f04117 0x38f02f99 0x38e75ebd 0x38e75d49 0x37cac2eb 0x3a4472f9 0xdf1ab 0x36324b20)
  </code></pre>
  
  <p>I want to add toggle feature so that user can use front / back camera to click photo. </p>
  
  <p>Any kind of help is highly appreciated. Thanks in advance.</p>