christopherdro / react-native-print

Print documents using React Native
MIT License
334 stars 141 forks source link

Silent print support #9

Closed theopolisme closed 6 years ago

theopolisme commented 8 years ago

Hi and thanks for the (highly useful) library!

I'm curious if you had any plans to support "silent printing" -- in other words, printing directly to a printer without a print dialog. The usecase here is for things like receipt / ticketing printing, where we want the print to start automatically without intervention.

It looks like this is definitely possible with Apple's printing API - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIPrintInteractionController_Class/index.html#//apple_ref/doc/uid/TP40010141-CH1-SW34 / http://stackoverflow.com/questions/8125560/is-there-a-way-to-silent-print-using-ios-airprint-e-g-no-print-dialog for an example implementation.

The one other thing that would need to be added is a method to list the connected printers (so that the user could then set the desired printer).

If this isn't something you have the time / interest in building, I would be willing to work on a PR myself... just might be a bit slower due to unfamiliarity with Apple's printing APIs in general :)

Please let me know - thanks again!

christopherdro commented 8 years ago

@theopolisme I'm not too familiar with the API either but if you would be willing to start putting together a PR I can try my best to help throughout the process.

edgeadjei commented 7 years ago

This enhancement would be a wonderful addition to the library. And is exactly what I've been looking for. @christopherdro thank you for creating this library.

stphnnnn commented 7 years ago

I have a proof-of-concept working on my local machine. I'll tidy about the code and publish a pull request soon 😬

alinaghavi commented 7 years ago

@stphnnnn can you please share your piece of code, or give me directions of how to do it? I really need this ;)

rizwan92 commented 7 years ago

i am trying to use this library . the only problem i am facing is how to connect to a printer to my react native app

alinaghavi commented 7 years ago

@stphnnnn did you see my message? I really need it.Thanks

stphnnnn commented 7 years ago

@alinaghavi Sorry, I haven't had time to get a pull request together but I'll post a couple of Obj-C snippets below, hopefully someone can get this up and running.

So in order for silent printing to work you need two methods; one to select the printer and the other to print.

Select printer method (presents a UIPrinterPickerController and stores the selected printer in a variable):

UIPrinter *pickedPrinter;
RCT_EXPORT_METHOD(selectPrinter:(RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {
    UIPrinterPickerController *printPicker = [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter: pickedPrinter];

    printPicker.delegate = self;

    [printPicker presentAnimated:YES completionHandler:
     ^(UIPrinterPickerController *printerPicker, BOOL userDidSelect, NSError *error) {
         if (!userDidSelect && error) {
             NSLog(@"Printing could not complete because of error: %@", error);
             reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(error.description));
         } else {
             [UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:printerPicker.selectedPrinter];
             if (userDidSelect) {
                 pickedPrinter = printerPicker.selectedPrinter;
                 NSDictionary *printerDetails = @{
                                                  @"name" : pickedPrinter.displayName,
                                                  @"url" : pickedPrinter.URL.absoluteString,
                                                  };
                 resolve(printerDetails);
             }
         }
     }];   
}

Print method (prints using previously selected printer):

RCT_EXPORT_METHOD(print:(NSString *)filePath
                  resolver: (RCTPromiseResolveBlock)resolve
                  rejecter:(RCTPromiseRejectBlock)reject) {

    NSData *printData = [NSData dataWithContentsOfFile:filePath];
    UIPrintInteractionController *printInteractionController = [UIPrintInteractionController sharedPrintController];
    printInteractionController.delegate = self;

    // Create printing info
    UIPrintInfo *printInfo = [UIPrintInfo printInfo];

    printInfo.outputType = UIPrintInfoOutputPhoto;
    printInfo.jobName = [filePath lastPathComponent];
    printInfo.duplex = UIPrintInfoDuplexNone;

    printInteractionController.printInfo = printInfo;
    printInteractionController.printingItem = printData;

    void (^completionHandler)(UIPrintInteractionController *, BOOL, NSError *) =
    ^(UIPrintInteractionController *printController, BOOL completed, NSError *error) {
        if (!completed && error) {
            NSLog(@"Printing could not complete because of error: %@", error);
            reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(error.description));
        } else {
            resolve(completed ? printInfo.jobName : nil);
        }
    };

    if (pickedPrinter) {
        [printInteractionController printToPrinter:pickedPrinter completionHandler:completionHandler];
    }
    else {
        NSLog(@"No printer is set, check your settings");
        reject(RCTErrorUnspecified, nil, RCTErrorWithMessage(@"No printer is set, check your settings"));
    }

}

Let me know if this is of any help, it may be buggy but as I said it's a proof of concept...

alinaghavi commented 7 years ago

@stphnnnn Thanks , I will tell you about the result

christopherdro commented 7 years ago

Long overdue but I've opened a new PR #20 to address this issue.

Let me know if this work for everyone and I'll go ahead and get a new release out with this feature.

PatrykTies commented 7 years ago

Hi. Thanks for a great tool for RN. Please add silent printing to your lib . Its really on high demand. Ticket/label printing. Cheers and good luck.

christopherdro commented 7 years ago

There a PR Open that's under testing atm