在Web View中生成PDF时,如何首先将PDF数据写入文件

时间:2020-12-10 21:10:53

My app keeps receiving a memory warning and subsequent crash when generating a PDF. Ive been advised to write my PDF to a file first, but no expansion was offered.

我的应用程序在生成PDF时不断收到内存警告和随后的崩溃。我被建议先将我的PDF写入文件,但没有提供扩展。

This is my first time on generating a PDF using iOS and despite checking out Apples documentation http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/GeneratingPDF/GeneratingPDF.html and searching SO, Google, and using UIGraphicsBeginPDFContextToFile I just keep getting warnings/no genration of PDF or exceptions thrown as im just guessing at this. I really haven't grasped this concept yet.

这是我第一次使用iOS生成PDF,尽管查看了Apples文档http://developer.apple.com/library/ios/#documentation/2ddrawing/conceptual/drawingprintingios/GeneratingPDF/GeneratingPDF.html并搜索了SO,Google ,并使用UIGraphicsBeginPDFContextToFile我只是不断收到警告/没有生成PDF或异常抛出,因为我只是在猜测。我还没有掌握这个概念。

Could someone offer some advice on how to write my PDF to a file first

有人可以先提供一些关于如何将PDF写入文件的建议

- (void)viewWillAppear:(BOOL)animated
 {
 LogCmd();

[super viewWillAppear:animated];
 if (self.pdfData != nil && self.viewHasUnloaded == YES) {
self.viewHasUnloaded = NO;
[self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8"   baseURL:nil];
 }
}



- (void)viewDidAppear:(BOOL)animated
 {

  LogCmd();
 [super viewDidAppear:animated];
 if (self.pdfData == nil) {



// Generate PDF
 [ICUtils showProgressViewWithTitle:@"Generating PDF. This may take a minute..."];
 [self performSelectorInBackground:@selector(generatePdf) withObject:nil];
  }
 }

 - (void)generatePdf
  {
  NSMutableArray *pagesArray = [NSMutableArray array];

 if ([self.certificate.certificateType.title isEqualToString:@"EICR"]) {
[pagesArray addObject:[[ICPDFEICRPage1 alloc] initWithCertificate:self.certificate]];
[pagesArray addObject:[[ICPDFEICRPage2 alloc] initWithCertificate:self.certificate]];
[self addObservationsToPagesArray:pagesArray];
[self addDistributionBoardsToPagesArray:pagesArray];
[pagesArray addObject:[[ICPDFEICRInspection alloc] initWithCertificate:self.certificate]];
[pagesArray addObject:[[ICPDFEICRInspectionPage1 alloc] initWithCertificate:self.certificate]];
[pagesArray addObject:[[ICPDFEICRInspectionPage2 alloc] initWithCertificate:self.certificate]];
[pagesArray addObject:[[ICPDFEICRInspectionPage3 alloc] initWithCertificate:self.certificate]];
[pagesArray addObject:[[ICPDFEICRPageFinal alloc] initWithCertificate:self.certificate]];
    }

    // Set page count on all pages
     int pageNumber = 0;
     for (ICCertificateComponent *page in pagesArray) {
     page.pageNumber.text = [NSString stringWithFormat:@"%d", ++pageNumber];
     page.pageCount.text = [NSString stringWithFormat:@"%d", pagesArray.count];
   }

   NSData *pdfData = [self createPdfWithPages:pagesArray];
   [self performSelectorOnMainThread:@selector(pdfDone:) withObject:pdfData waitUntilDone:YES];

  }
 }
 - (void)pdfDone:(NSData *)data
 {
self.pdfData = data;
[self.webView loadData:self.pdfData MIMEType:@"application/pdf" textEncodingName:@"utf-8"   baseURL:nil];
[ICUtils removeProgressView];
      }


- (NSData *)createPdfWithPages:(NSArray *)pages

     {
    // Creates a mutable data object for updating with binary data, like a byte array

 NSMutableData *pdfData = [NSMutableData data];

 ICCertificateComponent *firstPage = [pages objectAtIndex:0];

 UIGraphicsBeginPDFContextToData(pdfData, firstPage.contentView.bounds, nil);

 for (int i = 0; i < pages.count; i++) {
   ICCertificateComponent *thisPage = [pages objectAtIndex:i];
UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds, nil);

CGContextRef pdfContext = UIGraphicsGetCurrentContext();
[thisPage.contentView.layer renderInContext:pdfContext];
   }

 UIGraphicsEndPDFContext();

 return pdfData;

 }

What I have tried

我试过的

 -(void)createPDFfromUIView:(UIView*)aView saveToDocumentsWithFileName:(NSString*)aFilename
 {

 NSArray *pages;
// Creates a mutable data object for updating with binary data, like a byte array
        NSMutableData *pdfData = [NSMutableData data];

    ICCertificateComponent *firstPage = [pages objectAtIndex:0];

    UIGraphicsBeginPDFContextToData(pdfData, firstPage.contentView.bounds, nil);

    for (int i = 0; i < pages.count; i++) {
        ICCertificateComponent *thisPage = [pages objectAtIndex:i];
        UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds, nil);

        CGContextRef pdfContext = UIGraphicsGetCurrentContext();
        [thisPage.contentView.layer renderInContext:pdfContext];
      }

    UIGraphicsBeginPDFPage();
   CGContextRef currentContext = UIGraphicsGetCurrentContext();
 animated:NO];
 [_webView.layer renderInContext:currentContext];



  UIGraphicsEndPDFContext();

   NSArray* documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);

   NSString* documentDirectory = [documentDirectories objectAtIndex:0];
   NSString* documentDirectoryFilename = [documentDirectory stringByAppendingPathComponent:aFilename];

  //return pdfData;
  [pdfData writeToFile:documentDirectoryFilename atomically:YES];
}

