Is there a way in iOS to merge PDF files, that is, append the pages of one at the end of another and save it to disk?
Is there a way in iOS to merge PDF files, that is, append the pages of one at the end of another and save it to disk?
Swift 5:
import PDFKit
Merge pdfs like this to keep links, etc...
func mergePdf(data: Data, otherPdfDocumentData: Data) -> PDFDocument {
// get the pdfData
let pdfDocument = PDFDocument(data: data)!
let otherPdfDocument = PDFDocument(data: otherPdfDocumentData)!
// create new PDFDocument
let newPdfDocument = PDFDocument()
// insert all pages of first document
for p in 0..<pdfDocument.pageCount {
let page = pdfDocument.page(at: p)!
let copiedPage = page.copy() as! PDFPage // from docs
newPdfDocument.insert(copiedPage, at: newPdfDocument.pageCount)
}
// insert all pages of other document
for q in 0..<otherPdfDocument.pageCount {
let page = pdfDocument.page(at: q)!
let copiedPage = page.copy() as! PDFPage
newPdfDocument.insert(copiedPage, at: newPdfDocument.pageCount)
}
return newPdfDocument
}
The insert function of PDFs can be found in the doc, where it says:
open class PDFDocument : NSObject, NSCopying {
...
// Methods allowing pages to be inserted, removed, and re-ordered. Can throw range exceptions.
// Note: when inserting a PDFPage, you have to be careful if that page came from another PDFDocument. PDFPage's have a
// notion of a single document that owns them and when you call the methods below the PDFPage passed in is assigned a
// new owning document. You'll want to call -[PDFPage copy] first then and pass this copy to the blow methods. This
// allows the orignal PDFPage to maintain its original document.
open func insert(_ page: PDFPage, at index: Int)
open func removePage(at index: Int)
open func exchangePage(at indexA: Int, withPageAt indexB: Int)
...
}
Create your mergedPdf as variable of your class:
var mergedPdf: PDFDocument?
On viewDidLoad() call the merge function and show your merged PDF:
mergedPdf = mergePdf(data: pdfData1, otherPdfDocumentData: pdfData2)
// show merged pdf in pdfView
PDFView.document = mergedPdf!
First convert the newPDF like this:
let documentDataForSaving = mergedPdf.dataRepresentation()
Put the documentDataForSaving in this following function:
Use the save function:
let urlWhereTheFileIsSaved = writeDataToTemporaryDirectory(withFilename: "My File Name", inFolder: nil, data: documentDataForSaving)
Probably you want to avoid / in file name and don't make it longer than 256 characters
Save-Function:
// Export PDF to directory, e.g. here for sharing
func writeDataToTemporaryDirectory(withFilename: String, inFolder: String?, data: Data) -> URL? {
do {
// get a directory
var temporaryDirectory = FileManager.default.temporaryDirectory // for e.g. sharing
// FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).last! // to make it public in user's directory (update plist for user access)
// FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask).last! // to hide it from any user interactions)
// do you want to create subfolder?
if let inFolder = inFolder {
temporaryDirectory = temporaryDirectory.appendingPathComponent(inFolder)
if !FileManager.default.fileExists(atPath: temporaryDirectory.absoluteString) {
do {
try FileManager.default.createDirectory(at: temporaryDirectory, withIntermediateDirectories: true, attributes: nil)
} catch {
print(error.localizedDescription);
}
}
}
// name the file
let temporaryFileURL = temporaryDirectory.appendingPathComponent(withFilename)
print("writeDataToTemporaryDirectory at url:\t\(temporaryFileURL)")
try data.write(to: temporaryFileURL)
return temporaryFileURL
} catch {
print(error)
}
return nil
}