首先得获取kWeiXinAppSecret和kWeiXinAppId两个参数;
这两个参数都是在微信里面有体现的;
在项目中导入依赖库:
添加iOS9 URL Schemes.
添加URL Types
Appdelegate部分代码如下:
导入类#import “WXApi.h”
导入类#import “WXApiHan.h”
挂上代理:WXApiDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
root = [[ViewController alloc]init];
self.window.rootViewController = root;
[WXApi registerApp:@"wx********" withDescription:@"***************"];
// [WXApi registerApp:kWeiXinAppId withDescription:kAppDescription];
return YES;
}
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url {
return [WXApi handleOpenURL:url delegate:[WXApiHan sharedManager]];
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
return [WXApi handleOpenURL:url delegate:[WXApiHan sharedManager]];
}
- (void)onReq:(BaseReq*)req
{
/*
onReq是微信终端向第三方程序发起请求,要求第三方程序响应。第三方程序响应完后必须调用sendRsp返回。在调用sendRsp返回时,会切回到微信终端程序界面。
*/
}
需要放在一个继承NSObject的类里面实现(WXApiHan.m)
+(instancetype)sharedManager {
static dispatch_once_t onceToken;
static WXApiHan *instance;
dispatch_once(&onceToken, ^{
instance = [[WXApiHan alloc] init];
});
return instance;
}
#pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
NSLog(@"%d",resp.errCode);
/*
如果第三方程序向微信发送了sendReq的请求,那么onResp会被回调。sendReq请求调用后,会切到微信终端程序界面。
*/
if (resp.errCode == 0)
{
NSLog(@"用户同意");
SendAuthResp *aresp = (SendAuthResp *)resp;
[self getAccessTokenWithCode:aresp.code];
}else if (resp.errCode == -4){
NSLog(@"用户拒绝");
}else if (resp.errCode == -2){
NSLog(@"用户取消");
}
}
最后在发出请求授权,代码如下:
使用js调用OC方法授权
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
JSContext *context = [self.WebViewChat valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
context[@"wxLogin"] = ^() {
NSArray *args = [JSContext currentArguments];
for (id obj in args) {
//当OC调用JS的方法和JS调用OC的方法名一致时会出现循环调用
NSLog(@"重复调用%@",obj);
}
SendAuthReq* req =[[SendAuthReq alloc ] init];
req.scope = @"snsapi_userinfo" ;
req.state = @"123" ;
req.state = kAppDescription;
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApi sendReq:req];
//使用通知进行传值
[[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(WetchatNot:) name:@"not" object:nil];
};
}
//直接触发授权
- (void)sendAuthRequest{
//构造SendAuthReq结构体
SendAuthReq* req =[[SendAuthReq alloc ] init];
req.scope = @"snsapi_userinfo" ;
req.state = @"123" ;
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApi sendReq:req];
}
使用通知传值的,并且使用OC调用JS的代码如下
- (void)WetchatNot:(NSNotification *)not{
NSDictionary *Dic = not.userInfo;
if (Dic.count != 0) {
JSContext *context = [self.WebViewChat valueForKeyPath:@"documentView.webView.mainFrame.javaScriptContext"];
NSString *js = [NSString stringWithFormat:@"wxLogin2('%@','%@');",Dic[@"unionid"],Dic[@"nickname"]];
[context evaluateScript:js];
/*
[self.WebViewChat stringByEvaluatingJavaScriptFromString:js];
NSString *alertJS=@"alert('test js OC')"; //准备执行的js代码
[context evaluateScript:alertJS];//通过oc方法调用js的alert
*/
NSLog(@"jsjs:%@",js);
}
}
// 授权后回调在WXApiHan里面进行处理
// WXApiHan.m
#pragma mark - LifeCycle
+(instancetype)sharedManager {
static dispatch_once_t onceToken;
static WXApiHan *instance;
dispatch_once(&onceToken, ^{
instance = [[WXApiHan alloc] init];
});
return instance;
}
#pragma mark - WXApiDelegate
- (void)onResp:(BaseResp *)resp {
NSLog(@"%d",resp.errCode);
if (resp.errCode == 0)
{
NSLog(@"用户同意");
SendAuthResp *aresp = (SendAuthResp *)resp;
[self getAccessTokenWithCode:aresp.code];
}else if (resp.errCode == -4){
NSLog(@"用户拒绝");
}else if (resp.errCode == -2){
NSLog(@"用户取消");
}
}
- (void)getAccessTokenWithCode:(NSString *)code
{
NSString *urlString =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",kWeiXinAppId,kWeiXinAppSecret,code];
NSURL *url = [NSURL URLWithString:urlString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *dataStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
if (data)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
// NSLog(@"%@",dict);
if ([dict objectForKey:@"errcode"])
{
NSLog(@"%@",dict);
//获取token错误
}else{
/*
{
"access_token" = "tnSXfzh2w8zrDe8zCdi0m1ZmOR***************Ckz6S6xJLQFeUDgu5Hyhwyowg5fvOhW2ZpA7Rr_PGPPO8P1Sw";
"expires_in" = 7200;
openid = oKiGKvxz***************JEjaYTNZPmA6OU;
"refresh_token" = "piHYgVqYxjw8mGdS1Wrnq8bIihijEp_Tvz6K***************jveI4iv5MPvOyV9zIemT_YAzv5S9djY";
scope = "snsapi_userinfo";
unionid = "o6awM***************aYlc***************ft9-A";
}
*/
//存储AccessToken OpenId RefreshToken以便下次直接登陆
//AccessToken有效期两小时,RefreshToken有效期三十天
[self getUserInfoWithAccessToken:[dict objectForKey:@"access_token"] andOpenId:[dict objectForKey:@"openid"]];
}
}
});
});
/*
正确返回
"access_token" = “Oez*****8Q";
"expires_in" = 7200;
openid = ooVLKjppt7****p5cI;
"refresh_token" = “Oez*****smAM-g";
scope = "snsapi_userinfo";
*/
/*
错误返回
errcode = 40029;
errmsg = "invalid code";
*/
}
//使用AccessToken获取用户信息
- (void)getUserInfoWithAccessToken:(NSString *)accessToken andOpenId:(NSString *)openId
{
NSString *urlString =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@",accessToken,openId];
NSURL *url = [NSURL URLWithString:urlString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *dataStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
if (data)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if ([dict objectForKey:@"errcode"])
{
//AccessToken失效
[self getAccessTokenWithRefreshToken:[[NSUserDefaults standardUserDefaults]objectForKey:kWeiXinRefreshToken]];
}else{
/*
{
city = ***************;
country = CN;
headimgurl = "http://wx.qlogo.cn/mmopen/aHc3T6Vicag75TPSvsvesibnSQSy6NicDlg1vJVPfvPf34n0ccsYmIKKKEVN9W6mgxq22eH7XInjqGqW64KtFHwaAyD9WY59nnG/0";
language = "zh_CN";
nickname = "\U91d1\U826f\U5e73";
openid = ****************A6OU;
privilege = (
);
province = ***************;
sex = 1;
unionid = "***************-A";
}
*/
//获取需要的数据
NSLog(@"dictdict%@",dict);
[[NSNotificationCenter defaultCenter]postNotificationName:@"not" object:nil userInfo:dict];
}
}
});
});
/*
city = ****;
country = CN;
headimgurl = "http://wx.qlogo.cn/mmopen/q9UTH59ty0K1PRvIQkyydYMia4xN3gib2m2FGh0tiaMZrPS9t4yPJFKedOt5gDFUvM6GusdNGWOJVEqGcSsZjdQGKYm9gr60hibd/0";
language = "zh_CN";
nickname = “****";
openid = oo*********;
privilege = (
);
province = *****;
sex = 1;
unionid = “o7VbZjg***JrExs";
*/
/*
错误代码
errcode = 42001;
errmsg = "access_token expired";
*/
}
- (void)getAccessTokenWithRefreshToken:(NSString *)refreshToken
{
NSString *urlString =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/refresh_token?appid=%@&grant_type=refresh_token&refresh_token=%@",kWeiXinAppId,refreshToken];
NSURL *url = [NSURL URLWithString:urlString];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSString *dataStr = [NSString stringWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];
NSData *data = [dataStr dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
if (data)
{
NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
if ([dict objectForKey:@"errcode"])
{
//授权过期
}else{
//重新使用AccessToken获取信息
}
}
});
});
/*
"access_token" = “Oez****5tXA";
"expires_in" = 7200;
openid = ooV****p5cI;
"refresh_token" = “Oez****QNFLcA";
scope = "snsapi_userinfo,";
*/
/*
错误代码
"errcode":40030,
"errmsg":"invalid refresh_token"
*/
}
// AppDelegate.m
// 获取用户个人信息(UnionID机制)
- (void)wechatLoginByRequestForUserInfo {
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSString *accessToken = [[NSUserDefaults standardUserDefaults] objectForKey:WX_ACCESS_TOKEN];
NSString *openID = [[NSUserDefaults standardUserDefaults] objectForKey:WX_OPEN_ID];
NSString *userUrlStr = [NSString stringWithFormat:@"%@/userinfo?access_token=%@&openid=%@", WX_BASE_URL, accessToken, openID];
// 请求用户数据
[manager GET:userUrlStr parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"请求用户信息的response = %@", responseObject);
// NSMutableDictionary *userDict = [NSMutableDictionary dictionaryWithDictionary:responseObject];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"获取用户信息时出错 = %@", error);
}];
}
在使用调用微信授权时,如果出现输入手机号码进行登录的话,那就是白名单的设置问题:可查看,也可在Umeng上面查看,并且添加自己需要的。