PSPDFKit 11.4 Migration Guide

This guide covers updating an iOS or Mac Catalyst project from PSPDFKit 11.3 for iOS to PSPDFKit 11.4 for iOS. We encourage you to update as soon as possible, in order to take advantage of future new features and fixes.

PSPDFKit 11.4 for iOS drops support for iOS 13 in preparation for the expected announcement of iOS 16, which means you must ensure your app’s deployment target is at least iOS 14. All devices that support iOS 13 also support iOS 14 and iOS 15. This version fully supports iOS 14 and 15. Xcode 13 or later is required to use this version of PSPDFKit. Learn more in our version support guide.

Removed Deprecated APIs

This version of PSPDFKit removes APIs that have been deprecated for more than a year. This includes deprecations from PSPDFKit 9.1 to PSPDFKit 10.4 for iOS. Here’s a list of all the APIs that have been removed in this release:

Removed Deprecated APIMigration StrategyDeprecated In
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​CloseExpectedInsteadOfReadUse .closeExpectedInsteadOfRead instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​CryptorCreationFailedUse .cryptorCreationFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​CryptorFinalFailedUse .cryptorFinalFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​CryptorResetToIVFailedUse .cryptorResetToIVFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​ErrorDecryptingBlockUse .decryptingBlockFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​FailedToAllocateMemoryUse .memoryAllocationFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​HMACCheckFailedUse .hMACCheckFailed instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​IncorrectHMACInFileUse .incorrectHMACInFile instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​UnknownVersionInFileHeaderUse .unknownVersionInFileHeader instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​UnknownUse .unknown instead.9.4
AESCryptoInputStreamError.​PSPDFErrorCodeAESCryptoInputStream​WrongCloseCalledUse .wrongCloseCalled instead.9.4
AESCryptoInputStreamErrorCodeUse AESCryptoInputStreamError instead.9.4
AESCryptoOutputStreamError.​PSPDFErrorCodeAESCryptoOutputStream​CryptorFinalFailedUse .cryptorFinalFailed instead.9.4
AESCryptoOutputStreamError.​PSPDFErrorCodeAESCryptoOutputStream​EncryptionFailedUse .encryptionFailed instead.9.4
AESCryptoOutputStreamError.​PSPDFErrorCodeAESCryptoOutputStream​FailedToAllocateMemoryUse .memoryAllocationFailed instead.9.4
AESCryptoOutputStreamError.​PSPDFErrorCodeAESCryptoOutputStream​UnknownUse .unknown instead.9.4
AESCryptoOutputStreamError.​PSPDFErrorCodeAESCryptoOutputStream​WritingToParentStreamFailedUse .writingToParentStreamFailed instead.9.4
AESCryptoOutputStreamErrorCodeUse AESCryptoOutputStreamError instead.9.4
Annotation.​attachBinaryInstantJSONAttachment​(fromDataProvider:​mimeType:)Use attachBinaryInstantJSONAttachment​(fromDataProvider:).9.1
AnnotationManager.ChangeBehaviorKey.​animateViewKeyUse .animateView instead.9.3
AnnotationManager.ChangeBehaviorKey.​suppressNotificationsKeyUse .suppressNotifications instead.9.3
AnnotationSet.​init(annotations:)Use init(annotations:copyAnnotations:), with copyAnnotations as true.9.2
AnnotationStyleViewControllerDelegate.​annotationStyleController​(_:didEndChangingProperty:)Use annotationStyleController​(_:didEndChangingProperty:affectedProperties:) instead.10.4
AnnotationStyleViewControllerDelegate.​annotationStyleController​(_:willStartChangingProperty:)Use annotationStyleController​(_:didBeginChangingProperty:) instead.10.4
BackForwardActionList.​requestBack()Use requestBack(animated:) instead.9.4
BackForwardActionList.​requestBack(to:)Use requestBack(to:animated:) instead.9.4
BackForwardActionList.​requestForward()Use requestForward(animated:) instead.9.4
BackForwardActionList.​requestForward(to:)Use requestForward(to:animated:) instead.9.4
BackForwardActionListDelegate.​backForwardList​(_:requestedBackActionExecution:)Use backForwardList​(_:requestedBackActionExecution:animated:) instead.9.4
BackForwardActionListDelegate.​backForwardList​(_:requestedForwardActionExecution:)Use backForwardList​(_:requestedForwardActionExecution:animated:) instead.9.4
BackForwardButton.​longPressRecognizerReplaced by internally handled context menu.9.4
ButtonFormElement.​ButtonFlag.noToggleToOffWasn’t used.10.4
ButtonFormElement.​ButtonFlag.pushButtonWasn’t used. Use ButtonFormField.isPushButton instead.10.4
ButtonFormElement.​ButtonFlag.radioWasn’t used. Use ButtonFormField.isPushButton instead.10.4
ButtonFormElement.​ButtonFlag.radiosInUnisonWasn’t used.10.4
ButtonFormElement.​ButtonFlagValues of this enum weren’t used. Use the properties on ButtonFormField instead.10.4
ChoiceFormElement.​ChoiceFlag.comboWasn’t used. Use ChoiceFormField.isCombo instead.10.4
ChoiceFormElement.​ChoiceFlag.commitOnSelChangeWasn’t used. Use ChoiceFormField.commitOnSelChange instead.10.4
ChoiceFormElement.​ChoiceFlag.doNotSpellCheckWasn’t used. Use ChoiceFormField.doNotSpellCheck instead.10.4
ChoiceFormElement.​ChoiceFlag.editWasn’t used. Use ChoiceFormField.isEdit instead.10.4
ChoiceFormElement.​ChoiceFlag.multiSelectWasn’t used. Use ChoiceFormField.isMultiSelect instead.10.4
ChoiceFormElement.​ChoiceFlag.sortWasn’t used.10.4
ChoiceFormElement.​ChoiceFlagValues of this enum weren’t used. Use the properties on ChoiceFormField instead.10.4
ColorButton.​borderWidthUse outerBorderWidth instead.9.3
ColorButton.​displayAsEllipseUse shape instead.9.3
ColorButton.​indicatorSizeUse contentInset instead.9.3
Cryptor.ErrorCodeUse CryptorError instead.9.4
DrawingPoint.​isValidUse DrawingPoint.isFinite instead.10.0
FreeTextAnnotation.​convert(toIntentType:)This method has been renamed to convertIntent(to:)9.3
ImagePickerController.​ImageQuality.highUse ImagePickerController.​ImageQuality.best instead9.2
PDFCache.invalidateImage​(from:pageIndex:)Use invalidateImages​(from:pageIndex:) instead.10.1
PDFConfiguration.​showAnnotationMenuAfterCreationObserve the PSPDFAnnotationsAdded notification and programmatically select the new annotation and show the menu.10.4
PDFConfigurationBuilder.​showAnnotationMenuAfterCreationObserve the PSPDFAnnotationsAdded notification and programmatically select the new annotation and show the menu.10.4
PDFContainerAnnotationProvider.​prepareForRefresh()Nutrient handles refreshing internally now.9.1
PDFContainerAnnotationProvider.​refreshAnnotationsForPages(at:)Nutrient handles refreshing internally now.9.1
PDFFileAnnotationPoviderUse PDFFileAnnotationProvider instead.9.4
PDFLineUse [DrawingPoint] instead. An array of drawing points may be in a view coordinate space or a PDF page coordinate space.9.4
PDFPageView.​longPress(_:)Add your own gesture recognizer instead.9.5
PDFPageView.​showMenu(for:targetRect:​allowPopovers:animated:)Call showMenu​(for:targetRect:option:​animated:) instead.9.1
PDFPageView.​showMenuIfSelected(animated:allowPopovers:)Call showMenuIfSelected​(with:animated:) instead.9.1
PDFPageView.​singleTapped(_:)Add your own gesture recognizer instead.9.5
PDFPageView.​singleTapped(atViewPoint:)Add your own gesture recognizer instead.9.5
PDFPageView.​tappableAnnotations(at:)Use the interaction component activation conditions instead.9.5
PDFPageView.​tappableAnnotationsForLongPress(at:)Use the interaction component activation conditions instead.9.5
PDFSigner.subFilterUse signatureType instead.10.1
PDFViewController.​reloadPage(at:animated:)Use reloadPages(indexes:animated:) instead.10.1
PDFViewControllerDelegate.​pdfViewController(_:didLongPressOn:​at:gestureRecognizer:)Add your own gesture recognizer instead.9.5
PDFViewControllerDelegate.​pdfViewController(_:didTapOn:at:)Add your own gesture recognizer instead.9.5
PSPDFAdditionalFontDirectoriesUse SDK.Setting.additionalFontDirectories instead.9.3
PSPDFAnnotationProviderRefreshing.​performBlock(forWritingAndWait:)Nutrient now handles refreshing internally via PDFContainerAnnotationProvider.9.1
PSPDFAnnotationProviderRefreshing.​prepareForRefresh()Nutrient now handles refreshing internally via PDFContainerAnnotationProvider.9.1
PSPDFAnnotationProviderRefreshing.​refreshAnnotationsForPages(at:)Nutrient now handles refreshing internally via PDFContainerAnnotationProvider.9.1
PSPDFAnnotationProviderRefreshingNutrient now handles refreshing internally via PDFContainerAnnotationProvider.9.1
PSPDFAnnotationRegister​OverrideClasses​(_:_:)This functionality shouldn’t be needed. PDFFileAnnotationProvider already takes care of registering the appropriate overrides when reading an external annotation file.9.3
PSPDFDocumentCheckpoint​SavedNotificationSucessKeyUse PSPDFDocumentCheckpointSavedNotificationSuccessKey instead.10.1
PSPDFErrorUse PSPDFKitError instead.9.4
PSPDFFeatureRequireSignedSourceCompatibility constant. Migrate to Features.requireSignedSource.9.3
PSPDFFlexibleToolbarPositionsAllUse FlexibleToolbar.Position.all instead.9.3
PSPDFFlexibleToolbarPositionsVerticalUse FlexibleToolbar.Position.vertical instead.9.3
PSPDFGalleryItemCaptionKeyUse GalleryItem.Property.caption instead.9.3
PSPDFGalleryItemContentURLKeyUse GalleryItem.Property.contentURL instead.9.3
PSPDFGalleryItemOptionsKeyUse GalleryItem.Property.options instead.9.3
PSPDFGalleryItemTypeKeyUse GalleryItem.Property.type instead.9.3
PSPDFInstantErrorCodeUse InstantError instead.9.4
PSPDFLibrary​ExcludeAnnotationsKeyUse PDFLibrary.Option.​excludeAnnotations instead.9.4
PSPDFLibrary​ExcludeDocumentTextKeyUse PDFLibrary.Option.​excludeDocumentText instead.9.4
PSPDFLibrary​MatchExactPhrasesOnlyKeyUse PDFLibrary.Option.​matchExactPhrasesOnly instead.9.4
PSPDFLibrary​MatchExactWordsOnlyKeyUse PDFLibrary.Option.​matchExactWordsOnly instead.9.4
PSPDFLibrary​MaximumPreviewResultsPerDocumentKeyUse PDFLibrary.Option.​maximumPreviewResultsPerDocument instead.9.4
PSPDFLibrary​MaximumPreviewResultsTotalKeyUse PDFLibrary.Option.​maximumPreviewResultsTotal instead.9.4
PSPDFLibrary​MaximumSearchResultsPerDocumentKeyUse PDFLibrary.Option.​maximumSearchResultsPerDocument instead.9.4
PSPDFLibrary​MaximumSearchResultsTotalKeyUse PDFLibrary.Option.​maximumSearchResultsTotal instead.9.4
PSPDFLibrary​PreviewRangeKeyUse PDFLibrary.Option.​previewRange instead.9.4
PSPDFObjectMinDiameterKeyUse Document.ObjectFinderOption.​minDiameter instead.9.4
PSPDFObjects​AnnotationIncludedGroupedKeyUse Document.ObjectFinderOption.​annotationIncludedGrouped instead.9.4
PSPDFObjects​AnnotationPageBoundsKeyUse Document.ObjectFinderOption.​annotationPageBounds instead.9.4
PSPDFObjects​AnnotationTypesKeyUse Document.ObjectFinderOption.​annotationTypes instead.9.4
PSPDFObjects​AnnotationsKeyUse Document.ObjectFinderOption.​extractAnnotations or Document.ObjectFinderType.annotations instead.9.4
PSPDFObjects​FindFirstOnlyKeyUse Document.ObjectFinderOption.​findFirstOnly instead.9.4
PSPDFObjects​GlyphsKeyUse Document.ObjectFinderOption.​extractGlyphs or Document.ObjectFinderType.glyphs instead.9.4
PSPDFObjects​IgnoreLargeTextBlocksKeyUse Document.ObjectFinderOption.​ignoreLargeTextBlocks instead.9.4
PSPDFObjects​ImagesKeyUse Document.ObjectFinderOption.​extractImages or Document.ObjectFinderType.images instead.9.4
PSPDFObjects​PageZoomLevelKeyUse Document.ObjectFinderOption.​pageZoomLevel instead.9.4
PSPDFObjects​SmartSortKeyUse Document.ObjectFinderOption.​smartSort instead.9.4
PSPDFObjects​TestIntersectionFractionKeyUse Document.ObjectFinderOption.​testIntersectionFraction instead.9.4
PSPDFObjects​TestIntersectionKeyUse Document.ObjectFinderOption.​testIntersection instead.9.4
PSPDFObjects​TextBlocksKeyUse Document.ObjectFinderOption.​extractTextBlocks or Document.ObjectFinderType.textBlocks instead.9.4
PSPDFObjects​TextFlowKeyUse Document.ObjectFinderOption.​textFlow instead.9.4
PSPDFObjects​TextKeyUse Document.ObjectFinderOption.​extractText or Document.ObjectFinderType.text instead.9.4
PSPDFObjects​WordsKeyUse Document.ObjectFinderOption.​extractWords or Document.ObjectFinderType.words instead.9.4
PSPDFPresentation​CloseButtonKeyUse PresentationOption.​closeButton instead.9.3
PSPDFPresentation​ContentSizeKeyUse PresentationOption.​contentSize instead.9.3
PSPDFPresentation​HalfModalStyleKeyUse PresentationOption.​halfModalStyle instead.9.3
PSPDFPresentation​InNavigationControllerKeyUse PresentationOption.​inNavigationController instead.9.3
PSPDFPresentation​NonAdaptiveKeyUse PresentationOption.​halfModalStyle instead.9.3
PSPDFPresentation​PopoverArrowDirectionsKeyUse PresentationOption.​popoverArrowDirections instead.9.3
PSPDFPresentation​PopoverBackgroundColorKeyUse PresentationOption.​popoverBackgroundColor instead.9.3
PSPDFPresentation​PopoverPassthroughViewsKeyUse PresentationOption.​popoverPassthroughViews instead.9.3
PSPDFPresentation​RectBlockKeyUse PresentationOption.​sourceRectProvider instead.9.3
PSPDFPresentation​RectKeyUse PresentationOption.​sourceRect instead.9.3
PSPDFPresentation​ReuseNavigationControllerKeyUse PresentationOption.​reuseNavigationController instead.9.3
PSPDFPresentation​StyleKeyUse PresentationOption.​presentationStyle instead.9.3
PSPDFSafePreferredInterface​Orientation​(_:_:_:)Implement your own orientation handling.10.1
PSPDFSignerErrorUse PDFSignerError instead.9.4
PSPDFSpeechSynthesizer​AutoDetectLanguageUse SpeechController.Option.​autoDetectLanguage instead.9.4
PSPDFSpeechSynthesizer​LanguageHintKeyUse SpeechController.Option.​languageHint instead.9.4
PSPDFSpeechSynthesizer​LanguageKeyUse SpeechController.Option.​language instead.9.4
PSPDFViewControllerSearchHeadlessKeyUse PresentationOption.​searchHeadless instead.9.3
class Processor.​cancellAllConversionOperations()Renamed to cancelAllConversionOperations().9.5
Processor.Configuration.​mergePage(from:password:sourcePageIndex:​destinationPageIndex:transform:​blendMode:)Use mergeAutoRotatedPage​(from:password:sourcePageIndex:​destinationPageIndex:transform:blendMode:​) instead.9.4
SDK.Setting.​PSPDFXCallbackURLStringKeyUse .xCallbackURLString instead.9.3
SDK.Setting.​applicationPolicyKeyUse .applicationPolicy instead.9.3
SDK.Setting.​coordinatedFileManagerKeyUse .coordinatedFileManager instead.9.3
SDK.Setting.​fileCoordinationEnabledKeyUse .fileCoordinationEnabled instead.9.3
SDK.Setting.​fileManagerKeyUse .fileManager instead.9.3
SDK.Setting.​honorDocumentPermissionsKeyUse .honorDocumentPermissions instead.9.3
SDK.Setting.​kitDebugModeKeyUse .debugMode instead.9.3
SDK.Setting.​libraryIndexingPriorityKeyUse .libraryIndexingPriority instead.9.3
SegmentedControl.hitTestEdgeInsetsConsider creating your own segmented control subclass.10.3
SegmentedControlConsider creating your own segmented control subclass.10.3
SignatureContainer.annotationUse signatureAnnotation instead.10.3
SignatureContainer.​init(annotation:signer:biometricProperties:)Use init(signatureAnnotation:​signer:​biometricProperties:) instead.10.3
SignatureFormElement.​overlappingInkSignatureUse overlappingSignatureAnnotation instead.10.3
TextFieldFormElement.​TextFieldFlag.combWasn’t used. Use TextFormField.isComb instead.10.4
TextFieldFormElement.​TextFieldFlag.doNotScrollWasn’t used. Use TextFormField.doNotScroll instead.10.4
TextFieldFormElement.​TextFieldFlag.doNotSpellCheckWasn’t used. Use TextFormField.doNotSpellCheck instead.10.4
TextFieldFormElement.​TextFieldFlag.fileSelectWasn’t used. Use TextFormField.fileSelect instead.10.4
TextFieldFormElement.​TextFieldFlag.multilineWasn’t used. Use TextFormField.isMultiLine instead.10.4
TextFieldFormElement.​TextFieldFlag.passwordWasn’t used. Use TextFormField.isPassword instead.10.4
TextFieldFormElement.​TextFieldFlag.richTextWasn’t used. Use TextFormField.isRichText instead.10.4
TextFieldFormElement.​TextFieldFlagValues of this enum weren’t used. Use the properties on TextFormField instead.10.4
ToolbarDualButton.longPressRecognizerReplaced by internally handled context menu.9.4
ToolbarGroupButton.longPressRecognizerReplaced by internally handled context menu.9.4
ViewLineUse [CGPoint] instead. An array of points may be in a view coordinate space or a PDF page coordinate space.9.4
-[PSPDFCache imageForRequest:imageSizeMatching:]Use version with error handling, image(for:imageSizeMatching:) throws, instead.9.1
-[PSPDFSoundAnnotation initWithRecorder:]Use init(recorderOptions:) with a nil parameter instead.9.3

