ios实战开发之仿新浪微博(第四讲:OAuth认证)
1、效果演示http://player.youku.com/player.php/sid/XNjk5MzY4MDAw/v.swf
2、设计思路
2.1 创建一个OAuth认证控制器,并加载一个WebView
2.2 WebView加载新浪认证的URL(注册新浪帐号并成为新浪开发者),参照 http://open.weibo.com
2.3 使用WebView的代理方法发送RequestToken获取AccessToken
2.3.1 通过返回的URL截取code值即为requestToken
2.3.2 新建一个工具类封装第三方框架(AFNetWorking)的抓取网页数据方法获取JSON
2.3.3 创建一个数据模型保存JSON并归档
2.4 通过判断归档中是否存在AccessToken来修改当前显示的View,如果没有跳转到认证界面,如果有直接跳转到MainView
3、关键代码
SAOAuthController.h
//
//SAOAuthController.h
//SianWeibo
//
//Created by yusian on 14-4-14.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface SAOAuthController : UIViewController
@end
SAOAuthController.m
//
//SAOAuthController.m
//SianWeibo
//
//Created by yusian on 14-4-14.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SAOAuthController.h"
#import "SACommon.h"
#import "SAHttpTool.h"
#import "SAAccountTool.h"
#import "SAMainController.h"
#import "MBProgressHUD.h"
@interface SAOAuthController () <UIWebViewDelegate>
{
UIWebView *_webView;
}
@end
@implementation SAOAuthController
#pragma mark 设置WebView为主View
-(void)loadView
{
_webView = [ initWithFrame:.applicationFrame];
self.view = _webView;
_webView.delegate = self;
}
#pragma mark 加载web数据到View
- (void)viewDidLoad
{
;
// 1 拼接请求授权的URL
NSString *requestRULString = ;
NSURL *url = ;
// 2 将请求的页面加载到WebView
NSURLRequest *request = [ initWithURL:url];
;
}
#pragma mark 代理方法获取Token
-(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
// 1、获取全路径,将URL转换成字符串
NSString *url = request.URL.absoluteString;
// 2、查找code范围
NSRange range = ; // 匹配包含"code="的URL
if (range.length){ // 如果有,取"code="后跟的串,即为requestToken
NSInteger index = range.location + range.length;
NSString *requestToken = ;
// 3、换取accessToken
;
return NO;
}
return YES;
}
-(void)getAccessToken:(NSString *)requestToken
{
// SAHttpTool类中自定义方法,实为封装AFNetWorking的方法获取网页数据
[SAHttpTool httpToolPostWithBaseURL:@"https://api.weibo.com" path:@"oauth2/access_token" params:
@{
// 新浪要求必须传递的五个参数
@"client_id" : kAppKey,
@"client_secret" : kAppSecret,
@"grant_type" : @"authorization_code",
@"code" : requestToken,
@"redirect_uri" : kRedirect_uri
// 成功获取JSON
} success:^(id JSON) {
MyLog(@"请求成功");
// 1 将JSON转换成数据模型并归档
SAAccount *account = ;
[ saveAccount:account];
// 2 跳转到主页面
self.view.window.rootViewController = [init];
// MyLog(@"%@", JSON);
// 3 清除页面加载提示
;
// 获取信息失败
} failure:^(NSError *error) {
// 1 打印错误提示
MyLog(@"请求失败-%@", );
// 2 清除页面加载提示
;
}];
}
#pragma mark - webView的两个代理方法
#pragma mark 开始加载页面时调用
- (void)webViewDidStartLoad:(UIWebView *)webView
{
// 引入第三方框架"MBProgressHUD"添加页面加载提示
MBProgressHUD *hud = ;
hud.labelText = @"小龙虾加油中..."; // 设置文字
hud.labelFont = ;
}
#pragma mark 页面加载完毕后调用
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
// 清除页面加载提示
;
}
@end
SAAccount.h
//
//SAAccount.h
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface SAAccount : NSObject <NSCoding>
@property (nonatomic, copy) NSString *accessToken;
@property (nonatomic, copy) NSString *expiresIn;
@property (nonatomic, copy) NSString *remindIn;
@property (nonatomic, copy) NSString *uid;
- (id)initWithDict:(NSDictionary *)dict;
+ (id)accountWithDict:(NSDictionary *)dict;
@end
SAAccount.m
//
//SAAccount.m
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SAAccount.h"
@implementation SAAccount
- (id)initWithDict:(NSDictionary *)dict
{
if (self = )
{
self.accessToken = dict[@"access_token"];
self.expiresIn = dict[@"expires_in"];
self.remindIn = dict[@"remind_in"];
self.uid = dict[@"uid"];
}
return self;
}
+ (id)accountWithDict:(NSDictionary *)dict
{
return [ initWithDict:dict];
}
- (void)encodeWithCoder:(NSCoder *)aCoder
{
;
;
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = ) {
self.accessToken = ;
self.uid = ;
}
return self;
}
@end
SAAccountTool.h
//
//SAAccountTool.h
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import <Foundation/Foundation.h>
#import "SAAccount.h"
@interface SAAccountTool : NSObject
@property (nonatomic, readonly) SAAccount *account;
+ (SAAccountTool *)sharedAccountTool;
- (void)saveAccount:(SAAccount *)account;
@end
SAAccountTool.m
//
//SAAccountTool.m
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SAAccountTool.h"
#define kAccountFile stringByAppendingString:@"/account.data"]
@implementation SAAccountTool
// 单例创建三个条件
// 1、全局实例
static SAAccountTool *_instance;
// 2、类创建方法
+ (SAAccountTool *)sharedAccountTool
{
if (_instance) {
_instance = [ init];
}
return[ init];
}
// 3、重写alloc方法
+ (id)allocWithZone:(struct _NSZone *)zone
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_instance = ;
});
return _instance;
}
// 单例在MRC中还需要重写以下三个方法
/******************************
-(oneway void)release
{
return;
}
-(id)retain
{
return self;
}
-(NSUInteger)retainCount
{
return 1;
}
*******************************/
- (id)init
{
if (self = ) {
_account = ;
}
return self;
}
- (void)saveAccount:(SAAccount *)account
{
_account = account;
;
}
@end
SAHttpTool.h
//
//SAHttpTool.h
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import <Foundation/Foundation.h>
typedef void (^Success)(id JSON);
typedef void (^Failure)(NSError *error);
@interface SAHttpTool : NSObject
+ (void)httpToolPostWithBaseURL:(NSString *)urlString path:(NSString *)pathString params:(NSDictionary *)params success:(Success)success failure:(Failure)failure;
@end
SAHttpTool.m
//
//SAHttpTool.m
//SianWeibo
//
//Created by yusian on 14-4-15.
//Copyright (c) 2014年 小龙虾论坛. All rights reserved.
//
#import "SAHttpTool.h"
#import "AFNetWorking.h"
@implementation SAHttpTool
// 包装第三方框架AFNetWorking,对外提供类似方法
+ (void)httpToolPostWithBaseURL:(NSString *)urlString path:(NSString *)pathString params:(NSDictionary *)params success:(Success)success failure:(Failure)failure
{
// 获取授权
// 1、创建一个Operation
AFHTTPClient *client = [ initWithBaseURL:];
NSURLRequest *post = ;
// 2、发送Operation请求
AFJSONRequestOperation *json = [AFJSONRequestOperation JSONRequestOperationWithRequest:post
success:
^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
success(JSON); // 将方法中的实参传给内部的Success Block调用
}
failure:
^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
failure(error); // 将方法中的error传给内部的Failure Block调用
}];
;
}
@end
4、源码下载
**** Hidden Message *****
相关主题链接
1、ios实战开发之仿新浪微博(第一讲:新特性展示)
2、ios实战开发之仿新浪微博(第二讲:主框架搭建)
3、ios实战开发之仿新浪微博(第三讲:更多界面搭建)
4、ios实战开发之仿新浪微博(第四讲:OAuth认证)
5、ios实战开发之仿新浪微博(第五讲:微博数据加载)
6、ios实战开发之仿新浪微博(第六讲:微博数据展示一)
7、ios实战开发之仿新浪微博(第七讲:微博数据展示二)
8、ios实战开发之仿新浪微博(第八讲:微博数据展示三)
9、ios实战开发之仿新浪微博(第九讲:微博功能完善一)
10、ios实战开发之仿新浪微博(第十讲:微博功能完善二)
11、ios实战开发之仿新浪微博(第十一讲:微博功能完善三)
12、ios实战开发之仿新浪微博(小龙虾发布版)
给使用AFNetworking2.0以上版本的同学提个醒,新浪返回access_Token数据时,有个坑。
AFJSONRequestOperation默认不接收text/plain类型的数据,当服务器返回text/plain类型的数据时,会认为出错了。可以通过修改源代码解决问题
+ (NSSet *)acceptableContentTypes {
return ;
} 继续感谢!!!!! 看着挺好的,收藏了 囫囵吞枣啊、、、、、、、 挺好的,学习了 继续学习怎么进行OAuth认证 支持个,学习学习 继续学习怎么进行OAuth认证 请问kOAuthURL、kAppKey、kRedirect_url这三个常量在哪? lihaitao 发表于 2014-12-22 15:52
请问kOAuthURL、kAppKey、kRedirect_url这三个常量在哪?
Classes--Other--SACommon.h 工程常量文件