// // DSignatureApperanceManager.swift // PDF Reader Pro Edition // // Created by Niehaoyu on 2023/10/8. // import Cocoa class DSignatureAppearanceData: NSObject { var appearanceName = NSString() var signatureConfig = CPDFSignatureConfig() var tag = NSString() var drawType: CDSignatureCustomType = .none var isInputDSignatureText: Bool = false override init() { super.init() appearanceName = "" } } class DSignatureApperanceManager: NSObject { @objc public static let manager = DSignatureApperanceManager.init() var signatures: NSMutableArray! override init() { super.init() self.signatures = NSMutableArray.init() } @objc func tagString() -> NSString { let dateFormatter = DateFormatter.init() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let dateString = dateFormatter.string(from: NSDate() as Date) return NSString(format: "%@ %d", dateString, arc4random()%10000) } func getFileSize(atPath filePath : String) -> CGFloat { guard let dict = try? FileManager.default.attributesOfItem(atPath: filePath) as NSDictionary else { return 0 } return CGFloat(dict.fileSize()) } func sortContens(_ contens: NSArray) -> NSArray { let tContens = NSMutableArray() var nameItem: CPDFSignatureConfigItem! var dnItem: CPDFSignatureConfigItem! var reaItem: CPDFSignatureConfigItem! var locaItem: CPDFSignatureConfigItem! var dateItem: CPDFSignatureConfigItem! var verItem: CPDFSignatureConfigItem! for item in contens { if (item as! CPDFSignatureConfigItem).key == NAME_KEY { nameItem = item as? CPDFSignatureConfigItem } else if (item as! CPDFSignatureConfigItem).key == DN_KEY { dnItem = item as? CPDFSignatureConfigItem } else if (item as! CPDFSignatureConfigItem).key == REASON_KEY { reaItem = item as? CPDFSignatureConfigItem } else if (item as! CPDFSignatureConfigItem).key == LOCATION_KEY { locaItem = item as? CPDFSignatureConfigItem } else if (item as! CPDFSignatureConfigItem).key == DATE_KEY { dateItem = item as? CPDFSignatureConfigItem } else if (item as! CPDFSignatureConfigItem).key == VERSION_KEY { verItem = item as? CPDFSignatureConfigItem } } if nameItem != nil { tContens.add(nameItem as Any) } if dnItem != nil { tContens.add(dnItem as Any) } if reaItem != nil { tContens.add(reaItem as Any) } if locaItem != nil { tContens.add(locaItem as Any) } if dateItem != nil { tContens.add(dateItem as Any) } if verItem != nil { tContens.add(verItem as Any) } return tContens } //MARK: Load public func loadDSignatureAppearanceDatas() -> NSMutableArray{ self.signatures.removeAllObjects() if FileManager.default.fileExists(atPath: kDSignaturePlistPath) { let dictionary = NSDictionary(contentsOfFile: kDSignaturePlistPath)! for key in dictionary.allKeys { let dic: NSDictionary = dictionary[key] as! NSDictionary let data: DSignatureAppearanceData = DSignatureAppearanceData.init() data.tag = key as! NSString data.appearanceName = dic[kDSignatureOfAppearanceKey] as! NSString if (dic.value(forKey: kDSignatureOfDrawTypeKey) != nil) { data.drawType = CDSignatureCustomType(rawValue: dic[kDSignatureOfDrawTypeKey] as! NSInteger)! } else { data.drawType = .none } data.signatureConfig = self.switchDictionaryToWatermark(dic) data.isInputDSignatureText = (dic[kDSignatureOfIsTextKey] != nil) self.signatures.add(data) } } if self.signatures.count < 1 { let data = self.standardDSignatureAppearanceData() data.tag = self.tagString() data.appearanceName = NSLocalizedString("Standard Text", comment: "") as NSString _ = self.addDSignatureAppearanceData(watermark: data) } return self.signatures } func getLastDSignatureAppearanceData() -> DSignatureAppearanceData { let data = DSignatureAppearanceData.init() var info: [String : Any] = [:] if (UserDefaults.standard.value(forKey: kLastAddDSignatureDataKey) == nil) { } else { info = (UserDefaults.standard.value(forKey: kLastAddDSignatureDataKey) as! [String : Any]) } var watermarkDic = NSMutableDictionary(dictionary: info) if watermarkDic.allKeys.count > 0 { data.tag = watermarkDic.allKeys.first as! NSString var appearanceDic: [String : Any] = [:] if (watermarkDic.object(forKey: data.tag as Any) == nil) { } else { appearanceDic = watermarkDic.object(forKey: data.tag as Any) as! [String : Any] data.appearanceName = appearanceDic[kDSignatureOfAppearanceKey] as! NSString let typeA: CDSignatureCustomType = appearanceDic[kDSignatureOfDrawTypeKey] as? CDSignatureCustomType ?? .none data.drawType = typeA data.signatureConfig = self.switchDictionaryToWatermark(appearanceDic as NSDictionary) data.isInputDSignatureText = (appearanceDic[kDSignatureOfIsTextKey] != nil) } } return data } //MARK: Get func standardDSignatureAppearanceData() -> DSignatureAppearanceData { let data = DSignatureAppearanceData.init() data.drawType = .text let config = CPDFSignatureConfig.init() config.isDrawLogo = true config.isContentAlginLeft = false config.isDrawKey = true #if VERSION_FREE #if VERSION_DMG config.logo = NSImage(named: "PDFReaderProLogo") #else config.logo = NSImage(named: "PDFReaderProLogo") #endif #else config.logo = NSImage(named: "PDFReaderProEditionLogo") #endif let nameItem = CPDFSignatureConfigItem.init() nameItem.key = NAME_KEY nameItem.value = NSLocalizedString("", comment: "") let dateItem = CPDFSignatureConfigItem.init() dateItem.key = DATE_KEY let dateFormatter = DateFormatter.init() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" dateItem.value = dateFormatter.string(from: NSDate() as Date) let contents = NSMutableArray() contents.add(nameItem) contents.add(dateItem) config.contents = self.sortContens(contents) as? [CPDFSignatureConfigItem] data.signatureConfig = config data.isInputDSignatureText = false return data } //MARK: Switch func switchDictionaryToWatermark(_ dic: NSDictionary) -> CPDFSignatureConfig { let config = CPDFSignatureConfig.init() var contents = Array.init() for key in dic.allKeys { if key as! String == ISDRAWLOGO_KEY { if let isDrawLogo = dic[ISDRAWLOGO_KEY] as? Bool { config.isDrawLogo = isDrawLogo } } else if key as! String == ISDRAW_KEY { config.isDrawKey = (dic[ISDRAW_KEY] != nil) } else if key as! String == ISCONTENTALGINLEGF_KEY { if let isContentAlignLeft = dic[ISCONTENTALGINLEGF_KEY] as? Bool { config.isContentAlginLeft = isContentAlignLeft } } else if key as! String == kDSignatureOfTextKey { config.text = dic[kDSignatureOfTextKey] as? String } else if key as! String == kDSignatureOfImagePathKey { guard let keyValue = dic[kDSignatureOfImagePathKey] as? String else { return config } let filePath = kDSignatureFolderPath + "/" + keyValue if FileManager.default.fileExists(atPath: filePath) { config.image = NSImage.init(contentsOfFile: filePath) } } else { let item = CPDFSignatureConfigItem.init() item.key = NSLocalizedString(key as! String, comment: "") item.value = dic[key] as? String contents.append(item) } } // if config.isDrawLogo { #if VERSION_FREE #if VERSION_DMG config.logo = NSImage(named: "PDFReaderProLogo") #else config.logo = NSImage(named: "PDFReaderProLogo") #endif #else config.logo = NSImage(named: "PDFReaderProEditionLogo") #endif // } config.contents = self.sortContens(contents as NSArray) as? [CPDFSignatureConfigItem] return config } func switchDSignatureToDictionary(signatureConfig: CPDFSignatureConfig) -> NSDictionary { let configDictionary = NSMutableDictionary.init() if signatureConfig.isDrawLogo { configDictionary.setObject((1), forKey: ISDRAWLOGO_KEY as NSCopying) } else { configDictionary.setObject((0), forKey: ISDRAWLOGO_KEY as NSCopying) } if signatureConfig.isDrawKey { configDictionary.setObject((1), forKey: ISDRAW_KEY as NSCopying) } else { configDictionary.setObject((0), forKey: ISDRAW_KEY as NSCopying) } if signatureConfig.isContentAlginLeft { configDictionary.setObject((1), forKey: ISCONTENTALGINLEGF_KEY as NSCopying) } else { configDictionary.setObject((0), forKey: ISCONTENTALGINLEGF_KEY as NSCopying) } if signatureConfig.text != nil { configDictionary.setObject(signatureConfig.text as String, forKey: kDSignatureOfTextKey as NSCopying) } if signatureConfig.image != nil { let image = signatureConfig.image let data = image?.tiffRepresentation let imageRep = NSBitmapImageRep(data: data!) imageRep?.size = image!.size var imageData: NSData? imageData = imageRep?.representation(using: .png, properties: [:]) as NSData? let tag = self.tagString() let rPath = kDSignatureFolderPath.appending("/\(tag).png") imageData?.write(toFile: rPath, atomically: true) var pathComponent: NSString? pathComponent = NSString(format: "%@/%@.png", kDSignatureFolderPath, tag) configDictionary.setObject(pathComponent?.lastPathComponent as Any, forKey: kDSignatureOfImagePathKey as NSCopying) } for item in signatureConfig.contents { configDictionary.setValue(item.value, forKey: item.key) } return configDictionary as NSDictionary } //MARK: Add func addDSignatureAppearanceData(watermark: DSignatureAppearanceData) -> Bool { if FileManager.default.fileExists(atPath: kDSignatureFolderPath) == false { if FileManager.default.fileExists(atPath: ApplicationSupportDirectory) == false { try?FileManager.default.createDirectory(atPath: ApplicationSupportDirectory, withIntermediateDirectories: false) } try?FileManager.default.createDirectory(atPath: kDSignatureFolderPath, withIntermediateDirectories: false) if FileManager.default.fileExists(atPath: kDSignatureFolderPath) == false { return false } } if FileManager.default.fileExists(atPath: kDSignaturePlistPath) == false { if FileManager.default.createFile(atPath: kDSignaturePlistPath, contents: nil, attributes: nil) == false { return false } } var dictionary = NSDictionary.init() if self.getFileSize(atPath: kDSignaturePlistPath) > 0 { dictionary = NSDictionary(contentsOfFile: kDSignaturePlistPath)! } let newDictionary = NSMutableDictionary(dictionary: dictionary) let tag = watermark.tag let appearanceDic = self.switchDSignatureToDictionary(signatureConfig: watermark.signatureConfig) appearanceDic.setValue(watermark.appearanceName, forKey: kDSignatureOfAppearanceKey) appearanceDic.setValue((watermark.drawType.rawValue), forKey: kDSignatureOfDrawTypeKey) if watermark.isInputDSignatureText { appearanceDic.setValue((1), forKey: kDSignatureOfIsTextKey) } else { appearanceDic.setValue((0), forKey: kDSignatureOfIsTextKey) } newDictionary.setObject(appearanceDic, forKey: tag) if newDictionary.write(toFile: kDSignaturePlistPath, atomically: true) { if self.signatures.count < 1 { self.signatures.add(watermark) } else { self.signatures.insert(watermark, at: 0) } return true } return false } //MARK: Remove func removeDSignatureAppearanceData(watermark: DSignatureAppearanceData) -> Bool { let key = watermark.tag if key.length == 0 { return false } if FileManager.default.fileExists(atPath: kDSignaturePlistPath) == false { return false } let dictionary = NSDictionary(contentsOfFile: kDSignaturePlistPath)! let newDictionary = NSMutableDictionary(dictionary: dictionary) newDictionary.removeObject(forKey: key as Any) if newDictionary.write(toFile: kDSignaturePlistPath, atomically: true) { self.signatures.remove(watermark) return true } return false } //MARK: Save func saveDSignatureAppearanceData(watermark: DSignatureAppearanceData) ->() { let watermarkDictionary = NSMutableDictionary() let appearanceDic = self.switchDSignatureToDictionary(signatureConfig: watermark.signatureConfig) appearanceDic.setValue(watermark.appearanceName, forKey: kDSignatureOfAppearanceKey) appearanceDic.setValue((watermark.drawType.rawValue), forKey: kDSignatureOfDrawTypeKey) if watermark.isInputDSignatureText { appearanceDic.setValue((1), forKey: kDSignatureOfIsTextKey) } else { appearanceDic.setValue((0), forKey: kDSignatureOfIsTextKey) } watermarkDictionary.setObject(appearanceDic, forKey: watermark.tag) UserDefaults.standard.setValue(watermarkDictionary, forKey: kLastAddDSignatureDataKey) UserDefaults.standard.setValue((1), forKey: "kHaveSaveWatermarkData") UserDefaults.standard.synchronize() } }