首页 > 解决方案 > 为什么 PDFKit .beginFindStrings 的结果为零?

问题描述

自学新手在这里。

我的最终目标:

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

仅针对一个 PDF 进行原型设计的问题:

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

那不应该。内存显示 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)
    }

}


标签: iosswiftpdfkit

解决方案


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

1-将下面的行移至viewDidLoad(),因为您在触发该beginFindString()方法后添加了一个观察者。

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

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

3-要从beginFindString方法获取匹配项,您需要添加一个观察者PDFDocumentDidFindMatch并从中获取数据,userInfo而不是PDFDocumentDidEndFind. PDFDocumentDidEndFind搜索完成后将调用观察者,例如,您可以使用此观察者删除加载视图。

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

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)
}

推荐阅读