// // KMConvertURLToPDF.m // PDF Reader // // Created by 丁林圭 on 2019/3/11. // Copyright © 2019年 Kdan Mobile. All rights reserved. // #import "KMConvertURLToPDF.h" #import #import @interface KMConvertURLToPDF () { BOOL isProgressing; } @property (nonatomic,retain) NSString *savePath; @property (nonatomic,assign) NSInteger pageIndex; @property (nonatomic,retain) NSMutableArray * urls; @property (nonatomic,retain) NSMutableArray * failArray; @property (nonatomic,retain) NSMutableArray * successArray; @property (nonatomic,assign) CGSize pageSize; @property (nonatomic,assign) CGFloat gap; @property (nonatomic,retain) WebView *webView; @property (nonatomic,copy) void (^progress)(CGFloat value); @property (nonatomic,copy) void (^handler)(NSArray *successArray,NSArray *failArray); @end @implementation KMConvertURLToPDF -(void)dealloc { } + (KMConvertURLToPDF *)shareInstance { static KMConvertURLToPDF *sharedConvertUrlToPDF = nil; static dispatch_once_t predicate; dispatch_once(&predicate, ^{ sharedConvertUrlToPDF = [[KMConvertURLToPDF alloc] init]; }); return sharedConvertUrlToPDF; } - (void)convertUrlToPDF:(NSArray *)urls toPath:(NSString *)toPath pageSize:(CGSize)pageSize gap:(CGFloat)gap progress:(void (^)(CGFloat value))progress completionHandler:(void (^) (NSArray *successArray,NSArray *failArray))handler { self.urls = [NSMutableArray arrayWithArray:urls]; self.failArray = [NSMutableArray array]; self.successArray = [NSMutableArray array]; self.savePath = toPath; self.progress = progress; self.pageSize = pageSize; self.gap = gap; self.handler = handler; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ self.pageIndex = 0; dispatch_async(dispatch_get_main_queue(), ^{ [self convertFileAtPageIndex:self.pageIndex]; }); }); } - (void)convertFileAtPageIndex:(NSInteger)pageIndex { if (pageIndex >= self.urls.count) { if (self.handler) { self.handler (self.successArray,self.failArray); self.handler = nil; } return; } NSURL *url = self.urls[pageIndex]; if ([url.pathExtension.lowercaseString isEqualToString:@"pdf"]) { dispatch_async(dispatch_get_main_queue(), ^{ NSData *urlData = [NSData dataWithContentsOfURL:url]; NSString *name = [NSString stringWithFormat:@"webpage%ld",self.pageIndex]; NSString *savePath = [self.savePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf", self.fileName.length > 0? self.fileName : name]]; if (![[NSFileManager defaultManager]fileExistsAtPath:self.savePath]) { [[NSFileManager defaultManager] createDirectoryAtPath:self.savePath withIntermediateDirectories:YES attributes:nil error:nil]; } if ([urlData writeToFile:savePath atomically:YES]) { [self.successArray addObject:savePath]; if (self.pageIndex + 1 >= self.urls.count) { if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } else { [self convertFileAtPageIndex:++self.pageIndex]; } } else { [self.failArray addObject:self.urls[self.pageIndex]]; if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } }); } else { if (!self.webView) { _webView = [[WebView alloc] initWithFrame:NSMakeRect(0, 0, 400, 400)]; WebPreferences *webPrefs = [[WebPreferences alloc] init]; [webPrefs setShouldPrintBackgrounds:YES]; [self.webView setPreferences:webPrefs]; [self.webView setFrameLoadDelegate:self]; [self.webView setResourceLoadDelegate:self]; } [[self.webView mainFrame] loadRequest:[NSURLRequest requestWithURL:url]]; } if (pageIndex != 0 && self.progress) { self.progress((float)self.pageIndex/self.urls.count); } } - (void)convertWebViewFrame:(WebFrame *)frame { // if (isProgressing) { // return; // } // isProgressing = YES; NSString *name = [NSString stringWithFormat:@"webpage%ld",self.pageIndex]; if (self.fileName.length != 0) { name = self.fileName; } NSString *savePath = [self.savePath stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.pdf",name]]; if (![[NSFileManager defaultManager]fileExistsAtPath:self.savePath]) { [[NSFileManager defaultManager] createDirectoryAtPath:self.savePath withIntermediateDirectories:YES attributes:nil error:nil]; } CGFloat margin = self.gap; NSSize paperSize = self.pageSize; WebFrameView *frameView = [frame frameView]; NSPrintInfo *sharedInfo = [NSPrintInfo sharedPrintInfo]; NSMutableDictionary *printInfoDict = [NSMutableDictionary dictionaryWithDictionary:[sharedInfo dictionary]]; [printInfoDict setObject:NSPrintSaveJob forKey:NSPrintJobDisposition]; [printInfoDict setObject:[NSURL fileURLWithPath:savePath] forKey:NSPrintJobSavingURL]; NSPrintInfo *printInfo = [[NSPrintInfo alloc] initWithDictionary:printInfoDict]; [printInfo setHorizontalPagination:NSPrintingPaginationModeAutomatic]; [printInfo setVerticalPagination:NSPrintingPaginationModeAutomatic]; [printInfo setVerticallyCentered:NO]; if (!CGSizeEqualToSize(paperSize, CGSizeZero)) { [printInfo setBottomMargin:margin]; [printInfo setTopMargin:margin]; [printInfo setLeftMargin:margin]; [printInfo setRightMargin:margin]; [printInfo setPaperSize:paperSize]; } [printInfo setOrientation:NSPaperOrientationPortrait]; NSPrintOperation *printOp = [frameView printOperationWithPrintInfo:printInfo]; [printOp setShowsPrintPanel:NO]; [printOp setShowsProgressPanel:NO]; if ([printOp runOperation]) { [self.successArray addObject:savePath]; if (self.pageIndex + 1 >= self.urls.count) { if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } else { [self convertFileAtPageIndex:++self.pageIndex]; } } else { [self.failArray addObject:self.urls[self.pageIndex]]; if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } } #pragma mark - WebView Delegate Methods - (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame { if (frame == [sender mainFrame]) { NSString *htmlTitle = @"document.title"; if (!self.fileName) { self.fileName = [sender stringByEvaluatingJavaScriptFromString:htmlTitle]; if ([self.fileName length] < 1) { self.fileName = sender.mainFrameTitle; } if ([self.fileName length] < 1) { self.fileName = @"Untitled"; } } [self performSelector:@selector(convertWebViewFrame:) withObject:frame afterDelay:0.3]; } } - (void)webView:(WebView *)sender didFailLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { if([error code] == NSURLErrorCancelled) { return; } [self.failArray addObject:self.urls[self.pageIndex]]; if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } - (void)webView:(WebView *)sender didFailProvisionalLoadWithError:(NSError *)error forFrame:(WebFrame *)frame { [self.failArray addObject:self.urls[self.pageIndex]]; if (self.handler) { self.handler (self.successArray,self.failArray); self.handler= nil; } } @end