在objective-c中连接PDF?

时间:2015-10-29 18:37:37

标签: ios objective-c pdf

我遇到连接PDF的问题。 我必须连接2个pdf文件。让我们将第一个pdf文件称为“pdf1”,将第二个“pdf2”称为“pdf2”。它将始终具有一个页面。 为了连接它们,我使用了下面的函数,但是为了连接pdf1和pdf2以下的函数创建了一个新的pdf文件(让我们称之为pdf3)并继续在pdf3上添加pdf1和pdf2的所有页面。 我想知道的是,有没有一种方法可以在不创建pdf3的情况下在pdf1上连接pdf2。

-(void) concatenaPDF:(NSNumber*)paginaSendoBaixada{

    NSString *cacheDir = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject];

    // File paths
    cacheDir = [cacheDir stringByAppendingPathComponent:@"PDFs"];

    NSString *pdfPathOutput = [cacheDir stringByAppendingPathComponent:@"out.pdf"];

    // File URLs - bridge casting for ARC
    NSURL *pdfURL1 = [[NSURL alloc] initFileURLWithPath:self.filePath];
    NSURL *pdfURL2 = [[NSURL alloc] initFileURLWithPath:self.filePathPagina];
    CFURLRef pdfURLOutput =(__bridge_retained CFURLRef) [[NSURL alloc] initFileURLWithPath:(NSString *)pdfPathOutput];//(CFURLRef)

    // File references
    CGPDFDocumentRef pdfRef1 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL1);
    CGPDFDocumentRef pdfRef2 = CGPDFDocumentCreateWithURL((CFURLRef) pdfURL2);

    // Number of pages
    NSInteger numberOfPages1 = CGPDFDocumentGetNumberOfPages(pdfRef1);
    NSInteger numberOfPages2 = CGPDFDocumentGetNumberOfPages(pdfRef2);

    //se pagina do pdfbaxado for 0 e pq deu erro na baixa e vou ter que baixar denovo.
    if (numberOfPages2 == 0) {
        self.modeloParaItemSendoBaixado.model.paginaBaixando--;
        //vou apagar o pdf da pagina
        [self deleteFileAtPath:self.filePathPagina];
        return;    
    }

    if (numberOfPages1 > [paginaSendoBaixada integerValue]) {
        [self clearState];
        dispatch_async(dispatch_get_main_queue(), ^{
            UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Erro"
                                                            message:@"Falha na conexão.\nNão foi possível baixar a edição!"
                                                           delegate:nil
                                                  cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alertView show];
        });

    }

    // Create the output context
    CGContextRef writeContext = CGPDFContextCreateWithURL(pdfURLOutput, NULL, NULL);

    // Loop variables
    CGPDFPageRef page;
    CGRect mediaBox;

    // Read the first PDF and generate the output pages
    NSLog(@"GENERATING PAGES FROM PDF 1 (%li)...", (long)numberOfPages1);
    for (int i=1; i<=numberOfPages1; i++) {
        page = CGPDFDocumentGetPage(pdfRef1, i);
        mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
        CGContextBeginPage(writeContext, &mediaBox);
        CGContextDrawPDFPage(writeContext, page);
        CGContextEndPage(writeContext);
    }

    // Read the second PDF and generate the output pages
    NSLog(@"GENERATING PAGES FROM PDF 2 (%li)...", (long)numberOfPages2);
    for (int i=1; i<=numberOfPages2; i++) {
        page = CGPDFDocumentGetPage(pdfRef2, i);
        mediaBox = CGPDFPageGetBoxRect(page, kCGPDFMediaBox);
        CGContextBeginPage(writeContext, &mediaBox);
        CGContextDrawPDFPage(writeContext, page);
        CGContextEndPage(writeContext);
    }
    NSLog(@"DONE!");

    // Finalize the output file
    CGPDFContextClose(writeContext);

    // Release from memory
    CGPDFDocumentRelease(pdfRef1);
    CGPDFDocumentRelease(pdfRef2);
    CGContextRelease(writeContext);


    [self deleteFileAtPathWithoutImage:self.filePath];


    NSFileManager *fileMan = [NSFileManager defaultManager];
    NSError *error = nil;
    if (self.filePath != nil) {
        if (![fileMan moveItemAtPath:pdfPathOutput toPath:self.filePath error:&error])
        {
            [self clearState];
            dispatch_async(dispatch_get_main_queue(), ^{
                UIAlertView* alertView = [[UIAlertView alloc] initWithTitle:@"Erro"
                                                                message:@"Falha na conexão.\nNão foi possível baixar a edição!"
                                                               delegate:nil
                                                      cancelButtonTitle:@"OK" otherButtonTitles:nil];
            [alertView show];
            });
            NSLog(@"Failed to move '%@' to '%@': %@", pdfPathOutput, self.filePath, [error localizedDescription]);
        }
    }  
}

1 个答案:

答案 0 :(得分:0)

我不认为您能够在没有完全关闭并首先释放原始输入副本的情况下生成PDF1的新实例,以便操作系统可以使用新输出覆盖旧PDF1同名文件。将新合并的输出写为PDF3更直接,因为PDF1和PDF2的组合对象必须相互索引和重新编号。

也就是说,简单地将PDF2的内容移动到PDF1是不可行的,因为您将拥有两个对象1,两个对象2等等。因此,该过程将创建您的新PDF3作为新目的地,并将包括您输入的新数字下的第一个对象(或组合他们的词典,或其他),以及来自每个输入的第二个对象,第三个,等等。

(我在这里过分简化,因为PDF1和PDF2中的对象序列不匹配,但基本上合并需要合并两者的内容,然后重新排序和重新索引他们;这不仅仅是将第二个附加到第一个然后将其关闭。)

如果您的问题是您希望输出继承第一个输入文件的名称,我建议先使用新的PDF3完成该过程,然后在验证成功完成后,您可以删除旧的PDF1然后在其位置重命名PDF3。

请注意,如果您真的想让流程的输出带有原始输入文件的名称,那么您需要确保您的流程成功,或者您可能最终输出错误的输出文件而不是幸存的输入文件实例,可以再试一次。