Error: Exception thrown 'NSInvalidArgumentException', reason: '-[ICPDFPreviewController createPdfWithPages:]: unrecognized selector sent to instance amongst others im sure

错误:异常抛出'NSInvalidArgumentException',原因:' - [ICPDFPreviewController createPdfWithPages:]:无法识别的选择器发送到其他实例中我确定

Also tried:

 - (NSString *)createPdfWithPages:(NSArray *)pages
 {

    @autoreleasepool {



    ICCertificateComponent *firstPage = [pages objectAtIndex:0];

    NSString *docDirectory =
    [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
    NSString *pdfPath = [docDirectory stringByAppendingPathComponent:@"pdfFile.pdf"];

    UIGraphicsBeginPDFContextToFile(pdfPath, firstPage.contentView.bounds, nil);

    for (int i = 0; i < pages.count; i++) {
        ICCertificateComponent *thisPage = [pages objectAtIndex:i];
        UIGraphicsBeginPDFPageWithInfo(thisPage.contentView.bounds, nil);

        CGContextRef pdfContext = UIGraphicsGetCurrentContext();
        [thisPage.contentView.layer renderInContext:pdfContext];
               }

    UIGraphicsEndPDFContext();

    return pdfPath;

}

error: NSInvalidArgumentException', reason: '-[NSPathStore2 bytes]: unrecognized selector sent to instance 0x24aa4580'

错误:NSInvalidArgumentException',原因:' - [NSPathStore2 bytes]:无法识别的选择器发送到实例0x24aa4580'

1 个解决方案

#1


1  

you try below code.

你尝试下面的代码。

+(void)drawLineFromPoint:(CGPoint)from toPoint:(CGPoint)to
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 2.0);

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

    CGFloat components[] = {0.2, 0.2, 0.2, 0.3};

    CGColorRef color = CGColorCreate(colorspace, components);

    CGContextSetStrokeColorWithColor(context, color);

    CGContextMoveToPoint(context, from.x, from.y);
    CGContextAddLineToPoint(context, to.x, to.y);

    CGContextStrokePath(context);
    CGColorSpaceRelease(colorspace);
    CGColorRelease(color);

}

+(void)drawText
{

    NSString* textToDraw = @"Hello World";
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
    // Prepare the text using a Core Text Framesetter
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

    CGRect frameRect = CGRectMake(0, 0, 300, 50);
    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    CFRange currentRange = CFRangeMake(0, 0);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);

    // Get the graphics context.
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.
    CGContextTranslateCTM(currentContext, 0, 100);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);
}

+(void)drawPDF:(NSString*)fileName
{

    // Create the PDF context using the default page size of 612 x 792.
    UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
    // Mark the beginning of a new page.
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

    CGPoint from = CGPointMake(0, 0);
    CGPoint to = CGPointMake(200, 300);
    [PDFRenderer drawLineFromPoint:from toPoint:to];

    [self drawText];

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
}

#1


1  

you try below code.

你尝试下面的代码。

+(void)drawLineFromPoint:(CGPoint)from toPoint:(CGPoint)to
{

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSetLineWidth(context, 2.0);

    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();

    CGFloat components[] = {0.2, 0.2, 0.2, 0.3};

    CGColorRef color = CGColorCreate(colorspace, components);

    CGContextSetStrokeColorWithColor(context, color);

    CGContextMoveToPoint(context, from.x, from.y);
    CGContextAddLineToPoint(context, to.x, to.y);

    CGContextStrokePath(context);
    CGColorSpaceRelease(colorspace);
    CGColorRelease(color);

}

+(void)drawText
{

    NSString* textToDraw = @"Hello World";
    CFStringRef stringRef = (__bridge CFStringRef)textToDraw;
    // Prepare the text using a Core Text Framesetter
    CFAttributedStringRef currentText = CFAttributedStringCreate(NULL, stringRef, NULL);
    CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString(currentText);

    CGRect frameRect = CGRectMake(0, 0, 300, 50);
    CGMutablePathRef framePath = CGPathCreateMutable();
    CGPathAddRect(framePath, NULL, frameRect);

    // Get the frame that will do the rendering.
    CFRange currentRange = CFRangeMake(0, 0);
    CTFrameRef frameRef = CTFramesetterCreateFrame(framesetter, currentRange, framePath, NULL);
    CGPathRelease(framePath);

    // Get the graphics context.
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    // Put the text matrix into a known state. This ensures
    // that no old scaling factors are left in place.
    CGContextSetTextMatrix(currentContext, CGAffineTransformIdentity);

    // Core Text draws from the bottom-left corner up, so flip
    // the current transform prior to drawing.
    CGContextTranslateCTM(currentContext, 0, 100);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

    // Draw the frame.
    CTFrameDraw(frameRef, currentContext);

    CFRelease(frameRef);
    CFRelease(stringRef);
    CFRelease(framesetter);
}

+(void)drawPDF:(NSString*)fileName
{

    // Create the PDF context using the default page size of 612 x 792.
    UIGraphicsBeginPDFContextToFile(fileName, CGRectZero, nil);
    // Mark the beginning of a new page.
    UIGraphicsBeginPDFPageWithInfo(CGRectMake(0, 0, 612, 792), nil);

    CGPoint from = CGPointMake(0, 0);
    CGPoint to = CGPointMake(200, 300);
    [PDFRenderer drawLineFromPoint:from toPoint:to];

    [self drawText];

    // Close the PDF context and write the contents out.
    UIGraphicsEndPDFContext();
}