With PDFKit in SwiftUI, I'm using the findString
function to search the text of a PDF. That part works correctly, but when I use the extend
function to get some of the text on both sides of the found word (ie, its context in the page), it doesn't extend.
Am I doing this wrong? There is very little documentation or examples about the extend
function; even the Apple page doesn't specify what the units refer to in the extend call (presumably it means characters, but I suppose it could also be pixels, or some other measurement specific to PDFs).
Here is the code, and pictures of the app, the output (showing that the code can read all the text on the page), and the Acrobat Reader effect I'm trying to achieve.
If the extend
function truly is broken, and not just a problem in how I'm going about this, a workaround would be to use the text from the entire page, and extract the surrounding words from there, but that does get complicated, especially if there are multiple instances of the word on the page, or if the result straddles 2 pages.
import PDFKit
import SwiftUI
struct ContentView: View {
@StateObject var controller = PDFViewController()
@State var searchResults:[PDFSelection] = []
var body: some View {
VStack {
Button {
searchResults = controller.pdfView!.document!.findString("is", withOptions: [.caseInsensitive])
let fullPageText = controller.pdfView!.document!.string
print(fullPageText)
for result in searchResults {
let beforeExtending = result.string ?? ""
print("Before: \(beforeExtending)")
result.extend(atEnd: 3)
result.extend(atStart: 3)
let afterExtending = result.string ?? ""
print("After: \(afterExtending)")
}
} label: {
Text("Do search")
}
PDFKitView(url: generateURL(), controller: controller)
}
.padding()
}
func generateURL() -> URL {
let bundlePathRootAsString = Bundle.main.resourcePath!
var pdfPathInBundle = URL(fileURLWithPath: bundlePathRootAsString)
pdfPathInBundle.append(path: "TestPDF.pdf")
return pdfPathInBundle
}
}
struct PDFKitView: UIViewRepresentable {
func updateUIView(_ uiView: PDFView, context: Context) {
}
let url: URL
@ObservedObject var controller: PDFViewController
func makeUIView(context: Context) -> PDFView {
let pdfView = PDFView()
pdfView.document = PDFDocument(url: self.url)
pdfView.autoScales = true
controller.pdfView = pdfView
return pdfView
}
}
class PDFViewController: ObservableObject {
var pdfView: PDFView?
}
Thank you for providing some code and some screenshots. I was able to reproduce your results here using the current shipping OS and tools. This looks like a bug to me.
Our engineering teams need to investigate this issue, as resolution may involve changes to Apple's software. Please file a bug report, include a small Xcode project and some directions that can be used to reproduce the problem, and post the Feedback number here once you do. If you post the Feedback number here I'll check the status next time I do a sweep of forums posts where I've suggested bug reports.
Bug Reporting: How and Why? has tips on creating your bug report.