@munchi_oy/react-native-label-printer 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ios/BrotherPrinterModule.mm +283 -67
- package/package.json +1 -1
|
@@ -164,48 +164,160 @@ RCT_REMAP_METHOD(checkPrinterAtIp,
|
|
|
164
164
|
resolver:(RCTPromiseResolveBlock)resolve
|
|
165
165
|
rejecter:(RCTPromiseRejectBlock)reject)
|
|
166
166
|
{
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
167
|
+
dispatch_async([self labelPrintQueue], ^{
|
|
168
|
+
@try {
|
|
169
|
+
NSInteger maxAttempts = 4;
|
|
170
|
+
NSTimeInterval retryDelay = 1.0;
|
|
171
|
+
NSMutableArray *attemptLogs = [NSMutableArray array];
|
|
172
|
+
NSMutableDictionary *lastFailure = nil;
|
|
175
173
|
|
|
176
|
-
|
|
174
|
+
for (NSInteger attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
175
|
+
id driver = nil;
|
|
177
176
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
177
|
+
@try {
|
|
178
|
+
BRLMChannel *channel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
|
|
179
|
+
if (channel == nil) {
|
|
180
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
181
|
+
stage:@"channel_create"
|
|
182
|
+
reason:@"Failed to create BRLMChannel from IP"];
|
|
183
|
+
[attemptLogs addObject:lastFailure];
|
|
184
|
+
|
|
185
|
+
if (attempt < maxAttempts) {
|
|
186
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
187
|
+
}
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
BRLMPrinterDriverGenerateResult *openResult = [BRLMPrinterDriverGenerator openChannel:channel];
|
|
192
|
+
|
|
193
|
+
NSInteger openChannelCode = 0;
|
|
194
|
+
NSString *openChannelError = @"";
|
|
195
|
+
if (openResult != nil && openResult.error != nil) {
|
|
196
|
+
openChannelCode = openResult.error.code;
|
|
197
|
+
openChannelError = [openResult.error description] ?: @"";
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
if (openResult == nil || openResult.driver == nil) {
|
|
201
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
202
|
+
stage:@"open_channel"
|
|
203
|
+
reason:@"Failed to open printer driver from channel"
|
|
204
|
+
extras:@{
|
|
205
|
+
@"openChannelCode": @(openChannelCode),
|
|
206
|
+
@"openChannelError": openChannelError
|
|
207
|
+
}];
|
|
208
|
+
[attemptLogs addObject:lastFailure];
|
|
209
|
+
|
|
210
|
+
// warm-up open/close, same idea as print flow
|
|
211
|
+
if (attempt < maxAttempts) {
|
|
212
|
+
@try {
|
|
213
|
+
BRLMChannel *warmupChannel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
|
|
214
|
+
if (warmupChannel != nil) {
|
|
215
|
+
BRLMPrinterDriverGenerateResult *warmupResult =
|
|
216
|
+
[BRLMPrinterDriverGenerator openChannel:warmupChannel];
|
|
217
|
+
|
|
218
|
+
if (warmupResult != nil && warmupResult.driver != nil) {
|
|
219
|
+
if ([warmupResult.driver respondsToSelector:@selector(closeChannel)]) {
|
|
220
|
+
[warmupResult.driver closeChannel];
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
} @catch (NSException *warmupException) {
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
228
|
+
}
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
driver = openResult.driver;
|
|
233
|
+
|
|
234
|
+
// settle time after reconnect/open
|
|
235
|
+
[NSThread sleepForTimeInterval:0.8];
|
|
236
|
+
|
|
237
|
+
BRLMGetPrinterStatusResult *statusResult = nil;
|
|
238
|
+
BOOL printerReady = NO;
|
|
239
|
+
|
|
240
|
+
for (NSInteger statusTry = 1; statusTry <= 3; statusTry++) {
|
|
241
|
+
statusResult = [driver getPrinterStatus];
|
|
242
|
+
|
|
243
|
+
if (statusResult != nil && statusResult.status != nil) {
|
|
244
|
+
printerReady = YES;
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
if (statusTry < 3) {
|
|
249
|
+
[NSThread sleepForTimeInterval:0.7];
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
if (!printerReady) {
|
|
254
|
+
if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
|
|
255
|
+
[driver closeChannel];
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
259
|
+
stage:@"get_status"
|
|
260
|
+
reason:@"Failed to get printer status after reconnect"
|
|
261
|
+
extras:@{
|
|
262
|
+
@"statusAvailable": @(statusResult != nil),
|
|
263
|
+
@"statusObjectAvailable": @((statusResult != nil && statusResult.status != nil))
|
|
264
|
+
}];
|
|
265
|
+
[attemptLogs addObject:lastFailure];
|
|
266
|
+
|
|
267
|
+
if (attempt < maxAttempts) {
|
|
268
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
269
|
+
}
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
NSDictionary *success = @{
|
|
274
|
+
@"ok": @YES,
|
|
275
|
+
@"inputIp": ipAddress ?: @"",
|
|
276
|
+
@"stage": @"open_channel_success",
|
|
277
|
+
@"attempt": @(attempt),
|
|
278
|
+
@"attemptLogs": attemptLogs
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
|
|
282
|
+
[driver closeChannel];
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
resolve(success);
|
|
286
|
+
return;
|
|
184
287
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
288
|
+
} @catch (NSException *innerException) {
|
|
289
|
+
if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
|
|
290
|
+
[driver closeChannel];
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
294
|
+
stage:@"exception"
|
|
295
|
+
reason:innerException.reason ?: @"Unknown native exception"];
|
|
296
|
+
[attemptLogs addObject:lastFailure];
|
|
297
|
+
|
|
298
|
+
if (attempt < maxAttempts) {
|
|
299
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
NSMutableDictionary *result = [self errorWithStage:@"retry_exhausted"
|
|
305
|
+
reason:@"Printer connection test failed after all recovery attempts"];
|
|
189
306
|
result[@"inputIp"] = ipAddress ?: @"";
|
|
307
|
+
result[@"attemptLogs"] = attemptLogs;
|
|
308
|
+
|
|
309
|
+
if (lastFailure != nil) {
|
|
310
|
+
result[@"lastFailureStage"] = lastFailure[@"stage"] ?: @"unknown";
|
|
311
|
+
result[@"lastFailureReason"] = lastFailure[@"reason"] ?: @"Unknown error";
|
|
312
|
+
result[@"lastFailureDetails"] = lastFailure;
|
|
313
|
+
}
|
|
314
|
+
|
|
190
315
|
resolve(result);
|
|
191
|
-
return;
|
|
192
|
-
}
|
|
193
316
|
|
|
194
|
-
|
|
195
|
-
|
|
317
|
+
} @catch (NSException *exception) {
|
|
318
|
+
reject(@"CHECK_PRINTER_IP_ERROR", exception.reason, nil);
|
|
196
319
|
}
|
|
197
|
-
|
|
198
|
-
resolve(@{
|
|
199
|
-
@"ok": @YES,
|
|
200
|
-
@"inputIp": ipAddress ?: @"",
|
|
201
|
-
@"stage": @"open_channel_success",
|
|
202
|
-
@"channelInfo": channel.channelInfo ?: @"",
|
|
203
|
-
@"extraInfo": channel.extraInfo ?: @{},
|
|
204
|
-
@"driverClass": NSStringFromClass([openResult.driver class])
|
|
205
|
-
});
|
|
206
|
-
} @catch (NSException *exception) {
|
|
207
|
-
reject(@"CHECK_PRINTER_IP_ERROR", exception.reason, nil);
|
|
208
|
-
}
|
|
320
|
+
});
|
|
209
321
|
}
|
|
210
322
|
|
|
211
323
|
RCT_REMAP_METHOD(printLabel,
|
|
@@ -246,10 +358,11 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
246
358
|
CGFloat titlePointSize = [fontSizes[@"title"] doubleValue];
|
|
247
359
|
CGFloat bodyPointSize = [fontSizes[@"body"] doubleValue];
|
|
248
360
|
|
|
249
|
-
NSInteger maxAttempts =
|
|
250
|
-
NSTimeInterval retryDelay = 0
|
|
361
|
+
NSInteger maxAttempts = 4;
|
|
362
|
+
NSTimeInterval retryDelay = 1.0;
|
|
251
363
|
NSMutableArray *attemptLogs = [NSMutableArray array];
|
|
252
364
|
NSDictionary *finalSuccessResult = nil;
|
|
365
|
+
NSMutableDictionary *lastFailure = nil;
|
|
253
366
|
|
|
254
367
|
for (NSInteger attempt = 1; attempt <= maxAttempts; attempt++) {
|
|
255
368
|
BRLMChannel *channel = nil;
|
|
@@ -258,44 +371,123 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
258
371
|
@try {
|
|
259
372
|
channel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
|
|
260
373
|
if (channel == nil) {
|
|
261
|
-
|
|
262
|
-
|
|
374
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
375
|
+
stage:@"channel_create"
|
|
376
|
+
reason:@"Failed to create channel"];
|
|
377
|
+
[attemptLogs addObject:lastFailure];
|
|
378
|
+
|
|
379
|
+
if (attempt < maxAttempts) {
|
|
380
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
381
|
+
}
|
|
263
382
|
continue;
|
|
264
383
|
}
|
|
265
384
|
|
|
266
385
|
BRLMPrinterDriverGenerateResult *openResult = [BRLMPrinterDriverGenerator openChannel:channel];
|
|
267
386
|
|
|
387
|
+
NSInteger openChannelCode = 0;
|
|
388
|
+
NSString *openChannelError = @"";
|
|
389
|
+
if (openResult != nil && openResult.error != nil) {
|
|
390
|
+
openChannelCode = openResult.error.code;
|
|
391
|
+
openChannelError = [openResult.error description] ?: @"";
|
|
392
|
+
}
|
|
393
|
+
|
|
268
394
|
if (openResult == nil || openResult.driver == nil) {
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
395
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
396
|
+
stage:@"open_channel"
|
|
397
|
+
reason:@"Failed to open driver"
|
|
398
|
+
extras:@{
|
|
399
|
+
@"openChannelCode": @(openChannelCode),
|
|
400
|
+
@"openChannelError": openChannelError
|
|
401
|
+
}];
|
|
402
|
+
[attemptLogs addObject:lastFailure];
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
if (attempt < maxAttempts) {
|
|
406
|
+
@try {
|
|
407
|
+
BRLMChannel *warmupChannel = [[BRLMChannel alloc] initWithWifiIPAddress:ipAddress];
|
|
408
|
+
if (warmupChannel != nil) {
|
|
409
|
+
BRLMPrinterDriverGenerateResult *warmupResult = [BRLMPrinterDriverGenerator openChannel:warmupChannel];
|
|
410
|
+
if (warmupResult != nil && warmupResult.driver != nil) {
|
|
411
|
+
if ([warmupResult.driver respondsToSelector:@selector(closeChannel)]) {
|
|
412
|
+
[warmupResult.driver closeChannel];
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
} @catch (NSException *warmupException) {
|
|
417
|
+
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
421
|
+
}
|
|
274
422
|
continue;
|
|
275
423
|
}
|
|
276
424
|
|
|
277
425
|
driver = openResult.driver;
|
|
278
426
|
|
|
279
|
-
|
|
427
|
+
|
|
428
|
+
[NSThread sleepForTimeInterval:0.8];
|
|
429
|
+
|
|
280
430
|
BRLMQLPrintSettings *settings = [[BRLMQLPrintSettings alloc] initDefaultPrintSettingsWithPrinterModel:BRLMPrinterModelQL_810W];
|
|
281
431
|
|
|
282
432
|
if (settings == nil) {
|
|
283
433
|
if ([driver respondsToSelector:@selector(closeChannel)]) {
|
|
284
434
|
[driver closeChannel];
|
|
285
435
|
}
|
|
286
|
-
|
|
287
|
-
|
|
436
|
+
|
|
437
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
438
|
+
stage:@"settings_create"
|
|
439
|
+
reason:@"Failed to create QL print settings"];
|
|
440
|
+
[attemptLogs addObject:lastFailure];
|
|
441
|
+
|
|
442
|
+
if (attempt < maxAttempts) {
|
|
443
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
444
|
+
}
|
|
288
445
|
continue;
|
|
289
446
|
}
|
|
290
447
|
|
|
291
|
-
BRLMGetPrinterStatusResult *statusResult =
|
|
292
|
-
BRLMMediaInfo *mediaInfo =
|
|
448
|
+
BRLMGetPrinterStatusResult *statusResult = nil;
|
|
449
|
+
BRLMMediaInfo *mediaInfo = nil;
|
|
450
|
+
BOOL printerReady = NO;
|
|
293
451
|
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
452
|
+
for (NSInteger statusTry = 1; statusTry <= 3; statusTry++) {
|
|
453
|
+
statusResult = [driver getPrinterStatus];
|
|
454
|
+
|
|
455
|
+
if (statusResult != nil && statusResult.status != nil) {
|
|
456
|
+
mediaInfo = statusResult.status.mediaInfo;
|
|
457
|
+
if (mediaInfo != nil) {
|
|
458
|
+
printerReady = YES;
|
|
459
|
+
break;
|
|
460
|
+
}
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
if (statusTry < 3) {
|
|
464
|
+
[NSThread sleepForTimeInterval:0.7];
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
|
|
468
|
+
if (!printerReady) {
|
|
469
|
+
if ([driver respondsToSelector:@selector(closeChannel)]) {
|
|
470
|
+
[driver closeChannel];
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
474
|
+
stage:@"get_status"
|
|
475
|
+
reason:@"Printer status/media not ready after reconnect"
|
|
476
|
+
extras:@{
|
|
477
|
+
@"statusAvailable": @(statusResult != nil),
|
|
478
|
+
@"statusObjectAvailable": @((statusResult != nil && statusResult.status != nil))
|
|
479
|
+
}];
|
|
480
|
+
[attemptLogs addObject:lastFailure];
|
|
481
|
+
|
|
482
|
+
if (attempt < maxAttempts) {
|
|
483
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
484
|
+
}
|
|
485
|
+
continue;
|
|
297
486
|
}
|
|
298
487
|
|
|
488
|
+
bool succeeded = false;
|
|
489
|
+
settings.labelSize = [mediaInfo getQLLabelSize:&succeeded];
|
|
490
|
+
|
|
299
491
|
NSDictionary *mediaExtras = @{
|
|
300
492
|
@"mediaType": mediaInfo ? @(mediaInfo.mediaType) : [NSNull null],
|
|
301
493
|
@"width_mm": mediaInfo ? @(mediaInfo.width_mm) : [NSNull null],
|
|
@@ -307,11 +499,16 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
307
499
|
if ([driver respondsToSelector:@selector(closeChannel)]) {
|
|
308
500
|
[driver closeChannel];
|
|
309
501
|
}
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
502
|
+
|
|
503
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
504
|
+
stage:@"media_to_label_size"
|
|
505
|
+
reason:@"Failed to determine QL label size from loaded media"
|
|
506
|
+
extras:mediaExtras];
|
|
507
|
+
[attemptLogs addObject:lastFailure];
|
|
508
|
+
|
|
509
|
+
if (attempt < maxAttempts) {
|
|
510
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
511
|
+
}
|
|
315
512
|
continue;
|
|
316
513
|
}
|
|
317
514
|
|
|
@@ -391,12 +588,18 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
391
588
|
|
|
392
589
|
if (printError != nil && printError.code != BRLMPrintErrorCodeNoError) {
|
|
393
590
|
NSMutableDictionary *printExtras = [mediaExtras mutableCopy];
|
|
591
|
+
printExtras[@"printErrorCode"] = @(printError.code);
|
|
394
592
|
printExtras[@"printError"] = [printError description] ?: @"";
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
593
|
+
|
|
594
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
595
|
+
stage:@"print"
|
|
596
|
+
reason:@"Printer returned print error"
|
|
597
|
+
extras:printExtras];
|
|
598
|
+
[attemptLogs addObject:lastFailure];
|
|
599
|
+
|
|
600
|
+
if (attempt < maxAttempts) {
|
|
601
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
602
|
+
}
|
|
400
603
|
continue;
|
|
401
604
|
}
|
|
402
605
|
|
|
@@ -424,10 +627,15 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
424
627
|
if (driver && [driver respondsToSelector:@selector(closeChannel)]) {
|
|
425
628
|
[driver closeChannel];
|
|
426
629
|
}
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
630
|
+
|
|
631
|
+
lastFailure = [self attemptErrorWithAttempt:attempt
|
|
632
|
+
stage:@"exception"
|
|
633
|
+
reason:innerException.reason ?: @"Unknown native exception"];
|
|
634
|
+
[attemptLogs addObject:lastFailure];
|
|
635
|
+
|
|
636
|
+
if (attempt < maxAttempts) {
|
|
637
|
+
[NSThread sleepForTimeInterval:retryDelay];
|
|
638
|
+
}
|
|
431
639
|
}
|
|
432
640
|
}
|
|
433
641
|
|
|
@@ -436,13 +644,21 @@ RCT_REMAP_METHOD(printLabel,
|
|
|
436
644
|
return;
|
|
437
645
|
}
|
|
438
646
|
|
|
439
|
-
NSMutableDictionary *exhaustedResult = [self errorWithStage:@"retry_exhausted"
|
|
647
|
+
NSMutableDictionary *exhaustedResult = [self errorWithStage:@"retry_exhausted"
|
|
648
|
+
reason:@"Print failed after all recovery attempts"];
|
|
440
649
|
exhaustedResult[@"attemptLogs"] = attemptLogs;
|
|
441
650
|
exhaustedResult[@"fontSize"] = fontSizeValue ?: @"Medium";
|
|
442
651
|
exhaustedResult[@"fontStyle"] = fontStyleValue ?: @"Normal";
|
|
443
652
|
exhaustedResult[@"title"] = title ?: @"";
|
|
444
653
|
exhaustedResult[@"hideTitle"] = @(hideTitle);
|
|
445
654
|
exhaustedResult[@"copies"] = @(copies);
|
|
655
|
+
|
|
656
|
+
if (lastFailure != nil) {
|
|
657
|
+
exhaustedResult[@"lastFailureStage"] = lastFailure[@"stage"] ?: @"unknown";
|
|
658
|
+
exhaustedResult[@"lastFailureReason"] = lastFailure[@"reason"] ?: @"Unknown error";
|
|
659
|
+
exhaustedResult[@"lastFailureDetails"] = lastFailure;
|
|
660
|
+
}
|
|
661
|
+
|
|
446
662
|
resolve(exhaustedResult);
|
|
447
663
|
|
|
448
664
|
} @catch (NSException *exception) {
|