From 33f965c995e3cf7029fe6cf06cbdf8ab67865c75 Mon Sep 17 00:00:00 2001 From: wanghualei Date: Thu, 21 Apr 2022 10:52:28 +0800 Subject: [PATCH] =?UTF-8?q?add=20=E6=89=AB=E7=A0=81=E6=89=93=E5=BC=80?= =?UTF-8?q?=E5=B0=8F=E7=A8=8B=E5=BA=8F=E7=9A=84=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Podfile | 5 + demo.xcodeproj/project.pbxproj | 90 +++++-- demo/AppDelegate.m | 37 +-- demo/{ => Common}/FINCustomMenuModel.h | 0 demo/{ => Common}/FINCustomMenuModel.m | 0 demo/{ => Common}/FINDemoClientHelper.h | 0 demo/{ => Common}/FINDemoClientHelper.m | 0 demo/{ => Common}/FINExtensionHelper.h | 0 demo/{ => Common}/FINExtensionHelper.m | 0 ...{ViewController.h => MainViewController.h} | 4 +- ...{ViewController.m => MainViewController.m} | 63 ++++- .../Controller/FCQRCodeScanViewController.h | 18 ++ .../Controller/FCQRCodeScanViewController.m | 227 ++++++++++++++++++ demo/Scan/View/FCQRScanView.h | 26 ++ demo/Scan/View/FCQRScanView.m | 197 +++++++++++++++ demo/servers.plist | 58 +++-- 16 files changed, 659 insertions(+), 66 deletions(-) rename demo/{ => Common}/FINCustomMenuModel.h (100%) rename demo/{ => Common}/FINCustomMenuModel.m (100%) rename demo/{ => Common}/FINDemoClientHelper.h (100%) rename demo/{ => Common}/FINDemoClientHelper.m (100%) rename demo/{ => Common}/FINExtensionHelper.h (100%) rename demo/{ => Common}/FINExtensionHelper.m (100%) rename demo/{ViewController.h => MainViewController.h} (65%) rename demo/{ViewController.m => MainViewController.m} (62%) create mode 100644 demo/Scan/Controller/FCQRCodeScanViewController.h create mode 100644 demo/Scan/Controller/FCQRCodeScanViewController.m create mode 100644 demo/Scan/View/FCQRScanView.h create mode 100644 demo/Scan/View/FCQRScanView.m diff --git a/Podfile b/Podfile index ae305c5..f2b576e 100644 --- a/Podfile +++ b/Podfile @@ -1,11 +1,16 @@ platform :ios, "9.0" +source 'https://cdn.cocoapods.org/' + inhibit_all_warnings! target "demo" do pod 'FinApplet' pod 'FinAppletExt' + pod 'FinAppletWebRTC' + pod 'FinAppletBDMap' + pod 'FinAppletGDMap' pod 'WechatOpenSDK' end diff --git a/demo.xcodeproj/project.pbxproj b/demo.xcodeproj/project.pbxproj index 8cb32cf..a993478 100644 --- a/demo.xcodeproj/project.pbxproj +++ b/demo.xcodeproj/project.pbxproj @@ -8,7 +8,7 @@ /* Begin PBXBuildFile section */ 9DD565BE23EC45080011FC4A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD565BD23EC45080011FC4A /* AppDelegate.m */; }; - 9DD565C423EC45080011FC4A /* ViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD565C323EC45080011FC4A /* ViewController.m */; }; + 9DD565C423EC45080011FC4A /* MainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD565C323EC45080011FC4A /* MainViewController.m */; }; 9DD565C923EC450A0011FC4A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 9DD565C823EC450A0011FC4A /* Assets.xcassets */; }; 9DD565CC23EC450A0011FC4A /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 9DD565CA23EC450A0011FC4A /* LaunchScreen.storyboard */; }; 9DD565CF23EC450A0011FC4A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 9DD565CE23EC450A0011FC4A /* main.m */; }; @@ -18,6 +18,8 @@ A823321F258C3B7000C1B2D5 /* FINDemoClientHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = A823321D258C3B7000C1B2D5 /* FINDemoClientHelper.m */; }; A863B745257A09A300959AA1 /* FINExtensionHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = A863B744257A09A300959AA1 /* FINExtensionHelper.m */; }; A8BC097A258BA095001289A3 /* FINCustomMenuModel.m in Sources */ = {isa = PBXBuildFile; fileRef = A8BC0979258BA095001289A3 /* FINCustomMenuModel.m */; }; + A8CE73562810F8C800965B7E /* FCQRCodeScanViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = A8CE73512810F8C800965B7E /* FCQRCodeScanViewController.m */; }; + A8CE73572810F8C800965B7E /* FCQRScanView.m in Sources */ = {isa = PBXBuildFile; fileRef = A8CE73542810F8C800965B7E /* FCQRScanView.m */; }; FBF7F422A6EA50C856DB84F7 /* libPods-demo.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A582EE796CD12C1FF4F5DB /* libPods-demo.a */; }; /* End PBXBuildFile section */ @@ -27,8 +29,8 @@ 9DD565B923EC45080011FC4A /* demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = demo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 9DD565BC23EC45080011FC4A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 9DD565BD23EC45080011FC4A /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 9DD565C223EC45080011FC4A /* ViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ViewController.h; sourceTree = ""; }; - 9DD565C323EC45080011FC4A /* ViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ViewController.m; sourceTree = ""; }; + 9DD565C223EC45080011FC4A /* MainViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MainViewController.h; sourceTree = ""; }; + 9DD565C323EC45080011FC4A /* MainViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MainViewController.m; sourceTree = ""; }; 9DD565C823EC450A0011FC4A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 9DD565CB23EC450A0011FC4A /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 9DD565CD23EC450A0011FC4A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -42,6 +44,10 @@ A863B744257A09A300959AA1 /* FINExtensionHelper.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FINExtensionHelper.m; sourceTree = ""; }; A8BC0978258BA095001289A3 /* FINCustomMenuModel.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FINCustomMenuModel.h; sourceTree = ""; }; A8BC0979258BA095001289A3 /* FINCustomMenuModel.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FINCustomMenuModel.m; sourceTree = ""; }; + A8CE73512810F8C800965B7E /* FCQRCodeScanViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCQRCodeScanViewController.m; sourceTree = ""; }; + A8CE73522810F8C800965B7E /* FCQRCodeScanViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCQRCodeScanViewController.h; sourceTree = ""; }; + A8CE73542810F8C800965B7E /* FCQRScanView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FCQRScanView.m; sourceTree = ""; }; + A8CE73552810F8C800965B7E /* FCQRScanView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FCQRScanView.h; sourceTree = ""; }; FBEBA7E73B95B66C846E76FF /* Pods-demo.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-demo.debug.xcconfig"; path = "Target Support Files/Pods-demo/Pods-demo.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -78,16 +84,12 @@ 9DD565BB23EC45080011FC4A /* demo */ = { isa = PBXGroup; children = ( + A8CE734B2810F3B400965B7E /* Common */, 9DD565BC23EC45080011FC4A /* AppDelegate.h */, 9DD565BD23EC45080011FC4A /* AppDelegate.m */, - A823321E258C3B7000C1B2D5 /* FINDemoClientHelper.h */, - A823321D258C3B7000C1B2D5 /* FINDemoClientHelper.m */, - A863B743257A09A200959AA1 /* FINExtensionHelper.h */, - A863B744257A09A300959AA1 /* FINExtensionHelper.m */, - A8BC0978258BA095001289A3 /* FINCustomMenuModel.h */, - A8BC0979258BA095001289A3 /* FINCustomMenuModel.m */, - 9DD565C223EC45080011FC4A /* ViewController.h */, - 9DD565C323EC45080011FC4A /* ViewController.m */, + A8CE734F2810F8C800965B7E /* Scan */, + 9DD565C223EC45080011FC4A /* MainViewController.h */, + 9DD565C323EC45080011FC4A /* MainViewController.m */, 9DD565C823EC450A0011FC4A /* Assets.xcassets */, 9DD565CA23EC450A0011FC4A /* LaunchScreen.storyboard */, 9DD565CD23EC450A0011FC4A /* Info.plist */, @@ -99,6 +101,46 @@ path = demo; sourceTree = ""; }; + A8CE734B2810F3B400965B7E /* Common */ = { + isa = PBXGroup; + children = ( + A823321E258C3B7000C1B2D5 /* FINDemoClientHelper.h */, + A823321D258C3B7000C1B2D5 /* FINDemoClientHelper.m */, + A863B743257A09A200959AA1 /* FINExtensionHelper.h */, + A863B744257A09A300959AA1 /* FINExtensionHelper.m */, + A8BC0978258BA095001289A3 /* FINCustomMenuModel.h */, + A8BC0979258BA095001289A3 /* FINCustomMenuModel.m */, + ); + path = Common; + sourceTree = ""; + }; + A8CE734F2810F8C800965B7E /* Scan */ = { + isa = PBXGroup; + children = ( + A8CE73502810F8C800965B7E /* Controller */, + A8CE73532810F8C800965B7E /* View */, + ); + path = Scan; + sourceTree = ""; + }; + A8CE73502810F8C800965B7E /* Controller */ = { + isa = PBXGroup; + children = ( + A8CE73522810F8C800965B7E /* FCQRCodeScanViewController.h */, + A8CE73512810F8C800965B7E /* FCQRCodeScanViewController.m */, + ); + path = Controller; + sourceTree = ""; + }; + A8CE73532810F8C800965B7E /* View */ = { + isa = PBXGroup; + children = ( + A8CE73552810F8C800965B7E /* FCQRScanView.h */, + A8CE73542810F8C800965B7E /* FCQRScanView.m */, + ); + path = View; + sourceTree = ""; + }; ACE3AE3120D1733A6BB38C8A /* Frameworks */ = { isa = PBXGroup; children = ( @@ -127,7 +169,8 @@ 9DD565B523EC45080011FC4A /* Sources */, 9DD565B623EC45080011FC4A /* Frameworks */, 9DD565B723EC45080011FC4A /* Resources */, - D5CFBA4174EF15FFF4AA041A /* [CP] Copy Pods Resources */, + DFB054DF507DE3B18CCCE932 /* [CP] Embed Pods Frameworks */, + 74745716D7A4B2CB6E4BC657 /* [CP] Copy Pods Resources */, ); buildRules = ( ); @@ -186,7 +229,7 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - D5CFBA4174EF15FFF4AA041A /* [CP] Copy Pods Resources */ = { + 74745716D7A4B2CB6E4BC657 /* [CP] Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -203,6 +246,23 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-resources.sh\"\n"; showEnvVarsInLog = 0; }; + DFB054DF507DE3B18CCCE932 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-demo/Pods-demo-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; E71B82096235B4713AA534F8 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -232,10 +292,12 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 9DD565C423EC45080011FC4A /* ViewController.m in Sources */, + 9DD565C423EC45080011FC4A /* MainViewController.m in Sources */, A823321F258C3B7000C1B2D5 /* FINDemoClientHelper.m in Sources */, A8BC097A258BA095001289A3 /* FINCustomMenuModel.m in Sources */, + A8CE73562810F8C800965B7E /* FCQRCodeScanViewController.m in Sources */, A863B745257A09A300959AA1 /* FINExtensionHelper.m in Sources */, + A8CE73572810F8C800965B7E /* FCQRScanView.m in Sources */, 9DD565BE23EC45080011FC4A /* AppDelegate.m in Sources */, 9DD565CF23EC450A0011FC4A /* main.m in Sources */, ); diff --git a/demo/AppDelegate.m b/demo/AppDelegate.m index 41a0dfc..7ec1fc7 100644 --- a/demo/AppDelegate.m +++ b/demo/AppDelegate.m @@ -7,7 +7,7 @@ // #import "AppDelegate.h" -#import "ViewController.h" +#import "MainViewController.h" #import "FINExtensionHelper.h" #import "FINDemoClientHelper.h" @@ -28,17 +28,22 @@ NSString *bundleId = [NSBundle mainBundle].bundleIdentifier; NSString *path = [[NSBundle mainBundle] pathForResource:@"servers" ofType:@"plist"]; NSDictionary *servers = [NSDictionary dictionaryWithContentsOfFile:path]; - NSDictionary *data = servers[bundleId]; - NSString *appKey = data[@"appKey"]; - NSString *appSecret = data[@"appSecret"]; - NSString *apiServer = data[@"apiServer"]; - NSString *apiPrefix = data[@"apiPrefix"]; - FATApiCryptType cryptType = [data[@"cryptType"] isEqualToString:@"MD5"] ? FATApiCryptTypeMD5 : FATApiCryptTypeSM; + NSArray *array = servers[bundleId]; + NSMutableArray *configs = [NSMutableArray array]; + for (NSDictionary *data in array) { + NSString *appKey = data[@"appKey"]; + NSString *appSecret = data[@"appSecret"]; + NSString *apiServer = data[@"apiServer"]; + FATApiCryptType cryptType = [data[@"cryptType"] isEqualToString:@"MD5"] ? FATApiCryptTypeMD5 : FATApiCryptTypeSM; + FATStoreConfig *storeConfig = [[FATStoreConfig alloc] init]; + storeConfig.sdkKey = appKey; + storeConfig.sdkSecret = appSecret; + storeConfig.apiServer = apiServer; + storeConfig.cryptType = cryptType; + [configs addObject:storeConfig]; + } - FATConfig *config = [FATConfig configWithAppSecret:appSecret appKey:appKey]; - config.apiServer = apiServer; - config.apiPrefix = apiPrefix; - config.cryptType = cryptType; + FATConfig *config = [FATConfig configWithStoreConfigs:configs]; [[FATClient sharedClient] initWithConfig:config error:nil]; [[FATClient sharedClient] setEnableLog:YES]; @@ -46,12 +51,16 @@ // 注入自定义api [[FINExtensionHelper sharedHelper] registerCustomApis]; - // 该appID【wx85663af68a0cbbc8】绑定的应用为凡泰助手,若要生效,请修改BundleID为com.finogeeks.mop.finosprite - [WXApi registerApp:@"wx85663af68a0cbbc8" universalLink:apiServer]; + if ([bundleId isEqualToString:@"com.finogeeks.mop.finosprite"]) { + // 该appID【wx85663af68a0cbbc8】绑定的应用为凡泰助手,若要生效,请修改BundleID为com.finogeeks.mop.finosprite + [WXApi registerApp:@"wx85663af68a0cbbc8" universalLink:@"https://www.finclip.com"]; + } self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; self.window.backgroundColor = [UIColor whiteColor]; - self.window.rootViewController = [[ViewController alloc] init]; + + MainViewController *mainVC = [[MainViewController alloc] init]; + self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:mainVC]; [self.window makeKeyAndVisible]; return YES; diff --git a/demo/FINCustomMenuModel.h b/demo/Common/FINCustomMenuModel.h similarity index 100% rename from demo/FINCustomMenuModel.h rename to demo/Common/FINCustomMenuModel.h diff --git a/demo/FINCustomMenuModel.m b/demo/Common/FINCustomMenuModel.m similarity index 100% rename from demo/FINCustomMenuModel.m rename to demo/Common/FINCustomMenuModel.m diff --git a/demo/FINDemoClientHelper.h b/demo/Common/FINDemoClientHelper.h similarity index 100% rename from demo/FINDemoClientHelper.h rename to demo/Common/FINDemoClientHelper.h diff --git a/demo/FINDemoClientHelper.m b/demo/Common/FINDemoClientHelper.m similarity index 100% rename from demo/FINDemoClientHelper.m rename to demo/Common/FINDemoClientHelper.m diff --git a/demo/FINExtensionHelper.h b/demo/Common/FINExtensionHelper.h similarity index 100% rename from demo/FINExtensionHelper.h rename to demo/Common/FINExtensionHelper.h diff --git a/demo/FINExtensionHelper.m b/demo/Common/FINExtensionHelper.m similarity index 100% rename from demo/FINExtensionHelper.m rename to demo/Common/FINExtensionHelper.m diff --git a/demo/ViewController.h b/demo/MainViewController.h similarity index 65% rename from demo/ViewController.h rename to demo/MainViewController.h index 3d4ba29..44730f6 100644 --- a/demo/ViewController.h +++ b/demo/MainViewController.h @@ -1,5 +1,5 @@ // -// ViewController.h +// MainViewController.h // demo // // Created by 杨涛 on 2020/2/6. @@ -8,7 +8,7 @@ #import -@interface ViewController : UIViewController +@interface MainViewController : UIViewController @end diff --git a/demo/ViewController.m b/demo/MainViewController.m similarity index 62% rename from demo/ViewController.m rename to demo/MainViewController.m index c7b97c7..c6d15cc 100644 --- a/demo/ViewController.m +++ b/demo/MainViewController.m @@ -1,16 +1,18 @@ // -// ViewController.m +// MainViewController.m // demo // // Created by 杨涛 on 2020/2/6. // Copyright © 2020 finogeeks. All rights reserved. // -#import "ViewController.h" +#import "MainViewController.h" +#import "FCQRCodeScanViewController.h" + #import #import -@interface ViewController () +@interface MainViewController () @property (nonatomic, strong) UITableView *tableView; @@ -18,26 +20,29 @@ @end -@implementation ViewController +@implementation MainViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. + self.title = @"FinClip"; + + [self p_initNavigationBar]; [self p_loadData]; [self p_initSubViews]; } +- (void)p_initNavigationBar { + self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"扫码" style:UIBarButtonItemStylePlain target:self action:@selector(scanItemClick)]; +} + - (void)p_initSubViews { CGFloat screenWidth = [UIScreen mainScreen].bounds.size.width; CGFloat screenHeight = [UIScreen mainScreen].bounds.size.height; - UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, 44)]; - headerView.backgroundColor = [UIColor colorWithRed:0.9 green:0.9 blue:0.9 alpha:1]; - self.tableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, screenWidth, screenHeight) style:UITableViewStylePlain]; - self.tableView.tableHeaderView = headerView; self.tableView.tableFooterView = [UIView new]; self.tableView.delegate = self; self.tableView.dataSource = self; @@ -71,6 +76,35 @@ } } +- (void)handleQrCode:(NSString *)qrCode +{ + NSLog(@"qrCode:%@", qrCode); + if (![qrCode containsString:@"/runtime/applet/"]) { + NSLog(@"不能识别的二维码"); + return; + } + + FATAppletQrCodeRequest *qrcodeRequest = [[FATAppletQrCodeRequest alloc] init]; + qrcodeRequest.qrCode = qrCode; + [[FATClient sharedClient] startAppletWithQrCodeRequest:qrcodeRequest inParentViewController:self requestBlock:^(BOOL result, FATError *error) { + NSLog(@"请求完成:%@", error); + } completion:^(BOOL result, FATError *error) { + NSLog(@"打开完成:%@", error); + } closeCompletion:^{ + NSLog(@"关闭"); + }]; +} + +#pragma mark - click events +- (void)scanItemClick +{ + FCQRCodeScanViewController *scanVC = [[FCQRCodeScanViewController alloc] init]; + scanVC.scanCompletion = ^(NSString *qrcode) { + [self handleQrCode:qrcode]; + }; + [self.navigationController pushViewController:scanVC animated:YES]; +} + #pragma mark - UITableViewDataSource - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return self.appletList.count; @@ -95,10 +129,15 @@ NSString *appId = dict[@"appId"]; NSDictionary *startParams = dict[@"startParams"]; - [[FATClient sharedClient] startRemoteApplet:appId startParams:startParams InParentViewController:self completion:^(BOOL result, NSError *error) { - if ([appId isEqualToString:@"60c5bbf99e094f00015079ee"]) { - [self sendCustomEvent]; - } + FATAppletRequest *request = [[FATAppletRequest alloc] init]; + request.appletId = appId; + request.startParams = startParams; + request.apiServer = @"https://api.finclip.com"; + + [[FATClient sharedClient] startAppletWithRequest:request InParentViewController:self completion:^(BOOL result, FATError *error) { + + } closeCompletion:^{ + }]; } diff --git a/demo/Scan/Controller/FCQRCodeScanViewController.h b/demo/Scan/Controller/FCQRCodeScanViewController.h new file mode 100644 index 0000000..8a416ca --- /dev/null +++ b/demo/Scan/Controller/FCQRCodeScanViewController.h @@ -0,0 +1,18 @@ +// +// FCQRCodeScanViewController.h +// FinoSprite +// +// Created by Haley on 2019/12/6. +// Copyright © 2019 finogeeks. All rights reserved. +// + +#import + +typedef void(^ScanCompletion)(NSString *qrcode); + +@interface FCQRCodeScanViewController : UIViewController + +@property (nonatomic, copy) ScanCompletion scanCompletion; + +@end + diff --git a/demo/Scan/Controller/FCQRCodeScanViewController.m b/demo/Scan/Controller/FCQRCodeScanViewController.m new file mode 100644 index 0000000..2c8baf3 --- /dev/null +++ b/demo/Scan/Controller/FCQRCodeScanViewController.m @@ -0,0 +1,227 @@ +// +// FCQRCodeScanViewController.m +// FinoSprite +// +// Created by Haley on 2019/12/6. +// Copyright © 2019 finogeeks. All rights reserved. +// + +#import "FCQRCodeScanViewController.h" +#import "FCQRScanView.h" + +#import +#import +#import + +@interface FCQRCodeScanViewController () + +@property (nonatomic, strong) AVCaptureSession *session; + +@property (nonatomic, strong) FCQRScanView *scanView; + +@end + +@implementation FCQRCodeScanViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + + [self p_initNavigationBar]; + + [self p_addNotifications]; + + [self p_initSubView]; + + [self p_checkCameraStatus:^(BOOL granted) { + if (granted) { + [self p_initCameraSession]; + } else { + [self p_showAlert:@"请在”设置-隐私-相机”选项中,允许访问你的相机" btnTitle:@"确定"]; + } + }]; +} + +- (void)viewWillAppear:(BOOL)animated +{ + [super viewWillAppear:animated]; + + [self p_resumeScanning]; +} + +- (void)viewWillDisappear:(BOOL)animated +{ + [super viewWillDisappear:animated]; + [self p_pauseScanning]; +} + +#pragma mark - ovverride +- (void)updateNavigationBar +{ + self.navigationController.navigationBar.tintColor = [UIColor whiteColor]; + [self.navigationController.navigationBar setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}]; + self.navigationController.navigationBar.barTintColor = [UIColor blackColor]; + + [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleLightContent; + + [self.navigationController setNavigationBarHidden:NO animated:YES]; +} + +#pragma mark - private methods +- (void)p_initNavigationBar +{ + self.title = @"扫一扫"; +} + +- (void)p_addNotifications +{ + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appDidBecomeActive) name:UIApplicationDidBecomeActiveNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(appWillResignActive) name:UIApplicationWillResignActiveNotification object:nil]; +} + +- (void)p_initSubView +{ + self.view.backgroundColor = [UIColor blackColor]; + + [self.view addSubview:self.scanView]; +} + +- (void)p_initCameraSession +{ + AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo]; + if (!device) { + return; + } + + AVCaptureDeviceInput *deviceInput = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil]; + if (!deviceInput) { + return; + } + + AVCaptureMetadataOutput *metadataOutput = [[AVCaptureMetadataOutput alloc] init]; + [metadataOutput setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()]; + + // 配置扫描区域 + metadataOutput.rectOfInterest = CGRectMake(_scanView.scanner_y / self.view.frame.size.height, _scanView.scanner_x / self.view.frame.size.width, _scanView.scanner_width / self.view.frame.size.height, _scanView.scanner_width / self.view.frame.size.width); + + self.session = [[AVCaptureSession alloc] init]; + + [self.session canSetSessionPreset:AVCaptureSessionPresetHigh]; + if ([self.session canAddInput:deviceInput]) { + [self.session addInput:deviceInput]; + } + + if ([self.session canAddOutput:metadataOutput]) { + [self.session addOutput:metadataOutput]; + } + + metadataOutput.metadataObjectTypes = @[AVMetadataObjectTypeQRCode]; + + AVCaptureVideoPreviewLayer *videoPreviewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.session]; + videoPreviewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill; + videoPreviewLayer.frame = self.view.layer.bounds; + [self.view.layer insertSublayer:videoPreviewLayer atIndex:0]; + + [self.session startRunning]; +} + +- (void)p_showAlert:(NSString *)title btnTitle:(NSString *)btnTitle +{ + UIAlertController *alertVC = [UIAlertController alertControllerWithTitle:title message:nil preferredStyle:UIAlertControllerStyleAlert]; + UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:title style:UIAlertActionStyleCancel handler:nil]; + [alertVC addAction:cancelAction]; + [self presentViewController:alertVC animated:YES completion:nil]; +} + +- (void)p_checkCameraStatus:(void (^)(BOOL granted))completion +{ + AVAuthorizationStatus cameraStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo]; + + switch (cameraStatus) { + case AVAuthorizationStatusAuthorized: + { + if (completion) { + completion(true); + } + } + break; + case AVAuthorizationStatusNotDetermined: + { + if (completion) { + completion(true); + } + } + break; + default: + { + if (completion) { + completion(false); + } + } + break; + } +} + +/// 恢复扫一扫功能 +- (void)p_resumeScanning +{ + [self.session startRunning]; + [self.scanView p_startScannerLineAnimation]; +} + +/// 暂停扫一扫功能 +- (void)p_pauseScanning +{ + [self.session stopRunning]; + [self.scanView p_pauseScannerLineAnimation]; +} + +#pragma mark - QRCode handler +- (void)handleQrCode:(NSString *)qrCode +{ + [self.navigationController popViewControllerAnimated:YES]; + + if (self.scanCompletion) { + self.scanCompletion(qrCode); + } +} + +#pragma mark - notification handler +- (void)appDidBecomeActive +{ + [self p_resumeScanning]; +} + +- (void)appWillResignActive +{ + [self p_pauseScanning]; +} + +#pragma mark - AVCaptureMetadataOutputObjectsDelegate +-(void)captureOutput:(AVCaptureOutput *)output didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection +{ + if (metadataObjects != nil && metadataObjects.count > 0) { + + [self p_pauseScanning]; + + AVMetadataMachineReadableCodeObject *obj = metadataObjects[0]; + [self handleQrCode:[obj stringValue]]; + } else { + + } +} + +#pragma mark - setter && getter + +- (FCQRScanView *)scanView +{ + if (!_scanView) { + _scanView = [[FCQRScanView alloc] initWithFrame:self.view.bounds]; + } + return _scanView; +} + + + +@end diff --git a/demo/Scan/View/FCQRScanView.h b/demo/Scan/View/FCQRScanView.h new file mode 100644 index 0000000..767779e --- /dev/null +++ b/demo/Scan/View/FCQRScanView.h @@ -0,0 +1,26 @@ +// +// FCQRScanView.h +// FinoSprite +// +// Created by Haley on 2019/12/6. +// Copyright © 2019 finogeeks. All rights reserved. +// + +#import + +@interface FCQRScanView : UIView + +@property (nonatomic, assign) CGFloat scanner_width; +@property (nonatomic, assign) CGFloat scanner_x; +@property (nonatomic, assign) CGFloat scanner_y; + +- (void)p_startScannerLineAnimation; + +- (void)p_pauseScannerLineAnimation; + +- (void)p_addActivityIndicator; + +- (void)p_removeActivityIndicator; + +@end + diff --git a/demo/Scan/View/FCQRScanView.m b/demo/Scan/View/FCQRScanView.m new file mode 100644 index 0000000..a4dd11d --- /dev/null +++ b/demo/Scan/View/FCQRScanView.m @@ -0,0 +1,197 @@ +// +// FCQRScanView.m +// FinoSprite +// +// Created by Haley on 2019/12/6. +// Copyright © 2019 finogeeks. All rights reserved. +// + +#import "FCQRScanView.h" + +const CGFloat scanner_borderWidth = 1.0; /** 扫描器边框宽度 */ +const CGFloat scanner_cornerWidth = 3.0; /** 扫描器棱角宽度 */ +const CGFloat scanner_cornerLength = 20.0; /** 扫描器棱角长度 */ +const CGFloat scanner_lineHeight = 1.0; /** 扫描器线条高度 */ +const CGFloat tipLab_height = 50.0; /** 扫描器下方提示文字高度 */ + +static NSString *scannerLineAnmationKey = @"ScannerLineAnmationKey"; /** 扫描线条动画Key值 */ + +@interface FCQRScanView () + +@property (nonatomic, strong) UIColor *scannerBorderColor; + +@property (nonatomic, strong) UIColor *scannerCornerColor; + +@property (nonatomic, strong) UIImageView *scannerLine; + +@property (nonatomic, strong) UILabel *tipLabel; + +@property (nonatomic, strong) UIActivityIndicatorView *activityIndicator; + +@end + +@implementation FCQRScanView + +- (instancetype)initWithFrame:(CGRect)frame +{ + self = [super initWithFrame:frame]; + if (self) { + _scanner_width = 0.7 * frame.size.width; + _scanner_x = (frame.size.width - _scanner_width) / 2; + _scanner_y = 100; + + _scannerBorderColor = [UIColor whiteColor]; + _scannerCornerColor = [UIColor colorWithRed:66/255.0f green:134/255.0 blue:246/255.0 alpha:1.0]; + + [self p_initSubViews]; + } + return self; +} + +- (void)p_initSubViews +{ + self.backgroundColor = [UIColor clearColor]; + + [self addSubview:self.scannerLine]; + + [self addSubview:self.tipLabel]; +} + + +- (void)p_startScannerLineAnimation +{ + [self.scannerLine.layer removeAllAnimations]; + + CABasicAnimation *lineAnimation = [CABasicAnimation animationWithKeyPath:@"transform"]; + lineAnimation.toValue = [NSValue valueWithCATransform3D:CATransform3DMakeTranslation(0, _scanner_width - scanner_lineHeight, 1)]; + lineAnimation.duration = 4; + lineAnimation.repeatCount = MAXFLOAT; + [self.scannerLine.layer addAnimation:lineAnimation forKey:scannerLineAnmationKey]; + // 重置动画运行速度为1.0 + self.scannerLine.layer.speed = 1.0; +} + +- (void)p_pauseScannerLineAnimation +{ + // 取出当前时间,转成动画暂停的时间 + CFTimeInterval pauseTime = [self.scannerLine.layer convertTime:CACurrentMediaTime() fromLayer:nil]; + // 设置动画的时间偏移量,指定时间偏移量的目的是让动画定格在该时间点的位置 + self.scannerLine.layer.timeOffset = pauseTime; + // 将动画的运行速度设置为0, 默认的运行速度是1.0 + self.scannerLine.layer.speed = 0; +} + +- (void)p_addActivityIndicator +{ + if (!_activityIndicator) { + _activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + _activityIndicator.center = self.center; + [self addSubview:_activityIndicator]; + } + + [_activityIndicator startAnimating]; +} + +- (void)p_removeActivityIndicator +{ + if (_activityIndicator) { + [_activityIndicator removeFromSuperview]; + _activityIndicator = nil; + } +} + +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + // 半透明区域 + [[UIColor colorWithWhite:0 alpha:0.7] setFill]; + UIRectFill(rect); + + // 透明区域 + CGRect scanner_rect = CGRectMake(_scanner_x, _scanner_y, _scanner_width, _scanner_width); + [[UIColor clearColor] setFill]; + UIRectFill(scanner_rect); + + // 边框 + UIBezierPath *borderPath = [UIBezierPath bezierPathWithRect:CGRectMake(_scanner_x, _scanner_y, _scanner_width, _scanner_width)]; + borderPath.lineCapStyle = kCGLineCapRound; + borderPath.lineWidth = scanner_borderWidth; + [_scannerBorderColor set]; + [borderPath stroke]; + + for (int index = 0; index < 4; index++) { + UIBezierPath *tempPath = [UIBezierPath bezierPath]; + tempPath.lineWidth = scanner_cornerWidth; + [_scannerCornerColor set]; + switch (index) { + // 左上角 + case 0: + [tempPath moveToPoint:CGPointMake(_scanner_x + scanner_cornerLength, _scanner_y)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x, _scanner_y)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x, _scanner_y + scanner_cornerLength)]; + break; + // 右上角 + case 1: + [tempPath moveToPoint:CGPointMake(_scanner_x + _scanner_width - scanner_cornerLength, _scanner_y)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x + _scanner_width, _scanner_y)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x + _scanner_width, _scanner_y + scanner_cornerLength)]; + break; + // 左下角 + case 2: + [tempPath moveToPoint:CGPointMake(_scanner_x, _scanner_y + _scanner_width - scanner_cornerLength)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x, _scanner_y + _scanner_width)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x + scanner_cornerLength, _scanner_y + _scanner_width)]; + break; + // 右下角 + case 3: + [tempPath moveToPoint:CGPointMake(_scanner_x + _scanner_width - scanner_cornerLength, _scanner_y + _scanner_width)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x + _scanner_width, _scanner_y + _scanner_width)]; + [tempPath addLineToPoint:CGPointMake(_scanner_x + _scanner_width, _scanner_y + _scanner_width - scanner_cornerLength)]; + break; + } + [tempPath stroke]; + } + +} + +- (UIImage *)fin_imageWithColor:(UIColor *)color +{ + CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f); //宽高 1.0只要有值就够了 + UIGraphicsBeginImageContext(rect.size); //在这个范围内开启一段上下文 + CGContextRef context = UIGraphicsGetCurrentContext(); + + CGContextSetFillColorWithColor(context, [color CGColor]);//在这段上下文中获取到颜色UIColor + CGContextFillRect(context, rect);//用这个颜色填充这个上下文 + + UIImage *image = UIGraphicsGetImageFromCurrentImageContext();//从这段上下文中获取Image属性,,,结束 + UIGraphicsEndImageContext(); + + return image; +} + +#pragma mark - setter && getter +- (UIImageView *)scannerLine +{ + if (!_scannerLine) { + _scannerLine = [[UIImageView alloc] initWithFrame:CGRectMake(_scanner_x + 5, _scanner_y, _scanner_width - 10, scanner_lineHeight)]; + UIColor *tinColor = [UIColor colorWithRed:66/255.0f green:134/255.0 blue:246/255.0 alpha:1.0]; + _scannerLine.image = [self fin_imageWithColor:tinColor]; + } + + return _scannerLine; +} + +- (UILabel *)tipLabel +{ + if (!_tipLabel) { + _tipLabel = [[UILabel alloc] initWithFrame:CGRectMake(0, _scanner_y + _scanner_width, self.frame.size.width, 50)]; + _tipLabel.textAlignment = NSTextAlignmentCenter; + _tipLabel.textColor = [UIColor lightGrayColor]; + _tipLabel.font = [UIFont systemFontOfSize:13]; + _tipLabel.text = @"将二维码放入框内,即可自动扫描"; + } + return _tipLabel; +} + +@end diff --git a/demo/servers.plist b/demo/servers.plist index 8dd6317..2d7638b 100644 --- a/demo/servers.plist +++ b/demo/servers.plist @@ -3,30 +3,40 @@ com.finogeeks.finclip.demo - - appKey - 22LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM= - appSecret - bdfd76cae24d4313 - apiServer - https://api.finclip.com - apiPrefix - /api/v1/mop/ - cryptType - MD5 - + + + appKey + 22LyZEib0gLTQdU3MUauATBwgfnTCJjdr7FCnywmAEM= + appSecret + bdfd76cae24d4313 + apiServer + https://api.finclip.com + cryptType + MD5 + + + appKey + 22LyZEib0gLTQdU3MUauAUJPk2mIMV4Hq+tBzQxTSqhndG2JOPsS9yA5fww36gSp + appSecret + 1e9b3d1693d06fa1 + apiServer + https://finclip-testing.finogeeks.club + cryptType + SM + + com.finogeeks.mop.finosprite - - appKey - 22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk= - appSecret - ae55433be2f62915 - apiServer - https://finchat-mop-b.finogeeks.club - apiPrefix - /api/v1/mop/ - cryptType - SM - + + + appKey + 22LyZEib0gLTQdU3MUauAQVLIkNNhTSGIN42gXzlAsk= + appSecret + ae55433be2f62915 + apiServer + https://finchat-mop-b.finogeeks.club + cryptType + SM + +