Search code examples
iosswiftuicore-datavisionkit

Value of type 'CapturedImage' has no member 'append'


I'm trying to evolve my app to save an array of images in Core Data instead of pre-defined attributes of an Entity. Today, my Entity has 4 image attributes, and the user saves 4 images as 4 separate actions within the app. It works.

Now I'm trying to implement VisionKit so the user can just auto scan and crop the images one after another, and then save one time to get multiple images saved. I have the scan piece working:

import SwiftUI
import VisionKit

struct ScannerView: UIViewControllerRepresentable {
    
    @Binding var images: [Data]
    
    var didFinishScanning: ((_ result: Result<[UIImage], Error>) -> Void)
    var didCancelScanning: () -> Void
    
    func makeUIViewController(context: Context) -> VNDocumentCameraViewController {
        let scannerViewController = VNDocumentCameraViewController()
        scannerViewController.delegate = context.coordinator
        return scannerViewController
    }
    
    func updateUIViewController(_ uiViewController: VNDocumentCameraViewController, context: Context) { }
    
    
    func makeCoordinator() -> Coordinator {
        Coordinator(with: self)
    }
    
    
    class Coordinator: NSObject, VNDocumentCameraViewControllerDelegate {
        let scannerView: ScannerView
        
        init(with scannerView: ScannerView) {
            self.scannerView = scannerView
        }
        
        
        // MARK: - VNDocumentCameraViewControllerDelegate
        
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFinishWith scan: VNDocumentCameraScan) {
            var scannedPages = [UIImage]()
            
            for i in 0..<scan.pageCount {
                scannedPages.append(scan.imageOfPage(at: i))
                
                    let image = scan.imageOfPage(at: i)
                    scannerView.images.append( image.jpegData(compressionQuality: 0.55)! )
                    
            }
            
            scannerView.didFinishScanning(.success(scannedPages))
            controller.dismiss(animated: true, completion: nil)
        }
        
        
        func documentCameraViewControllerDidCancel(_ controller: VNDocumentCameraViewController) {
            scannerView.didCancelScanning()
        }
        
        func documentCameraViewController(_ controller: VNDocumentCameraViewController, didFailWithError error: Error) {
            scannerView.didFinishScanning(.failure(error))
        }
    }
    
}

And can immediately view the images in the View

LazyHStack {
    ForEach(0..<images.count, id: \.self) { imageIdx in
       Image(uiImage: UIImage(data: self.images[imageIdx])!)
             .resizable()
             .cornerRadius(6)
             .scaledToFit()
             .frame(width: self.width, height: self.height)

          }
    }

Here's a quick video showing everything to this point: https://i.sstatic.net/dAC10.jpg

I'm stuck trying to properly save the array of images. I get error Value of type 'CapturedImage' has no member 'append'

for image in images {
    let capImage = CapturedImage(context: viewContext)
    capImage.image = image
    capImage.timestamp = Date()
    project.capturedimage?.append(capImage) --->>> error

  }

My CapturedImage+CoreDataProperties.swift looks like this:

import Foundation
import CoreData


extension CapturedImage {

    @nonobjc public class func fetchRequest() -> NSFetchRequest<CapturedImage> {
        return NSFetchRequest<CapturedImage>(entityName: "CapturedImage")
    }

    @NSManaged public var image: Data?
    @NSManaged public var timestamp: Date?
    @NSManaged public var project: Project?

}

extension CapturedImage : Identifiable {

}

And here is the relationship between Project and CapturedImage entities (you'll also notice the image1 image2 image3 image4 attributes that currently work for single image saves... enter image description here enter image description here

What do I need to do in order to overcome that append error above? Am I on the right track for saving the array to CD properly?

Apologies for the length of this post! I wanted to provide as much info as I could while trying to keep it brief. Thanks for looking


Solution

  • According to your model capturedimage in Project is a To Many relationship, the type is NSSet or Set<CapturedImage>. And the naming is misleading, it should be named in plural form capturedImages.

    Sets are unordered, you have to insert the object. Depending on your settings Core Data might create a convenient setter addToCapturedImages on your behalf

    project.addToCapturedImages(capImage)
    

    Please see Generating Code in the documentation.