1.AppDelegate中账号设置
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window makeKeyAndVisible];
// 先判断有无存储账号信息
MRAccount *account = [MRAccountTool account];
if (account) { // 之前登录成功
[MRWeiboTools chooseRootController];
} else { // 之前没有登录成功
self.window.rootViewController = [[UIOauthController alloc] init];
}
在工具类MRWeiboTools中设置
#import <Foundation/Foundation.h>
@interface MRWeiboTools : NSObject
/**
* 选择根控制器
*/
+ (void)chooseRootController;
@end
#import "MRWeiboTools.h"
#import "MRNewFeatureController.h"
#import "MRRootTabBarController.h"
@implementation MRWeiboTools
+ (void)chooseRootController
{
NSString *key = @"CFBundleVersion";
// 取出沙盒中存储的上次使用软件的版本号
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSString *lastVersion = [defaults stringForKey:key];
// 获得当前软件的版本号
NSString *currentVersion = [NSBundle mainBundle].infoDictionary[key];
if ([currentVersion isEqualToString:lastVersion]) {
// 显示状态栏
[UIApplication sharedApplication].statusBarHidden = NO;
[UIApplication sharedApplication].keyWindow.rootViewController = [[MRRootTabBarController alloc] init];
} else { // 新版本
[UIApplication sharedApplication].keyWindow.rootViewController = [[MRNewFeatureController alloc] init];
// 存储新版本
[defaults setObject:currentVersion forKey:key];
[defaults synchronize];
}
}
@end
2.Oauth授权设置
#import "UIOauthController.h"
#import "AFNetworking.h"
#import "MRAccount.h"
#import "MRRootTabBarController.h"
#import "MRNewFeatureController.h"
#import "Header.h"
#import "MRAccountTool.h"
#import "MRWeiboTools.h"
@interface UIOauthController ()<UIWebViewDelegate>
@end
@implementation UIOauthController
- (void)viewDidLoad {
[super viewDidLoad];
UIWebView *webView = [[UIWebView alloc]init];
webView.frame = self.view.bounds;
webView.delegate = self;
[self.view addSubview:webView];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://api.weibo.com/oauth2/authorize?client_id=2141405173&redirect_uri=http://blog.csdn.net/supersonico"]];
[webView loadRequest:request];
// Do any additional setup after loading the view.
}
#pragma mark - webView代理方法
/**
* 当webView发送一个请求之前都会先调用这个方法, 询问代理可不可以加载这个页面(请求)
*
* @param request <#request description#>
*
* @return YES : 可以加载页面, NO : 不可以加载页面
*/
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// 1.请求的URL路径: http://blog.csdn.net/supersonico?code=4ed0b0e7f93594a935b5b6d149daf090
NSString *urlStr = request.URL.absoluteString;
// 2.查找code=在urlStr中的范围
NSRange range = [urlStr rangeOfString:@"code="];
// 3.如果urlStr中包含了code=
if (range.length) {
// 4.截取code=后面的请求标记(经过用户授权成功的)
int loc = range.location + range.length;
NSString *code = [urlStr substringFromIndex:loc];
// 5.发送POST请求给新浪, 通过code换取一个accessToken
[self accessTokenWithCode:code];
}
return YES;
}
/**
* 通过code换取一个accessToken
redirect_uri true string 回调地址,需需与注册应用里的回调地址一致。
*/
- (void)accessTokenWithCode:(NSString *)code
{
// AFNetworking\AFN
// 1.创建请求管理对象
AFHTTPRequestOperationManager *mgr = [AFHTTPRequestOperationManager manager];
// 说明服务器返回的JSON数据
mgr.responseSerializer = [AFJSONResponseSerializer serializer];
// 2.封装请求参数
NSMutableDictionary *params = [NSMutableDictionary dictionary];
params[@"client_id"] = @"2141405173";
params[@"client_secret"] = @"e015a9dd429266eae4415fc450fcbe46";
params[@"grant_type"] = @"authorization_code";
params[@"code"] = code;
params[@"redirect_uri"] = @"http://blog.csdn.net/supersonico";
// 3.发送请求
[mgr POST:@"https://api.weibo.com/oauth2/access_token" parameters:params
success:^(AFHTTPRequestOperation *operation, id responseObject) {
// 4.先将字典转为模型
NSLog(@"-------%@-------",responseObject);
MRAccount *account = [MRAccount accountWithDict:responseObject];
// 5.存储模型数据
[MRAccountTool saveAccount:account];
// 6.新特性\去首页
[MRWeiboTools chooseRootController];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
IWLog(@"请求失败:%@", error);
}];
}
@end
MRAccountTool.h中设置
#import <Foundation/Foundation.h>
@class MRAccount;
@interface MRAccountTool : NSObject
/**
* 存储账号信息
*
* @param account 需要存储的账号
*/
+ (void)saveAccount:(MRAccount *)account;
/**
* 返回存储的账号信息
*/
+ (MRAccount *)account;
@end
#import "MRAccountTool.h"
#import "MRAccount.h"
#define MRAccountFile [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"account.data"]
@implementation MRAccountTool
+ (void)saveAccount:(MRAccount *)account
{
// 计算账号的过期时间
NSDate *now = [NSDate date];
account.expiresTime = [now dateByAddingTimeInterval:account.expires_in];
[NSKeyedArchiver archiveRootObject:account toFile:MRAccountFile];
}
+ (MRAccount *)account
{
// 取出账号
MRAccount *account = [NSKeyedUnarchiver unarchiveObjectWithFile:MRAccountFile];
// 判断账号是否过期
NSDate *now = [NSDate date];
if ([now compare:account.expiresTime] == NSOrderedAscending) { // 还没有过期
return account;
} else { // 过期
return nil;
}
}
@end
MRAccount:
#import <Foundation/Foundation.h>
@interface MRAccount : NSObject<NSCoding>
@property (nonatomic, copy) NSString *access_token;
// 如果服务器返回的数字很大, 建议用long long(比如主键, ID)
@property (nonatomic, assign) long long expires_in;
@property (nonatomic, assign) long long remind_in;
@property (nonatomic, assign) long long uid;
@property (nonatomic, strong) NSDate *expiresTime; // 账号的过期时间
+ (instancetype)accountWithDict:(NSDictionary *)dict;
- (instancetype)initWithDict:(NSDictionary *)dict;
@end
#import "MRAccount.h"
@implementation MRAccount
+ (instancetype)accountWithDict:(NSDictionary *)dict
{
return [[self alloc] initWithDict:dict];
}
- (instancetype)initWithDict:(NSDictionary *)dict
{
if (self = [super init]) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
/**
* 从文件中解析对象的时候调
*/
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
self.access_token = [decoder decodeObjectForKey:@"access_token"];
self.remind_in = [decoder decodeInt64ForKey:@"remind_in"];
self.expires_in = [decoder decodeInt64ForKey:@"expires_in"];
self.uid = [decoder decodeInt64ForKey:@"uid"];
self.expiresTime = [decoder decodeObjectForKey:@"expiresTime"];
}
return self;
}
/**
* 将对象写入文件的时候调用
*/
- (void)encodeWithCoder:(NSCoder *)encoder
{
[encoder encodeObject:self.access_token forKey:@"access_token"];
[encoder encodeObject:self.expiresTime forKey:@"expiresTime"];
[encoder encodeInt64:self.remind_in forKey:@"remind_in"];
[encoder encodeInt64:self.expires_in forKey:@"expires_in"];
[encoder encodeInt64:self.uid forKey:@"uid"];
}
@end