일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- ios
- 네트워크
- iphone
- SwiftUI
- dataflow
- WWDC
- authentication
- UIKit
- Concurrency
- RxSwift
- 달력
- auth
- Animation
- firebase
- CS
- fullscreencover
- 데이터최적화
- realitykit
- Network
- swift
- ar
- environmentobjet
- stateobject
- gesture
- Performance
- withAnimation
- combine
- arkit
- state
- GCD
- Today
- Total
XLOG
[SwiftUI] QR Code Scanner 만들기 (SwifUI 에 ViewController 사용하기) 본문
[SwiftUI] QR Code Scanner 만들기 (SwifUI 에 ViewController 사용하기)
X_PROFIT 2023. 3. 8. 20:43SwiftUI 만으론 QR Code Scanner를 만들 수 없다......
그 이유는 UIKit Framework 가 필요하다. AVFoundation, AVCaptureMetadataOutputObjectsDelegate 를 사용하기 위해서......
우선 AVFoundation 은 swift 에서 제공하는 Audio, Video 를 다루기 위한 frameworkd 다.
여기서의 핵심은 AVCaptureSession 을 사용하는 것이다.
디바이스로 부터 들어온 데이터를 출력해주는 세션, 즉 input 과 Output을 연결해주는 역할을 한다.
우리는 이 센션에 AVCaptureDeviceInput 을 Input으로 추가, 가져온 메타데이터를 위해 AVCaptureMetadataOutput 을 ouput에 추가해 준다. AVCaptureMetadataOutput 에 델리게이트를 설정해주면 읽어온 데이터 처리가 가능하다. 또한 읽어온 객체타입을 설정할 수 있는데, 기본정으로 Apple에서 ML Model이 장착되어 있는제 얼굴, 사람의몸 등 다양한 것을 읽을 수 잇다.
private func settting() {
guard let captureDevice = AVCaptureDevice.default(for: .video) else {
fatalError("No Video")
}
do {
// QR코드를 인식할 영역 값
let rectOfInterest = CGRect(x: (UIScreen.main.bounds.width - 200) / 2 , y: (view.bounds.height - width * 1.4) / 2 + 100 , width: 200, height: 200)
// cameraDevice를 설정하여 AVCaptureSEssion에 input 으로 추가
let input = try AVCaptureDeviceInput(device: captureDevice)
captureSession.addInput(input)
// Input으로 들어온 데이터를 metadata로 출력하기 위해 AVCapturMetadataOutput 을 세션에 추가
let output = AVCaptureMetadataOutput()
captureSession.addOutput(output)
// 메타데이터를 읽을 때 동작할 델리게이트 붙여주기
output.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
// 메타데이터의 타입 설정, humanBody, dogBody, face 등등 다양하게 있음
output.metadataObjectTypes = [AVMetadataObject.ObjectType.qr]
let rectConverted = setVideoLayer(rectOfInterest: rectOfInterest)
// QR코드 인식 영역 설정
output.rectOfInterest = rectConverted
// QR코드 인식 영역 프레임 그리기
setGuideCrossLineView(rectOfInterest: rectOfInterest)
// session 은 background thread 에서 동작해야 하여 GCD를 이용하여 background qod thread 에서 동작할 수 있도록....
DispatchQueue.global(qos: .background).async {
self.captureSession.startRunning()
}
} catch {
print("error")
}
extension QRCodeReaderViewController: AVCaptureMetadataOutputObjectsDelegate {
func metadataOutput(_ output: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
if let metadataObject = metadataObjects.first {
guard let readableObject = metadataObject as? AVMetadataMachineReadableCodeObject, let stringValue = readableObject.stringValue else {
return
}
// URL 주소의 QR 코드 값이 읽힐 때만 Label 변경
if stringValue.hasPrefix("http://") || stringValue.hasPrefix("https://") {
labelView.text = stringValue
}
}
}
}
또한 메디타이터를 처리하기 위한 Delegate 설정이 필요하다.
이렇게 QR Code Reader View Controller 가 준비가 되었으면 우리는 UIViewControllerRepresentable 를 사용하여 SwiftUI 가 인식할 수 있는 View로 다시 만들어 줘야 한다.
struct QRCodeReaderViewRepresentable: UIViewControllerRepresentable {
typealias UIViewControllerType = QRCodeReaderViewController
func makeUIViewController(context: Context) -> QRCodeReaderViewController {
let qr = QRCodeReaderViewController()
return qr
}
func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) {
}
}
이렇게 생성된 구조체를 ContentView에서 사용하면 끝이다.
참고로 AVFoundation 에서 카메라를 사용하기 위해서
info.plist 에서 Privacy - Camera Usage Description 을 통해 카메라 권한을 받는걸 잊으면 안된다.
- 참고 : https://developer.apple.com/documentation/avfoundation
- 참고 : https://developer.apple.com/documentation/swiftui/uiviewcontrollerrepresentable
- 참고 : https://gyuios.tistory.com/79
- 참고 : https://nebori.tistory.com/28
- 참고 : https://hururuek-chapchap.tistory.com/34
- 참고 : https://blog.devgenius.io/camera-preview-and-a-qr-code-scanner-in-swiftui-48b111155c66
'Swift > SwiftUI' 카테고리의 다른 글
[SwiftUI] Camera Shutter Button Animation (0) | 2023.09.18 |
---|---|
[SwiftUI] Animation 적용 기본 이론편 (0) | 2023.08.07 |
[SwiftUI] 날짜 계산, 월간달력 만들기 (0) | 2023.03.04 |
[SwiftUI] 캘린더용 InfinityScroll 로직에 대한 아이디어 (0) | 2023.02.27 |
[SwiftUI] onAppear 에서 async 함수 실행하기 (0) | 2023.02.18 |