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