macOS/iOS PDFKit: create document's outline root

740 Views Asked by At

The following example code allows to add an outline (or "bookmark" in Acrobat's terminology) to a existing PDFDocument pdfDoc with label Page n pointing to page number n where n is the passed argument pageNum.

void insertOutline( PDFDocument *pdfDoc, NSUInteger pageNum )
{
    PDFOutline      *otl,
                    *root;

    NSString        *label = [NSString stringWithFormat:@"Page %lu", (unsigned long)pageNum + 1];
    PDFDestination  *destination;
    PDFAction       *action;
    NSPoint         point = {FLT_MAX, FLT_MAX};
    PDFPage         *page;


    // Build the outline

    page = [pdfDoc pageAtIndex: pageNum];
    destination = [[PDFDestination alloc] initWithPage:page atPoint:point];
    action = [[PDFActionGoTo alloc] initWithDestination: destination];

    root = [pdfDoc outlineRoot];

    otl = [[PDFOutline alloc] init];

    [otl setLabel: label];
    [otl setAction: action];

    // Insert the outline

    [root insertChild: otl atIndex: pageNum];

    // Release resources

    [otl release];
    [action release];
    [destination release];
}

The outline created is added as child to the root outline at the top of the document's outline hierarchy tree.

A problem arises attempting to add an outline to a PDF that does not contain any outline yet.

In that case root = [pdfDoc outlineRoot]; will result in root set to NULL and the code that follows obviously fail.

If I open the source document with Acrobat Pro and add manually a single outline/bookmark then the code works.

The question is: how can I add to the PDFDocument a root outline when it is missing?

1

There are 1 best solutions below

1
On BEST ANSWER

By looking at Apple's reference here PDFDocument class provides a method to set the outline root.

So the fix is:

root = [pdfDoc outlineRoot];

if( ! root )
{
    root = [[PDFOutline alloc] init];
    [pdfDoc setOutlineRoot: root];
}