1// Copyright 2016-present 650 Industries. All rights reserved. 2 3#import <UIKit/UIKit.h> 4#import <AVFoundation/AVFoundation.h> 5#import <ZXingObjC/ZXingObjCCore.h> 6#import <EXBarCodeScanner/EXBarCodeScannerUtils.h> 7 8@implementation EXBarCodeScannerUtils 9 10+ (NSDictionary *)validBarCodeTypes 11{ 12 NSMutableDictionary *validTypes = [@{ 13 @"upc_e" : AVMetadataObjectTypeUPCECode, 14 @"code39" : AVMetadataObjectTypeCode39Code, 15 @"code39mod43" : AVMetadataObjectTypeCode39Mod43Code, 16 @"ean13" : AVMetadataObjectTypeEAN13Code, 17 @"ean8" : AVMetadataObjectTypeEAN8Code, 18 @"code93" : AVMetadataObjectTypeCode93Code, 19 @"code128" : AVMetadataObjectTypeCode128Code, 20 @"pdf417" : AVMetadataObjectTypePDF417Code, 21 @"qr" : AVMetadataObjectTypeQRCode, 22 @"aztec" : AVMetadataObjectTypeAztecCode, 23 @"interleaved2of5" : AVMetadataObjectTypeInterleaved2of5Code, 24 @"itf14" : AVMetadataObjectTypeITF14Code, 25 @"datamatrix" : AVMetadataObjectTypeDataMatrixCode, 26 } mutableCopy]; 27#ifdef __IPHONE_15_4 28 if (@available(iOS 15.4, *)) { 29 validTypes[@"codabar"] = AVMetadataObjectTypeCodabarCode; 30 } 31#endif 32 return validTypes; 33} 34 35+ (AVCaptureVideoOrientation)videoOrientationForInterfaceOrientation:(UIInterfaceOrientation)orientation 36{ 37 switch (orientation) { 38 case UIInterfaceOrientationPortrait: 39 return AVCaptureVideoOrientationPortrait; 40 case UIInterfaceOrientationPortraitUpsideDown: 41 return AVCaptureVideoOrientationPortraitUpsideDown; 42 case UIInterfaceOrientationLandscapeRight: 43 return AVCaptureVideoOrientationLandscapeRight; 44 case UIInterfaceOrientationLandscapeLeft: 45 return AVCaptureVideoOrientationLandscapeLeft; 46 default: 47 return 0; 48 } 49} 50 51+ (AVCaptureDevice *)deviceWithMediaType:(AVMediaType)mediaType 52 preferringPosition:(AVCaptureDevicePosition)position 53{ 54 return [AVCaptureDevice defaultDeviceWithDeviceType:AVCaptureDeviceTypeBuiltInWideAngleCamera mediaType:mediaType position:position]; 55} 56 57+ (NSDictionary *)ciQRCodeFeatureToDicitionary:(CIQRCodeFeature *)barCodeScannerResult barCodeType:(NSString *)type 58{ 59 NSMutableDictionary *result = [NSMutableDictionary new]; 60 result[@"type"] = type; 61 result[@"data"] = barCodeScannerResult.messageString; 62 63 if (!CGRectIsEmpty(barCodeScannerResult.bounds)) { 64 NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new]; 65 for (NSValue *nsPoint in @[ 66 [NSValue valueWithCGPoint:barCodeScannerResult.topLeft], 67 [NSValue valueWithCGPoint:barCodeScannerResult.topRight], 68 [NSValue valueWithCGPoint:barCodeScannerResult.bottomRight], 69 [NSValue valueWithCGPoint:barCodeScannerResult.bottomLeft] 70 ]) { 71 CGPoint point = [nsPoint CGPointValue]; 72 [cornerPointsResult addObject:@{ 73 @"x": @(point.x), 74 @"y": @(point.y) 75 }]; 76 } 77 78 result[@"cornerPoints"] = cornerPointsResult; 79 result[@"bounds"] = @{ 80 @"origin": @{ 81 @"x": @(barCodeScannerResult.bounds.origin.x), 82 @"y": @(barCodeScannerResult.bounds.origin.y), 83 }, 84 @"size": @{ 85 @"width": @(barCodeScannerResult.bounds.size.width), 86 @"height": @(barCodeScannerResult.bounds.size.height), 87 } 88 }; 89 } else { 90 [EXBarCodeScannerUtils addEmptyCornerPoints:result]; 91 } 92 93 return result; 94} 95 96+ (NSDictionary *)avMetadataCodeObjectToDicitionary:(AVMetadataMachineReadableCodeObject *)barCodeScannerResult 97{ 98 NSMutableDictionary *result = [NSMutableDictionary new]; 99 result[@"type"] = barCodeScannerResult.type; 100 result[@"data"] = barCodeScannerResult.stringValue; 101 102 if (barCodeScannerResult.corners.count) { 103 NSMutableArray<NSDictionary *> *cornerPointsResult = [NSMutableArray new]; 104 for (NSDictionary *point in barCodeScannerResult.corners) { 105 [cornerPointsResult addObject:@{ 106 @"x": point[@"X"], 107 @"y": point[@"Y"] 108 }]; 109 } 110 result[@"cornerPoints"] = cornerPointsResult; 111 result[@"bounds"] = @{ 112 @"origin": @{ 113 @"x": @(barCodeScannerResult.bounds.origin.x), 114 @"y": @(barCodeScannerResult.bounds.origin.y), 115 }, 116 @"size": @{ 117 @"width": @(barCodeScannerResult.bounds.size.width), 118 @"height": @(barCodeScannerResult.bounds.size.height), 119 } 120 }; 121 } else { 122 [EXBarCodeScannerUtils addEmptyCornerPoints:result]; 123 } 124 return result; 125} 126 127+ (NSDictionary *)zxResultToDicitionary:(ZXResult *)barCodeScannerResult 128{ 129 NSMutableDictionary *result = [NSMutableDictionary new]; 130 result[@"type"] = [EXBarCodeScannerUtils zxingFormatToString:barCodeScannerResult.barcodeFormat]; 131 132 // text contains characteres u'\0' (null character) that malforme resulting string, so we get rid of them 133 NSMutableString* data = [NSMutableString new]; 134 for (int i = 0; i < [barCodeScannerResult.text length]; i++) { 135 if ([barCodeScannerResult.text characterAtIndex:i] != u'\0') { 136 [data appendFormat:@"%c", [barCodeScannerResult.text characterAtIndex:i]]; 137 } 138 } 139 result[@"data"] = data; 140 141 return result; 142} 143 144+ (NSString *)zxingFormatToString:(ZXBarcodeFormat)format 145{ 146 switch (format) { 147 case kBarcodeFormatPDF417: 148 return AVMetadataObjectTypePDF417Code; 149 case kBarcodeFormatCode39: 150 return AVMetadataObjectTypeCode39Code; 151 case kBarcodeFormatCodabar: 152#ifdef __IPHONE_15_4 153 if (@available(iOS 15.4, *)) { 154 return AVMetadataObjectTypeCodabarCode; 155 } 156#endif 157 return @"unknown"; 158 default: 159 return @"unknown"; 160 } 161} 162 163+ (void)addEmptyCornerPoints:(NSMutableDictionary *)result 164{ 165 result[@"cornerPoints"] = @[]; 166 result[@"bounds"] = @{ 167 @"origin": @{ 168 @"x": @(0), 169 @"y": @(0), 170 }, 171 @"size": @{ 172 @"width": @(0), 173 @"height": @(0), 174 } 175 }; 176} 177 178@end 179