RNPrint.m 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Created by Christopher Dro on 9/4/15.
  2. #import "RNPrint.h"
  3. #import <React/RCTConvert.h>
  4. #import <React/RCTUtils.h>
  5. @implementation RNPrint
  6. - (dispatch_queue_t)methodQueue
  7. {
  8. return dispatch_get_main_queue();
  9. }
  10. RCT_EXPORT_MODULE();
  11. RCT_EXPORT_METHOD(print:(NSDictionary *)options
  12. resolver:(RCTPromiseResolveBlock)resolve
  13. rejecter:(RCTPromiseRejectBlock)reject) {
  14. if (options[@"filePath"]){
  15. _filePath = [RCTConvert NSString:options[@"filePath"]];
  16. }
  17. if (options[@"html"]){
  18. _htmlString = [RCTConvert NSString:options[@"html"]];
  19. }
  20. if (options[@"printerURL"]){
  21. _printerURL = [NSURL URLWithString:[RCTConvert NSString:options[@"printerURL"]]];
  22. _pickedPrinter = [UIPrinter printerWithURL:_printerURL];
  23. }
  24. if(options[@"isLandscape"]) {
  25. _isLandscape = [[RCTConvert NSNumber:options[@"isLandscape"]] boolValue];
  26. }
  27. if ((_filePath && _htmlString) || (_filePath == nil && _htmlString == nil)) {
  28. reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(@"Must provide either `html` or `filePath`. Both are either missing or passed together"));
  29. }
  30. NSData *printData;
  31. BOOL isValidURL = NO;
  32. NSURL *candidateURL = [NSURL URLWithString: _filePath];
  33. if (candidateURL && candidateURL.scheme && candidateURL.host)
  34. isValidURL = YES;
  35. if (isValidURL) {
  36. // TODO: This needs updated to use NSURLSession dataTaskWithURL:completionHandler:
  37. printData = [NSData dataWithContentsOfURL:candidateURL];
  38. } else {
  39. printData = [NSData dataWithContentsOfFile: _filePath];
  40. }
  41. UIPrintInteractionController *printInteractionController = [UIPrintInteractionController sharedPrintController];
  42. printInteractionController.delegate = self;
  43. // Create printing info
  44. UIPrintInfo *printInfo = [UIPrintInfo printInfo];
  45. printInfo.outputType = UIPrintInfoOutputGeneral;
  46. printInfo.jobName = [_filePath lastPathComponent];
  47. printInfo.duplex = UIPrintInfoDuplexLongEdge;
  48. printInfo.orientation = _isLandscape? UIPrintInfoOrientationLandscape: UIPrintInfoOrientationPortrait;
  49. printInteractionController.printInfo = printInfo;
  50. printInteractionController.showsPageRange = YES;
  51. if (_htmlString) {
  52. UIMarkupTextPrintFormatter *formatter = [[UIMarkupTextPrintFormatter alloc] initWithMarkupText:_htmlString];
  53. printInteractionController.printFormatter = formatter;
  54. } else {
  55. printInteractionController.printingItem = printData;
  56. }
  57. // Completion handler
  58. void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
  59. ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
  60. if (!completed && error) {
  61. NSLog(@"Printing could not complete because of error: %@", error);
  62. reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(error.description));
  63. } else {
  64. resolve(completed ? printInfo.jobName : nil);
  65. }
  66. };
  67. if (_pickedPrinter) {
  68. [printInteractionController printToPrinter:_pickedPrinter completionHandler:completionHandler];
  69. } else {
  70. [printInteractionController presentAnimated:YES completionHandler:completionHandler];
  71. }
  72. }
  73. RCT_EXPORT_METHOD(selectPrinter:(RCTPromiseResolveBlock)resolve
  74. rejecter:(RCTPromiseRejectBlock)reject) {
  75. UIPrinterPickerController *printPicker = [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter: _pickedPrinter];
  76. printPicker.delegate = self;
  77. [printPicker presentAnimated:YES completionHandler:
  78. ^(UIPrinterPickerController *printerPicker, BOOL userDidSelect, NSError *error) {
  79. if (!userDidSelect && error) {
  80. NSLog(@"Printing could not complete because of error: %@", error);
  81. reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(error.description));
  82. } else {
  83. [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:printerPicker.selectedPrinter];
  84. if (userDidSelect) {
  85. _pickedPrinter = printerPicker.selectedPrinter;
  86. NSDictionary *printerDetails = @{
  87. @"name" : _pickedPrinter.displayName,
  88. @"url" : _pickedPrinter.URL.absoluteString,
  89. };
  90. resolve(printerDetails);
  91. }
  92. }
  93. }];
  94. }
  95. #pragma mark - UIPrintInteractionControllerDelegate
  96. -(UIViewController*)printInteractionControllerParentViewController:(UIPrintInteractionController*)printInteractionController {
  97. UIViewController *result = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
  98. while (result.presentedViewController) {
  99. result = result.presentedViewController;
  100. }
  101. return result;
  102. }
  103. -(void)printInteractionControllerWillDismissPrinterOptions:(UIPrintInteractionController*)printInteractionController {}
  104. -(void)printInteractionControllerDidDismissPrinterOptions:(UIPrintInteractionController*)printInteractionController {}
  105. -(void)printInteractionControllerWillPresentPrinterOptions:(UIPrintInteractionController*)printInteractionController {}
  106. -(void)printInteractionControllerDidPresentPrinterOptions:(UIPrintInteractionController*)printInteractionController {}
  107. -(void)printInteractionControllerWillStartJob:(UIPrintInteractionController*)printInteractionController {}
  108. -(void)printInteractionControllerDidFinishJob:(UIPrintInteractionController*)printInteractionController {}
  109. @end