1. plist에 Camera 권한 추가
<key>NSCameraUsageDescription</key>
<string>test</string>
2. Camera 권한 체크
2-1. import
#import <AVFoundation/AVFoundation.h>
2-2. 권한 얻기
- (void)permissionCamera {
AVAuthorizationStatus status = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
if(status == AVAuthorizationStatusAuthorized) {
// 카메라 접근 권한 동의
[self setupScanningSession];
}
else if(status == AVAuthorizationStatusDenied) {
// 카메라 접근 권한 동의 해제
dispatch_async(dispatch_get_main_queue(), ^{
[SSLoader showErrorWithMessage:@"설정 > APP > 카메라 접근 권한을 허용해주세요."];
});
}
else if(status == AVAuthorizationStatusNotDetermined) {
// 카메라 접근 권한 동의 전
[AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
if (granted) {
[self setupScanningSession];
}
else {
dispatch_async(dispatch_get_main_queue(), ^{
[SSLoader showErrorWithMessage:@"설정 > APP > 카메라 접근 권한을 허용해주세요."];
});
}
}];
}
}
3. AVCaptureSession 초기화
3-1. session metadata에대한 딜리게이트 추가
@interface BarcodeViewController () <AVCaptureMetadataOutputObjectsDelegate>
3-2. AVCaptureSession, AVCaptureDevice, AVCaptureVideoPreviewLayer 초기화
- (void)setupScanningSession {
// Initalising hte Capture session before doing any video capture/scanning.
self.captureSession = [[AVCaptureSession alloc] init];
NSError *error;
// Set camera capture device to default and the media type to video.
self.captureDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
[self.captureDevice lockForConfiguration:nil];
self.captureDevice.focusMode = AVCaptureFocusModeContinuousAutoFocus;
[self.captureDevice unlockForConfiguration];
// Set video capture input: If there a problem initialising the camera, it will give am error.
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:self.captureDevice error:&error];
if (!input || error) {
NSLog(@"Error Getting Camera Input : %@", error? error.userInfo:@"");
return;
}
// Adding input souce for capture session. i.e., Camera
[self.captureSession addInput:input];
AVCaptureMetadataOutput *captureMetadataOutput = [[AVCaptureMetadataOutput alloc] init];
// Set output to capture session. Initalising an output object we will use later.
[self.captureSession addOutput:captureMetadataOutput];
// Create a new queue and set delegate for metadata objects scanned.
dispatch_queue_t dispatchQueue;
dispatchQueue = dispatch_queue_create("scanQueue", NULL);
[captureMetadataOutput setMetadataObjectsDelegate:self queue:dispatchQueue];
// Delegate should implement captureOutput:didOutputMetadataObjects:fromConnection: to get callbacks on detected metadata.
[captureMetadataOutput setMetadataObjectTypes:[captureMetadataOutput availableMetadataObjectTypes]];
// Layer that will display what the camera is capturing.
self.captureLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
[self.captureLayer setVideoGravity:AVLayerVideoGravityResizeAspectFill];
[self.captureLayer setFrame:self.barcodeView.layer.bounds];
// Adding the camera AVCaptureVideoPreviewLayer to our view's layer.
[self.barcodeView.layer addSublayer:self.captureLayer];
}
3-3. 이슈 있었던 부분
viewDidLoad, viewWillAppear 메소드에 3-2부분을 넣어주면 layer가 뷰에 설정해놓은 값으로 들어가게 된다.
즉, 뷰(xib, storyboard)에서 SE 기준으로 XR에 빌드했을 경우! 왼쪽 이미지처럼 나오게 된다.
viewWillAppear는 괜찮을 줄 알았는데 로드하는데 있어 약간 타이밍 문제가 있나보다.
해결 방법은 파란 코드 부분을 viewDidAppear로 분리시켰을 때 오른쪽 이미지처럼 정상작동 했다.
최종 작업해놓은 코드는 viewDidLoad에서 통신하는 부분이 있어 통신이 끝난 후에 3번을 수행하도록 해놓았다.
4. 바코드 인식 시작
[self.captureSession startRunning];
5. 인식된 데이터 처리
#pragma mark - AVCaptureMetadataOutputObjectsDelegate
- (void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
// Do your action on barcode capture here:
NSString *capturedBarcode = nil;
// Specify the barcodes you want to read here:
NSArray *supportedBarcodeTypes = @[AVMetadataObjectTypeUPCECode,
AVMetadataObjectTypeCode39Code,
AVMetadataObjectTypeCode39Mod43Code,
AVMetadataObjectTypeEAN13Code,
AVMetadataObjectTypeEAN8Code,
AVMetadataObjectTypeCode93Code,
AVMetadataObjectTypeCode128Code,
AVMetadataObjectTypePDF417Code,
AVMetadataObjectTypeQRCode,
AVMetadataObjectTypeAztecCode];
// In all scanned values..
for (AVMetadataObject *barcodeMetadata in metadataObjects) {
// ..check if it is a suported barcode
for (NSString *supportedBarcode in supportedBarcodeTypes) {
if ([supportedBarcode isEqualToString:barcodeMetadata.type]) {
// This is a supported barcode
// Note barcodeMetadata is of type AVMetadataObject
// AND barcodeObject is of type AVMetadataMachineReadableCodeObject
AVMetadataMachineReadableCodeObject *barcodeObject = (AVMetadataMachineReadableCodeObject *)[self.captureLayer transformedMetadataObjectForMetadataObject:barcodeMetadata];
capturedBarcode = [barcodeObject stringValue];
NSLog(@"capturedBarcode = %@", capturedBarcode);
break;
}
}
}
}
6. 바코드 인식 멈춤
[self.captureSession stopRunning];
- 플래시 기능 추가
flash와 torch의 차이 : https://developer.apple.com/library/archive/documentation/AudioVideo/Conceptual/AVFoundationPG/Articles/04_MediaCapture.html
flash : 이미지를 밝게 촬영하는데 사용.
torch : 비디오를 지속적으로 밝게 비추는데 사용.
기존 카메라에서도 확인해보면 사진 촬영할 때 플래시를 키면 찍는 순간 플래시가 켜지고, 비디오 촬영할 때 플래시를 키면 플래시가 계속 켜져있는 것을 확인 할 수 있다.
if (self.captureDevice && self.captureDevice.hasTorch) {
if (self.captureDevice.torchMode == AVCaptureTorchModeOff) {
if ([self.captureDevice isTorchModeSupported:AVCaptureTorchModeOn]) {
[self.captureDevice lockForConfiguration:nil];
[self.captureDevice setTorchMode:AVCaptureTorchModeOn];
[self.captureDevice unlockForConfiguration];
}
}
else {
if ([self.captureDevice isTorchModeSupported:AVCaptureTorchModeOff]) {
[self.captureDevice lockForConfiguration:nil];
[self.captureDevice setTorchMode:AVCaptureTorchModeOff];
[self.captureDevice unlockForConfiguration];
}
}
}
참고한 URL :
https://ayeohyes.wordpress.com/2015/05/09/barcode-scanning-in-ios-using-avfoundation/
'iOS' 카테고리의 다른 글
[iOS] Firebase 호스팅 설정 (0) | 2020.09.23 |
---|---|
[Xcode] git ignore 설정 (0) | 2020.07.02 |
[iOS] iOS 13.0 DarkMode Check (Widget 포함) (0) | 2019.08.30 |
[iOS] WKWebView setCookie not working!!! 해결 (6) | 2019.08.08 |
[iOS] 푸시 인증서_서버 전달 (0) | 2019.07.31 |