diff --git a/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate b/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate index 51695c61ca0d70f656135192bdbd4069618711b0..5bf33ff80c21bdce1f603c315d95940de5c9a601 100644 Binary files a/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate and b/MiniScanner.xcworkspace/xcuserdata/g.makhoul.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/MiniScanner/Managers/PDFManager.swift b/MiniScanner/Managers/PDFManager.swift index e699bbf8e7be9a14e383b1db8736fa4b2ebc5e81..01beeaf06b8cc8ca2f02745089c9316afe56b295 100644 --- a/MiniScanner/Managers/PDFManager.swift +++ b/MiniScanner/Managers/PDFManager.swift @@ -94,12 +94,12 @@ class PDFManager { } } - class func createMultiPDFPage(from imageURLs: [URL], localFileManager: LocalFileManager?, folder: AppConfigurator.Folder, name: String = "", _ completion: @escaping () -> ()) { + class func createMultiPDFPage(from imageURLs: [URL], localFileManager: LocalFileManager?, folder: AppConfigurator.Folder, name: String = "", session: MultiPageScanSession = MultiPageScanSession(), _ completion: @escaping () -> ()) { guard let allDoc = localFileManager?.AllDocUrl else { return } guard let scannerURL = localFileManager?.getFolderUrl(folder: folder) else { return } - - let urlPDFtoSave = scannerURL.appendingPathComponent(name == "" ? String.getDocumentName() : name) - let urlPDFtoSaveInAllDoc = allDoc.appendingPathComponent(name == "" ? String.getDocumentName() : name) + let displayName = name == "" ? String.getDocumentName() : name + let urlPDFtoSave = scannerURL.appendingPathComponent(displayName) + let urlPDFtoSaveInAllDoc = allDoc.appendingPathComponent(displayName) if imageURLs.isEmpty { return } let document = PDFDocument() @@ -140,50 +140,32 @@ class PDFManager { } catch { print(error.localizedDescription) // handle error } + + let pdfDocumentObject = PDFDocumentObject(name: displayName.replacingOccurrences(of: ".pdf", with: ""), session: session) + let defaults = UserDefaults.standard + let encoder = JSONEncoder() + let decoder = JSONDecoder() + + // Fetch the existing array of PDFDocumentObjects from UserDefaults + var existingPDFDocumentObjects: [PDFDocumentObject] = [] + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + existingPDFDocumentObjects = loadedPDFDocumentObjects + } + } + + // Add the new PDFDocumentObject to the existing array + existingPDFDocumentObjects.append(pdfDocumentObject) + // Save the updated array back to UserDefaults + if let encodedData = try? encoder.encode(existingPDFDocumentObjects) { + defaults.set(encodedData, forKey: "pdfDocumentObjects") + } + print("All images have been processed") } } -// class func createMultiPDFPageAndReturn(from imageURLs: [URL], localFileManager: LocalFileManager?, folder: AppConfigurator.Folder, name: String = "", _ completion: @escaping (URL) -> ()) { -// guard let scannerURL = localFileManager?.getFolderUrl(folder: folder) else { return } -// -// let urlPDFtoSave = scannerURL.appendingPathComponent(name == "" ? String.getDocumentName() : "\(name).pdf") -// -// if imageURLs.isEmpty { return } -// let document = PDFDocument() -// -// let dispatchGroup = DispatchGroup() -// -// // Iterate through image URLs -// for (index, imageURL) in imageURLs.enumerated() { -// dispatchGroup.enter() -// DispatchQueue.global().async { -// if let data = try? Data(contentsOf: imageURL), -// let image = UIImage(data: data), -// let pdfPage = PDFPage(image: image) { -// DispatchQueue.main.async { -// document.insert(pdfPage, at: index) -// if document.pageCount == imageURLs.count { -// do { -// try document.dataRepresentation()?.write(to: urlPDFtoSave) -// completion(urlPDFtoSave) -// } catch { -// print(error.localizedDescription) // handle error -// } -// } -// dispatchGroup.leave() -// } -// } else { -// dispatchGroup.leave() -// } -// } -// } -// dispatchGroup.notify(queue: .main) { -// print("All images have been processed") -// } -// } - class func createMultiPDFPageAndReturn(from imageURLs: [URL], localFileManager: LocalFileManager?, folder: AppConfigurator.Folder, name: String = "", _ completion: @escaping (URL) -> ()) { guard let scannerURL = localFileManager?.getFolderUrl(folder: folder) else { return } @@ -233,15 +215,39 @@ class PDFManager { } } - class func appendPage(image: UIImage, pdfView: PDFView, documentURL: URL?) { + class func appendPage(image: UIImage, pdfView: PDFView, documentURL: URL?, name: String = "") { guard let page = PDFPage(image: image), let documentURL = documentURL, let lastIndex = pdfView.document?.pageCount else { return } pdfView.document?.insert(page, at: lastIndex) pdfView.document?.write(to: documentURL) pdfView.go(to: page) - LocalFileManager().updateThumbnail(forURL: documentURL) + + let defaults = UserDefaults.standard + let encoder = JSONEncoder() + let decoder = JSONDecoder() + + // Fetch the existing array of PDFDocumentObjects from UserDefaults + var existingPDFDocumentObjects: [PDFDocumentObject] = [] + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + existingPDFDocumentObjects = loadedPDFDocumentObjects + } + } + + // Add the new PDFDocumentObject to the existing array + for item in existingPDFDocumentObjects { + if item.name.replacingOccurrences(of: ".pdf", with: "") == name { + let newItem = ScannedItem(originalImage: image, renderImage: image) + item.session.add(item: newItem) + } + } + + // Save the updated array back to UserDefaults + if let encodedData = try? encoder.encode(existingPDFDocumentObjects) { + defaults.set(encodedData, forKey: "pdfDocumentObjects") + } } class func appendPage(imageURL: URL, pdfView: PDFView, documentURL: URL?) { @@ -283,12 +289,40 @@ class PDFManager { pdfView.layoutDocumentView() } - class func deletePage(at index: Int, pdfDocument: PDFDocument?, documentURL: URL?, pdfView: PDFView!) { - guard let pdfDocument = pdfDocument, let documentURL = documentURL, let pdfView = pdfView else { return } + class func deletePage(at index: Int, pdfDocument: PDFDocument?, documentURL: URL?, pdfView: PDFView!, name: String = "") -> PDFDocument { + guard let pdfDocument = pdfDocument, let documentURL = documentURL, let pdfView = pdfView else { return PDFDocument() } pdfDocument.removePage(at: index) pdfDocument.write(to: documentURL) pdfView.document = pdfDocument pdfView.layoutDocumentView() + + let defaults = UserDefaults.standard + let encoder = JSONEncoder() + let decoder = JSONDecoder() + + // Fetch the existing array of PDFDocumentObjects from UserDefaults + var existingPDFDocumentObjects: [PDFDocumentObject] = [] + var changedExistingPDFDocumentObjects: [PDFDocumentObject] = [] + + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + existingPDFDocumentObjects = loadedPDFDocumentObjects + changedExistingPDFDocumentObjects = existingPDFDocumentObjects + } + } + + // Add the new PDFDocumentObject to the existing array + for (i,item) in existingPDFDocumentObjects.enumerated() { + if item.name.replacingOccurrences(of: ".pdf", with: "") == name { + changedExistingPDFDocumentObjects[i].session.remove(index: index) + } + } + + // Save the updated array back to UserDefaults + if let encodedData = try? encoder.encode(changedExistingPDFDocumentObjects) { + defaults.set(encodedData, forKey: "pdfDocumentObjects") + } + LocalFileManager().updateThumbnail(forURL: documentURL) if pdfView.canGoToNextPage { pdfView.goToNextPage(pdfView) @@ -305,5 +339,6 @@ class PDFManager { } else { pdfView.layoutDocumentView() } + return pdfDocument } } diff --git a/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift b/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift index 390760695b824aa5b10e949a24ddfd872b82227c..649a35f68403345704715d0a6bb832af8046bcd9 100644 --- a/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift +++ b/MiniScanner/Modules/DocumentPreview/DocumentPreviewViewController.swift @@ -22,6 +22,8 @@ final class DocumentPreviewViewController: UIViewController { var file: File? private var scannedItem: ScannedItem! var payload: [Any] = [] + var session: MultiPageScanSession? + var selectedFolder: AppConfigurator.Folder? lazy private var activityIndicator: UIActivityIndicatorView = { let activityIndicator = UIActivityIndicatorView(style: .large) @@ -145,11 +147,23 @@ final class DocumentPreviewViewController: UIViewController { } @IBAction func drawTapped(_ sender: UIBarButtonItem) { - let previewController = PencilKitViewController() - previewController.dataSource = self - previewController.delegate = self - previewController.modalPresentationStyle = .fullScreen - present(previewController, animated: true, completion: nil) + let defaults = UserDefaults.standard + let decoder = JSONDecoder() + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + // loadedPDFDocumentObjects is your array of PDFDocumentObject instances + for pdfDocument in loadedPDFDocumentObjects { + if pdfDocument.name == file?.displayName { + self.session = pdfDocument.session + let editViewController = EditViewController(scanSession: self.session ?? MultiPageScanSession()) + editViewController.selectedFolder = self.selectedFolder + self.navigationController?.pushViewController(editViewController, animated: true) + break + } + } + } + } + } @IBAction func deleteTapped(_ sender: UIBarButtonItem) { @@ -163,8 +177,10 @@ final class DocumentPreviewViewController: UIViewController { try? FileManager.default.removeItem(at: documentURL) self.navigationController?.popViewController(animated: true) } else { - PDFManager.deletePage(at: pdfView.getCurrentPageIndex(), pdfDocument: pdfView.document, + let newDoc = PDFManager.deletePage(at: pdfView.getCurrentPageIndex(), pdfDocument: pdfView.document, documentURL: self.file?.fileURL, pdfView: pdfView) + pdfView.setDocument(nil) + pdfView.setDocument(newDoc) } }) @@ -176,8 +192,14 @@ final class DocumentPreviewViewController: UIViewController { try? FileManager.default.removeItem(at: documentURL) self.navigationController?.popViewController(animated: true) } else { - PDFManager.deletePage(at: pdfView.getCurrentPageIndex(), pdfDocument: pdfView.document, - documentURL: self.file?.fileURL, pdfView: pdfView) + let newDoc = PDFManager.deletePage(at: pdfView.getCurrentPageIndex(), pdfDocument: pdfView.document, + documentURL: self.file?.fileURL, pdfView: pdfView, name: self.file?.displayName ?? "") + + pdfView.setDocument(nil) + pdfView.setDocument(newDoc) + if let url = self.file?.fileURL { + self.payload = [url] + } } }) @@ -235,7 +257,7 @@ extension DocumentPreviewViewController: UINavigationControllerDelegate, UIImage picker.dismiss(animated: true) { [weak self] in guard let self = self else { return } guard let image = info[UserDefaults.standard.isPhotoEditigOn ? UIImagePickerController.InfoKey.editedImage : UIImagePickerController.InfoKey.originalImage] as? UIImage else { return } - PDFManager.appendPage(image: image, pdfView: self.pdfView, documentURL: self.file?.fileURL) + PDFManager.appendPage(image: image, pdfView: self.pdfView, documentURL: self.file?.fileURL, name: self.file?.displayName ?? "") } } } diff --git a/MiniScanner/Modules/Documents/DocumentsTableViewController.swift b/MiniScanner/Modules/Documents/DocumentsTableViewController.swift index b7d8e80de7c71d94ef8fd396193545cfc6ef4177..e4eaaaeddba06a6fb1ef62218477ada102009b77 100644 --- a/MiniScanner/Modules/Documents/DocumentsTableViewController.swift +++ b/MiniScanner/Modules/Documents/DocumentsTableViewController.swift @@ -49,6 +49,18 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, private var localFileManager: LocalFileManager? override func viewDidLoad() { super.viewDidLoad() + let defaults = UserDefaults.standard + let decoder = JSONDecoder() + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + // loadedPDFDocumentObjects is your array of PDFDocumentObject instances + for pdfDocument in loadedPDFDocumentObjects { +// if pdfDocument.fileURL == viewModel.fileURL { + print("*****count****:\(pdfDocument.session.scannedItems.count)") +// } + } + } + } scanSession = MultiPageScanSession() options = ImageScannerOptions() navigationItem.title = "File Manager" @@ -212,8 +224,23 @@ final class DocumentsTableViewController: UIViewController, UITableViewDelegate, func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { let viewModel = isSearching ? searchedViewModel[indexPath.row] : viewModels[indexPath.row] + var session: MultiPageScanSession? + let defaults = UserDefaults.standard + let decoder = JSONDecoder() + if let savedData = defaults.object(forKey: "pdfDocumentObjects") as? Data { + if let loadedPDFDocumentObjects = try? decoder.decode([PDFDocumentObject].self, from: savedData) { + // loadedPDFDocumentObjects is your array of PDFDocumentObject instances + for pdfDocument in loadedPDFDocumentObjects { + if pdfDocument.name == viewModel.displayName { + session = pdfDocument.session + } + } + } + } let controller = DocumentPreviewViewController.buildViewController() controller.file = viewModel + controller.session = session + controller.selectedFolder = self.selectedFolder controller.hidesBottomBarWhenPushed = true navigationController?.pushViewController(controller, animated: true) } diff --git a/MiniScanner/Modules/EditViewController/EditViewController.swift b/MiniScanner/Modules/EditViewController/EditViewController.swift index 39695a93cb1bb0ebdd0779d69c52d3d3e097988b..eae8c3c390a623602038bcafe67329031af69267 100644 --- a/MiniScanner/Modules/EditViewController/EditViewController.swift +++ b/MiniScanner/Modules/EditViewController/EditViewController.swift @@ -547,13 +547,13 @@ extension EditViewController: ShareSheetViewControllerDelegate { activityIndicator.startAnimating() var images = [URL]() for index in 0..<(scanSession?.scannedItems.count ?? 0) { - if let url = scanSession?.scannedItems[index].originalImage { + if let url = scanSession?.scannedItems[index].renderedImage { images.append(url) } } print("images: \(images)") if let folder = selectedFolder { - PDFManager.createMultiPDFPage(from: images, localFileManager: localFileManager, folder: folder, name: name, { + PDFManager.createMultiPDFPage(from: images, localFileManager: localFileManager, folder: folder, name: name, session: scanSession ?? MultiPageScanSession(), { self.activityIndicator.stopAnimating() self.navigationController?.popViewController(animated: true) }) diff --git a/MiniScanner/Supporting Files/CustomWeScan/MultiPageSession/MultiPageScanSession.swift b/MiniScanner/Supporting Files/CustomWeScan/MultiPageSession/MultiPageScanSession.swift index 613c186e3fe8a84371b6e0a91d3951a264d6c30c..51c527c38fdd49409363de8cf3bf55d68a0f079f 100644 --- a/MiniScanner/Supporting Files/CustomWeScan/MultiPageSession/MultiPageScanSession.swift +++ b/MiniScanner/Supporting Files/CustomWeScan/MultiPageSession/MultiPageScanSession.swift @@ -9,17 +9,17 @@ import Foundation import UIKit -public enum ScannedItemColorOption{ +public enum ScannedItemColorOption: Codable{ case color case grayscale } /// Data structure containing information about one page scanned -public class ScannedItem{ +public class ScannedItem: Codable { /// The original image taken by the user, prior to the cropping applied by WeScan. var originalImage:URL? - + /// The detected rectangle which was used to generate the `scannedImage`. var quad:Quadrilateral? @@ -75,9 +75,40 @@ public class ScannedItem{ public func addScreenShot(screen: UIImage) { self.screenShot = screen } + enum CodingKeys: CodingKey { + case originalImage, quad, rotation, colorOption, renderedImage, signaturePosition, size, rotate + } + + public required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + + originalImage = try? container.decode(URL.self, forKey: .originalImage) + rotation = try container.decode(Double.self, forKey: .rotation) + colorOption = try container.decode(ScannedItemColorOption.self, forKey: .colorOption) + renderedImage = try? container.decode(URL.self, forKey: .renderedImage) + signaturePosition = try? container.decode(CGPoint.self, forKey: .signaturePosition) + size = try? container.decode(CGSize.self, forKey: .size) + rotate = try? container.decode(CGFloat.self, forKey: .rotate) + + // Custom decoding for `quad` here + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(originalImage, forKey: .originalImage) + try container.encode(rotation, forKey: .rotation) + try container.encode(colorOption, forKey: .colorOption) + try container.encode(renderedImage, forKey: .renderedImage) + try container.encode(signaturePosition, forKey: .signaturePosition) + try container.encode(size, forKey: .size) + try container.encode(rotate, forKey: .rotate) + + // Custom encoding for `quad` here + } } -public class MultiPageScanSession { +public class MultiPageScanSession: Codable { public private(set) var scannedItems:Array<ScannedItem> = [] @@ -120,3 +151,30 @@ extension ScannedItem { return documentURL.appendingPathComponent("\(UUID().uuidString).jpg") } } + +class PDFDocumentObject: Codable { + let name: String + let session: MultiPageScanSession + + enum CodingKeys: CodingKey { + case name, session + } + + public required init(from decoder: Decoder) throws { + let container = try decoder.container(keyedBy: CodingKeys.self) + name = try! container.decode(String.self, forKey: .name) + session = try container.decode(MultiPageScanSession.self, forKey: .session) + } + + public init(name: String, session: MultiPageScanSession) { + self.name = name + self.session = session + } + + public func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + + try container.encode(name, forKey: .name) + try container.encode(session, forKey: .session) + } +} diff --git a/MiniScanner/Supporting Files/CustomWeScan/Scan/ScannerViewController.swift b/MiniScanner/Supporting Files/CustomWeScan/Scan/ScannerViewController.swift index ff23add096b8dc5a5a58c909d2795d337a9f9504..edb61f500bada738964a86c1f3201226ae51c9bc 100644 --- a/MiniScanner/Supporting Files/CustomWeScan/Scan/ScannerViewController.swift +++ b/MiniScanner/Supporting Files/CustomWeScan/Scan/ScannerViewController.swift @@ -651,7 +651,7 @@ extension ScannerViewController: ShareSheetViewControllerDelegate, PreviewDelega } print("images: \(images)") if let folder = selectedFolder { - PDFManager.createMultiPDFPage(from: images, localFileManager: localFileManager, folder: folder, name: name, { + PDFManager.createMultiPDFPage(from: images, localFileManager: localFileManager, folder: folder, name: name,session: self.multipageSession, { self.activityIndicator.stopAnimating() self.navigationController?.popViewController(animated: true) })