From 6767874ecd381f1659aaed57a40531b757385e43 Mon Sep 17 00:00:00 2001 From: Brent Anderson Date: Sat, 27 Jul 2013 19:18:47 -0600 Subject: [PATCH] Fix a bug where the `UIWebView` goes out of scope when a method calling `saveHtmlAsPdf:` or `saveUrlAsPdf:` finishes. UIWebView objects were locally scoped to the method calls, meaning that when those methods returned the web view was deallocated. Now the webView object is scoped to the entire class, ensuring that the delegate methods are triggered and that the PDFs are generated properly. webView is disposed of after the callbacks, since web pages for PDFs may be pretty hefty in size. Also updated the README with similar instructions for use: Your examples suggest that a local allocation of BNHtmlPdfKit will work as expected, however it goes out of scope before the delegate methods are called. --- BNHtmlPdfKit.m | 17 +++++++++++------ README.md | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/BNHtmlPdfKit.m b/BNHtmlPdfKit.m index 761e9f3..1a17343 100644 --- a/BNHtmlPdfKit.m +++ b/BNHtmlPdfKit.m @@ -43,6 +43,7 @@ - (CGRect)printableRect { @interface BNHtmlPdfKit () { NSString *_outputFile; + UIWebView *_webView; } - (CGSize)_sizeFromPageSize:(BNPageSize)pageSize; @end @@ -106,9 +107,9 @@ - (void)saveHtmlAsPdf:(NSString *)html { - (void)saveHtmlAsPdf:(NSString *)html toFile:(NSString *)file { _outputFile = file; - UIWebView *webView = [[UIWebView alloc] init]; - webView.delegate = self; - [webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://localhost"]]; + _webView = [[UIWebView alloc] init]; + _webView.delegate = self; + [_webView loadHTMLString:html baseURL:[NSURL URLWithString:@"http://localhost"]]; } - (void)saveUrlAsPdf:(NSURL *)url { @@ -118,9 +119,9 @@ - (void)saveUrlAsPdf:(NSURL *)url { - (void)saveUrlAsPdf:(NSURL *)url toFile:(NSString *)file { _outputFile = file; - UIWebView *webView = [[UIWebView alloc] init]; - webView.delegate = self; - [webView loadRequest:[NSURLRequest requestWithURL:url]]; + _webView = [[UIWebView alloc] init]; + _webView.delegate = self; + [_webView loadRequest:[NSURLRequest requestWithURL:url]]; } #pragma mark - UIWebViewDelegate @@ -163,12 +164,16 @@ - (void)webViewDidFinishLoad:(UIWebView *)webView { [_delegate htmlPdfKit:self didSavePdfFile:_outputFile]; } } + + _webView = nil; } -(void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { if ([_delegate respondsToSelector:@selector(htmlPdfKit:didFailWithError:)]) { [_delegate htmlPdfKit:self didFailWithError:error]; } + + _webView = nil; } #pragma mark - Private Methods diff --git a/README.md b/README.md index fb616d3..0254ba3 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,26 @@ This all started with a [post of mine](http://itsbrent.net/2011/06/printing-conv ## Usage +Be sure to retain a reference to the `BNHtmlPdfKit` object outside the scope of the calling method. Otherwise, no delegate methods will be called: + +```objective-c +@interface MyCoolViewController () +{ + BNHtmlPdfKit *_htmlPdfKit; +} + +- (void) createPdf:(id)sender { + _htmlPdfKit = [[BNHtmlPdfKit alloc] init]; + _htmlPdfKit.delegate = self; + [_htmlPdfKit saveUrlAsPdf:[NSURL URLWithString:@"http://itsbrent.net/index.html"]]; +} + +@end + +// Delegate methods go here... + +``` + ### Initializers ```objective-c