一,总体架构
1,引入第三方库
除了必须引入对应的登录SDK外,额外引入了SDWebImage,SVProgressHUD,看名字大家都明白吧,引入登录SDK请各自看官方的开发文档,需要加入什么系统库文件,需要配置Other Linker Flags 等,请参考各自官方文档即可;
2,配置连接桥文件
因为创建的工程是基于Swift语言,目前官方SDK和其它三方库都是用OC写的,所以为了在swift中调用oc代码,需要配置连接桥文件Bridging-Header.h,搜索objective-C bridging Header健,然后在值里面输入XXXLogin/Bridging-Header.h,注意是绝对路径,里面可以输入需要调用的头文件,如
#import "WXApi.h"
#import "SVProgressHUD.h"
#import "UIImageView+WebCache.h"
3,配置工程
因为是SSO跳转方式,需要配置URL Schemes,以便程序返回识别宿主程序,配置方法很简单,参考各自文档即可,在info里面可以可视化添加,各自的key值采用官方demo所提供;
二,微信
1,注册
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
//向微信注册
WXApi.registerApp(kWXAPP_ID)
return true
}
2,授权登录
-
override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view, typically from a nib. NSNotificationCenter.defaultCenter().addObserver(self, selector:"onRecviceWX_CODE_Notification:", name: "WX_CODE", object: nil) let sendBtn:UIButton = UIButton() sendBtn.frame = CGRectMake(30, 100, kIPHONE_WIDTH-60, 40) sendBtn.backgroundColor = UIColor.redColor() sendBtn.setTitleColor(UIColor.whiteColor(), forState: UIControlState.Normal) sendBtn.setTitle("Swift版本之微信授权登录", forState: UIControlState.Normal) sendBtn.addTarget(self, action: "sendBtnClick:", forControlEvents: UIControlEvents.TouchUpInside) self.view.addSubview(sendBtn) headerImg = UIImageView(frame: CGRectMake(30, 160, 120, 120)) headerImg.backgroundColor = UIColor.yellowColor() self.view.addSubview(headerImg) nicknameLbl.frame = CGRectMake(170, 160, kIPHONE_WIDTH-60-140, 40) nicknameLbl.backgroundColor = UIColor.lightGrayColor() nicknameLbl.textColor = UIColor.purpleColor() nicknameLbl.textAlignment = NSTextAlignment.Center self.view.addSubview(nicknameLbl) } func sendBtnClick(sneder:UIButton) { sendWXAuthRequest() } //微信登录 第一步 func sendWXAuthRequest(){ let req : SendAuthReq = SendAuthReq() req.scope = "snsapi_userinfo,snsapi_base" WXApi .sendReq(req) }
3,回调
-
func onResp(resp: BaseResp!) { /* ErrCode ERR_OK = 0(用户同意) ERR_AUTH_DENIED = -4(用户拒绝授权) ERR_USER_CANCEL = -2(用户取消) code 用户换取access_token的code,仅在ErrCode为0时有效 state 第三方程序发送时用来标识其请求的唯一性的标志,由第三方程序调用sendReq时传入,由微信终端回传,state字符串长度不能超过1K lang 微信客户端当前语言 country 微信用户当前国家信息 */ // var aresp resp :SendAuthResp! var aresp = resp as! SendAuthResp // var aresp1 = resp as? SendAuthResp if (aresp.errCode == 0) { println(aresp.code) //031076fd11ebfa5d32adf46b37c75aax var dic:Dictionary<String,String>=["code":aresp.code]; let value = dic["code"] println("code:\(value)") NSNotificationCenter.defaultCenter().postNotificationName("WX_CODE", object: nil, userInfo: dic) } }
4,获取用户信息
//微信回调通知,获取code 第二步
func onRecviceWX_CODE_Notification(notification:NSNotification)
{
SVProgressHUD.showSuccessWithStatus("获取到code", duration: 1)
var userinfoDic : Dictionary = notification.userInfo!
let code: String = userinfoDic["code"] as! String
println("Recevice Code: \(code)")
self.getAccess_token(code)
}
//获取token 第三步
func getAccess_token(code :String){
//https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
var requestUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=\(kWXAPP_ID)&secret=\(kWXAPP_SECRET)&code=\(code)&grant_type=authorization_code"
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
var requestURL: NSURL = NSURL(string: requestUrl)!
var data = NSData(contentsOfURL: requestURL, options: NSDataReadingOptions(), error: nil)
dispatch_async(dispatch_get_main_queue(), {
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
println("Recevice Token: \(jsonResult)")
SVProgressHUD.showSuccessWithStatus("获取到Token和openid", duration: 1)
let token: String = jsonResult["access_token"] as! String
let openid: String = jsonResult["openid"] as! String
self.getUserInfo(token, openid: openid)
})
})
}
//获取用户信息 第四步
func getUserInfo(token :String,openid:String){
// https://api.weixin.qq.com/sns/userinfo?access_token=ACCESS_TOKEN&openid=OPENID
var requestUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=\(token)&openid=\(openid)"
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {
var requestURL: NSURL = NSURL(string: requestUrl)!
var data = NSData(contentsOfURL: requestURL, options: NSDataReadingOptions(), error: nil)
dispatch_async(dispatch_get_main_queue(), {
var jsonResult: NSDictionary = NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers, error: nil) as! NSDictionary
println("Recevice UserInfo: \(jsonResult)")
/*
Recevice UserInfo:
{
city = Chaoyang;
country = CN;
headimgurl = "http://wx.qlogo.cn/mmopen/FrdAUicrPIibcpGzxuD0kjfssQogj3icL8QTJQYUCLpgzSnvY6rJFGORreicPUiaPCzojwNlsXq4ibbc8e3gGFricWqJU5ia7ibicLVhfT/0";
language = "zh_CN";
nickname = "\U706b\U9505\U6599";
openid = "oyAaTjkR8T6kcKWyA4VPYDa_Wy_w";
privilege = (
);
province = Beijing;
sex = 1;
unionid = "o1A_Bjg52MglJiEjhLmB8SyYfZIY";
}
*/
SVProgressHUD.showSuccessWithStatus("获取到用户信息", duration: 1)
let headimgurl: String = jsonResult["headimgurl"] as! String
let nickname: String = jsonResult["nickname"] as! String
self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl))
self.nicknameLbl.text = nickname
})
})
}
5,跳转
//微信的跳转回调
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return WXApi.handleOpenURL(url, delegate: self)
}
func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool
{
return WXApi.handleOpenURL(url, delegate: self)
}
三,QQ
1,注册
-
func sendBtnClick(sneder:UIButton) { sendQQAuthRequest() } //第一步 QQ登录 func sendQQAuthRequest(){ tencentOAuth = TencentOAuth(appId: kQQAPP_ID, andDelegate: self) var permissions = [kOPEN_PERMISSION_GET_INFO,kOPEN_PERMISSION_GET_USER_INFO,kOPEN_PERMISSION_GET_SIMPLE_USER_INFO] tencentOAuth.authorize(permissions, inSafari: false) }
2,授权登录
如上
3,回调
-
//第二步 登录成功回调 func tencentDidLogin() { let accessToken = tencentOAuth.accessToken println("accessToken:\(accessToken)") //641B23508B62392C52D6DFADF67FAA9C getUserInfo() } //失败 func tencentDidNotLogin(cancelled: Bool) { println("登录失败了") } //无网络 func tencentDidNotNetWork() { println("没有网络") }
4,获取用户信息
-
//第三步 获取用户信息 func getUserInfo() { SVProgressHUD.showWithStatus("正在获取用户信息...") tencentOAuth.getUserInfo() } //第四步 在获取用户回调中获取用户信息 func getUserInfoResponse(response: APIResponse!) { SVProgressHUD.dismissWithSuccess("获取用户信息成功", afterDelay: 1) var dic:Dictionary = response.jsonResponse println("dic:\(dic)") // [is_lost: 0, figureurl: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/30, vip: 0, is_yellow_year_vip: 0, province: 北京, ret: 0, is_yellow_vip: 0, figureurl_qq_1: http://q.qlogo.cn/qqapp/222222/C5527A2F775D9EA7C20317128FAC202B/40, yellow_vip_level: 0, level: 0, figureurl_1: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/50, city: 海淀, figureurl_2: http://qzapp.qlogo.cn/qzapp/222222/C5527A2F775D9EA7C20317128FAC202B/100, nickname: 竹中雨滴, msg: , gender: 男, figureurl_qq_2: http://q.qlogo.cn/qqapp/222222/C5527A2F775D9EA7C20317128FAC202B/100] refeshUserInfo(dic) } //第五步 刷新用户界面 func refeshUserInfo(dic : NSDictionary){ let headimgurl: String = dic["figureurl_qq_2"] as! String let nickname: String = dic["nickname"] as! String self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl)) self.nicknameLbl.text = nickname }
5,跳转
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
return TencentOAuth.HandleOpenURL(url)
}
func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool {
return TencentOAuth.HandleOpenURL(url)
}
四,微博
1,注册
-
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { // Override point for customization after application launch. WeiboSDK.registerApp(kAppKey) return true }
2,授权登录
-
func sendBtnClick(sneder:UIButton) { sendSinaAuthRequest() } //第一步 微博登录 func sendSinaAuthRequest(){ var request : WBAuthorizeRequest = WBAuthorizeRequest.request() as! WBAuthorizeRequest request.redirectURI = kRedirectURI request.scope = "all" request.userInfo = ["SSO_Key":"SSO_Value"] WeiboSDK.sendRequest(request) }
3,回调
-
func didReceiveWeiboRequest(request: WBBaseRequest!) { } func didReceiveWeiboResponse(response: WBBaseResponse!) { if response.isKindOfClass(WBAuthorizeResponse){ if (response.statusCode == WeiboSDKResponseStatusCode.Success) { var authorizeResponse : WBAuthorizeResponse = response as! WBAuthorizeResponse var userID = authorizeResponse.userID var accessToken = authorizeResponse.accessToken println("userID:\(userID)\naccessToken:\(accessToken)") var userInfo = response.userInfo as Dictionary NSNotificationCenter.defaultCenter().postNotificationName("SINA_CODE", object: nil, userInfo: userInfo) } } }
-
//第二步 通过通知得到登录后获取的用户信息 func onRecviceSINA_CODE_Notification(notification:NSNotification) { SVProgressHUD.showSuccessWithStatus("获取到用户信息", duration: 1) var userinfoDic : Dictionary = notification.userInfo! println("userInfo:\(userinfoDic)") /* userID:2627289515 accessToken:2.002BqnrCyY87OC80500cab28Ofqd3B userInfo: [uid: 2627289515, remind_in: 647057, scope: invitation_write, refresh_token: 2.002BqnrCyY87OC10f7877765yPietB, app: { logo = "http://ww1.sinaimg.cn/square/65745bf7jw1ea399us692j2028028glf.jpg"; name = "SDK\U5fae\U535a\U5e94\U7528demo"; }, access_token: 2.002BqnrCyY87OC80500cab28Ofqd3B, expires_in: 647057 ] */ var userAppInfo: Dictionary<String,String> = userinfoDic["app"] as! Dictionary refeshUserInfo(userAppInfo) } //第三步 刷新用户界面 func refeshUserInfo(dic : NSDictionary){ let headimgurl: String = dic["logo"] as! String let nickname: String = dic["name"] as! String self.headerImg.sd_setImageWithURL(NSURL(string: headimgurl)) self.nicknameLbl.text = nickname }
5,跳转
-
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool { return WeiboSDK.handleOpenURL(url, delegate: self) } func application(application: UIApplication, handleOpenURL url: NSURL) -> Bool { return WeiboSDK.handleOpenURL(url, delegate: self) }