'How I can print with brother printer using react native

I am using iOS and I am trying to print an image or a file with the library react-native-brother-printers with this example https://github.com/Avery246813579/react-native-brother-printers/tree/master/example

I have the PT-P950NW model (thermal printer).

Does any one do that or have any idea to do that ?

This is my code in app.js

export default class App extends Component {
  state = {
    printer: "PT-P950NW",
    ip: "192.168.10.232",
  };


 render() {
    const {printer, ip} = this.state;

    return (
      <ScrollView style={{flex: 1}}>
        <ViewShot ref={(e) => {
          this.viewShot = e;
        }} options={{format: "jpg", quality: 0.9}}>

          <Text style={{fontSize: 24}}>
           // printer test
          </Text>
        </ViewShot>

        <View style={styles.container}>
          <Text>
            Test Connection
          </Text>

          <Button title="Discover Readers" onPress={() => {
            discoverPrinters().then(() => {
              console.log("Discover Readers Successful");
            }).catch(() => {
              console.log("Discover Readers failed")
            });
          }}/>

          {printer && (
            <Button title="Print from Memory" onPress={() => {
              this.viewShot.capture().then(uri => {
                console.log("do something with ", './icon.png');

                printImage(
                  {
                ipAddress: "192.168.10.232",
                modelName: "PT-P950NW"
                }, uri, {autoCut: false}).then(() => {
                  console.log("Discover Memory Successful");
                }).catch((err) => {
                  console.log(err);
                  console.log("Discover Memory failed");
                });
              });
            }}/>
          )}


          <Button title="Print from Manual" onPress={() => {
            this.viewShot.capture().then(uri => {
              console.log("do something with ", uri);

              printImage({
                ipAddress: "192.168.10.232",
                modelName: "PT-P950NW"
                }, uri, {autoCut: false}).then(() => {
                console.log("Discover Manual Successful");
              }).catch((err) => {
                  console.log(err);
                console.log("Discover Manual failed")
              });
            });
          }}/>

          <TextInput placeholder="Ip Address" value={ip} onChangeText={(ip) => this.setState({ip})}/>

          <Button title="Test Printer" onPress={() => {
            pingPrinter(ip).then(() => {
               //}).then(() => {
            // alert("We found the printer");
              console.log("We found the printer");
        console.log("Printer accessed");
            })catch((err) => {
                  console.log(err);
              console.log("Printer could not be accessed");

              console.log("Printer is dead", err);
            });
          }}/>
        </View>
      </ScrollView>
    );
  }
}

and the index.js of the library

// main index.js

import {NativeModules, NativeEventEmitter} from "react-native";

const {ReactNativeBrotherPrinters} = NativeModules;

const {
  discoverPrinters: _discoverPrinters,
  pingPrinter: _pingPrinter,
  printImage: _printImage,
  printPDF: _printPDF,
} = ReactNativeBrotherPrinters;

/**
 * Starts the discovery process for brother printers
 *
 * @param params
 * @param params.V6             If we should searching using IP v6.
 * @param params.printerName    If we should name the printer something specific.
 *
 * @return {Promise<void>}
 */
export async function discoverPrinters(params = {}) {
  return _discoverPrinters(params);
}

/**
 * Checks if a reader is discoverable
 *
 * @param ip
 *
 * @return {Promise<void>}
 */
export async function pingPrinter(ip) {
  return _pingPrinter(ip);
}

/**
 * Prints an image
 *
 * @param device                  Device object
 * @param uri                     URI of image wanting to be printed
 * @param params
 * @param params.autoCut          Boolean if the printer should auto cut the receipt/label
 *
 * @return {Promise<*>}
 */
export async function printImage(device, uri, params = {}) {
  return _printImage(device, uri, params);
}

// export async function printPDF(device, uri, params = {}) {
//   return _printPDF(device, uri, params);
// }

const listeners = new NativeEventEmitter(ReactNativeBrotherPrinters);

export function registerBrotherListener(key, method) {
  return listeners.addListener(key, method);
}

and this is the code in ReactNativeBrotherPrinters.m file in Objective-c.

// ReactNativeBrotherPrinters.m

#import "ReactNativeBrotherPrinters.h"
#import <React/RCTConvert.h>

@implementation ReactNativeBrotherPrinters

NSString *const DISCOVER_READERS_ERROR = @"DISCOVER_READERS_ERROR";
NSString *const DISCOVER_READER_ERROR = @"DISCOVER_READER_ERROR";
NSString *const PRINT_ERROR = @"PRINT_ERROR";

- (dispatch_queue_t)methodQueue
{
    return dispatch_get_main_queue();
}

RCT_EXPORT_MODULE()

-(void)startObserving {
    hasListeners = YES;
}

-(void)stopObserving {
    hasListeners = NO;
}

- (NSArray<NSString *> *)supportedEvents {
    return @[
        @"onBrotherLog",

        @"onDiscoverPrinters",
    ];
}

