data persistence is working!

This commit is contained in:
breadone 2024-07-03 18:27:17 +12:00
parent 5eb79457bd
commit a5eb4a049f
No known key found for this signature in database
4 changed files with 92 additions and 12 deletions

View File

@ -12,6 +12,7 @@
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 */; }; 466989D62C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466989D52C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift */; };
466989D92C35206E009884D1 /* Scan.swift in Sources */ = {isa = PBXBuildFile; fileRef = 466989D82C35206E009884D1 /* Scan.swift */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
@ -21,6 +22,7 @@
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>"; }; 466989D52C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VNDocumentCameraViewControllerR.swift; sourceTree = "<group>"; };
466989D82C35206E009884D1 /* Scan.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scan.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */ /* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */ /* Begin PBXFrameworksBuildPhase section */
@ -53,6 +55,7 @@
466989C52C34DC7A009884D1 /* JustScanIt */ = { 466989C52C34DC7A009884D1 /* JustScanIt */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
466989D72C351F23009884D1 /* Model */,
466989D42C34DCB9009884D1 /* Controllers */, 466989D42C34DCB9009884D1 /* Controllers */,
466989C62C34DC7A009884D1 /* JustScanItApp.swift */, 466989C62C34DC7A009884D1 /* JustScanItApp.swift */,
466989C82C34DC7A009884D1 /* ContentView.swift */, 466989C82C34DC7A009884D1 /* ContentView.swift */,
@ -78,6 +81,14 @@
path = Controllers; path = Controllers;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
466989D72C351F23009884D1 /* Model */ = {
isa = PBXGroup;
children = (
466989D82C35206E009884D1 /* Scan.swift */,
);
path = Model;
sourceTree = "<group>";
};
/* End PBXGroup section */ /* End PBXGroup section */
/* Begin PBXNativeTarget section */ /* Begin PBXNativeTarget section */
@ -150,6 +161,7 @@
files = ( files = (
466989C92C34DC7A009884D1 /* ContentView.swift in Sources */, 466989C92C34DC7A009884D1 /* ContentView.swift in Sources */,
466989C72C34DC7A009884D1 /* JustScanItApp.swift in Sources */, 466989C72C34DC7A009884D1 /* JustScanItApp.swift in Sources */,
466989D92C35206E009884D1 /* Scan.swift in Sources */,
466989D62C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift in Sources */, 466989D62C34DCE4009884D1 /* VNDocumentCameraViewControllerR.swift in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;

View File

@ -6,12 +6,17 @@
// //
import SwiftUI import SwiftUI
import SwiftData
import AVKit import AVKit
struct ContentView: View { struct ContentView: View {
@Environment(\.modelContext) var ctx
@State private var scannedImages: [UIImage] = [] @State private var scannedImages: [UIImage] = []
@State private var isShowingVNDocumentCameraView = false @State private var isShowingVNDocumentCameraView = false
@Query var scans: [Scan]
var isAuthorized: Bool { var isAuthorized: Bool {
get async { get async {
let status = AVCaptureDevice.authorizationStatus(for: .video) let status = AVCaptureDevice.authorizationStatus(for: .video)
@ -23,6 +28,8 @@ struct ContentView: View {
// explicitly prompt them for approval. // explicitly prompt them for approval.
if status == .notDetermined { if status == .notDetermined {
isAuthorized = await AVCaptureDevice.requestAccess(for: .video) isAuthorized = await AVCaptureDevice.requestAccess(for: .video)
} else if status == .denied {
// TODO: show alert when denied
} }
return isAuthorized return isAuthorized
@ -31,19 +38,22 @@ struct ContentView: View {
var body: some View { var body: some View {
NavigationView { NavigationView {
Grid { ScrollView {
ForEach(scannedImages, id: \.self) { image in ForEach(scans, id: \.self) { scan in
VStack { HStack {
Image(uiImage: image) ForEach(scan.uiImages, id: \.self) { image in
.resizable() Image(uiImage: image)
.scaledToFit() .resizable()
.frame(width: 100, height: 100) .scaledToFit()
.padding() .frame(width: 100, height: 100)
.padding()
}
} }
} }
} }
.navigationTitle("Just Scan It!") .navigationTitle("Just Scan It!")
.sheet(isPresented: $isShowingVNDocumentCameraView) { .sheet(isPresented: $isShowingVNDocumentCameraView, onDismiss: saveImages) {
VNDocumentCameraViewControllerRepresentable(scanResult: $scannedImages) VNDocumentCameraViewControllerRepresentable(scanResult: $scannedImages)
} }
.toolbar { .toolbar {
@ -57,12 +67,19 @@ struct ContentView: View {
} }
private func showVNDocumentCameraView() { private func showVNDocumentCameraView() {
Task { Task { guard await isAuthorized else { return } }
guard await isAuthorized else { return }
}
isShowingVNDocumentCameraView = true isShowingVNDocumentCameraView = true
} }
private func saveImages() {
let newScan = Scan(images: scannedImages)
ctx.insert(newScan)
try? ctx.save()
scannedImages = []
}
} }
#Preview { #Preview {

View File

@ -6,12 +6,26 @@
// //
import SwiftUI import SwiftUI
import SwiftData
@main @main
struct JustScanItApp: App { struct JustScanItApp: App {
var sharedModelContainer: ModelContainer = {
let schema = Schema([ Scan.self ])
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false)
do {
return try ModelContainer(for: schema, configurations: [modelConfiguration])
} catch {
fatalError("Could not create ModelContainer: \(error)")
}
}()
var body: some Scene { var body: some Scene {
WindowGroup { WindowGroup {
ContentView() ContentView()
} }
.modelContainer(sharedModelContainer)
} }
} }

View File

@ -0,0 +1,37 @@
//
// Scan.swift
// JustScanIt
//
// Created by Pradyun Setti on 03/07/2024.
//
import Foundation
import SwiftData
import UIKit
@Model
final class Scan {
let timestamp: Date
var images: [Data]
var uiImages: [UIImage] {
self.images.map { UIImage(data: $0) ?? UIImage(systemName: "exclamationmark.questionmark")! }
}
init() {
self.timestamp = Date()
self.images = []
}
init(images: [Data]) {
self.timestamp = Date()
self.images = images
}
init(images: [UIImage]) {
self.timestamp = Date()
self.images = images.map{ $0.pngData() ?? Data() }
}
}