当前位置:首页 » 编程语言

【新浪微博项目】11--OAuth授权设置

2015-04-13 11:25 本站整理 浏览(106)


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