RCT_REMAP_METHOD(discoverPrinters, discoverOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSLog(@"Called the function");

    _brotherDeviceList = [[NSMutableArray alloc] initWithCapacity:0];

    _networkManager = [[BRPtouchNetworkManager alloc] init];
    _networkManager.delegate = self;

    NSString *path = [[NSBundle mainBundle] pathForResource:@"PrinterList" ofType:@"plist"];

    if (path) {
        NSDictionary *printerDict = [NSDictionary dictionaryWithContentsOfFile:path];
        NSArray *printerList = [[NSArray alloc] initWithArray:printerDict.allKeys];

        [_networkManager setPrinterNames:printerList];
    } else {
        NSLog(@"Could not find PrinterList.plist");
    }

    //    Start printer search
    int response = [_networkManager startSearch: 5.0];

    if (response == RET_TRUE) {
        resolve(Nil);
    } else {
        reject(DISCOVER_READERS_ERROR, @"A problem occured when trying to execute discoverPrinters", Nil);
    }
}

RCT_REMAP_METHOD(pingPrinter, printerAddress:(NSString *)ip resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    BRLMChannel *channel = [[BRLMChannel alloc] initWithWifiIPAddress:ip];

    BRLMPrinterDriverGenerateResult *driverGenerateResult = [BRLMPrinterDriverGenerator openChannel:channel];
    if (driverGenerateResult.error.code != BRLMOpenChannelErrorCodeNoError ||
        driverGenerateResult.driver == nil) {
        
        NSLog(@"%@", @(driverGenerateResult.error.code));
        
        return reject(DISCOVER_READER_ERROR, @"A problem occured when trying to execute discoverPrinters", Nil);
    }

    NSLog(@"We were able to discover a printer");
    
    resolve(Nil);
}

RCT_REMAP_METHOD(printImage, deviceInfo:(NSDictionary *)device printerUri: (NSString *)imageStr printImageOptions:(NSDictionary *)options resolver:(RCTPromiseResolveBlock)resolve rejecter:(RCTPromiseRejectBlock)reject)
{
    NSLog(@"Called the printImage function");
    BRPtouchDeviceInfo *deviceInfo = [self deserializeDeviceInfo:device];

    BRLMChannel *channel = [[BRLMChannel alloc] initWithWifiIPAddress:deviceInfo.strIPAddress];

    BRLMPrinterDriverGenerateResult *driverGenerateResult = [BRLMPrinterDriverGenerator openChannel:channel];
    if (driverGenerateResult.error.code != BRLMOpenChannelErrorCodeNoError ||
        driverGenerateResult.driver == nil) {
        NSLog(@"%@", @(driverGenerateResult.error.code));
        return;
    }

    NSString * paperSize = [self defaultPaperSize:deviceInfo.strModelName];
    NSLog(@"Paper Size: %@", paperSize);

    BRLMPrinterDriver *printerDriver = driverGenerateResult.driver;

    BRLMPrinterModel model = [BRLMPrinterClassifier transferEnumFromString:deviceInfo.strModelName];
    // BRLMQLPrintSettings *qlSettings = [[BRLMQLPrintSettings alloc] initDefaultPrintSettingsWithPrinterModel:model];
    BRLMPTPrintSettings *ptSettings = [[BRLMPTPrintSettings alloc] initDefaultPrintSettingsWithPrinterModel:model];

    // BRLMPTPrintSettings *ptSettings = [[BRLMPTPrintSettings alloc] initDefaultPrintSettingsWithPrinterModel:BRLMPrinterModelPT_P950NW];


    ptSettings.autoCut = true;
    
    NSLog(@"Cut Options %@", options[@"autoCut"]);
    if (options[@"autoCut"]) {
        ptSettings.autoCut = [options[@"autoCut"] boolValue];
    }

      NSURL *url = [NSURL URLWithString:imageStr];
    
  

    BRLMPrintError *printError = [printerDriver printImageWithURL:url settings:ptSettings];
    
    if (printError.code != BRLMPrintErrorCodeNoError) {
         NSLog(@"Error - Print Image: %@", printError); 
         // NSLog(@"Error - Print Image: %@", @(printError.code)); 
        
        NSError* error = [NSError errorWithDomain:@"com.react-native-brother-printers.rn" code:1 userInfo:[NSDictionary dictionaryWithObject:printError.description forKey:NSLocalizedDescriptionKey]];

        reject(PRINT_ERROR, @"There was an error trying to print the image", error);
    } else {
        NSLog(@"Success - Print Image");
        
        resolve(Nil);
    }

    [printerDriver closeChannel];
}

-(void)didFinishSearch:(id)sender
{
    NSLog(@"didFinishedSearch");

    //  get BRPtouchNetworkInfo Class list
    [_brotherDeviceList removeAllObjects];
    _brotherDeviceList = (NSMutableArray*)[_networkManager getPrinterNetInfo];

    NSLog(@"_brotherDeviceList [%@]",_brotherDeviceList);

    NSMutableArray *_serializedArray = [[NSMutableArray alloc] initWithCapacity:_brotherDeviceList.count];

    for (BRPtouchDeviceInfo *deviceInfo in _brotherDeviceList) {
        [_serializedArray addObject:[self serializeDeviceInfo:deviceInfo]];

        NSLog(@"Model: %@, IP Address: %@", deviceInfo.strModelName, deviceInfo.strIPAddress);
        // NSLog(@"IP Address: %@",deviceInfo.strIPAddress);

    }

    [self sendEventWithName:@"onDiscoverPrinters" body:_serializedArray];

    return;
}