Other Breaking Changes

This release changes the superclass of ThumbnailFilterSegmentedControl from SegmentedControl to UISegmentedControl, since SegmentedControl was deprecated and is now removed.

MutableRenderRequest.document has been changed to a read-only property. If you need to request renders for many different documents, create a new request for each document instead.

This release also changes the type of ImageDocument.supportedContentTypes and OfficeDocument.supportedContentTypes from an array of String to an array of UTType, which has been the preferred way to describe type information of data since iOS 14. If you require a string representation of a supported content type, you can use the identifier property of UTType.

The LogLevelMask option set changed to a LogLevel enum. Refer to the logging guide for more details.

This release also removes some APIs that were implementation details and unintentionally ended up in our public API. This includes the removal of the following symbols, and if applicable, migration strategies in case you used any:

Removed APIMigration Strategy
KeyPathReferenceWritableSet value directly on the instance.
UIHostingController.init​(rootView:largeTitleDisplayMode:)Set the navigationItem.largeTitleDisplayMode yourself.
View.customizeTextFieldOnAppear​(customizeBlock:)Customize text fields yourself directly.
Dictionary.valueForKey(_:)Use your own helper for accessing nested dictionary values.
String.init(_: Annotation.Kind)Use String(describing:) instead.
String.init(_: Annotation.Tool)Use String(describing:) instead.
UnfairLockUse your own or system-provided locking mechanism instead.
CGSize.*Use your own helper for geometry arithmetic.
CGSize.*=Use your own helper for geometry arithmetic.
CGSize./Use your own helper for geometry arithmetic.
CGSize./=Use your own helper for geometry arithmetic.
Rotation: ExpressibleByIntegerLiteralUse the enum cases instead.
PSPDFRenderDrawBlockRenamed to PDFRenderDrawBlock

