應公司項目要求,這段時間接手開始接入微信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調用,嵌入到項目中才能執行)