- Integrate ali_auth plugin as local package (previously pub dependency) - Fix AppCompatActivity ClassNotFoundException via proguard keep rules - Add dialog popup mode matching iOS style (white background, rounded corners) - Fix invisible login button by adding blue GradientDrawable background - Add Airhub logo to authorization dialog via logoImgPath - Fix auth page not closing after login by calling quitPage() on token success - Update .gitignore to exclude plugin examples, screenshots, docs and backups Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
684 lines
30 KiB
Objective-C
684 lines
30 KiB
Objective-C
#import "AliAuthPlugin.h"
|
||
#import <UIKit/UIKit.h>
|
||
|
||
#import "AliAuthEnum.h"
|
||
#import "MJExtension.h"
|
||
#import <ATAuthSDK/ATAuthSDK.h>
|
||
//#import "MBProgressHUD.h"
|
||
#import "PNSBuildModelUtils.h"
|
||
#import "NSDictionary+Utils.h"
|
||
#import "UIColor+Hex.h"
|
||
#import <AuthenticationServices/AuthenticationServices.h>
|
||
|
||
#define TX_SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height
|
||
#define TX_SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width
|
||
|
||
bool bool_true = true;
|
||
bool bool_false = false;
|
||
|
||
// 打印长度比较大的字符串
|
||
//#define NSLog(format,...) printf("%s",[[NSString stringWithFormat:(format), ##__VA_ARGS__] UTF8String])
|
||
|
||
/// 添加ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding 取消
|
||
/// authorizationController.delegate = self; authorizationController.presentationContextProvider = self; 警告信息
|
||
@interface AliAuthPlugin()<UIApplicationDelegate, FlutterStreamHandler, ASAuthorizationControllerDelegate, ASAuthorizationControllerPresentationContextProviding>
|
||
@property (nonatomic, strong) UINavigationController *navigationController;
|
||
@end
|
||
|
||
@implementation AliAuthPlugin{
|
||
FlutterEventSink _eventSink;
|
||
FlutterResult _result;
|
||
FlutterMethodCall * _callData;
|
||
TXCustomModel * _model;
|
||
Boolean _isChecked;
|
||
Boolean _isHideToast;
|
||
}
|
||
+ (void)registerWithRegistrar:(NSObject<FlutterPluginRegistrar>*)registrar {
|
||
AliAuthPlugin* instance = [[AliAuthPlugin alloc] init];
|
||
|
||
FlutterMethodChannel *channel = [FlutterMethodChannel methodChannelWithName:@"ali_auth" binaryMessenger: [registrar messenger]];
|
||
FlutterEventChannel* chargingChannel = [FlutterEventChannel eventChannelWithName:@"ali_auth/event" binaryMessenger: [registrar messenger]];
|
||
|
||
[chargingChannel setStreamHandler: instance];
|
||
[registrar addMethodCallDelegate:instance channel: channel];
|
||
//为了让手机安装demo弹出使用网络权限弹出框
|
||
[[AliAuthPlugin alloc] httpAuthority];
|
||
|
||
}
|
||
|
||
#pragma mark - IOS 主动发送通知让 flutter调用监听 eventChannel start
|
||
- (FlutterError*)onListenWithArguments:(id)arguments eventSink:(FlutterEventSink)eventSink {
|
||
if (_eventSink == nil) {
|
||
_eventSink = eventSink;
|
||
/** 返回初始化状态 */
|
||
NSString *version = [[TXCommonHandler sharedInstance] getVersion];
|
||
|
||
NSDictionary *dict = @{ @"resultCode": @"500004", @"msg": version };
|
||
[self showResultMsg: dict msg:version];
|
||
}
|
||
return nil;
|
||
}
|
||
|
||
- (FlutterError*)onCancelWithArguments:(id)arguments {
|
||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||
_eventSink = nil;
|
||
return nil;
|
||
}
|
||
|
||
// eventChannel end
|
||
#pragma mark - 测试联网阿里授权必须
|
||
-(void)httpAuthority{
|
||
NSURL *url = [NSURL URLWithString:@"https://www.baidu.com/"];//此处修改为自己公司的服务器地址
|
||
NSURLRequest *request = [NSURLRequest requestWithURL:url];
|
||
NSURLSession *session = [NSURLSession sharedSession];
|
||
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
|
||
if (error == nil) {
|
||
// NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
|
||
NSLog(@"联网成功!");
|
||
} else {
|
||
NSLog(@"联网失败!");
|
||
}
|
||
}];
|
||
|
||
[dataTask resume];
|
||
}
|
||
|
||
#pragma mark - flutter调用 oc eventChannel start
|
||
- (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||
// SDK 初始化
|
||
_callData = call;
|
||
_result = result;
|
||
if ([@"getPlatformVersion" isEqualToString:call.method]) {
|
||
result([@"iOS " stringByAppendingString:[[UIDevice currentDevice] systemVersion]]);
|
||
}
|
||
else if ([@"getCurrentCarrierName" isEqualToString:call.method]) {
|
||
// 获取当前上网卡运营商名称,比如中国移动、中国电信、中国联通
|
||
result([TXCommonUtils getCurrentCarrierName]);
|
||
}
|
||
// 初始化SDK
|
||
else if ([@"initSdk" isEqualToString:call.method]) {
|
||
_isHideToast = [call.arguments boolValueForKey: @"isHideToast" defaultValue: NO];
|
||
if (_eventSink == nil) {
|
||
result(@{ @"code": @"500001", @"msg": @"请先对插件进行监听!" });
|
||
} else {
|
||
[self initSdk];
|
||
}
|
||
}
|
||
// 延时登录获取非延时登录
|
||
else if ([@"login" isEqualToString:call.method]) {
|
||
if(_model == nil){
|
||
NSDictionary *dict = @{ @"resultCode": @"500003" };
|
||
[self showResult: dict];
|
||
return;
|
||
}
|
||
self->_isChecked = [_callData.arguments boolValueForKey: @"privacyState" defaultValue: NO];
|
||
[self loginWithModel: _model complete:^{}];
|
||
}
|
||
else if ([@"checkEnvAvailable" isEqualToString:call.method]) {
|
||
[self checkVerifyEnable:call result:result];
|
||
}
|
||
else if ([@"queryCheckBoxIsChecked" isEqualToString:call.method]) {
|
||
BOOL status = [[TXCommonHandler sharedInstance] queryCheckBoxIsChecked];
|
||
result(@(status));
|
||
}
|
||
else if ([@"setCheckboxIsChecked" isEqualToString:call.method]) {
|
||
[[TXCommonHandler sharedInstance] setCheckboxIsChecked:YES];
|
||
result(@(bool_true));
|
||
}
|
||
else if ([@"checkCellularDataEnable" isEqualToString:call.method]) {
|
||
[self checkCellularDataEnable:call result:result];
|
||
}
|
||
else if ([@"preLogin" isEqualToString:call.method]) {
|
||
[self getPreLogin:call result:result];
|
||
}
|
||
else if ([@"quitPage" isEqualToString:call.method]) {
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
|
||
}
|
||
else if ([@"hideLoading" isEqualToString:call.method]) {
|
||
[[TXCommonHandler sharedInstance] hideLoginLoading];
|
||
}
|
||
else if ([@"appleLogin" isEqualToString:call.method]) {
|
||
[self handleAuthorizationAppleIDButtonPress:call result:result];
|
||
}
|
||
else if ([@"openPage" isEqualToString:call.method]) {
|
||
// 1.初始化flutter控制器,并指定路由 “home”,flutter中根据该路由标识显示对应的界面
|
||
FlutterViewController* flutterViewController = [
|
||
[FlutterViewController alloc] initWithProject:nil
|
||
initialRoute:[call.arguments stringValueForKey: @"pageRoute" defaultValue: @"/"]
|
||
nibName:nil
|
||
bundle:nil
|
||
];
|
||
// 2. 跳转
|
||
flutterViewController.modalPresentationStyle = UIModalPresentationFullScreen;
|
||
[[self findCurrentViewController] presentViewController:flutterViewController animated: YES completion:nil];
|
||
}
|
||
else {
|
||
result(FlutterMethodNotImplemented);
|
||
}
|
||
}
|
||
|
||
#pragma mark - 初始化SDK以及相关布局
|
||
- (void)initSdk {
|
||
NSDictionary *dic = _callData.arguments;
|
||
// _model = [TXCustomModel mj_objectWithKeyValues: dic];
|
||
if ([[dic stringValueForKey: @"iosSk" defaultValue: @""] isEqualToString:@""]) {
|
||
NSDictionary *dict = @{ @"resultCode": @"500000" };
|
||
[self showResult: dict];
|
||
}
|
||
else {
|
||
NSString *secret = [dic stringValueForKey: @"iosSk" defaultValue: @""];
|
||
/** 不管是否延时登录都需要,先初始化model */
|
||
_model = [PNSBuildModelUtils buildModelWithStyle: dic target:self selector:@selector(btnClick:)];
|
||
//1. 初始化sdk,设置secret
|
||
[[TXCommonHandler sharedInstance] setAuthSDKInfo:secret complete:^(NSDictionary * _Nonnull resultDic) {
|
||
//2. 调用check接口检查及准备接口调用环境
|
||
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable checkDic) {
|
||
if ([PNSCodeSuccess isEqualToString:[checkDic objectForKey:@"resultCode"]] == YES) {
|
||
NSDictionary *dict = @{ @"resultCode": @"600024" };
|
||
[self showResult: dict];
|
||
//3. 调用取号接口,加速授权页的弹起
|
||
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout: 5.0 complete:^(NSDictionary * _Nonnull resultDic) {
|
||
//4. 预取号成功后判断是否延时登录,否则立即登录
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == YES) {
|
||
if (![dic boolValueForKey: @"isDelay" defaultValue: NO]) {
|
||
[self loginWithModel: self->_model complete:^{}];
|
||
}
|
||
NSString *carrierNam = [TXCommonUtils getCurrentCarrierName];
|
||
NSDictionary *acceleDict = @{ @"resultCode": @"600016", @"data": carrierNam };
|
||
[self showResult: acceleDict];
|
||
return;
|
||
}
|
||
[self showResult: resultDic];
|
||
}];
|
||
} else {
|
||
NSMutableDictionary *result = [NSMutableDictionary dictionaryWithDictionary:checkDic];
|
||
[result setValue:@(bool_false) forKey: @"token"];
|
||
[self showResult: result];
|
||
}
|
||
}];
|
||
}];
|
||
}
|
||
}
|
||
|
||
/** SDK 判断网络环境是否支持 */
|
||
- (void)checkVerifyEnable:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||
__weak typeof(self) weakSelf = self;
|
||
|
||
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
|
||
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
|
||
[dict setValue: [resultDic objectForKey:@"resultCode"] forKey: @"code"];
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
|
||
[weakSelf showResult:resultDic];
|
||
[dict setValue: @(bool_false) forKey: @"data"];
|
||
} else {
|
||
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:5.0 complete:^(NSDictionary * _Nonnull resultDic) {
|
||
/// NSLog(@"为后面授权页拉起加个速,加速结果:%@", resultDic);
|
||
}];
|
||
// 中国移动支持2G/3G/4G、中国联通支持3G/4G、中国电信支持4G。 2G网络下认证失败率较高
|
||
// WiFi,4G,3G,2G,NoInternet等
|
||
// NSString *networktype = [[TXCommonUtils init] getNetworktype];
|
||
// // 中国移动,中国联通,中国电信等
|
||
// NSString *carrierName = [[TXCommonUtils init] getCurrentCarrierName];
|
||
// if( [carrierName isEqual:(@"中国移动")] && [networktype isEqual:(@"2G")] && [networktype isEqual:(@"3G")] && [networktype isEqual:(@"4G")] ){
|
||
// result(@(bool_true));
|
||
// } else if( [carrierName isEqual:(@"中国联通")] && [networktype isEqual:(@"3G")] && [networktype isEqual:(@"4G")]){
|
||
// result(@(bool_true));
|
||
// } else if( [carrierName isEqual:(@"中国电信")] && [networktype isEqual:(@"4G")]){
|
||
// result(@(bool_true));
|
||
// }
|
||
// result(@(bool_false));
|
||
[dict setValue: @"终端环境检查⽀持认证" forKey: @"msg"];
|
||
[dict setValue: @"600024" forKey: @"code"];
|
||
[dict setValue: @(bool_true) forKey: @"data"];
|
||
}
|
||
[self resultData: dict];
|
||
}];
|
||
}
|
||
|
||
/** 检测是否开启蜂窝网络 */
|
||
- (void)checkCellularDataEnable:(FlutterMethodCall*)call result:(FlutterResult)result {
|
||
bool status = [TXCommonUtils checkDeviceCellularDataEnable];
|
||
NSDictionary *dict = @{
|
||
@"code": @"1",
|
||
@"msg" : @"蜂窝网络检测",
|
||
@"data" : @(status)
|
||
};
|
||
result(dict);
|
||
}
|
||
|
||
|
||
#pragma mark - action 选中第三方按钮时回调
|
||
- (void)btnClick: (UIGestureRecognizer *) sender {
|
||
UIButton *view = (UIButton *)sender;
|
||
NSInteger index = view.tag;
|
||
NSDictionary *dict = @{
|
||
@"code": @"700005",
|
||
@"msg" : @"点击第三方登录按钮",
|
||
@"data" : [NSNumber numberWithInteger: index]
|
||
};
|
||
[self resultData: dict];
|
||
if (!self->_isChecked && !self->_isHideToast) {
|
||
NSDictionary *dic = self -> _callData.arguments;
|
||
// [self showToast: [dic stringValueForKey: @"toastText" defaultValue: @"请先阅读用户协议"]];
|
||
} else {
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated: YES complete:^(void) {}];
|
||
}
|
||
}
|
||
|
||
// 一键登录预取号
|
||
- (void)getPreLogin:(FlutterMethodCall*)call result:(FlutterResult)result{
|
||
[self accelerateLogin:_model call:call result:result complete:^{}];
|
||
}
|
||
|
||
/**
|
||
* 函数名: accelerateLoginPageWithTimeout
|
||
* @brief 加速一键登录授权页弹起,防止调用 getLoginTokenWithTimeout:controller:model:complete: 等待弹起授权页时间过长
|
||
* @param timeout:接口超时时间,单位s,默认3.0s,值为0.0时采用默认超时时间
|
||
* @param complete 结果异步回调,成功时resultDic=@{resultCode:600000, msg:...},其他情况时"resultCode"值请参考PNSReturnCode
|
||
*/
|
||
#pragma mark - action 一键登录预取号
|
||
- (void)accelerateLogin:(TXCustomModel *)model call:(FlutterMethodCall*)call result:(FlutterResult)result complete:(void (^)(void))completion {
|
||
float timeout = 5.0; // self.tf_timeout.text.floatValue;
|
||
__weak typeof(self) weakSelf = self;
|
||
|
||
//1. 调用check接口检查及准备接口调用环境
|
||
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
|
||
[weakSelf showResult:resultDic];
|
||
return;
|
||
}
|
||
NSDictionary *dict = @{ @"resultCode": @"600024" };
|
||
[self showResult: dict];
|
||
|
||
//2. 调用取号接口,加速授权页的弹起
|
||
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:timeout complete:^(NSDictionary * _Nonnull resultDic) {
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
|
||
[weakSelf showResult:resultDic];
|
||
return;
|
||
}
|
||
NSDictionary *acceleDict = @{ @"resultCode": @"600016" };
|
||
[self showResult: acceleDict];
|
||
}];
|
||
}];
|
||
}
|
||
|
||
// 跳转Flutter混合原生view界面
|
||
-(void)handleSingleTap:(UITapGestureRecognizer *)sender{ //获得参数
|
||
NSLog(@"%@", @"我被点击了");
|
||
}
|
||
|
||
#pragma mark - action 一键登录公共方法
|
||
- (void)loginWithModel:(TXCustomModel *)model complete:(void (^)(void))completion {
|
||
float timeout = 5.0; //self.tf_timeout.text.floatValue;
|
||
__weak typeof(self) weakSelf = self;
|
||
|
||
// UIWindow *window = [[UIApplication sharedApplication].delegate window];
|
||
// UIViewController * _vc = [[ViewController alloc] init];
|
||
// window.rootViewController = _vc;
|
||
|
||
UIViewController *_vc = [self findCurrentViewController];
|
||
|
||
// UIButton *pushFlutterNativePageButton = [UIButton buttonWithType:UIButtonTypeSystem];
|
||
// pushFlutterNativePageButton.frame = CGRectMake(100, 300, 300, 100);
|
||
// [pushFlutterNativePageButton setTitleColor:[UIColor blueColor] forState:UIControlStateNormal];
|
||
// [pushFlutterNativePageButton setTitle:@"跳转到Flutter混合原生view界面" forState:UIControlStateNormal];
|
||
// [pushFlutterNativePageButton addTarget:self action:@selector(pushFlutterNativePage) forControlEvents:UIControlEventTouchUpInside];
|
||
// [_vc.view addSubview:pushFlutterNativePageButton];
|
||
|
||
// 每次登录时都设置没有登录状态
|
||
self->_isChecked = false;
|
||
|
||
//1. 调用check接口检查及准备接口调用环境
|
||
[[TXCommonHandler sharedInstance] checkEnvAvailableWithAuthType:PNSAuthTypeLoginToken complete:^(NSDictionary * _Nullable resultDic) {
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
|
||
[weakSelf showResult:resultDic];
|
||
return;
|
||
}
|
||
//2. 调用取号接口,加速授权页的弹起
|
||
[[TXCommonHandler sharedInstance] accelerateLoginPageWithTimeout:timeout complete:^(NSDictionary * _Nonnull resultDic) {
|
||
if ([PNSCodeSuccess isEqualToString:[resultDic objectForKey:@"resultCode"]] == NO) {
|
||
[weakSelf showResult:resultDic];
|
||
return;
|
||
}
|
||
|
||
//3. 调用获取登录Token接口,可以立马弹起授权页
|
||
// 关闭loading
|
||
// [MBProgressHUD hideHUDForView:_vc.view animated:YES];
|
||
[[TXCommonHandler sharedInstance] getLoginTokenWithTimeout:timeout controller:_vc model:model complete:^(NSDictionary * _Nonnull resultDic) {
|
||
NSString *code = [resultDic objectForKey:@"resultCode"];
|
||
// UITapGestureRecognizer * tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickAllScreen:)];
|
||
//
|
||
// UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, _vc.view.bounds.size.width, _vc.view.bounds.size.height)];
|
||
//将手势添加到需要相应的view中去
|
||
[[weakSelf findCurrentViewController].view hitTest:CGPointMake(_vc.view.bounds.size.width, _vc.view.bounds.size.height) withEvent:nil];
|
||
// [[weakSelf findCurrentViewController].view addSubview:headerView];
|
||
|
||
// 当未勾选隐私协议时,弹出 Toast 提示
|
||
if ([PNSCodeLoginControllerClickLoginBtn isEqualToString:code] && !self->_isChecked) {
|
||
} else if ([PNSCodeSuccess isEqualToString:code]) {
|
||
bool autoQuitPage = [self->_callData.arguments boolValueForKey: @"autoQuitPage" defaultValue: YES];
|
||
// 登录成功后是否自动关闭页面
|
||
if (autoQuitPage) {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
|
||
});
|
||
}
|
||
} else if ([PNSCodeLoginControllerClickChangeBtn isEqualToString:code]) {
|
||
// 通过switchCheck 参数动态控制 是否需要切换其他方式时需要勾选
|
||
NSDictionary *dic = self -> _callData.arguments;
|
||
if (!self->_isChecked && !self-> _isHideToast && [dic boolValueForKey: @"switchCheck" defaultValue: YES]) {
|
||
} else {
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
|
||
}
|
||
} else if ([PNSCodeLoginControllerClickCheckBoxBtn isEqualToString:code]) { // 点击同意协议
|
||
self->_isChecked = [[resultDic objectForKey:@"isChecked"] boolValue];
|
||
} else if ([PNSCodeLoginControllerClickCancel isEqualToString:code]) { // 取消
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
|
||
} else if ([PNSCodeCarrierChanged isEqualToString:code]) { // 切换运营商
|
||
[[TXCommonHandler sharedInstance] cancelLoginVCAnimated:YES complete:nil];
|
||
}
|
||
[weakSelf showResult:resultDic];
|
||
}];
|
||
}];
|
||
}];
|
||
}
|
||
|
||
#pragma mark - toast
|
||
- (void)showToast:(NSString*) message {
|
||
// NSDictionary *dic = _callData.arguments;
|
||
// UIView *view = [self findCurrentViewController].view;
|
||
// MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo: view animated:YES];
|
||
// // Set the text mode to show only text.
|
||
// hud.mode = MBProgressHUDModeText;
|
||
// hud.label.text = NSLocalizedString(message, @"温馨提示");
|
||
// // 内边剧
|
||
// hud.margin = [dic floatValueForKey: @"toastPadding" defaultValue: 10];
|
||
// // 文本颜色
|
||
// hud.contentColor = [UIColor colorWithHex: [dic stringValueForKey: @"toastColor" defaultValue: @"#FFFFFF"] defaultValue: @"#FFFFFF"];
|
||
// // 弹窗背景
|
||
// hud.bezelView.color = [UIColor colorWithHex: [dic stringValueForKey: @"toastBackground" defaultValue: @"#000000"] defaultValue: @"#000000"];
|
||
// // 弹窗背景样式
|
||
// hud.bezelView.style = MBProgressHUDBackgroundStyleSolidColor;
|
||
//
|
||
// CGFloat offSetY = view.bounds.size.height / 2;
|
||
// NSString* toastPosition = [dic stringValueForKey: @"toastPositionMode" defaultValue: @"bottom"];
|
||
// if ([toastPosition isEqual: @"top"]) {
|
||
// CGFloat top = [dic floatValueForKey: @"toastMarginTop" defaultValue: 30.f];
|
||
// offSetY = - offSetY + view.window.safeAreaInsets.top + top;
|
||
// } else if ([toastPosition isEqual: @"bottom"]) {
|
||
// CGFloat bottom = [dic floatValueForKey: @"toastMarginBottom" defaultValue: 30.f];
|
||
// offSetY = offSetY - view.window.safeAreaInsets.bottom - bottom;
|
||
// } else if ([toastPosition isEqual: @"center"]) {
|
||
// offSetY = 0;
|
||
// }
|
||
// // 设置上下的位置
|
||
// hud.offset = CGPointMake(0.f, offSetY);
|
||
// [hud hideAnimated:YES afterDelay: [dic floatValueForKey: @"toastDelay" defaultValue: 3]];
|
||
}
|
||
|
||
-(void) resultData:(NSDictionary *)dict{
|
||
if (_eventSink != nil) {
|
||
NSMutableDictionary *mutableDict = [dict mutableCopy];
|
||
[mutableDict setObject: self->_isChecked ? @(bool_true):@(bool_false) forKey: @"isChecked"];
|
||
_eventSink(mutableDict);
|
||
}
|
||
}
|
||
|
||
#pragma mark - 格式化数据utils返回数据
|
||
- (void)showResult:(id __nullable)showResult {
|
||
// 当存在autoHideLoginLoading时需要执行关闭
|
||
// if (![self->_callData.arguments boolValueForKey: @"autoHideLoginLoading" defaultValue: YES]) {
|
||
// dispatch_async(dispatch_get_main_queue(), ^{
|
||
// [MBProgressHUD hideHUDForView: [self findCurrentViewController].view animated:YES];
|
||
// });
|
||
// }
|
||
|
||
NSDictionary *dict = @{
|
||
@"code": [NSString stringWithFormat: @"%@", [showResult objectForKey:@"resultCode"]],
|
||
@"msg" : [AliAuthEnum initData][[showResult objectForKey:@"resultCode"]]?:@"",
|
||
@"data" : [showResult objectForKey: @"token"]?:@"",
|
||
@"isChecked": self->_isChecked ? @(bool_true):@(bool_false)
|
||
};
|
||
|
||
[self resultData: dict];
|
||
[self showResultLog: showResult];
|
||
}
|
||
|
||
#pragma mark - 格式化数据utils返回数据
|
||
- (void)showResultMsg:(id __nullable)showResult msg: (NSString*)msg {
|
||
NSString *resultMsg = [NSString stringWithFormat: [AliAuthEnum initData][[showResult objectForKey:@"resultCode"]], msg]?:@"";
|
||
NSDictionary *dict = @{
|
||
@"code": [NSString stringWithFormat: @"%@", [showResult objectForKey:@"resultCode"]],
|
||
@"msg" : resultMsg,
|
||
@"data" : [showResult objectForKey: @"token"]?:@""
|
||
};
|
||
|
||
[self resultData: dict];
|
||
[self showResultLog: showResult];
|
||
}
|
||
|
||
#pragma mark - 格式化数据utils统一输出日志
|
||
- (void)showResultLog:(id __nullable)showResult {
|
||
dispatch_async(dispatch_get_main_queue(), ^{
|
||
NSString *desc = nil;
|
||
if ([showResult isKindOfClass:NSString.class]) {
|
||
desc = (NSString *)showResult;
|
||
} else {
|
||
desc = [showResult description];
|
||
// if (desc != nil) {
|
||
// desc = [NSString stringWithCString:[desc cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding];
|
||
// }
|
||
}
|
||
// NSLog( @"打印日志---->>%@", desc );
|
||
});
|
||
}
|
||
|
||
#pragma mark - Apple授权登录
|
||
// 处理授权
|
||
- (void)handleAuthorizationAppleIDButtonPress:(FlutterMethodCall*)call result:(FlutterResult)result{
|
||
NSLog(@"点击授权---开始授权");
|
||
if (@available(iOS 13.0, *)) {
|
||
// 基于用户的Apple ID授权用户,生成用户授权请求的一种机制
|
||
ASAuthorizationAppleIDProvider *appleIDProvider = [[ASAuthorizationAppleIDProvider alloc] init];
|
||
// 创建新的AppleID 授权请求
|
||
ASAuthorizationAppleIDRequest *appleIDRequest = [appleIDProvider createRequest];
|
||
// 在用户授权期间请求的联系信息
|
||
appleIDRequest.requestedScopes = @[ASAuthorizationScopeFullName, ASAuthorizationScopeEmail];
|
||
// 由ASAuthorizationAppleIDProvider创建的授权请求 管理授权请求的控制器
|
||
ASAuthorizationController *authorizationController = [[ASAuthorizationController alloc] initWithAuthorizationRequests:@[appleIDRequest]];
|
||
// 设置授权控制器通知授权请求的成功与失败的代理
|
||
authorizationController.delegate = self;
|
||
// 设置提供 展示上下文的代理,在这个上下文中 系统可以展示授权界面给用户
|
||
authorizationController.presentationContextProvider = self;
|
||
// 在控制器初始化期间启动授权流
|
||
[authorizationController performRequests];
|
||
}
|
||
else{
|
||
// 处理不支持系统版本
|
||
NSLog(@"该系统版本不可用Apple登录");
|
||
NSDictionary *resultData = @{
|
||
@"code": @500,
|
||
@"msg" : @"该系统版本不可用Apple登录",
|
||
@"user" : @"",
|
||
@"familyName" : @"",
|
||
@"givenName" : @"",
|
||
@"email" : @"",
|
||
@"identityTokenStr": @"",
|
||
@"authorizationCodeStr": @""
|
||
};
|
||
|
||
[self resultData: resultData];
|
||
}
|
||
}
|
||
|
||
|
||
#pragma mark - delegate
|
||
//@optional 授权成功地回调
|
||
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithAuthorization:(ASAuthorization *)authorization API_AVAILABLE(ios(13.0)){
|
||
// NSLog(@"授权完成:::%@", authorization.credential);
|
||
NSLog(@"授权完成---开始返回数据");
|
||
if ([authorization.credential isKindOfClass:[ASAuthorizationAppleIDCredential class]]) {
|
||
// 用户登录使用ASAuthorizationAppleIDCredential
|
||
ASAuthorizationAppleIDCredential *appleIDCredential = (ASAuthorizationAppleIDCredential *)authorization.credential;
|
||
NSString *user = appleIDCredential.user;
|
||
// 使用过授权的,可能获取不到以下三个参数
|
||
NSString *familyName = appleIDCredential.fullName.familyName;
|
||
NSString *givenName = appleIDCredential.fullName.givenName;
|
||
NSString *email = appleIDCredential.email;
|
||
|
||
NSData *identityToken = appleIDCredential.identityToken;
|
||
NSData *authorizationCode = appleIDCredential.authorizationCode;
|
||
|
||
// 服务器验证需要使用的参数
|
||
NSString *identityTokenStr = [[NSString alloc] initWithData:identityToken encoding:NSUTF8StringEncoding];
|
||
NSString *authorizationCodeStr = [[NSString alloc] initWithData:authorizationCode encoding:NSUTF8StringEncoding];
|
||
// NSLog(@"后台参数--%@\n\n%@", identityTokenStr, authorizationCodeStr);
|
||
// NSLog(@"后台参数identityTokenStr---%@", identityTokenStr);
|
||
// NSLog(@"后台参数authorizationCodeStr---%@", authorizationCodeStr);
|
||
|
||
// Create an account in your system.
|
||
// For the purpose of this demo app, store the userIdentifier in the keychain.
|
||
// 需要使用钥匙串的方式保存用户的唯一信息
|
||
// [YostarKeychain save:KEYCHAIN_IDENTIFIER(@"userIdentifier") data:user];
|
||
// NSLog(@"user--%@", user);
|
||
// NSLog(@"familyName--%@", familyName);
|
||
// NSLog(@"givenName--%@", givenName);
|
||
// NSLog(@"email--%@", email);
|
||
|
||
NSDictionary *resultData = @{
|
||
@"code": @200,
|
||
@"msg" : @"获取成功",
|
||
@"user" : user,
|
||
@"familyName" : familyName != nil ? familyName : @"",
|
||
@"givenName" : givenName != nil ? givenName : @"",
|
||
@"email" : email != nil ? email : @"",
|
||
@"identityTokenStr": identityTokenStr,
|
||
@"authorizationCodeStr": authorizationCodeStr
|
||
};
|
||
|
||
[self resultData: resultData];
|
||
}else if ([authorization.credential isKindOfClass:[ASPasswordCredential class]]){
|
||
// 这个获取的是iCloud记录的账号密码,需要输入框支持iOS 12 记录账号密码的新特性,如果不支持,可以忽略
|
||
// Sign in using an existing iCloud Keychain credential.
|
||
// 用户登录使用现有的密码凭证
|
||
ASPasswordCredential *passwordCredential = (ASPasswordCredential*)authorization.credential;
|
||
// 密码凭证对象的用户标识 用户的唯一标识
|
||
NSString *user = passwordCredential.user;
|
||
// 密码凭证对象的密码
|
||
NSString *password = passwordCredential.password;
|
||
NSLog(@"user--%@", user);
|
||
NSLog(@"password--%@", password);
|
||
|
||
NSDictionary *resultData = @{
|
||
@"code": @200,
|
||
@"msg" : @"获取成功",
|
||
@"user" : user,
|
||
@"familyName" : @"",
|
||
@"givenName" : @"",
|
||
@"email" : @"",
|
||
@"identityTokenStr": @"",
|
||
@"authorizationCodeStr": @""
|
||
};
|
||
|
||
[self resultData: resultData];
|
||
}else{
|
||
NSLog(@"授权信息均不符");
|
||
NSDictionary *resultData = @{
|
||
@"code": @500,
|
||
@"msg" : @"授权信息均不符",
|
||
@"user" : @"",
|
||
@"familyName" : @"",
|
||
@"givenName" : @"",
|
||
@"email" : @"",
|
||
@"identityTokenStr": @"",
|
||
@"authorizationCodeStr": @""
|
||
};
|
||
|
||
[self resultData: resultData];
|
||
}
|
||
}
|
||
|
||
// 授权失败的回调
|
||
- (void)authorizationController:(ASAuthorizationController *)controller didCompleteWithError:(NSError *)error API_AVAILABLE(ios(13.0)){
|
||
// Handle error.
|
||
NSLog(@"苹果登录授权失败:%@", error);
|
||
NSString *errorMsg = nil;
|
||
switch (error.code) {
|
||
case ASAuthorizationErrorCanceled:
|
||
errorMsg = @"用户取消了授权请求";
|
||
break;
|
||
case ASAuthorizationErrorFailed:
|
||
errorMsg = @"授权请求失败";
|
||
break;
|
||
case ASAuthorizationErrorInvalidResponse:
|
||
errorMsg = @"授权请求响应无效";
|
||
break;
|
||
case ASAuthorizationErrorNotHandled:
|
||
errorMsg = @"未能处理授权请求";
|
||
break;
|
||
case ASAuthorizationErrorUnknown:
|
||
errorMsg = @"授权请求失败未知原因";
|
||
break;
|
||
|
||
default:
|
||
break;
|
||
}
|
||
|
||
NSLog(@"%@", errorMsg);
|
||
NSDictionary *resultData = @{
|
||
@"code": @500,
|
||
@"msg" : errorMsg,
|
||
@"user" : @"",
|
||
@"familyName" : @"",
|
||
@"givenName" : @"",
|
||
@"email" : @"",
|
||
@"identityTokenStr": @"",
|
||
@"authorizationCodeStr": @""
|
||
};
|
||
|
||
[self resultData: resultData];
|
||
}
|
||
|
||
#pragma mark - 告诉代理应该在哪个window 展示内容给用户
|
||
- (ASPresentationAnchor)presentationAnchorForAuthorizationController:(ASAuthorizationController *)controller API_AVAILABLE(ios(13.0)){
|
||
NSLog(@"88888888888");
|
||
// 返回window
|
||
return [UIApplication sharedApplication].windows.lastObject;
|
||
}
|
||
|
||
#pragma mark - 获取到跟视图
|
||
- (UIViewController *)getRootViewController {
|
||
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
|
||
return window.rootViewController;
|
||
}
|
||
|
||
#pragma mark ======在view上添加UIViewController========
|
||
- (UIViewController *)findCurrentViewController{
|
||
UIWindow *window = [[UIApplication sharedApplication].delegate window];
|
||
|
||
// UIViewController * vc = [[ViewController alloc] init];
|
||
// window.rootViewController = vc;
|
||
// UITapGestureRecognizer* singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(clickAllScreen:)];
|
||
// [window addGestureRecognizer:singleTap];
|
||
UIViewController *topViewController = [window rootViewController];
|
||
while (true) {
|
||
if (topViewController.presentedViewController) {
|
||
topViewController = topViewController.presentedViewController;
|
||
} else if ([topViewController isKindOfClass:[UINavigationController class]] && [(UINavigationController*)topViewController topViewController]) {
|
||
topViewController = [(UINavigationController *)topViewController topViewController];
|
||
} else if ([topViewController isKindOfClass:[UITabBarController class]]) {
|
||
UITabBarController *tab = (UITabBarController *)topViewController;
|
||
topViewController = tab.selectedViewController;
|
||
} else {
|
||
break;
|
||
}
|
||
}
|
||
return topViewController;
|
||
}
|
||
|
||
- (void) clickAllScreen:(UITapGestureRecognizer *) recognizer {
|
||
NSLog(@"点击事件屏蔽");
|
||
}
|
||
|
||
@end
|