应公司项目要求,这段时间接手开始接入微信sdk,由于还未获取到微信的支付权限,所以这里只做了一下登录的记录,https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=1417694084&token=9e8dccd0b7280c180642a80c08f21682c73e3b77&lang=zh_CN这是微信官方接入文档,看了下,感觉没什么叼用,就在网上查阅了众多资料,也是第一次接手ios代码,花了我整整三天的时间终于尘埃落定了,下面就一一做下记录。
首先第一步,去官网下载微信sdk文件,SDK文件包括 libWeChatSDK.a,WXApi.h,WXApiObject.h 三个。下载链接:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319164&lang=zh_CN
第二步:讲下载后的sdk文件libWeChatSDK.a,,WXApi.h,WXApiObject.h添加到你的工程中如下图(因为项目保密性,我就贴张官网上的图来说明问题)
(注:请使用xCode4.5及以上版本),
第三步:微信开放平台新增了微信模块用户统计功能,便于开发者统计微信功能模块的用户使用和活跃情况。开发者需要在选中工程->build Phases->Link Binary With Libraries添加SystemConfiguration.framework,libz.dylib,libsqlite3.0.dylib,libc++.dylib库文件
第四步:选中工程选项->info->URL Types添加"URL scheme”为你所注册的应用程序id(如下图所示)。
第五步:在你准备使用微信终端API文件中import WXApi.h 头文件,并增加 WXApiDelegate 协议。如下:
接下来开始编码了
1、要使你的程序启动后微信终端能够响应你的程序,必须在代码像微信注册你的应用id,如下:
2、重写AppDelegate的handleOpenURL和openURL方法,// 这个方法是用于从微信返回第三方App
这里提一下,刚开始做时,我在这两个函数的delegate参数给的是self,并且设置appController集成到WXApidelegate,然而并没有什么卵用,程序执行后点击确定授权不会跳转到-(void) onResp:(BaseResp*)resp函数,最后在论坛上发现有人建议直接使用你准备调用微信API所在类的对象即可,我便试了下关于果然如此。
3、接下来就开始做登录的逻辑了
-(void) goWXLogin
{
if ([WXApi isWXAppInstalled]) {
[self sendAuthRequest];
}
else{
[self setupAlertController];
}
}
提示用户安装微信弹框
-(void) setupAlertController{
UIAlertController* alert = [UIAlertController alertControllerWithTitle:@"温馨提示" message:
@"请先安装微信客户端" preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionConfirm = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleDefault handler:nil];
[alert addAction:actionConfirm];
//[self presentViewController :alert animated:YES completion:nil];
}
note:
a、目前移动应用上微信登录只提供原生的登录方式,需要用户安装微信客户端才能配合使用。
b、对于Android应用,建议总是显示微信登录按钮,当用户手机没有安装微信客户端时,请引导用户下载安装微信客户端。
c、对于iOS应用,考虑到iOS应用商店审核指南中的相关规定,建议开发者接入微信登录时,先检测用户手机是否已安装微信客户端(使用sdk中isWXAppInstalled函 数 ),对未安装的用户隐藏微信登录按钮,只提供其他登录方式(比如手机号注册登录、游客登录等)。
//发送授权登录请求,这里的参数解释下
appid:应用唯一标识,在微信开放平台提交应用审核通过后获得
score:应用授权作用域,如获取用户个人信息需要填写snsapi_userinfo什么是授权域
state:用于保持请求和回调的状态,授权请求后原样带回给第三方。该参数可用于防止csrf攻击(跨站请求伪造攻击),建议第三方带上该参数,可设置为简单的随机数加 session进行校验
-(void)sendAuthRequest
{
//构造SendAuthReq结构体
SendAuthReq* req =[[SendAuthReq alloc ] init];
req.scope = @"snsapi_userinfo" ;
req.state = @"wechat_sdk_huaqianguyouxi" ;
//第三方向微信发送一个SendAuthReq消息结构
[WXApi sendReq:req];
}
运行返回大致为:
appid: wxd477edab60670232
scope: snsapi_userinfo
state: wechat_sdk_demo
到这里我们的应用便可以拉起微信授权界面了,在授权界面,我们点击确定之后会回调-(void) onResp:(BaseResp*)resp函数,先上代码,
-(void) onResp:(BaseResp*)resp
{
SendAuthResp *aresp = (SendAuthResp *)resp;
if (aresp.errCode== 0) {
self->code = aresp.code;
NSString* token = [[NSUserDefaults standardUserDefaults]objectForKey:@"access_token"];
NSString* openId = [[NSUserDefaults standardUserDefaults]objectForKey:@"openid"];
NSString* refreshToken = [[NSUserDefaults standardUserDefaults]objectForKey:@"refresh_token"];
if (token && openId && refreshToken) {
[self setUid:openId];
[self setRefreshToken:refreshToken];
[self checkValidToken:token uid:(NSString*)openId];
}
else
[self getAccess_token];
}
else if (aresp.errCode == -2) {
NSLog(@"用户取消登录");
} else if (aresp.errCode == -4) {
NSLog(@"用户拒绝登录");
} else {
NSLog(@"errCode = %d", aresp.errCode);
NSLog(@"code = %@", aresp.code);
}
}
这里的函数返回值有以下几个:
ErrCode:错误码,ERR_OK = 0(用户同意),ERR_AUTH_DENIED = -4(用户拒绝授权)ERR_USER_CANCEL = -2(用户取消)
code:用户换取access_token的code,仅在ErrCode为0时有效
state:第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K
lang:微信客户端当前语言
country:微信用户当前国家信息
这里我是把获取到的token保存在了本地,并没有加密,目的是为了token的有效性处理
获取了code之后可以会用官方提供的链接来获取access_token,链接为https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
代码如下:
//通过code获取access_token
-(void)getAccess_token
{
NSString *url =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code",APP_ID,APP_KEY,self->code];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *zoneUrl = [NSURL URLWithString:url];
NSString *zoneStr = [NSString stringWithContentsOfURL:zoneUrl encoding:NSUTF8StringEncoding error:nil];
NSData *data = [zoneStr dataUsingEncoding:NSUTF8StringEncoding];
dispatch_async(dispatch_get_main_queue(), ^{
if (data) {
NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSString* token = [dic objectForKey:@"access_token"];
NSString* openId = [dic objectForKey:@"openid"];
NSString* refreshToken = [dic objectForKey:@"refresh_token"];
[self setUid:openId];
[self setRefreshToken:refreshToken];
[self checkValidToken:token uid:(NSString*)openId];
}
});
});
}
这个函数处理结果和刷新token函数的的返回值都是如下
access_token:接口调用凭证
expires_in:access_token接口调用凭证超时时间,单位(秒)
refresh_token:用户刷新access_token
openid:授权用户唯一标识
scope:用户授权的作用域,使用逗号(,)分隔
unionid:当且仅当该移动应用已获得该用户的userinfo授权时,才会出现该字段
程序到了这里,基本上已经可以利用微信登录到你的应用了。完整代码下载(只有登录的sdk调用,嵌入到项目中才能执行)