Here is the Swift version that can be run as a Swift script or a compiled Swift command-line application. It assumes that the first PDF file on the command line is your non-existent arbitrarily named output PDF file that the remaining PDFs on the command-line will be merged too. PDF tilde paths are accepted. There are instructions in the comments on how to build a universal2 application.
You will need the Swift interpreter/compiler for this script to work. If you have installed Xcode 13.2.1, or later, that is fine, but you can also save about 40GB of storage by just installing the Command Line tools for your version of Xcode. I have tested this script and compiled application on the following:
- macOS 11.6.8
- Xcode 13.2.1
- Command Line Tools for Xcode 13.2 (3.4 GB installed)
- Swift v5.5.2
- macOS 12.5
- Xcode 13.4.1
- Command Line Tools for Xcode 13.4 (4.0 GB installed)
- Swift v5.6.1
This is the simplest means to get the Command Line tools:
xcode-select
if this tells you they are already installed, it won't tell you what version, so to be current for your given operating system, sign into developer.apple.com/downloads/other with your Apple ID, and choose the appropriate from above.
Here is the Swift code to merge PDFs into a specified output PDF. It is a year old, but still compiles and runs correctly per the above Swift versions and platforms:
#!/usr/bin/swift
import Foundation
import PDFKit
let fileManager = FileManager.default
let args = CommandLine.arguments.map { URL(fileURLWithPath: $0) }
for i in 2..<args.count {
guard args[i].pathExtension == "pdf",
fileManager.fileExists(atPath: args[i].path) == true
else {
print("\(args[i].lastPathComponent) is either not a PDF document or it does not exist.")
exit(EXIT_FAILURE)
}
}
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)
}
}
guard doc.write(to: args[1]) == true else {
print("\(args[1]): could not write merged PDF.")
exit(EXIT_FAILURE)
}
exit(EXIT_SUCCESS)
Usage:
pdfmerge.swift arbitrary.pdf a.pdf b.pdf c.pdf ... x.pdf
# after compiled to mergePDF
mergePDF arbitrary.pdf a.pdf b.pdf c.pdf ... x.pdf