cordova-plugin-printer/src/ios/APPPrinter.m

417 lines
12 KiB
Mathematica
Raw Normal View History

2013-12-11 20:00:16 +08:00
/*
2019-01-21 22:17:07 +08:00
Copyright 2013 appPlant GmbH
Licensed to the Apache Software Foundation (ASF) under one
or more contributor license agreements. See the NOTICE file
distributed with this work for additional information
regarding copyright ownership. The ASF licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*/
2013-08-10 22:13:04 +08:00
#import "APPPrinter.h"
2019-01-21 22:17:07 +08:00
#import "APPPrinterItem.h"
#import "APPPrinterPaper.h"
2019-01-22 00:52:28 +08:00
#include "APPPrinterRenderer.h"
#include "UIPrintInteractionController+APPPrinter.h"
2014-09-08 04:52:36 +08:00
@interface APPPrinter ()
@property (nonatomic) UIPrinter *previousPrinter;
@end
2013-08-10 22:13:04 +08:00
@implementation APPPrinter
2016-07-25 21:04:20 +08:00
#pragma mark -
#pragma mark Interface
/*
2014-09-08 04:52:36 +08:00
* Checks if the printing service is available.
*/
2019-01-21 22:17:07 +08:00
- (void) check:(CDVInvokedUrlCommand *)command
2013-08-11 17:35:40 +08:00
{
[self.commandDelegate runInBackground:^{
2019-01-21 22:17:07 +08:00
BOOL res = NO;
2019-01-21 22:17:07 +08:00
if (command.arguments.count == 0)
{
res = UIPrintInteractionController.isPrintingAvailable;
}
else
{
res = [APPPrinterItem canPrintURL:command.arguments[0]];
}
2019-01-21 22:17:07 +08:00
[self sendResultWithMessageAsBool:res
callbackId:command.callbackId];
}];
}
2016-07-25 21:04:20 +08:00
/**
* Displays system interface for selecting a printer.
2016-07-25 21:04:20 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) pick:(CDVInvokedUrlCommand *)command
2016-07-25 21:04:20 +08:00
{
2019-01-21 22:17:07 +08:00
[self.commandDelegate runInBackground:^{
NSMutableDictionary* settings = command.arguments[0];
settings[@"callbackId"] = command.callbackId;
2019-01-21 22:17:07 +08:00
[self presentPickerWithSettings:settings];
}];
2016-07-25 21:04:20 +08:00
}
/**
2019-01-21 22:17:07 +08:00
* Sends the printing content to the printer controller and opens them.
2016-07-25 21:04:20 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) print:(CDVInvokedUrlCommand *)command
{
2019-01-21 22:17:07 +08:00
[self.commandDelegate runInBackground:^{
NSString* content = command.arguments[0];
NSMutableDictionary* settings = command.arguments[1];
settings[@"callbackId"] = command.callbackId;
2016-07-21 03:00:33 +08:00
2019-01-21 22:17:07 +08:00
[self printContent:content withSettings:settings];
}];
2016-07-25 21:04:20 +08:00
}
#pragma mark -
#pragma mark UIPrintInteractionControllerDelegate
/**
* Asks the delegate for an object encapsulating the paper size and printing
* area to use for the print job. If Paper-Size is given it selects the best
* fitting papersize
*/
2019-01-21 22:17:07 +08:00
- (UIPrintPaper *) printInteractionController:(UIPrintInteractionController *)ctrl
choosePaper:(NSArray *)paperList
{
2019-01-21 22:17:07 +08:00
APPPrinterPaper* paperSpec = [[APPPrinterPaper alloc]
initWithDictionary:ctrl.settings[@"paper"]];
2019-01-21 22:17:07 +08:00
return [paperSpec bestPaperFromArray:paperList];
}
/**
* Asks the delegate for a length to use when cutting the page. If using roll
* printers like Label-Printer (brother QL-710W) you can cut paper after given
* length.
*/
2019-01-21 22:17:07 +08:00
- (CGFloat) printInteractionController:(UIPrintInteractionController *)ctrl
cutLengthForPaper:(UIPrintPaper *)paper
{
2019-01-21 22:17:07 +08:00
APPPrinterPaper* paperSpec = [[APPPrinterPaper alloc]
initWithDictionary:ctrl.settings[@"paper"]];
2019-01-21 22:17:07 +08:00
return paperSpec.length || paper.paperSize.height;
}
2016-07-25 21:04:20 +08:00
#pragma mark -
#pragma mark Core
/**
2019-01-21 22:17:07 +08:00
* Displays system interface for selecting a printer.
*
* @param settings Describes additional settings like from where to present the
* picker for iPad.
*
* @return [ Void ]
2016-07-25 21:04:20 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) presentPickerWithSettings:(NSDictionary *)settings
2016-07-25 21:04:20 +08:00
{
2019-01-21 22:17:07 +08:00
UIPrinterPickerController* controller =
[UIPrinterPickerController printerPickerControllerWithInitiallySelectedPrinter:nil];
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
UIPrinterPickerCompletionHandler handler =
^(UIPrinterPickerController *ctrl, BOOL selected, NSError *e) {
[self returnPickerResultForController:ctrl
callbackId:settings[@"callbackId"]];
};
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
dispatch_async(dispatch_get_main_queue(), ^{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) {
NSArray* bounds = settings[@"ui"][@"bounds"];
CGRect rect = [self convertIntoRect:bounds];
[controller presentFromRect:rect
inView:self.webView
animated:YES
completionHandler:handler];
} else {
[controller presentAnimated:YES
completionHandler:handler];
}
});
}
2016-07-25 21:04:20 +08:00
/**
2019-01-21 22:17:07 +08:00
* Loads the content into the print controller.
*
2019-01-21 22:17:07 +08:00
* @param content The HTML content or remote web page URI to print.
* @param settings The print job specs.
*
* @return [ Void ]
*/
2019-01-21 22:17:07 +08:00
- (void) printContent:(NSString *)content
withSettings:(NSDictionary *)settings
{
2019-01-21 22:17:07 +08:00
__block id item;
2019-01-21 22:17:07 +08:00
UIPrintInteractionController* ctrl =
[UIPrintInteractionController sharedPrintControllerWithSettings:settings];
ctrl.delegate = self;
2019-01-21 22:17:07 +08:00
if ([self strIsNullOrEmpty:content])
{
dispatch_sync(dispatch_get_main_queue(), ^{
item = self.webView.viewPrintFormatter;
});
}
else if ([content characterAtIndex:0] == '<')
{
dispatch_sync(dispatch_get_main_queue(), ^{
item = [[UIMarkupTextPrintFormatter alloc]
initWithMarkupText:content];
});
}
else if ([NSURL URLWithString:content])
{
item = [APPPrinterItem ItemFromURL:content];
}
else
{
dispatch_sync(dispatch_get_main_queue(), ^{
item = [[UISimpleTextPrintFormatter alloc]
initWithText:content];
});
}
2019-01-21 22:17:07 +08:00
[self useController:ctrl toPrintItem:item withSettings:settings];
}
/**
2019-01-21 22:17:07 +08:00
* Print the rendered content of the given view.
*
2019-01-21 22:17:07 +08:00
* @param ctrl The interactive printer controller.
* @param item Either the item to print or the formatted content.
* @param settings The print job specs.
2016-07-25 21:04:20 +08:00
*
* @return [ Void ]
2016-07-25 21:04:20 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) useController:(UIPrintInteractionController *)ctrl
toPrintItem:(id)item
withSettings:(NSDictionary *)settings
2016-07-25 21:04:20 +08:00
{
2019-01-21 22:17:07 +08:00
NSString* printer = settings[@"printerId"];
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
if ([item isKindOfClass:UIPrintFormatter.class])
{
2019-01-22 00:52:28 +08:00
ctrl.printPageRenderer =
[[APPPrinterRenderer alloc] initWithDictionary:settings formatter:item];
2019-01-21 22:17:07 +08:00
}
else
{
ctrl.printingItem = item;
}
2019-01-21 22:17:07 +08:00
if ([self strIsNullOrEmpty:printer])
{
[self presentController:ctrl withSettings:settings];
}
else
{
[self printToPrinter:ctrl withSettings:settings];
2016-07-25 21:04:20 +08:00
}
}
2016-07-25 21:04:20 +08:00
/**
2019-01-21 22:17:07 +08:00
* Sends the content directly to the specified or previously selected printer.
*
2019-01-21 22:17:07 +08:00
* @param ctrl The interactive printer controller.
* @param printerURL The printer specified by its URL.
* @param settings The print job specs.
2016-07-25 21:04:20 +08:00
*
* @return [ Void ]
2016-07-25 21:04:20 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) printToPrinter:(UIPrintInteractionController *)ctrl
withSettings:(NSDictionary *)settings
2016-07-25 21:04:20 +08:00
{
2019-01-21 22:17:07 +08:00
NSString* callbackId = settings[@"callbackId"];
NSString* printerURL = settings[@"printerId"];
UIPrinter* printer = [self printerWithURL:printerURL];
dispatch_async(dispatch_get_main_queue(), ^{
[ctrl printToPrinter:printer completionHandler:
^(UIPrintInteractionController *ctrl, BOOL ok, NSError *e) {
[self rememberPrinter:(ok ? printer : NULL)];
[self sendResultWithMessageAsBool:ok callbackId:callbackId];
}];
});
}
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
/**
* Opens the print controller so that the user can choose between
* available iPrinters.
*
* @param ctrl The interactive printer controller.
* @param settings The print job specs.
*
* @return [ Void ]
*/
- (void) presentController:(UIPrintInteractionController *)ctrl
withSettings:(NSDictionary *)settings
{
NSString* callbackId = settings[@"callbackId"];
NSArray* bounds = settings[@"ui"][@"bounds"];
CGRect rect = [self convertIntoRect:bounds];
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
UIPrintInteractionCompletionHandler handler =
^(UIPrintInteractionController *ctrl, BOOL ok, NSError *e) {
[self sendResultWithMessageAsBool:ok callbackId:callbackId];
};
2016-08-03 23:20:10 +08:00
2019-01-21 22:17:07 +08:00
dispatch_async(dispatch_get_main_queue(), ^{
if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
{
[ctrl presentFromRect:rect
inView:self.webView
animated:YES
completionHandler:handler];
}
else
{
[ctrl presentAnimated:YES
completionHandler:handler];
}
});
}
2016-07-25 21:04:20 +08:00
#pragma mark -
#pragma mark Helper
/**
2019-01-21 22:17:07 +08:00
* Tells the system to pre-select the given printer next time.
*
* @param printer The printer to remeber.
*
* @return [ Void ]
*/
2019-01-21 22:17:07 +08:00
- (void) rememberPrinter:(UIPrinter*)printer
2013-08-11 17:35:40 +08:00
{
2019-01-21 22:17:07 +08:00
[UIPrinterPickerController
printerPickerControllerWithInitiallySelectedPrinter:(_previousPrinter = printer)];
2013-08-13 21:39:22 +08:00
}
2013-08-13 21:39:22 +08:00
/**
2019-01-21 22:17:07 +08:00
* Returns an object that can be used to connect to the network printer.
2014-09-08 04:52:36 +08:00
*
2019-01-21 22:17:07 +08:00
* @param url The network URL as a string.
2014-09-08 04:52:36 +08:00
*
2019-01-21 22:17:07 +08:00
* @return A printer even if the URL is not a valid printer.
2013-08-13 21:39:22 +08:00
*/
2019-01-21 22:17:07 +08:00
- (UIPrinter *)printerWithURL:(NSString *)urlAsString
2013-08-13 21:39:22 +08:00
{
2019-01-21 22:17:07 +08:00
NSURL* url = [NSURL URLWithString:urlAsString];
UIPrinter* printer;
2014-09-08 04:52:36 +08:00
2019-01-21 22:17:07 +08:00
if (_previousPrinter && [_previousPrinter.URL.absoluteString isEqualToString:urlAsString])
{
printer = _previousPrinter;
2014-09-08 04:52:36 +08:00
}
2019-01-21 22:17:07 +08:00
else
{
printer = [UIPrinter printerWithURL:url];
}
2019-01-21 22:17:07 +08:00
return printer;
2013-08-13 21:39:22 +08:00
}
2014-09-08 04:52:36 +08:00
/**
2019-01-21 22:17:07 +08:00
* Convert Array into Rect object.
2014-09-08 04:52:36 +08:00
*
2019-01-21 22:17:07 +08:00
* @param bounds The bounds
*
2019-01-21 22:17:07 +08:00
* @return A converted Rect object
2013-08-13 21:39:22 +08:00
*/
2019-01-21 22:17:07 +08:00
- (CGRect) convertIntoRect:(NSArray*)bounds
2013-08-13 21:39:22 +08:00
{
2019-01-21 22:17:07 +08:00
if (!bounds) {
bounds = @[@40, @30, @0, @0];
}
2013-08-13 21:39:22 +08:00
2019-01-21 22:17:07 +08:00
return CGRectMake([bounds[0] floatValue],
[bounds[1] floatValue],
[bounds[2] floatValue],
[bounds[3] floatValue]);
}
2019-01-21 22:17:07 +08:00
/**
* Test if the given string is null or empty.
*
* @param string The string to test.
*
* @return true or false
*/
- (BOOL) strIsNullOrEmpty:(NSString *)string
{
return [string isEqual:[NSNull null]] || string.length == 0;
}
/**
2019-01-21 22:17:07 +08:00
* Calls the callback funtion with the result of the selected printer.
*
2019-01-21 22:17:07 +08:00
* @param ctrl The controller used to display the printer selector interface.
* @param callbackId The ID of the callback that shall receive the info.
*
* @return [ Void ]
*/
2019-01-21 22:17:07 +08:00
- (void) returnPickerResultForController:(UIPrinterPickerController *)ctrl
callbackId:(NSString *)callbackId
{
2019-01-21 22:17:07 +08:00
UIPrinter* printer = ctrl.selectedPrinter;
CDVPluginResult* result;
[self rememberPrinter:printer];
if (printer) {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsString:printer.URL.absoluteString];
} else {
result = [CDVPluginResult resultWithStatus:CDVCommandStatus_NO_RESULT];
}
[self.commandDelegate sendPluginResult:result
callbackId:callbackId];
2013-08-13 21:39:22 +08:00
}
2014-10-14 05:31:12 +08:00
/**
2019-01-21 22:17:07 +08:00
* Sends the plugin result by invoking the callback function with a boolean arg.
2014-10-14 05:31:12 +08:00
*
2019-01-21 22:17:07 +08:00
* @param msg The boolean message value.
2014-10-14 05:31:12 +08:00
*
2019-01-21 22:17:07 +08:00
* @return [ Void ]
2014-10-14 05:31:12 +08:00
*/
2019-01-21 22:17:07 +08:00
- (void) sendResultWithMessageAsBool:(BOOL)msg
callbackId:(NSString *)callbackId
2014-10-14 05:31:12 +08:00
{
2019-01-21 22:17:07 +08:00
CDVPluginResult* result =
[CDVPluginResult resultWithStatus:CDVCommandStatus_OK
messageAsBool:msg];
[self.commandDelegate sendPluginResult:result
callbackId:callbackId];
2014-10-14 05:31:12 +08:00
}
@end