Display and manipulate PDF documents in your applications using PDFKit.

Posts under PDFKit tag

63 Posts
Sort by:

Post

Replies

Boosts

Views

Activity

PDFKit deletes certificates on document load
Why does PDFKit delete signature widgets that have already been digitally signed? This should not happen. Is there an undocumented flag that needs to be set so that PDFKit doesn't remove them when loading or saving the PDF? It's difficult to tell if it is happening at PDFDocument(url: fileURL) or document.write(to: outputURL) If a document is signed and still allows annotations, form filling, comments, etc. we should be able to load the PDF into a PDFDocument and save it without losing the certs. Instead the certs are gone and only the signature annotation widgets are present. Here is a simple example of loading and then saving the PDF with out any changes and it shows that the data is actually being changed... ... import UIKit import PDFKit class ViewController: UIViewController { var pdfView: PDFView! @IBOutlet weak var myButton: UIButton! override func viewDidLoad() { super.viewDidLoad() pdfView = PDFView(frame: self.view.bounds) pdfView.autoresizingMask = [.flexibleWidth, .flexibleHeight] self.view.addSubview(pdfView) self.view.bringSubviewToFront(myButton) // Load and compare the PDF data if let originalData = loadPDF() { if let loadedData = getRawDataFromLoadedPDF() { let isDataEqual = comparePDFData(originalData, loadedData) print("Is original data equal to loaded data? \(isDataEqual)") } } } @IBAction func onSave(_ sender: Any) { if let savedData = savePDF() { if let originalData = loadPDF() { let isDataEqual = comparePDFData(originalData, savedData) print("Is original data equal to saved data? \(isDataEqual)") } } } func loadPDF() -> Data? { guard let fileURL = Bundle.main.url(forResource: "document", withExtension: "pdf") else { print("Error: document.pdf not found in bundle.") return nil } do { let originalData = try Data(contentsOf: fileURL) if let document = PDFDocument(url: fileURL) { pdfView.document = document print("PDF loaded successfully.") return originalData } else { print("Error: Unable to load PDF document.") return nil } } catch { print("Error reading PDF data: \(error)") return nil } } func getRawDataFromLoadedPDF() -> Data? { guard let document = pdfView.document else { print("Error: No document is currently loaded in pdfView.") return nil } if let data = document.dataRepresentation() { return data } else { print("Error: Unable to get raw data from loaded PDF document.") return nil } } func comparePDFData(_ data1: Data, _ data2: Data) -> Bool { return data1 == data2 } func savePDF() -> Data? { guard let document = pdfView.document else { print("Error: No document is currently loaded in pdfView.") return nil } let fileManager = FileManager.default let urls = fileManager.urls(for: .documentDirectory, in: .userDomainMask) guard let documentsURL = urls.first else { print("Error: Could not find the documents directory.") return nil } let outputURL = documentsURL.appendingPathComponent("document_out.pdf") if document.write(to: outputURL) { print("PDF saved successfully to \(outputURL.path)") do { let savedData = try Data(contentsOf: outputURL) return savedData } catch { print("Error reading saved PDF data: \(error)") return nil } } else { print("Error: Unable to save PDF document.") return nil } } }
1
1
336
Aug ’24
PDF Text Selection Crashes When Cursor Moves Over QR Code Only on iOS 18
We are experiencing a crash when selecting text in a PDF and moving the cursor over a QR code. This happens when the QR code at the end of the PDF file with no text following it. [Only on iOS 18] Steps to Reproduce: Clone the repository: git clone https://github.com/aliakhtar49/ios18-pdf-crash/tree/main cd ios18-pdf-crash Run the application to load the provided PDF Select some text and move the cursor over the QR code several times Observe the crash. You can see the gif in the repo Expected Behavior: The application should not crash Actual Behavior: The application crashes: Environment: iOS version: 18.0 Device: iPhone 15 Pro, iPhone 12 Pro Max Additional Context: This issue occurs when the QR code is at the end of the PDF file with no text following it StackTrace `thread #1, queue = 'com.apple.main-thread', stop reason = EXC_BREAKPOINT (code=1, subcode=0x19f3e6ec0) * frame #0: 0x000000019f3e6ec0 CoreGraphics`void PageLayout::ConvertTextRangesToStringRanges<std::__1::span<CFRange, 18446744073709551615ul>, std::__1::back_insert_iterator<std::__1::vector<CFRange, std::__1::allocator<CFRange>>>>(std::__1::span<CFRange, 18446744073709551615ul>&&, std::__1::back_insert_iterator<std::__1::vector<CFRange, std::__1::allocator<CFRange>>>&&) const + 664 frame #1: 0x000000019f424c5c CoreGraphics`CGPDFPageLayoutGetStringRangeIndexNearestPoint + 100 frame #2: 0x000000022b4c096c PDFKit`-[PDFPage characterIndexNearestPoint:] + 128 frame #3: 0x000000022b450950 PDFKit`-[PDFTextInputView _closestPositionToPoint:withinRange:] + 420 frame #4: 0x00000001a0bd02f0 UIKitCore`-[UITextSelectionInteraction _hasTextAlternativesAtLocation:] + 120 frame #5: 0x00000001a03e3834 UIKitCore`-[_UIRemoteKeyboardsEventObserver _hasTextAlternativesForTouch:] + 256 frame #6: 0x000000019fa4e0f8 UIKitCore`-[_UIRemoteKeyboardsEventObserver _endTrackingForTouch:] + 212 frame #7: 0x000000019fa4ca38 UIKitCore`-[_UIRemoteKeyboardsEventObserver _trackTouch:] + 132 frame #8: 0x000000019fa4c94c UIKitCore`-[_UIRemoteKeyboardsEventObserver peekApplicationEvent:] + 220 frame #9: 0x000000019fa4c304 UIKitCore`-[_UIRemoteKeyboards peekApplicationEvent:] + 84 frame #10: 0x000000019fa35dc4 UIKitCore`__dispatchPreprocessedEventFromEventQueue + 4180 frame #11: 0x000000019fa3ef7c UIKitCore`__processEventQueue + 5696 frame #12: 0x000000019f936df4 UIKitCore`updateCycleEntry + 160 frame #13: 0x000000019f934d28 UIKitCore`_UIUpdateSequenceRun + 84 frame #14: 0x000000019f934978 UIKitCore`schedulerStepScheduledMainSection + 172 frame #15: 0x000000019f93580c UIKitCore`runloopSourceCallback + 92 frame #16: 0x000000019d126f9c CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 28 frame #17: 0x000000019d126f30 CoreFoundation`__CFRunLoopDoSource0 + 176 frame #18: 0x000000019d124a08 CoreFoundation`__CFRunLoopDoSources0 + 244 frame #19: 0x000000019d123c14 CoreFoundation`__CFRunLoopRun + 856 frame #20: 0x000000019d123424 CoreFoundation`CFRunLoopRunSpecific + 608 frame #21: 0x00000001e93211c4 GraphicsServices`GSEventRunModal + 164 frame #22: 0x000000019fc6a130 UIKitCore`-[UIApplication _run] + 816 frame #23: 0x000000019fd1855c UIKitCore`UIApplicationMain + 340 frame #24: 0x0000000105e77c38 MyApp.debug.dylib`main at HSAppDelegate.swift:19:20 frame #25: 0x00000001c3058a74 dyld`start + 2724`
3
1
639
Aug ’24
Saving edited PDFs directly to application from QuickLook
I'm stuck on a problem where I need to be able to have the same editing capabilities as in .quickLookPreview and be able to save the edited file to the application with the "Done" button. So, in nutshell, I need to implement the same functionality many other applications provide including Apple's Files. However with .quickLookPreview I don't get the ability to save edited files directly to the application, and I've had no luck finding help from the internet (thus this question). Perhaps somebody has implemented this before and could give me a lead somewhere? PS. I'm trying to find a solution without any third party libraries
1
0
443
Jul ’24
TextKit2 to PDF WITHOUT Font embedding
I can render text from TextKit2 into a PDF everything is fine. But in this case the font is embedded into the PDF. I need the Pdf to contains only the paths / glyphs and not font. I can't find a solution yet. I don't want to create an image or using UIViews etc. It would be nice to get the bezier path of the text I have done this with TextKit1 but the glyphs are gone with TextKit2 Can anyone help me ? Thanks :)
0
0
459
Jun ’24
UIPrintPageRenderer hangs app after iPhone update
After updating iPhone from 17.4 to 17.5.1 UIPrintPageRenderer completely hangs app when getting NumberOfPages from Renderer. var render = new UIPrintPageRenderer(); if (webViewPages != null && reportIndex < webViewPages.Length) { render.AddPrintFormatter( webViewPages[reportIndex].ViewPrintFormatter, 0); } else { render.AddPrintFormatter( new UIMarkupTextPrintFormatter(reportContent), 0); } var printable = CoreGraphics.CGRectExtensions.Inset(page, 0, 0); render.SetValueForKey(NSValue.FromCGRect(page), new NSString("paperRect")); render.SetValueForKey(NSValue.FromCGRect(printable), new NSString("printableRect")); var pdfData = new NSMutableData(); UIGraphics.BeginPDFContext(pdfData, page, null); int pageNum = 0; for (pageNum = 0; pageNum < render.NumberOfPages; pageNum++) { UIGraphics.BeginPDFPage(); var bounds = UIGraphics.PDFContextBounds; render.DrawPage(pageNum, bounds); } UIGraphics.EndPDFContext();
0
1
347
Jun ’24
The application crashes when an image of a certain PDF (50 MB, 1 page) is drawn on the context page in background.
Hi Team, I am using CGPDFPage and CGContext to convert the PDF to an image. It is working fine in all circumstances but fails in one circumstance where the size of the PDF is above 50 MB and when the application is made to be on background and again opened. It is also occurring only on physical devices; emulators are working fine. We are using the following code for this conversation: fileStream.CopyTo(memoryStream); CGDataProvider provider = new CGDataProvider(memoryStream.ToArray()); CGPDFDocument cGPDFDocument = null; image = null; cGPDFDocument = new CGPDFDocument(provider); using(CGPDFPage pdfPage = cGPDFDocument?.GetPage(1)) { if (pdfPage != null) { CGRect rect = pdfPage.GetBoxRect(CGPDFBox.Media); if (pdfPage.RotationAngle == 90 || pdfPage.RotationAngle == 270) { rect = new CGRect(rect.X, rect.Y, rect.Height, rect.Width); } nfloat factor = (nfloat)0.5; CGRect bounds = new CGRect(rect.X * factor, rect.Y * factor, rect.Width * factor, rect.Height * factor); UIGraphics.BeginImageContext(bounds.Size); CGContext context = UIGraphics.GetCurrentContext(); context.SetFillColor(1.0f, 1.0f, 1.0f, 1.0f); context.FillRect(bounds); context.TranslateCTM(0, bounds.Height); context.ScaleCTM(factor, -factor); context.ConcatCTM(pdfPage.GetDrawingTransform(CGPDFBox.Crop, rect, 0, true)); context.SetRenderingIntent(CGColorRenderingIntent.Default); context.InterpolationQuality = CGInterpolationQuality.Default; context.DrawPDFPage(pdfPage); image = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); imageView.Image = image; parentView.AddSubview(imageView); } } We have added a simple application created on Xamarin.iOS platform that replicates this issue in Assets we have added the PDF with this issue https://www.syncfusion.com/downloads/support/directtrac/general/ze/PdfToImageSample-556012354 We have recorded this for the reference, https://www.syncfusion.com/downloads/support/directtrac/general/ze/CrashBGImgRec-1376481150 This issue is constantly occurring on the "context.DrawPDFPage(pdfPage);" line in my application. On the provided sample, this issue is occurring consistently when the break point is placed on the "context.DrawPDFPage(pdfPage);" line. It also occurs randomly without placing the breakpoint. We are invoking this function on DidEnterBackground override method of AppDelegate Do we need to set any to properly retrieve the image from CGPDFPage and add them into context?
1
0
456
Aug ’24
Files App Share Context with Security scoped resource fails
I'm creating an App that can accepted PDFs from a shared context. I am using iOS, Swift, and UIKit with IOS 17.1+ The logic is: get the context see who is sending in (this is always unknown) see if I can open in place (in case I want to save later) send the URL off to open the (PDF) document and load it into PDFKit's pdfView.document I have no trouble loading PDF docs with the file picker. And everything works as expected for shares from apps like Messages, email, etc... (in which case URLContexts.first.options.openInPlace == False) The problem is with opening (sharing) a PDF that is sent from the Files App. (openInPlace == True) If the PDF is in the App's Document Folder, I need the Security scoped resource, to access the URL from the File's App so that I can copy the PDF's data to the PDFViewer.document. I get Security scoped resource access granted each time I get the File App's context URL. But, when I call fileCoordinator.coordinate and try to access a file outside of the App's document folder using the newUrl, I get an error. FYI - The newUrl (byAccessor) and context url (readingItemAt) paths are always same for the Files App URL share context. I can, however, copy the file to a new location in my apps directory and then open it from there and load in the data. But I really do not want to do that. . . . . . Questions: Am I missing something in my pList or are there other parameters specific to sharing a file from the Files App? I'd appreciate if someone shed some light on this? . . . . . Here are the parts of my code related to this with some print statements... . . . . . SceneDelegate func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) { // nothing to see here, move along guard let urlContext = URLContexts.first else { print("No URLContext found") return } // let's get the URL (it will be a PDF) let url = urlContext.url let openInPlace = urlContext.options.openInPlace let bundleID = urlContext.options.sourceApplication print("Triggered with URL: \(url)") print("Can Open In Place?: \(openInPlace)") print("For Bundle ID: \(bundleID ?? "None")") // get my Root ViewController from window if let rootViewController = self.window?.rootViewController { // currently using just the view if let targetViewController = rootViewController as? ViewController { targetViewController.prepareToLoadSharedPDFDocument(at: url) } // I might use a UINavigationController in the future else if let navigationController = rootViewController as? UINavigationController, let targetViewController = navigationController.viewControllers.first as? ViewController { targetViewController.prepareToLoadSharedPDFDocument(at: url) } } } . . . . ViewController function I broke out the if statement for accessingScope just to make it easier for me the debug and play around with the code in accessingScope == True func loadPDF(fromUrl url: URL) { // If using the File Picker / don't use this // If going through a Share.... we pass the URL and have three outcomes (1, 2a, 2b) // 1. Security scoped resource access NOT needed if from a Share Like Messages or EMail // 2. Security scoped resource access granted/needed from 'Files' App // a. success if in the App's doc directory // b. fail if NOT in the App's doc directory // Set the securty scope variable var accessingScope = false // Log the URLs for debugging print("URL String: \(url.absoluteString)") print("URL Path: \(url.path())") // Check if the URL requires security scoped resource access if url.startAccessingSecurityScopedResource() { accessingScope = true print("Security scoped resource access granted.") } else { print("Security scoped resource access denied or not needed.") } // Stop accessing the scope once everything is compeleted defer { if accessingScope { url.stopAccessingSecurityScopedResource() print("Security scoped resource access stopped.") } } // Make sure the file is still there (it should be in this case) guard FileManager.default.fileExists(atPath: url.path) else { print("File does not exist at URL: \(url)") return } // Let's see if we can open it in place if accessingScope { let fileCoordinator = NSFileCoordinator() var error: NSError? fileCoordinator.coordinate(readingItemAt: url, options: [], error: &error) { (newUrl) in DispatchQueue.main.async { print(url.path()) print(newUrl.path()) if let document = PDFDocument(url: newUrl) { self.pdfView.document = document self.documentFileName = newUrl.deletingPathExtension().lastPathComponent self.fileLoadLocation = newUrl.path() self.updateGUI(pdfLoaded: true) self.setPDFScale(to: self.VM.pdfPageScale, asNewPDF: true) } else { print("Could not load PDF directly from url: \(newUrl)") } } } if let error = error { PRINT("File coordination error: \(error)") } } else { DispatchQueue.main.async { if let document = PDFDocument(url: url) { self.pdfView.document = document self.documentFileName = url.deletingPathExtension().lastPathComponent self.fileLoadLocation = url.path() self.updateGUI(pdfLoaded: true) self.setPDFScale(to: self.VM.pdfPageScale, asNewPDF: true) } else { PRINT("Could not load PDF from url: \(url)") } } } } . . . . Other relevant pList settings I've added are: Supports opening documents in place - YES Document types - PDFs (com.adobe.pdf) UIDocumentBrowserRecentDocumentContentTypes - com.adobe.pdf Application supports iTunes file sharing - YES And iCloud is one for Entitlements with iCloud Container Identifiers Ubiquity Container Identifiers . . . . Thank you in advance!. B
1
0
495
Jun ’24
PDFKIT, Static Text, on MacOS
Hi community: I'm trying to create a form PDF form a script in swift on Mac First approach was trying to add a simple and static text not collapsible. But I tried multiple options. And all ends on something that is not a static text. The best approach was to create a textfield not editable with widget PDFKit, but when you go to the preview app on Mac and pass the the mouse over the field, it is highlighted in blue ... Thanks for the support.
0
0
456
Apr ’24
Rotate PDF Annotation
I'm working with PDFKit and trying to rotate PDFAnnotation from a PDFView: Here is my code for a normal case(no rotated): class ImageAnnotation: PDFAnnotation { var image: UIImage? init(image: UIImage?, bounds: CGRect) { self.image = image super.init(bounds: bounds, forType: .stamp, withProperties: nil) } override func draw(with box: PDFDisplayBox, in context: CGContext) { guard let cgImage = self.image?.cgImage else { return } context.draw(cgImage, in: bound) } } And here is the way I used to rotate PDFAnnotation: init(image: UIImage?, bounds: CGRect) { self.image = image super.init(bounds: bounds.applying(CGAffineTransform(rotationAngle: -CGFloat.pi/12)), forType: .stamp, withProperties: nil) } override func draw(with box: PDFDisplayBox, in context: CGContext) { guard let cgImage = self.image?.cgImage else { return } context.rotate(by: CGFloat.pi/12) context.draw(cgImage, in: bounds) } But it doesn't work as expected. Can you help me? Thank you.
0
0
444
Apr ’24
Create an Image from PDFPage in SwiftUI
Im trying to duplicate the display of the built in Files app for documents in my app. How do I convert a page in a PDFDocument to an Image to display as an icon like seen here (from Files App) with SwiftUI. SOLVED: Image(uiImage: (document.page(at: 0)?.thumbnail(of: CGSize(width: 100, height: 100), for: .cropBox))!)
0
0
593
Mar ’24
Blurry and low resolution of PKCanvasView, as overlayview from PDFView.
Hi, I am trying to make a simple note taking app that users can draw something on pdfview with apple pencil. (I used PDFKit, PencilKit for the code.) I followed the instruction code of WWDC22's "What's new in PDFKit." - "overlayProvider" (so you can see the code at the video.) I was able to draw something each view of pdf page. But the issue was, the resolution of overlayview or subview of pdfview is low. As far as I know, the pkcanvasview draws vertor-based drawings. So I never thought the image or the lines I draw will be that blurry. Is this buggy or is this the normal thing? (+ I added a uibutton as subview of pdfview and the button also looks blurry.) I even tried to scale up the all the subviews when the subviews' layout is done, using contentScaleFactor. PKCanvasView inherits UIScrollView, so I enlarged the frame of pkcanvas view and fixed the scale to below 1.0. If the pkcanvasview looks blurry and that is because somewhat zoomed in wrong way, zooming out should be the solution. But, didn't work. Still blurry. and any other stuff like changing frame or size. So, anyone having same problem with me, or anyone can give me any solution. Please help me. I wish this is bug thing that can be fixed in any moment. -> This image is little bit zoomed in. but the drawing is blurry. and this is the normal pkcanvasview drawing, just subview of view(of VC).
3
1
795
Mar ’24
Black image when rendering PDF to image with UIGraphicsImageRendererFormat
Hi everyone, We have been noticing since release iOS 17, that our code which renders PDFPage objects to images was randomly failing (while no error is logged) and produced full black images. This problem seems to mainly occurs on old devices (iPad Pro 2017 and 2018). I mention that this portion code has been running for several years in our app without any issue from iOS10 to iOS16. let renderFormat = UIGraphicsImageRendererFormat.default() renderFormat.opaque = true renderFormat.scale = CGFloat(scale) let renderer = UIGraphicsImageRenderer(size: pageRect.size, format: renderFormat) mainImage = renderer.image { context in // Setup drawing context context.cgContext.setShouldAntialias(false) context.cgContext.setShouldSmoothFonts(false) context.cgContext.setAllowsFontSmoothing(false) context.cgContext.setShouldSubpixelPositionFonts(true) context.cgContext.setShouldSubpixelQuantizeFonts(true) // Draw pdf page context.saveGState() UIColor.white.setFill() context.clip(to: rect) context.fill(rect) page.draw(with: .cropBox, to: context) context.restoreGState() } Did anyone encountered a similar issue? Is there any mean to get an error at least in such cases ? Thanks for any help or advice on this issue.
1
0
479
Mar ’24
PDF Text recognition in WKWebView iOS 16 iOS 17
Problem: Hello! I have some problems with UIEditMenuInteraction in WKWebView which show PDF using PDFKit (as far as I know) - when text is selected, there is no copy/paste buttons on iOS 16.4 or higher. Also I've noticed that selection blue view take less space than actual text is on iOS 17. The problem both cyrillic and latin characters. How I can fix this? p.s. I found on stackoverflow that PDFKit can treat PDF files like images, but on view hierarchy there is no differences between 16 and 17 iOS How it looks: The problem file: https://drive.google.com/file/d/1Tu8RCrlwOI_H3TcwOGFbDR0G9h1OP7MU/view?usp=sharing
0
0
473
Mar ’24