// // UIViewController+QR.m // Unity-iPhone // // Created by zhl on 2022/11/28. // #import "UIViewController+QR.h" #import "QRCodeReaderViewController.h" #import "QRCodeReader.h" #import "QRCodeReaderDelegate.h" #include "permission/LBXPermission.h" #include "permission/LBXPermissionSetting.h" #include "LBXScanNative.h" #include "LBXScanTypes.h" #include "QrCodeViewController.h" #include #import "NSString+Customer.h" #include "JcWallet.h" @interface UIViewController (QR) @end @implementation UIViewController (QR) -(void)showQRCode:(NSString *) content title:(NSString *) title oid:(NSString *) oid { NSLog(@"showQRCode content: %@, title: %@, oid: %@", content, title, oid); dispatch_async(dispatch_get_main_queue(), ^{ QrCodeViewController *vc = [QrCodeViewController new]; vc.content = content; vc.tipTitle = title; vc.autosave = TRUE; NSString *tipTxt = @"This QR code is only used to export account recovery private key.\n \ \n \ 1. Use CEBG client to scan the QR code to get the account recovery private key. \n\ \n \ 2. Account of ios cannot login to Andorid device. \n \ \n \ 3. Please keep your private key as safe as possible."; vc.tipTxt = tipTxt; [self presentViewController:vc animated:YES completion:nil]; }); } -(void)loadRestoreKey:(NSString *)funid oid:(NSString *) oid{ NSLog(@"loadRestoreKey::funid: %@, oid:%@", funid, oid); dispatch_async(dispatch_get_main_queue(), ^{ UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Tips" message:@"In order to restore recovery key, please Scan QRCode or Pick from Photo Library." preferredStyle:UIAlertControllerStyleActionSheet]; UIAlertAction *actionCancel = [UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleCancel handler: ^(UIAlertAction *action){ [self nativeCb:funid hasErr:YES dataStr: @"user cancel"]; }]; UIAlertAction *scanAction = [UIAlertAction actionWithTitle:@"Scan" style:UIAlertActionStyleDefault handler: ^(UIAlertAction *action){ [self scanQRCode:funid title: @"" restore:YES ]; }]; UIAlertAction *photoAction = [UIAlertAction actionWithTitle:@"Photo" style:UIAlertActionStyleDefault handler: ^(UIAlertAction *action){ [self openLocalPhotoAlbum: funid]; }]; [alertController addAction:actionCancel]; [alertController addAction:scanAction]; [alertController addAction:photoAction]; [self presentViewController:alertController animated:YES completion:nil]; }); } -(void)beginScanQRCode:(NSString *)funid title:(NSString *) title{ std::string sfunid = std::string([funid UTF8String], [funid lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); __weak __typeof(self) weakSelf = self; if ([QRCodeReader supportsMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]) { static QRCodeReaderViewController *vc = nil; static dispatch_once_t onceToken; dispatch_async(dispatch_get_main_queue(), ^{ // if we are active again, we don't need to do this anymore if (vc == nil) { QRCodeReader *reader = [QRCodeReader readerWithMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; vc = [QRCodeReaderViewController readerWithCancelButtonTitle:@"Cancel" codeReader:reader startScanningAtLoad:YES showSwitchCameraButton:YES showTorchButton:YES]; vc.modalPresentationStyle = UIModalPresentationFormSheet; } [vc setCompletionWithBlock:^(NSString *resultAsString) { NSLog(@"Completion with result: %@", resultAsString); [self dismissViewControllerAnimated:YES completion:^{ NSString *result; if (resultAsString.length > 0) { [self nativeCb:funid hasErr:NO dataStr: resultAsString]; } else { NSLog(@"user cancel scan"); [weakSelf loadRestoreKey:funid oid:@""]; } }]; }]; [self presentViewController:vc animated:YES completion:NULL]; }); } } -(void)scanQRCode:(NSString *)funid title:(NSString *) title{ [self scanQRCode:funid title:title restore:false]; } -(void)scanQRCode:(NSString *)funid title:(NSString *) title restore: (BOOL) restore{ NSLog(@"scanQRCode:: funId: %@ title: %@", funid, title); __weak __typeof(self) weakSelf = self; [LBXPermission authorizeWithType:LBXPermissionType_Camera completion:^(BOOL granted, BOOL firstTime) { if (granted) { [weakSelf beginScanQRCode:funid title:title]; } else if(!firstTime) { [LBXPermissionSetting showAlertToDislayPrivacySettingWithTitle:@"Error" msg:@"The camera is need to scan QR codes" cancel:@"Cancel" setting:@"Setting" completion:^{ if (restore) { [weakSelf loadRestoreKey:funid oid:@""]; } else { [weakSelf nativeCb:funid hasErr:YES dataStr: @"no permission, need resend"]; } }]; } }]; } #pragma mark- - PhotoAlbum - (void)openLocalPhotoAlbum:(NSString *)funid { __weak __typeof(self) weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [LBXPermission authorizeWithType:LBXPermissionType_Photos completion:^(BOOL granted, BOOL firstTime) { if (granted) { [weakSelf openLocalPhoto:funid]; } else if (!firstTime ) { [LBXPermissionSetting showAlertToDislayPrivacySettingWithTitle:@"Error" msg:@"The Photo Library is need to restore recovery key." cancel:@"Cancel" setting:@"Setting" completion:^{ [weakSelf loadRestoreKey:funid oid:@""]; }]; } }]; }); } /*! * open local Photo Library */ - (void)openLocalPhoto:(NSString *)funid { UIImagePickerController *picker = [[UIImagePickerController alloc] init]; picker.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; picker.delegate = self; // crash on some mobile picker.allowsEditing = NO; picker.title = funid; [self presentViewController:picker animated:YES completion:nil]; } #pragma mark- - UIImagePickerControllerDelegate -(void)imagePickerController:(UIImagePickerController*)picker didFinishPickingMediaWithInfo:(NSDictionary *)info{ [picker dismissViewControllerAnimated:YES completion:^{ NSString *funid = picker.title; [self handPhotoDidFinishPickingMediaWithInfo:funid info:info]; }]; } -(void)imagePickerControllerDidCancel:(UIImagePickerController*)picker { [picker dismissViewControllerAnimated:YES completion:^{ NSLog(@"imagePickerControllerDidCancel %@", picker.title); [self loadRestoreKey: picker.title oid: @"" ]; }]; } - (void)handPhotoDidFinishPickingMediaWithInfo:(NSString *)funid info:(NSDictionary *)info { __block UIImage* image = [info objectForKey:UIImagePickerControllerEditedImage]; if (!image){ image = [info objectForKey:UIImagePickerControllerOriginalImage]; } if (@available(iOS 8.0, *)) { __weak __typeof(self) weakSelf = self; [LBXScanNative recognizeImage:image success:^(NSArray *array) { [weakSelf scanResultWithArray:funid array:array]; }]; }else{ [self nativeCb:funid hasErr:YES dataStr: @"os version is lower then IOS8.0"]; } } - (void)scanResultWithArray:(NSString *)funid array:(NSArray*)array { if (!array || array.count < 1) { [self nativeCb:funid hasErr:YES dataStr: @"error scan photo"]; return; } if (!array[0].strScanned || [array[0].strScanned isEqualToString:@""] ) { [self nativeCb:funid hasErr:YES dataStr: @"failed decoding QR code"]; return; } LBXScanResult *scanResult = array[0]; [self nativeCb:funid hasErr:NO dataStr: scanResult.strScanned]; } -(void)nativeCb:(NSString *)funid hasErr: (BOOL) hasErr dataStr:(NSString *) dataStr { if ([NSString isStringEmpty:funid]) { NSLog(@"nativeCallBack with empty funid: %@", funid); return; } std::string methodName = "nativeCallBack"; NSString *paramStr; if (hasErr) { paramStr = [NSString stringWithFormat:@"{\"errcode\": 1, \"errmessage\": \"%@\"}", dataStr]; } else { paramStr = [NSString stringWithFormat:@"{\"errcode\": 0, \"data\": \"%@\"}", dataStr]; } std::string sfunid = std::string([funid UTF8String], [funid lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); std::string sparam = std::string([paramStr UTF8String], [paramStr lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); cocos2d::nativeCallBack(sfunid.c_str(), methodName.c_str(), sparam.c_str()); } @end