Added the document camera controller and very basic mockup of the view
This commit is contained in:
parent
66c7a37e32
commit
5eb79457bd
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
Build/
|
@ -11,6 +11,7 @@
|
|||||||
466989C92C34DC7A009884D1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466989C82C34DC7A009884D1 /* ContentView.swift */; };
|
466989C92C34DC7A009884D1 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466989C82C34DC7A009884D1 /* ContentView.swift */; };
|
||||||
466989CB2C34DC7B009884D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 466989CA2C34DC7B009884D1 /* Assets.xcassets */; };
|
466989CB2C34DC7B009884D1 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 466989CA2C34DC7B009884D1 /* Assets.xcassets */; };
|
||||||
466989CE2C34DC7B009884D1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 466989CD2C34DC7B009884D1 /* Preview Assets.xcassets */; };
|
466989CE2C34DC7B009884D1 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 466989CD2C34DC7B009884D1 /* Preview Assets.xcassets */; };
|
||||||
|
466989D62C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466989D52C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXFileReference section */
|
/* Begin PBXFileReference section */
|
||||||
@ -19,6 +20,7 @@
|
|||||||
466989C82C34DC7A009884D1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
466989C82C34DC7A009884D1 /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = "<group>"; };
|
||||||
466989CA2C34DC7B009884D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
466989CA2C34DC7B009884D1 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
|
||||||
466989CD2C34DC7B009884D1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
466989CD2C34DC7B009884D1 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = "<group>"; };
|
||||||
|
466989D52C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VNDocumentCameraViewControllerR.swift; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@ -51,6 +53,7 @@
|
|||||||
466989C52C34DC7A009884D1 /* JustScanIt */ = {
|
466989C52C34DC7A009884D1 /* JustScanIt */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
466989D42C34DCB9009884D1 /* Controllers */,
|
||||||
466989C62C34DC7A009884D1 /* JustScanItApp.swift */,
|
466989C62C34DC7A009884D1 /* JustScanItApp.swift */,
|
||||||
466989C82C34DC7A009884D1 /* ContentView.swift */,
|
466989C82C34DC7A009884D1 /* ContentView.swift */,
|
||||||
466989CA2C34DC7B009884D1 /* Assets.xcassets */,
|
466989CA2C34DC7B009884D1 /* Assets.xcassets */,
|
||||||
@ -67,6 +70,14 @@
|
|||||||
path = "Preview Content";
|
path = "Preview Content";
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
466989D42C34DCB9009884D1 /* Controllers */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
466989D52C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift */,
|
||||||
|
);
|
||||||
|
path = Controllers;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
/* End PBXGroup section */
|
/* End PBXGroup section */
|
||||||
|
|
||||||
/* Begin PBXNativeTarget section */
|
/* Begin PBXNativeTarget section */
|
||||||
@ -139,6 +150,7 @@
|
|||||||
files = (
|
files = (
|
||||||
466989C92C34DC7A009884D1 /* ContentView.swift in Sources */,
|
466989C92C34DC7A009884D1 /* ContentView.swift in Sources */,
|
||||||
466989C72C34DC7A009884D1 /* JustScanItApp.swift in Sources */,
|
466989C72C34DC7A009884D1 /* JustScanItApp.swift in Sources */,
|
||||||
|
466989D62C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@ -275,11 +287,14 @@
|
|||||||
DEVELOPMENT_TEAM = 9MP5435PRF;
|
DEVELOPMENT_TEAM = 9MP5435PRF;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Just Scan It";
|
||||||
|
INFOPLIST_KEY_NSCameraUsageDescription = "Scan documents with the camera.";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -287,9 +302,13 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.JustScanIt;
|
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.JustScanIt;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
};
|
};
|
||||||
name = Debug;
|
name = Debug;
|
||||||
};
|
};
|
||||||
@ -304,11 +323,14 @@
|
|||||||
DEVELOPMENT_TEAM = 9MP5435PRF;
|
DEVELOPMENT_TEAM = 9MP5435PRF;
|
||||||
ENABLE_PREVIEWS = YES;
|
ENABLE_PREVIEWS = YES;
|
||||||
GENERATE_INFOPLIST_FILE = YES;
|
GENERATE_INFOPLIST_FILE = YES;
|
||||||
|
INFOPLIST_KEY_CFBundleDisplayName = "Just Scan It";
|
||||||
|
INFOPLIST_KEY_NSCameraUsageDescription = "Scan documents with the camera.";
|
||||||
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES;
|
||||||
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
|
||||||
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
INFOPLIST_KEY_UILaunchScreen_Generation = YES;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait;
|
||||||
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
|
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown";
|
||||||
|
IPHONEOS_DEPLOYMENT_TARGET = 17.0;
|
||||||
LD_RUNPATH_SEARCH_PATHS = (
|
LD_RUNPATH_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
"@executable_path/Frameworks",
|
"@executable_path/Frameworks",
|
||||||
@ -316,9 +338,13 @@
|
|||||||
MARKETING_VERSION = 1.0;
|
MARKETING_VERSION = 1.0;
|
||||||
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.JustScanIt;
|
PRODUCT_BUNDLE_IDENTIFIER = xyz.breadone.JustScanIt;
|
||||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||||
|
SUPPORTED_PLATFORMS = "iphoneos iphonesimulator";
|
||||||
|
SUPPORTS_MACCATALYST = NO;
|
||||||
|
SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
|
SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO;
|
||||||
SWIFT_EMIT_LOC_STRINGS = YES;
|
SWIFT_EMIT_LOC_STRINGS = YES;
|
||||||
SWIFT_VERSION = 5.0;
|
SWIFT_VERSION = 5.0;
|
||||||
TARGETED_DEVICE_FAMILY = "1,2";
|
TARGETED_DEVICE_FAMILY = 1;
|
||||||
};
|
};
|
||||||
name = Release;
|
name = Release;
|
||||||
};
|
};
|
||||||
|
@ -6,18 +6,64 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
import AVKit
|
||||||
|
|
||||||
struct ContentView: View {
|
struct ContentView: View {
|
||||||
var body: some View {
|
@State private var scannedImages: [UIImage] = []
|
||||||
VStack {
|
@State private var isShowingVNDocumentCameraView = false
|
||||||
Image(systemName: "globe")
|
|
||||||
.imageScale(.large)
|
var isAuthorized: Bool {
|
||||||
.foregroundStyle(.tint)
|
get async {
|
||||||
Text("Hello, world!")
|
let status = AVCaptureDevice.authorizationStatus(for: .video)
|
||||||
|
|
||||||
|
// Determine if the user previously authorized camera access.
|
||||||
|
var isAuthorized = status == .authorized
|
||||||
|
|
||||||
|
// If the system hasn't determined the user's authorization status,
|
||||||
|
// explicitly prompt them for approval.
|
||||||
|
if status == .notDetermined {
|
||||||
|
isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return isAuthorized
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
NavigationView {
|
||||||
|
Grid {
|
||||||
|
ForEach(scannedImages, id: \.self) { image in
|
||||||
|
VStack {
|
||||||
|
Image(uiImage: image)
|
||||||
|
.resizable()
|
||||||
|
.scaledToFit()
|
||||||
|
.frame(width: 100, height: 100)
|
||||||
.padding()
|
.padding()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
.navigationTitle("Just Scan It!")
|
||||||
|
.sheet(isPresented: $isShowingVNDocumentCameraView) {
|
||||||
|
VNDocumentCameraViewControllerRepresentable(scanResult: $scannedImages)
|
||||||
|
}
|
||||||
|
.toolbar {
|
||||||
|
ToolbarItem {
|
||||||
|
Button(action: showVNDocumentCameraView) {
|
||||||
|
Image(systemName: "scanner")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func showVNDocumentCameraView() {
|
||||||
|
Task {
|
||||||
|
guard await isAuthorized else { return }
|
||||||
|
}
|
||||||
|
|
||||||
|
isShowingVNDocumentCameraView = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#Preview {
|
#Preview {
|
||||||
ContentView()
|
ContentView()
|
||||||
|
51
JustScanIt/Controllers/VNDocumentCameraViewControllerR.swift
Normal file
51
JustScanIt/Controllers/VNDocumentCameraViewControllerR.swift
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
//
|
||||||
|
// VNDocumentCameraViewControllerR.swift
|
||||||
|
// JustScanIt
|
||||||
|
//
|
||||||
|
// Created by Pradyun Setti on 03/07/2024.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
import VisionKit
|
||||||
|
|
||||||
|
struct VNDocumentCameraViewControllerRepresentable: UIViewControllerRepresentable {
|
||||||
|
@Binding var scanResult: [UIImage]
|
||||||
|
|
||||||
|
func makeUIViewController(context: Context) -> VNDocumentCameraViewController {
|
||||||
|
let documentCameraViewController = VNDocumentCameraViewController()
|
||||||
|
documentCameraViewController.delegate = context.coordinator
|
||||||
|
|
||||||
|
return documentCameraViewController
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: Context) { }
|
||||||
|
|
||||||
|
func makeCoordinator() -> Coordinator {
|
||||||
|
Coordinator(scanResult: $scanResult)
|
||||||
|
}
|
||||||
|
|
||||||
|
final class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
|
||||||
|
@Binding var scanResult: [UIImage]
|
||||||
|
|
||||||
|
init(scanResult: Binding<[UIImage]>) {
|
||||||
|
_scanResult = scanResult
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tells the delegate that the user successfully saved a scanned document from the document camera.
|
||||||
|
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
|
||||||
|
controller.dismiss(animated: true, completion: nil)
|
||||||
|
scanResult = (0..<scan.pageCount).compactMap { scan.imageOfPage(at: $0) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Tells the delegate that the user canceled out of the document scanner camera.
|
||||||
|
func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
|
||||||
|
controller.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Tells the delegate that document scanning failed while the camera view controller was active.
|
||||||
|
func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
|
||||||
|
print("Document scanner error: \(error.localizedDescription)")
|
||||||
|
controller.dismiss(animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user