RCTCPDFView.swift 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235
  1. //
  2. // RCTCPDFView.swift
  3. // react-native-compdfkit-pdf
  4. //
  5. // Copyright © 2014-2024 PDF Technologies, Inc. All Rights Reserved.
  6. //
  7. // THIS SOURCE CODE AND ANY ACCOMPANYING DOCUMENTATION ARE PROTECTED BY INTERNATIONAL COPYRIGHT LAW
  8. // AND MAY NOT BE RESOLD OR REDISTRIBUTED. USAGE IS BOUND TO THE ComPDFKit LICENSE AGREEMENT.
  9. // UNAUTHORIZED REPRODUCTION OR DISTRIBUTION IS SUBJECT TO CIVIL AND CRIMINAL PENALTIES.
  10. // This notice may not be removed from this file.
  11. //
  12. import UIKit
  13. import ComPDFKit_Tools
  14. import ComPDFKit
  15. protocol RCTCPDFViewDelegate: AnyObject {
  16. func cpdfViewAttached(_ cpdfView: RCTCPDFView)
  17. func saveDocumentChange(_ cpdfView: RCTCPDFView)
  18. func onPageChanged(_ cpdfView: RCTCPDFView, pageIndex: Int)
  19. }
  20. class RCTCPDFView: UIView, CPDFViewBaseControllerDelete {
  21. weak var delegate: RCTCPDFViewDelegate?
  22. public var pdfViewController : CPDFViewController?
  23. private var navigationController : CNavigationController?
  24. init() {
  25. super.init(frame: CGRect(x: 0, y: 0, width: 500, height: 400))
  26. }
  27. required init?(coder: NSCoder) {
  28. fatalError("init(coder:) has not been implemented")
  29. }
  30. // MARK: - Private Methods
  31. private func createCPDFView() {
  32. var documentPath = document.path
  33. var success = false
  34. let homeDiectory = NSHomeDirectory()
  35. if (documentPath.hasPrefix(homeDiectory)) {
  36. let fileManager = FileManager.default
  37. let samplesFilePath = NSHomeDirectory().appending("/Documents/Files")
  38. let fileName = document.lastPathComponent
  39. let docsFilePath = samplesFilePath + "/" + fileName
  40. if !fileManager.fileExists(atPath: samplesFilePath) {
  41. try? FileManager.default.createDirectory(atPath: samplesFilePath, withIntermediateDirectories: true, attributes: nil)
  42. }
  43. try? FileManager.default.copyItem(atPath: document.path, toPath: docsFilePath)
  44. documentPath = docsFilePath
  45. } else {
  46. success = document.startAccessingSecurityScopedResource()
  47. }
  48. let jsonData = CPDFJSONDataParse(String: configuration)
  49. let configurations = jsonData.configuration ?? CPDFConfiguration()
  50. pdfViewController = CPDFViewController(filePath: documentPath, password: password, configuration: configurations)
  51. pdfViewController?.delegate = self
  52. navigationController = CNavigationController(rootViewController: pdfViewController!)
  53. navigationController?.view.autoresizingMask = [.flexibleWidth, .flexibleHeight]
  54. navigationController?.view.frame = self.frame
  55. navigationController?.setViewControllers([pdfViewController!], animated: true)
  56. addSubview(navigationController?.view ?? UIView())
  57. self.delegate?.cpdfViewAttached(self)
  58. if success {
  59. document.stopAccessingSecurityScopedResource()
  60. }
  61. }
  62. // MARK: - Public Methods
  63. func saveDocument(completionHandler: @escaping (Bool) -> Void) {
  64. if (self.pdfViewController?.pdfListView?.isEditing() == true && self.pdfViewController?.pdfListView?.isEdited() == true) {
  65. self.pdfViewController?.pdfListView?.commitEditing()
  66. if self.pdfViewController?.pdfListView?.document.isModified() == true {
  67. let document = self.pdfViewController?.pdfListView?.document
  68. let success = document?.write(to: document?.documentURL ?? URL(fileURLWithPath: ""), isSaveFontSubset: true) ?? false
  69. completionHandler(success)
  70. } else {
  71. completionHandler(true)
  72. }
  73. } else {
  74. if self.pdfViewController?.pdfListView?.document.isModified() == true {
  75. let document = self.pdfViewController?.pdfListView?.document
  76. let success = document?.write(to: document?.documentURL ?? URL(fileURLWithPath: ""), isSaveFontSubset: true) ?? false
  77. completionHandler(success)
  78. } else {
  79. completionHandler(true)
  80. }
  81. }
  82. }
  83. func setMargins(left : Int, top : Int, right : Int, bottom : Int) {
  84. if let pdfListView = self.pdfViewController?.pdfListView {
  85. pdfListView.pageBreakMargins = .init(top: CGFloat(top), left: CGFloat(left), bottom: CGFloat(bottom), right: CGFloat(right))
  86. pdfListView.layoutDocumentView()
  87. }
  88. }
  89. func removeAllAnnotations(completionHandler: @escaping (Bool) -> Void) {
  90. if let pdfListView = self.pdfViewController?.pdfListView {
  91. let pageCount = pdfListView.document?.pageCount ?? 0
  92. for i in 0..<pageCount {
  93. let page = pdfListView.document?.page(at: i)
  94. page?.removeAllAnnotations()
  95. }
  96. self.pdfViewController?.pdfListView?.setNeedsDisplayForVisiblePages()
  97. self.pdfViewController?.pdfListView?.updateActiveAnnotations([])
  98. completionHandler(true)
  99. } else {
  100. completionHandler(false)
  101. }
  102. }
  103. func importAnnotations(xfdfFile : URL, completionHandler: @escaping (Bool) -> Void) {
  104. if let pdfListView = self.pdfViewController?.pdfListView {
  105. let documentFolder = NSHomeDirectory().appending("/Documents/Files")
  106. if !FileManager.default.fileExists(atPath: documentFolder) {
  107. try? FileManager.default.createDirectory(at: URL(fileURLWithPath: documentFolder), withIntermediateDirectories: true, attributes: nil)
  108. }
  109. let documentPath = documentFolder + "/\(xfdfFile.lastPathComponent)"
  110. try? FileManager.default.copyItem(atPath: xfdfFile.path, toPath: documentPath)
  111. if !FileManager.default.fileExists(atPath: documentPath) {
  112. print("fail")
  113. }
  114. let success = pdfListView.document?.importAnnotation(fromXFDFPath: documentPath) ?? false
  115. if success {
  116. self.pdfViewController?.pdfListView?.setNeedsDisplayForVisiblePages()
  117. }
  118. completionHandler(success)
  119. } else {
  120. completionHandler(false)
  121. }
  122. }
  123. func exportAnnotations(completionHandler: @escaping (String) -> Void) {
  124. if let pdfListView = self.pdfViewController?.pdfListView {
  125. let fileNameWithExtension = pdfListView.document?.documentURL.lastPathComponent ?? ""
  126. let fileName = (fileNameWithExtension as NSString).deletingPathExtension
  127. let documentFolder = NSHomeDirectory().appending("/Documents/\(fileName)_xfdf.xfdf")
  128. let succes = pdfListView.document?.exportAnnotation(toXFDFPath: documentFolder) ?? false
  129. if succes {
  130. completionHandler(documentFolder)
  131. } else {
  132. completionHandler("")
  133. }
  134. } else {
  135. completionHandler("")
  136. }
  137. }
  138. func setDisplayPageIndex(pageIndex : Int) {
  139. if let pdfListView = self.pdfViewController?.pdfListView {
  140. pdfListView.go(toPageIndex: pageIndex, animated: false)
  141. }
  142. }
  143. func getCurrentPageIndex(completionHandler: @escaping (Int) -> Void) {
  144. if let pdfListView = self.pdfViewController?.pdfListView {
  145. completionHandler(pdfListView.currentPageIndex)
  146. } else {
  147. completionHandler(0)
  148. }
  149. }
  150. func hasChange(completionHandler: @escaping (Bool) -> Void) {
  151. if let pdfListView = self.pdfViewController?.pdfListView {
  152. let success = pdfListView.document?.isModified() ?? false
  153. completionHandler(success)
  154. } else {
  155. completionHandler(false)
  156. }
  157. }
  158. // MARK: - CPDFViewBaseControllerDelete
  159. func PDFViewBaseController(_ baseController: CPDFViewBaseController, SaveState success: Bool) {
  160. self.delegate?.saveDocumentChange(self)
  161. }
  162. func PDFViewBaseController(_ baseController: CPDFViewBaseController, currentPageIndex index: Int) {
  163. self.delegate?.onPageChanged(self, pageIndex: index)
  164. }
  165. // MARK: - RCT Methods
  166. private var configuration: String = ""
  167. @objc func setConfiguration(_ newSection: String) {
  168. configuration = newSection
  169. if (document.path.count > 1) && (configuration.count > 1) {
  170. createCPDFView()
  171. }
  172. }
  173. private var document: URL = URL(fileURLWithPath: "")
  174. @objc func setDocument(_ newSection: URL) {
  175. document = newSection
  176. if (document.path.count > 1) && (configuration.count > 1) {
  177. createCPDFView()
  178. }
  179. }
  180. private var password: String = ""
  181. @objc func setPassword(_ newSection: String) {
  182. password = newSection
  183. }
  184. public var onChange: RCTBubblingEventBlock?
  185. @objc func setOnChange(_ newSection: @escaping RCTBubblingEventBlock) {
  186. onChange = newSection
  187. }
  188. }