- (NSString *)defaultPaperSize: (NSString *) printer
{
    NSString *result = nil;

    NSString *pathInPrintSettings   = [[NSBundle mainBundle] pathForResource:@"PrinterList" ofType:@"plist"];
    if (pathInPrintSettings) {
        NSDictionary *priterListArray = [NSDictionary dictionaryWithContentsOfFile:pathInPrintSettings];
        if (priterListArray) {
            result = [[[priterListArray objectForKey:printer] objectForKey:@"PaperSize"] objectAtIndex:0];
        }
    }
    return result;
}

- (NSDictionary *) serializeDeviceInfo:(BRPtouchDeviceInfo *)device {
    return @{
        @"ipAddress": device.strIPAddress,
        @"location": device.strLocation,
        @"modelName": device.strModelName,
        @"printerName": device.strPrinterName,
        @"serialNumber": device.strSerialNumber,
        @"nodeName": device.strNodeName,
        @"macAddress": device.strMACAddress,
    };
}

- (BRPtouchDeviceInfo *) deserializeDeviceInfo:(NSDictionary *)device {
    BRPtouchDeviceInfo *deviceInfo = [[BRPtouchDeviceInfo alloc] init];

//    return @{
//        @"ipAddress": device.strIPAddress,
//        @"location": device.strLocation,
//        @"modelName": device.strModelName,
//        @"printerName": device.strPrinterName,
//        @"serialNumber": device.strSerialNumber,
//        @"nodeName": device.strNodeName,
//        @"macAddress": device.strMACAddress,
//    };
//
//
    deviceInfo.strIPAddress = [RCTConvert NSString:device[@"ipAddress"]];
    deviceInfo.strLocation = [RCTConvert NSString:device[@"location"]];
    deviceInfo.strModelName = [RCTConvert NSString:device[@"modelName"]];
    deviceInfo.strPrinterName = [RCTConvert NSString:device[@"printerName"]];
    deviceInfo.strSerialNumber = [RCTConvert NSString:device[@"serialNumber"]];
    deviceInfo.strNodeName = [RCTConvert NSString:device[@"nodeName"]];
    deviceInfo.strMACAddress = [RCTConvert NSString:device[@"macAddress"]];

    NSLog(@"We got here");

    return deviceInfo;
}

@end

If a use the pingPrinter function and I put the ip of the printer I get : Discover Readers Successful LOG We found these listeners [{"ipAddress": "169.254.33.242", "location": "", "macAddress": "00:80:77:57:83:df", "modelName": "Brother PT-P950NW", "nodeName": "BRN0080775783DF", "printerName": "Brother PT-P950NW", "serialNumber": "E6Z987778"}]

But if a use PrintImage function I get : There was an error trying to print the image, this error is in Objective-c file ReactNativeBrotherPrinters.m (https://github.com/Avery246813579/react-native-brother-printers/blob/master/ios/ReactNativeBrotherPrinters.m) in this condition :

if (printError.code != BRLMPrintErrorCodeNoError) {
     NSLog(@"Error - Print Image: %@", printError); 
    
    NSError* error = [NSError errorWithDomain:@"com.react-native-brother-printers.rn" code:1 userInfo:[NSDictionary dictionaryWithObject:printError.description forKey:NSLocalizedDescriptionKey]];

    reject(PRINT_ERROR, @"There was an error trying to print the image", error);
} else {
    NSLog(@"Success - Print Image");
    
    resolve(Nil);
}

Also if try to change the url like that:

NSURL *url = [[NSBundle mainBundle] URLForResource:@"./Resources/icon" withExtension:@"png"];

I get this error message:

Error - Print Image: setLabelSizeError

and if add this line to specify the size like that:

ptSettings.labelSize = BRLMMWPrintSettingsPaperSizeA7;

I get also another error message: Error - Print Image: FilePathURLError

those error messages are in this log:

NSLog(@"Error - Print Image: %@", printError);

So what I should do to correct those errors ?

Thank you for your help.



Solution 1:[1]

Finally I get it, the library react-native-brother-printers work awesome.

Just this library is for the QL series, and if someone has another printer module he should edit the ReactNativeBrotherPrinters.m file.

Because in the Brother Print SDK Manual (https://support.brother.com/g/s/es/htmldoc/mobilesdk/guide/print-image.html), they offer an example for each series.

And if someone has an error message for example SetLabelSizeError he should return in the Manual and search the setting of his printer, in my case it is BRLMPTPrintSettingsLabelSize :(https://support.brother.com/g/s/es/htmldoc/mobilesdk/reference/ios_v4/brlmptprintsettings.html#labelsize).

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1