检测本地是否保存有用户的密码。如果有,则下次自动登录;如果没有,则提示用户登录。
DJAccount.h
#import@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()@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@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 ()@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
最终效果: