1

My goal is to combine two PDFs. One has 10 pages, and another has 6 pages, so the output should be 16 pages. My approach is to load both PDFs into two NSData stored in an NSMutableArray.

Here is my saving method:

NSMutableData *toSave = [NSMutableData data];
for(NSData *pdf in PDFArray){
    [toSave appendData:pdf];
}
[toSave writeToFile:path atomically:YES];

However the output PDF only has the second part, which only contains 6 pages. So I don't know what did I miss. Can anyone give me some hints?

clemens
  • 16,716
  • 11
  • 50
  • 65
GiddensA
  • 21
  • 7

2 Answers2

4

PDF is a file format which describes a single document. You cannot concatenate to PDF files to get the concatenated document.

But might achieve this with PDFKit:

  1. Create both documents with initWithData:.
  2. Insert all pages of the second document into the first one with insertPage:atIndex:.

This should look like:

PDFDocument *theDocument = [[PDFDocument alloc] initWithData:PDFArray[0]]
PDFDocument *theSecondDocument = [[PDFDocument alloc] initWithData:PDFArray[1]]
NSInteger theCount = theDocument.pageCount;
NSInteger theSecondCount = theSecondDocument.pageCount;

for(NSInteger i = 0; i < theSecondCount; ++i) {
    PDFPage *thePage = [theSecondDocument pageAtIndex:i];

    [theDocument insertPage:thePage atIndex:theCount + i];
}
[theDocument writeToURL:theTargetURL];

You have to add either #import <PDFKit/PDFKit.h> or @import PDFKit; to your source file, and you should add PDFKit.framework to the Linked Frameworks and Libraries of the build target in Xcode.

clemens
  • 16,716
  • 11
  • 50
  • 65
  • @GiddensA: I've extended my post. – clemens Feb 17 '18 at 13:09
  • Yes, thats what I'm looking for! Thanks. But I still have a further question. My app is a Cocoa App(I realized I should have mention this before), and I tried to add PDFKit.framework but I cannot find the framework. I read the document of PDFKit, and it says PDFKit is available after OSX 10.4. So what did I miss? – GiddensA Feb 17 '18 at 13:31
0

I've made a Swift command line tool to combine any number of PDF files. It takes the output path as the first argument and the input PDF files as the other arguments. There's no error handling whatsoever, so you can add that if you want to. Here's the full code:

import PDFKit

let args = CommandLine.arguments.map { URL(fileURLWithPath: $0) }
let doc = PDFDocument(url: args[2])!

for i in 3..<args.count {
    let docAdd = PDFDocument(url: args[i])!
    for i in 0..<docAdd.pageCount {
        let page = docAdd.page(at: i)!
        doc.insert(page, at: doc.pageCount)
    }
}
doc.write(to: args[1])
Daan
  • 1,417
  • 5
  • 25
  • 40