// // File.swift // PDF Reader Pro // // Created by liujiajie on 2023/11/30. // import Foundation typealias compressCallbackBlock = (_ isSuccess: Bool) -> Void class KMCompressOperation: KMBatchOperation{ var dpiValue: NSNumber = 0 var pdfDocument: CPDFDocument? init(file: KMBatchOperateFile, compressValue dpiType: NSNumber) { super.init(file: file) self.dpiValue = dpiType } override func start() { if !self.isCancelled { self.pdfDocument = CPDFDocument(url: URL(fileURLWithPath: self.operateFile?.filePath ?? "")) if let data = self.pdfDocument?.isLocked, data { self.pdfDocument?.unlock(withPassword: self.operateFile?.password) } self.delegate?.fileBeginOperate?(self.operateFile!, info: self.operateFile!.compressInfo) willChangeValue(forKey: "isExecuting") self.hasExcuting = true didChangeValue(forKey: "isExecuting") if !FileManager.default.fileExists(atPath: self.operateFile?.filePath ?? "") { self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("File Not Exist")), info: self.operateFile!.removePasswordInfo) self.willChangeValue(forKey: "isFinished") self.hasFinished = true self.didChangeValue(forKey: "isFinished") return } if self.pdfDocument == nil { self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("An error occurred while opening this document. The file is damaged and could not be repaired.")), info: self.operateFile!.removeWatermarkInfo) self.willChangeValue(forKey: "isFinished") self.hasFinished = true self.didChangeValue(forKey: "isFinished") return } self.compressToPath(targetPath: (self.operateFile?.compressInfo.fetchDestinationFilepath()), documentPath: self.operateFile?.filePath ?? "", password: self.operateFile?.password ?? "", compressType: self.dpiValue) { isSuccess in if isSuccess { self.delegate?.fileOperateSuccessed?(self.operateFile!, info: self.operateFile!.compressInfo) }else{ self.delegate?.fileOperateFailed?(self.operateFile!, error: self.errorWithMsg(KMLocalizedString("Failed")), info: self.operateFile!.compressInfo) } } DispatchQueue.main.async { if self.viewController?.view.window?.isVisible == true { self.willChangeValue(forKey: "isFinished") self.hasFinished = true self.didChangeValue(forKey: "isFinished") } } }else { DispatchQueue.main.async { if self.viewController?.view.window?.isVisible == true { self.willChangeValue(forKey: "isFinished") self.willChangeValue(forKey: "isExecuting") self.hasExcuting = false self.hasFinished = true self.didChangeValue(forKey: "isExecuting") self.didChangeValue(forKey: "isFinished") } } } } override func cancel() { // super.cancel() if isExecuting { self.operateFile?.compressInfo.status = .Waiting if FileManager.default.fileExists(atPath: (operateFile?.compressInfo.outPutPath)!) { try? FileManager.default.removeItem(atPath: (operateFile!.compressInfo.outPutPath)!) } self.delegate?.fileOperateCanceled?(self.operateFile!, info: self.operateFile!.compressInfo) DispatchQueue.main.async { if self.viewController?.view.window?.isVisible == true { self.willChangeValue(forKey: "isFinished") self.hasFinished = true self.didChangeValue(forKey: "isFinished") } } } else { DispatchQueue.main.async { if self.viewController?.view.window?.isVisible == true { self.willChangeValue(forKey: "isCancelled") self.hasCanceled = true self.didChangeValue(forKey: "isCancelled") } } } } func compressToPath(targetPath: String?, documentPath: String, password: String, compressType: NSNumber?, completeHandler: compressCallbackBlock) { if self.pdfDocument!.isLocked { let unlockSuccess = self.pdfDocument!.unlock(withPassword: password) if !unlockSuccess { completeHandler(false) return } } if compressType == nil { completeHandler(false) return } let isSuccessfully = self.pdfDocument!.writeOptimize(to: URL(fileURLWithPath: targetPath ?? ""), withOptions: [CPDFDocumentOptimizeOption.imageQualityOption: compressType as Any]) completeHandler(isSuccessfully) } }