// // 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" #import "LBXPermission.h" #import "LBXPermissionSetting.h" #include "LBXScanNative.h" #include "LBXScanTypes.h" #include "QrCodeViewController.h" #include #import "NSString+Customer.h" #include "JcWallet.h" @interface UIViewController (QR) @end static QRCodeReaderViewController *qrcodeReaderVC = nil; @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]; [self scanQRCode:funid title: @"" restore:YES ]; }); } -(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 dispatch_once_t onceToken; dispatch_async(dispatch_get_main_queue(), ^{ // if we are active again, we don't need to do this anymore if (qrcodeReaderVC == nil) { QRCodeReader *reader = [QRCodeReader readerWithMetadataObjectTypes:@[AVMetadataObjectTypeQRCode]]; qrcodeReaderVC = [QRCodeReaderViewController readerWithCancelButtonTitle:@"Cancel" codeReader:reader startScanningAtLoad:YES showSwitchCameraButton:YES showTorchButton:YES]; qrcodeReaderVC.modalPresentationStyle = UIModalPresentationFormSheet; } [qrcodeReaderVC setCompletionWithBlock:^(NSString *resultAsString, NSError *error){ if (error != nil) { [self nativeCb:funid hasErr:YES dataStr: error.localizedDescription]; } else { NSLog(@"scan result: %@", resultAsString); [self nativeCb:funid hasErr:NO dataStr: resultAsString]; } }]; [self presentViewController:qrcodeReaderVC 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; [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