检测本地是否保存有用户的密码。如果有,则下次自动登录;如果没有,则提示用户登录。
DJAccount.h
#import <Foundation/Foundation.h> @interface DJAccount : NSObject /** 访问token */ @property (nonatomic,copy) NSString *access_token; /** 过期时间,单位是秒 */ @property (nonatomic,copy) NSNumber *expires_in; /** 当前user id */ @property (nonatomic,copy) NSString *uid; /** 当前帐号创建时间 */ @property (nonatomic,strong) NSDate *create_time; + (instancetype)accountWithDictionary:(NSDictionary *)dict; @end
DJAccount.m
#import "DJAccount.h" @interface DJAccount() <NSCoding> @end @implementation DJAccount + (instancetype)accountWithDictionary:(NSDictionary *)dict { DJAccount *account = [[DJAccount alloc] init]; account.access_token = dict[@"access_token"]; account.expires_in = dict[@"expires_in"]; account.uid = dict[@"uid"]; account.create_time = [NSDate date]; return account; } - (void)encodeWithCoder:(NSCoder *)encoder { [encoder encodeObject:self.access_token forKey:@"access_token"]; [encoder encodeObject:self.expires_in forKey:@"expires_in"]; [encoder encodeObject:self.uid forKey:@"uid"]; [encoder encodeObject:self.create_time forKey:@"create_time"]; } - (instancetype)initWithCoder:(NSCoder *)decoder { if (self = [super init]) { self.access_token = [decoder decodeObjectForKey:@"access_token"]; self.expires_in = [decoder decodeObjectForKey:@"expires_in"]; self.uid = [decoder decodeObjectForKey:@"uid"]; self.create_time = [decoder decodeObjectForKey:@"create_time"]; } return self; } @end
DJAccountTool.h
#import <Foundation/Foundation.h> @class DJAccount; @interface DJAccountTool : NSObject + (void)saveAccount:(DJAccount *)account; + (DJAccount *)account; @end
DJAccountTool.m
#import "DJAccountTool.h" #import "DJAccount.h" #define DJAccountPath [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.archiver"] @implementation DJAccountTool + (void)saveAccount:(DJAccount *)account { [NSKeyedArchiver archiveRootObject:account toFile:DJAccountPath]; } + (DJAccount *)account { DJAccount *account = [NSKeyedUnarchiver unarchiveObjectWithFile:DJAccountPath]; // 判断当前帐号是否过期 long long expires_in = [account.expires_in longLongValue]; // 获得过期时间 NSDate *expires_time = [account.create_time dateByAddingTimeInterval:expires_in]; // 获得当前时间 NSDate *now_time = [NSDate date]; // 如果now大于expires_time,则代表过期 NSComparisonResult result = [expires_time compare:now_time]; if (result != NSOrderedDescending) { return nil; } return account; } @end
UIWindow+Extension.m
#import "UIWindow+Extension.h" #import "DJMainViewController.h" #import "DJNewFeatureViewController.h" @implementation UIWindow (Extension) + (void)switchRootViewController { // 获取当前主窗口 UIWindow *window = [UIApplication sharedApplication].keyWindow; NSString *versionKey = @"CFBundleVersion"; // 从Info.plist中读取当前软件版本号 NSString *currentVersion = [NSBundle mainBundle].infoDictionary[versionKey]; // 从沙盒中读取保存的历史版本号 NSString *lastVersion = [[NSUserDefaults standardUserDefaults] objectForKey:versionKey]; // 判断当前软件版本号是否与沙盒中保存的一致 if ([currentVersion isEqualToString:lastVersion]) { // 版本号一致 DJMainViewController *mainVc = [[DJMainViewController alloc] init]; window.rootViewController = mainVc; } else { // 版本号不一致,显示新特性,并将当前软件版本号保存到沙盒 /* 1.显示新特性 */ DJNewFeatureViewController *newVc = [[DJNewFeatureViewController alloc] init]; window.rootViewController = newVc; /* 2.将当前版本号写入到沙盒 */ [[NSUserDefaults standardUserDefaults] setValue:currentVersion forKey:versionKey]; // 立即将内存中的数据同步到沙盒 [[NSUserDefaults standardUserDefaults] synchronize]; } } @end
AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // 1. 创建窗口 self.window = [[UIWindow alloc] init]; self.window.frame = [UIScreen mainScreen].bounds; // 2. 显示窗口 [self.window makeKeyAndVisible]; // 3. 判断当前帐户是否已经被授权来决定根控制器显示 DJAccount *account = [DJAccountTool account]; if (account) { // 之前已经成功授权 [UIWindow switchRootViewController]; } else { // 尚未成功授权 self.window.rootViewController = [[DJOAuthViewController alloc] init]; } return YES; }
DJOAuthViewController.m
#import "DJOAuthViewController.h" #import "AFNetworking.h" #import "DJAccount.h" #import "DJAccountTool.h" #import "MBProgressHUD+MJ.h" @interface DJOAuthViewController () <UIWebViewDelegate> @end @implementation DJOAuthViewController - (void)viewDidLoad { [super viewDidLoad]; /* client_id&redirect_uri */ NSString *client_id = @"249054863"; NSString *redirect_uri = @"https://www.baidu.com"; UIWebView *webView = [[UIWebView alloc] init]; webView.frame = self.view.bounds; webView.delegate = self; [self.view addSubview:webView]; NSString *urlString = [NSString stringWithFormat:@"https://api.weibo.com/oauth2/authorize?client_id=%@&redirect_uri=%@",client_id,redirect_uri]; NSURL *url = [NSURL URLWithString:urlString]; NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [webView loadRequest:urlRequest]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - webView 代理方法 - (void)webViewDidStartLoad:(UIWebView *)webView { [MBProgressHUD showMessage:@"加载中..."]; } - (void)webViewDidFinishLoad:(UIWebView *)webView { [MBProgressHUD hideHUD]; } /** 此方法可用于拦截http请求 */ - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType { NSString *urlString = request.URL.absoluteString; DJLog(@"current access url str : %@",urlString); // 1. 判断当前地址是否是回调地址(https://www.baidu.com/?code=27a3d9fb9bbc5d3c20be9ae8e4331b02) NSRange range= [urlString rangeOfString:@"code="]; if (range.length != 0) { // 是回调地址 // 2.截取code=后面的参数值 NSUInteger fromIndex = range.location + range.length; NSString *code = [urlString substringFromIndex:fromIndex]; // code 就是授权成功的请求标记 // 3.使用授权成功的请求标记(code)来换取accessToken [self getAccessTokenWithCode:code]; // 4.禁止加载回调地址 return NO; } return YES; } - (void)getAccessTokenWithCode:(NSString *)code { // 1. 创建请求管理者 AFHTTPSessionManager *requestManager = [AFHTTPSessionManager manager]; // 2. 配置请求参数 NSString *urlString = @"https://api.weibo.com/oauth2/access_token"; // 请求授权的access_token URL NSMutableDictionary *params = [NSMutableDictionary dictionary]; params[@"client_id"] = @"249054863"; params[@"client_secret"] = @"71d5b761bac9f377af3b938f6d89ba85"; params[@"grant_type"] = @"authorization_code"; params[@"code"] = code; params[@"redirect_uri"] = @"https://www.baidu.com"; // 3. 发送请求 [requestManager POST:urlString parameters:params progress:nil success:^(NSURLSessionDataTask * _Nonnull task, NSDictionary * _Nullable dict) { [MBProgressHUD hideHUD]; // 1. 将返回的字典转换为模型 DJAccount *account = [DJAccount accountWithDictionary:dict]; // 2. 存储当前帐号信息 [DJAccountTool saveAccount:account]; // 3. 切换根控制器到DJMainViewController [UIWindow switchRootViewController]; } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) { [MBProgressHUD showError:@"授权失败"]; DJLog(@"failure responseObject: %@",error); }]; } @end
最终效果:
时间: 2024-10-10 14:15:33