The app crashes when I try to use pdfkit to display pdf-file. Here's the simple example:
import UIKit
import PDFKit
class ViewController: UIViewController {
@IBOutlet weak var pdfView: PDFView!
override func viewDidLoad() {
super.viewDidLoad()
if let path = Bundle.main.path(forResource: "file", ofType: "pdf") {
let url = URL(fileURLWithPath: path)
if let pdfDocument = PDFDocument(url: url) {
pdfView.displayMode = .singlePageContinuous
pdfView.autoScales = true
// pdfView.displayDirection = .horizontal
pdfView.document = pdfDocument
}
}
}
}
This crashes with "uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]'":
2019-03-26 21:09:47.837837+0400 pdfKitTest[3163:93151] libMobileGestalt MobileGestalt.c:890: MGIsDeviceOneOfType is not supported on this platform.
2019-03-26 21:09:47.927078+0400 pdfKitTest[3163:93151] *** Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010e2326fb __exceptionPreprocess + 331
1 libobjc.A.dylib 0x000000010c8daac5 objc_exception_throw + 48
2 CoreFoundation 0x000000010e232555 +[NSException raise:format:] + 197
3 QuartzCore 0x00000001112d52ae _ZN2CA5Layer12set_positionERKNS_4Vec2IdEEb + 140
4 QuartzCore 0x00000001112c468b -[CALayer setPosition:] + 57
5 QuartzCore 0x00000001112c4de3 -[CALayer setFrame:] + 560
6 PDFKit 0x000000010c059097 -[PDFPageLayerTile initWithFrame:forPageLayer:withRenderingTransform:tileContentsScale:generationID:] + 168
7 PDFKit 0x000000010c05e805 -[PDFPageLayer _updateTiles] + 3439
8 PDFKit 0x000000010c059d8e -[PDFPageLayer setNeedsTilesUpdate] + 87
9 PDFKit 0x000000010c06e97d -[PDFPageView setNeedsTilesUpdate] + 48
10 PDFKit 0x000000010c070816 -[PDFPageView setFrame:] + 334
11 PDFKit 0x000000010c06711c -[PDFDocumentView createPageViewForPageAtIndex:] + 764
12 PDFKit 0x000000010c068326 -[PDFDocumentView updateVisibility] + 1726
13 PDFKit 0x000000010c0d776f -[PDFView resizeDisplayView:] + 517
14 PDFKit 0x000000010c0d0cdf -[PDFView layoutDocumentView] + 464
15 PDFKit 0x000000010c0cc36a -[PDFView setDocument:waitDuration:] + 1246
16 pdfKitTest 0x000000010bd277e2 $s10pdfKitTest14ViewControllerC11viewDidLoadyyF + 1506
17 pdfKitTest 0x000000010bd27924 $s10pdfKitTest14ViewControllerC11viewDidLoadyyFTo + 36
18 UIKitCore 0x0000000112fda43b -[UIViewController loadViewIfRequired] + 1183
19 UIKitCore 0x0000000112fda868 -[UIViewController view] + 27
20 UIKitCore 0x0000000113612c33 -[UIWindow addRootViewControllerViewIfPossible] + 122
21 UIKitCore 0x0000000113613327 -[UIWindow _setHidden:forced:] + 289
22 UIKitCore 0x0000000113625f86 -[UIWindow makeKeyAndVisible] + 42
23 UIKitCore 0x00000001135d5f1c -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 4555
24 UIKitCore 0x00000001135db0c6 -[UIApplication _runWithMainScene:transitionContext:completion:] + 1617
25 UIKitCore 0x0000000112e206d6 __111-[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:]_block_invoke + 904
26 UIKitCore 0x0000000112e28fce +[_UICanvas _enqueuePostSettingUpdateTransactionBlock:] + 153
27 UIKitCore 0x0000000112e202ec -[__UICanvasLifecycleMonitor_Compatability _scheduleFirstCommitForScene:transition:firstActivation:completion:] + 236
28 UIKitCore 0x0000000112e20c48 -[__UICanvasLifecycleMonitor_Compatability activateEventsOnly:withContext:completion:] + 1091
29 UIKitCore 0x0000000112e1efba __82-[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:]_block_invoke + 782
30 UIKitCore 0x0000000112e1ec71 -[_UIApplicationCanvas _transitionLifecycleStateWithTransitionContext:completion:] + 433
31 UIKitCore 0x0000000112e239b6 __125-[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:]_block_invoke + 576
32 UIKitCore 0x0000000112e24610 _performActionsWithDelayForTransitionContext + 100
33 UIKitCore 0x0000000112e2371d -[_UICanvasLifecycleSettingsDiffAction performActionsForCanvas:withUpdatedScene:settingsDiff:fromSettings:transitionContext:] + 223
34 UIKitCore 0x0000000112e286d0 -[_UICanvas scene:didUpdateWithDiff:transitionContext:completion:] + 392
35 UIKitCore 0x00000001135d99a8 -[UIApplication workspace:didCreateScene:withTransitionContext:completion:] + 514
36 UIKitCore 0x0000000113190dfa -[UIApplicationSceneClientAgent scene:didInitializeWithEvent:completion:] + 361
37 FrontBoardServices 0x00000001194cd125 -[FBSSceneImpl _didCreateWithTransitionContext:completion:] + 448
38 FrontBoardServices 0x00000001194d6ed6 __56-[FBSWorkspace client:handleCreateScene:withCompletion:]_block_invoke_2 + 283
39 FrontBoardServices 0x00000001194d6700 __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 53
40 libdispatch.dylib 0x000000010f5c5db5 _dispatch_client_callout + 8
41 libdispatch.dylib 0x000000010f5c92ba _dispatch_block_invoke_direct + 300
42 FrontBoardServices 0x0000000119508146 __FBSSERIALQUEUE_IS_CALLING_OUT_TO_A_BLOCK__ + 30
43 FrontBoardServices 0x0000000119507dfe -[FBSSerialQueue _performNext] + 451
44 FrontBoardServices 0x0000000119508393 -[FBSSerialQueue _performNextFromRunLoopSource] + 42
45 CoreFoundation 0x000000010e199be1 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 17
46 CoreFoundation 0x000000010e199463 __CFRunLoopDoSources0 + 243
47 CoreFoundation 0x000000010e193b1f __CFRunLoopRun + 1231
48 CoreFoundation 0x000000010e193302 CFRunLoopRunSpecific + 626
49 GraphicsServices 0x00000001166b42fe GSEventRunModal + 65
50 UIKitCore 0x00000001135dcba2 UIApplicationMain + 140
51 pdfKitTest 0x000000010bd28a7b main + 75
52 libdyld.dylib 0x000000010f63a541 start + 1
53 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
If I comment this line:
pdfView.document = pdfDocument
the app doesn't crash, but pdf-file also doesn't show, of course. How to fix this problem?
For me moving PDFView code from "viewDidLoad" into "viewDidAppear()" did NOT solve the problem! PDFView created in storyboard with a View -> Class: "PDFView".
Moving into "viewDidLayoutSubviews()" (with boolean flag to detect multiple calls) DID resolve this issue.
Also: sample code of PDFKitDemo from Vipul on github from 12/19/17 crashes on my xcode 10.2.1 environment for the same reason, as PDFView handling is in "viewDidLoad" in this sample code as well!
Code snippet working now below:
As an alternative I would like to point out that you can also resolve (/hack) this issue by refraining from setting the frame for PDFView before
viewDidLayoutSubviews
(via: Terminating app due to uncaught exception 'CALayerInvalidGeometry', reason: 'CALayer position contains NaN: [nan nan]'). I'm guessing this delays calls that otherwise lead to the crash.This is useful when moving the
pdfView.document = pdfDocument
is cumbersome because for instance the PDFView preparation happens outside of the Viewcontroller. (Personally I would have had to change the entire structure of my program to perform the document setting in viewDidLayoutSubviews).In short, after changing this:
to this:
I could set
pdfView.document
without crashing the app.I would suggest (just guessing) that maybe
viewDidLoad
is too early. The view is not yet in the view hierarchy, so there are things you cannot do. The error is complaining that the layer has no position, which makes sense because it has no superlayer.To confirm that that's the issue, try moving all that code to
viewDidAppear
. If the crash goes away, we’re on the right track. You can then experiment with moving it into some better event if desired. I would suggestviewDidLayoutSubviews
. You will need to make sure the code doesn't run multiple times (using a Bool instance property as a flag).