Changes to DrawView’s Undo Recording

When presented within PSPDFKit, the DrawView(opens in a new tab) API handles persisting changes to a document and recording the undo/redo commands of the annotations it’s displaying. However, if you’re using the DrawView(opens in a new tab) API outside of PSPDFKit, you’ll have to persist the changes to the document and record the undo/redo commands for the annotations yourself. This can be done by conforming to the new DrawViewDelegate(opens in a new tab) protocol and setting that instance as the DrawView.delegate(opens in a new tab).

The modification and deletion of annotations can involve multiple user interactions, and each user interaction has to be recorded as a separate undo command. For example, a user erasing parts of multiple ink annotations in a single gesture is a single interaction, hence these modifications of multiple ink annotations should be recorded as a single undo command. However, if a user is erasing different parts of an ink annotation in two interactions, it should be recorded as a separate undo command. Likewise, adding multiple strokes to an ink annotation demands recording separate undo commands for each drawing stroke. To support all these interactions, you need to use a DetachedUndoRecorder(opens in a new tab), which facilitates recording undoable actions over time until they’re manually committed.

Your DrawViewDelegate(opens in a new tab) implementation will require an optional property of type DetachedUndoRecorder(opens in a new tab), which you can use to record the modification and deletion of annotations. The addition and deletion of annotations can be recorded directly to the document.

