PSPDFContainerAnnotationProvider

Objective-C


@interface PSPDFContainerAnnotationProvider
    : NSObject <PSPDFAnnotationProviderRefreshing, PSPDFUndoSupport>

Swift

class PDFContainerAnnotationProvider : NSObject, PSPDFAnnotationProviderRefreshing, UndoSupport

Default container for annotations. It’s crucial that you use this class as your base class if you implement a custom annotation provider, because this class offers efficient undo/redo which otherwise is almost impossible to replicate unless you understand the PSPDFKit internals extremely well.

This class conforms to the deprecated protocol PSPDFAnnotationProviderRefreshing. In a future release, this protocol will be removed. The reason is that this class handles refreshing internally. This class will continue to conform to PSPDFAnnotationProvider.

  • Whether this class tracks removed annotations as soft deletions — defaults to true.

    When true, instances of this class track annotations that have been passed to removeAnnotations:options: in the dirtyAnnotations until clearNeedsSaveFlag is called. When implementing your own annotation provider, you can opt out of this behavior by overriding this class method to return false.

    Declaration

    Objective-C

    @property (class, nonatomic, readonly) BOOL shouldTrackDeletions;

    Swift

    class var shouldTrackDeletions: Bool { get }
  • Clears shouldSaveAnnotations, disposes of any soft deleted annotations, and clears the “dirty” flag of all the receiver’s annotations.

    Adding, removing, and updating annotations not only marks the annotation itself as “dirty”, but also triggers an internal flag that the provider requires saving. This method clears those flags and disposes of any “soft deleted” annotations. The receiver is left without dirtyAnnotations and shouldSaveAnnotations returns false until the next annotation change.

    Warning

    This method must be called inside a write block! Failing to do so will (at best) crash your program. At worst it will silently corrupt user data.

    Declaration

    Objective-C

    - (void)clearNeedsSaveFlag;

    Swift

    func clearNeedsSaveFlag()
  • Registers annotations for the undo system.

    Warning

    This method must be called within a write block!

    Declaration

    Objective-C

    - (void)registerAnnotationsForUndo:
        (nonnull NSArray<PSPDFAnnotation *> *)annotations;

    Swift

    func registerAnnotations(forUndo annotations: [PSPDFAnnotation])
  • Directly accesses the annotation cache used internally. Be extremely careful when accessing this, and use the locking methods.

    Declaration

    Objective-C

    @property (nonatomic, readonly) NSMutableDictionary<NSNumber *, NSArray<PSPDFAnnotation *> *> *_Nonnull annotationCache;

    Swift

    var annotationCache: NSMutableDictionary { get }
  • Called before new annotations are inserted. Subclass to perform custom actions.

    This method is called inside of a writing block. You can therefore safely inspect and even modify the annotationCache directly.

    Declaration

    Objective-C

    - (void)willInsertAnnotations:(nonnull NSArray<PSPDFAnnotation *> *)annotations;

    Swift

    func willInsertAnnotations(_ annotations: [PSPDFAnnotation])
  • Allows synchronization with the internal reader queue.

    This method is safe to call inside of a write block. That is a block passed into performBlockForWriting: or performBlockForWritingAndWait:. The reverse is not necessarily true. Specifically…

    Warning

    Calling performBlockForWritingAndWait: inside of the read block is unsafe, and will almost certainly cause deadlock! This includes making calls that have write semantics and are not documented to require to be called inside a write block.

    Declaration

    Objective-C

    - (void)performBlockForReading:(nonnull void (^)(void))block;

    Swift

    func performBlock(forReading block: @escaping () -> Void)
  • Allows synchronization with the internal writer queue.

    This method is safe to call at any time — including inside a read block. The exact execution characteristics may be surprising, though:

    1. When this method is called inside a write block, the block parameter is executed inline.
    2. When this method is called in any other context, the block parameter is executed asynchronously on a background queue.
    3. When executed, the block parameter will have writer status. It is therefore safe to call any instance method of this class inside the block.

    Declaration

    Objective-C

    - (void)performBlockForWriting:(nonnull void (^)(void))block;

    Swift

    func performBlock(forWriting block: @escaping () -> Void)
  • Allows synchronization with the internal writer queue and blocks until the block is processed.

    When executed, the block parameter will have writer status. It is therefore safe to call any instance method of this class inside the block. This specifically includes calls to performBlockForWritingAndWait: and calls to performBlockForReading:. The reverse, however, is not true. Specifically…

    Warning

    Calling this method as part of a block passed to performBlockForReading: will almost certainly cause deadlock!

    Declaration

    Objective-C

    - (void)performBlockForWritingAndWait:(nonnull void (^)(void))block;

    Swift

    func performBlock(forWritingAndWait block: @escaping () -> Void)
  • Modify the internal store. Optionally appends annotations instead of replacing them.

    Note

    The page set in the annotations need to match the page.

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a write block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    - (void)setAnnotations:(nonnull NSArray<PSPDFAnnotation *> *)annotations
            forPageAtIndex:(PSPDFPageIndex)pageIndex
                    append:(BOOL)append;

    Swift

    func setAnnotations(_ annotations: [PSPDFAnnotation], forPageAt pageIndex: PageIndex, append: Bool)
  • Set annotations, evaluate the page value of each annotation.

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a write block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    - (void)setAnnotations:(nonnull NSArray<PSPDFAnnotation *> *)annotations
                    append:(BOOL)append;

    Swift

    func setAnnotations(_ annotations: [PSPDFAnnotation], append: Bool)
  • Super needs to be called for undo/redo management.

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a performLockForWritingAndWait:. Otherwise you risk breaking atomicity of the operation or deadlock.

    Declaration

    Objective-C

    - (nullable NSArray<__kindof PSPDFAnnotation *> *)
        addAnnotations:(nonnull NSArray<__kindof PSPDFAnnotation *> *)annotations
               options:(nullable NSDictionary<PSPDFAnnotationOption, id> *)options;

    Swift

    func add(_ annotations: [PSPDFAnnotation], options: [String : Any]? = nil) -> [PSPDFAnnotation]?
  • Super needs to be called for undo/redo management.

    As of PSPDFKit 7.4, PSPDFContainerAnnotationProvider tracks annotations passed into this method as deleted, unless you override +shouldTrackDeletions to return false. So when you are inheriting from this class, you must call clearNeedsSaveFlag when implementing saveAnnotationsWithOptions:error: to purge those deleted annotations.

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a performLockForWritingAndWait:. Otherwise you risk breaking atomicity of the operation or deadlock.

    Declaration

    Objective-C

    - (nullable NSArray<__kindof PSPDFAnnotation *> *)
        removeAnnotations:(nonnull NSArray<__kindof PSPDFAnnotation *> *)annotations
                  options:
                      (nullable NSDictionary<PSPDFAnnotationOption, id> *)options;

    Swift

    func remove(_ annotations: [PSPDFAnnotation], options: [String : Any]? = nil) -> [PSPDFAnnotation]?

    Parameters

    annotations

    The annotations to delete.

    options

    Options for the deletion. For the full set of options, see PSPDFAnnotationOption constants in PSPDFAnnotationManager.h.

  • Remove all annotations (effectively clears the cache).

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a write block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    - (void)removeAllAnnotationsWithOptions:
        (nonnull NSDictionary<PSPDFAnnotationOption, id> *)options;

    Swift

    func removeAllAnnotations(options: [String : Any] = [:])

    Parameters

    options

    Deletion options (see the (see PSPDFAnnotationOption constants in PSPDFAnnotationManager.h).

  • Returns the cached annotations of all pages in one array.

    This will not force loading if the provider lazily loads annotations into the cache in annotationsForPageAtIndex:. Both PSPDFFileAnnotationProvider and PSPDFXFDFAnnotationProvider do this lazy loading.

    Note

    Subclassing Note: This is a reading operation. If you need to override this method to query mutable state, wrap these queries as well as the call to super in a read block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    @property (nonatomic, readonly) NSArray<PSPDFAnnotation *> *_Nonnull allAnnotations;

    Swift

    var allAnnotations: [PSPDFAnnotation] { get }
  • Returns cached annotations as a page->annotations per page dictionary.

    This will not force loading if the provider lazily loads annotations into the cache in annotationsForPageAtIndex:. Both PSPDFFileAnnotationProvider and PSPDFXFDFAnnotationProvider do this lazy loading.

    Note

    Subclassing Note: This is a reading operation. If you need to override this method to query mutable state, wrap these queries as well as the call to super in a read block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    @property (nonatomic, readonly) NSDictionary<NSNumber *, NSArray<PSPDFAnnotation *> *> *_Nonnull annotations;

    Swift

    var annotations: [NSNumber : [PSPDFAnnotation]] { get }
  • May be used to override the annotation cache directly. Faster than using setAnnotations:.

    Note

    Subclassing Note: If you override this method and modify additional internal state of your subclass, wrap the modifications as well as the call to super in a write block. Otherwise you risk breaking atomicity of the operation.

    Declaration

    Objective-C

    - (void)setAnnotationCacheDirect:
        (nonnull NSDictionary<NSNumber *, NSArray<PSPDFAnnotation *> *> *)
            annotationCache;

    Swift

    func setAnnotationCacheDirect(_ annotationCache: [NSNumber : [PSPDFAnnotation]])
  • Deprecated

    Deprecated in PSPDFKit 4.1 for macOS. PSPDFKit handles refreshing internally now.

    This method is from PSPDFAnnotationProviderRefreshing. You must call super if you override this but ideally do not override this and instead let PSPDFKit handle refreshing internally.

    Declaration

    Objective-C

    - (void)prepareForRefresh;
  • Deprecated

    Deprecated in PSPDFKit 4.1 for macOS. PSPDFKit handles refreshing internally now.

    This method is from PSPDFAnnotationProviderRefreshing. You must call super if you override this but ideally do not override this and instead let PSPDFKit handle refreshing internally.

    Declaration

    Objective-C

    - (void)refreshAnnotationsForPagesAtIndexes:(nonnull NSIndexSet *)pageIndexes;