【问题标题】:Why are the results of PDFKit .beginFindStrings nil?为什么 PDFKit .beginFindStrings 的结果为零?
【发布时间】:2019-11-13 22:37:12
【问题描述】:

这里是自学新手。

我的最终目标:

加载 PDF 目录的 iOS/Mac 应用程序,在每个目录中搜索字符串数组,并列出哪些 PDF 包含哪些字符串。

只有一个 PDF 的原型设计问题:

我从加载选定的 PDF、运行 .beginFindStrings(["and", "the"], withOptions: .caseInsensitive) 并等待通知 .PDFDocumentDidEndFind 检查 [PDFSelection] 收到一个令人困惑的 nil。

那不应该。内存显示 PDF 已加载。我在线程上做错了吗?我想我在这里遵循了async 的建议:PDFKit background search

代码

import UIKit
import MobileCoreServices
import PDFKit

class ViewController: UIViewController, UIDocumentPickerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

    var matchesFound: PDFSelection?

    @IBOutlet weak var resultsLabel: UILabel!

    @IBAction func importPDF(_ sender: Any) {
        let picker = UIDocumentPickerViewController(documentTypes: [kUTTypePDF as String], in: .import)
        picker.delegate = self
        picker.allowsMultipleSelection = false
        self.present(picker, animated: true)
    }

    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard urls.count == 1 else {return}
        let data = try! Data(contentsOf: urls[0])
        let subjectPDF = PDFDocument.init(data: data)
        guard subjectPDF!.isLocked == false else {return}

        subjectPDF!.beginFindStrings(["the", "and"], withOptions: .caseInsensitive)

        NotificationCenter.default.addObserver(self, selector: #selector(onDidFindMatch(_:)), name: Notification.Name.PDFDocumentDidEndFind, object: nil)
    }

    @objc func onDidFindMatch(_ notification: Notification) {
        resultsLabel.text = "\(String(describing: matchesFound?.string))"
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
            dismiss(animated: true, completion: nil)
    }

}

带标记的代码

import UIKit
import MobileCoreServices
import PDFKit

class ViewController: UIViewController, UIDocumentPickerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
    }

//Array of PDFSelection search results
    var matchesFound: PDFSelection?

//Temporary display for search result strings
    @IBOutlet weak var resultsLabel: UILabel!

//Choose a PDF to import, temporarily limited to one
    @IBAction func importPDF(_ sender: Any) {
        let picker = UIDocumentPickerViewController(documentTypes: [kUTTypePDF as String], in: .import)
        picker.delegate = self
        picker.allowsMultipleSelection = false
        self.present(picker, animated: true)
    }

//Load the picked PDF as subjectPDF, if unlocked
    func documentPicker(_ controller: UIDocumentPickerViewController, didPickDocumentsAt urls: [URL]) {
        guard urls.count == 1 else {return}
        let data = try! Data(contentsOf: urls[0])
        let subjectPDF = PDFDocument.init(data: data)
        guard subjectPDF!.isLocked == false else {return}

//Find temporary array of strings
        subjectPDF!.beginFindStrings(["the", "and"], withOptions: .caseInsensitive)

//Trigger results readout upon search competion
        NotificationCenter.default.addObserver(self, selector: #selector(onDidFindMatch(_:)), name: Notification.Name.PDFDocumentDidEndFind, object: nil)
    }

//Readout found strings to temporary label
    @objc func onDidFindMatch(_ notification: Notification) {
        resultsLabel.text = "\(String(describing: matchesFound?.string))"
    }

    func documentPickerWasCancelled(_ controller: UIDocumentPickerViewController) {
            dismiss(animated: true, completion: nil)
    }

}


【问题讨论】:

    标签: ios swift pdfkit


    【解决方案1】:

    这个问题是在 7 个月前提出的,但我希望你已经找到了解决方案。 无论如何解决您的问题:

    1-将下面的行移到viewDidLoad(),因为你是在触发beginFindString()方法后添加观察者。

    NotificationCenter.default.addObserver(self, selector: #selector(onDidFindMatch(_:)), name: Notification.Name.PDFDocumentDidEndFind, object: nil)
    

    2- 您永远不会为 matchesFound 变量分配任何值,因此它始终为 nil。

    3- 要从beginFindString 方法获取匹配,您需要为PDFDocumentDidFindMatch 添加一个观察者,并从userInfo 而不是PDFDocumentDidEndFind 获取数据。 PDFDocumentDidEndFindobserver 将在搜索完成时被调用,你可以使用这个观察者来移除你正在加载的视图。

    这是正确实现的示例代码:

    var matchesFound = [PDFSelection]()
    
    // MARK: Life cycle
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        NotificationCenter.default.addObserver(self, selector: #selector(didFindMatch(_:)), name: NSNotification.Name.PDFDocumentDidFindMatch, object: nil)
    }
    
    deinit {
        NotificationCenter.default.removeObserver(self)
    }
    
    // This method will get called every-time a match has been found.
    @objc private func didFindMatch(_ sender: Notification) {
        guard let selection = sender.userInfo?["PDFDocumentFoundSelection"] as? PDFSelection else { return }
    
        self.matchesFound.append(selection)
    }
    

    【讨论】:

    • 感谢您回到老问题。我最终只是将它转换为文本,这对于我查询它以查找彼此接近的字符串的目的要容易得多。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多