Below is an example snippet of code for illustrating the recording of undo commands for a DrawView presented outside of PSPDFKit:

/// Document to which the annotations displayed in the `DrawView` belong.
let document: Document = ... // The document to which the undo actions should be recorded to.
/// Detached undo recorder for recording the modification and erasing of annotations.
var pendingUndoRecorder: DetachedUndoRecorder?
func drawView(_ drawView: DrawView, didBeginDrawingIn inputMode: DrawView.InputMode) {
if inputMode == .erase {
// Begin recording erasing of annotations.
pendingUndoRecorder = document.undoController.beginRecordingCommand(named: "Erase")
}
}
func drawView(_ drawView: DrawView, didEndDrawingIn inputMode: DrawView.InputMode, finished didFinish: Bool) {
if inputMode == .erase {
if didFinish {
// Commit the changes only if the stroke was carried out successfully.
pendingUndoRecorder?.commit()
}
pendingUndoRecorder = nil
}
}
func drawView(_ drawView: DrawView, wantsToAdd annotation: Annotation) {
// Add the annotation to the document recording its undo command.
document.undoController.recordCommand(named: "Add", adding: [annotation]) {
document.add(annotations: [annotation])
}
}
func drawView(_ drawView: DrawView, wantsToDelete annotation: Annotation) {
// Remove the annotation from the document with an undo command.
pendingUndoRecorder?.record(removing: [annotation], in: {
document.remove(annotations: [annotation])
})
}
func drawView(_ drawView: DrawView, wantsToModifyAnnotation annotation: Annotation, inScope scope: @escaping () -> Void) {
if drawView.inputMode == .erase {
// Use the detached pending recorder to record the undo command for erasing an annotation.
pendingUndoRecorder?.record(changing: [annotation], in: scope)
} else {
// We're appending to an annotation, so this can be recorded manually.
document.undoController.recordCommand(named: "Draw", changing: [annotation], in: scope)
}
}