关于第三方的登录及分享,网上已经有很多集成好的框架,比如友盟和Mob。但是呢,有一个地方得注意,不过这个得看产品经理了,有些要求比较高,看下图
集成三方框架,默认会获取红框内那些信息。不管是友盟还是Mob,都有这个问题,这个与技术客服确认过,说是腾讯那边要求的。一般我们只需要获取用户的基础资料即可。考虑到这点,再加上包的大小,So,撸起袖子自己接SDK了~~
我比较懒,凡是能用cocoapods导入的,绝不会手动导入,因为添加依赖库什么的,一不小心就bia几崩溃了。(注意:记得把微博测试账号添加进去,不然授权会失败)
- 去各个平台注册应用,获取相应的应用Id并在
Target--> Info-->URL Types
添加各个平台的应用Id。
微博:wb'你的应用Id'
微信:wx'你的应用Id'
QQ:tencent'你的应用Id'
和QQ'你的应用Id转十六进制'
AppKey转成十六进制方法,直接在终端输入
echo 'ibase=10;obase=16;您的腾讯QQ互联应用Id'|bc
- 针对iOS9默认使用https,现在先还原成http请求方式。
在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES
- 在info里配置以下scheme
LSApplicationQueriesSchemes
mqqOpensdkSSoLogin
mqzone
mqq
mqqapi
mqqopensdkapiV3
mqqopensdkapiV2
mqqapiwallet
mqqwpa
mqqbrowser
wtloginmqq2
sinaweibo
sinaweibohd
sinaweibosso
sinaweibohdsso
weibosdk
weibosdk2.5
weixin
wechat
- 导入sdk(cocoapods的用法这里我就不介绍了)
pod 'TencentOpenApiSDK'
pod 'WeiboSDK'
pod 'WechatOpenSDK'
- 代码接入
在AppDelegate中导入头文件
#import
#import
#import "WXApi.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[WXApi registerApp:@"您的应用Id"];
[WeiboSDK registerApp:@"您的应用Id"];
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options {
if ([url.absoluteString hasPrefix:@"tencent"]) {
[QQApiInterface handleOpenURL:url delegate:self];
return [TencentOAuth HandleOpenURL:url];
}else if ([url.absoluteString hasPrefix:@"wx"]){
[WXApi handleOpenURL:url delegate:(id)self];
}else if ([url.absoluteString hasPrefix:@"wb"]){
[WeiboSDK handleOpenURL:url delegate:self];
}
return YES;
}
// 处理来自微信和QQ的响应(方法名相同,合并,用id接收参数)
- (void)onResp:(id )resp {
//WX授权登录的类。
if ([resp isKindOfClass:[SendAuthResp class]]) {
SendAuthResp *response = (SendAuthResp *)resp;
if (response.errCode == 0) {
// 微信登录成功
SendAuthResp *aresp = (SendAuthResp *)resp;
NSString *code = aresp.code;
//@TODO 这个code需要保存下来传给后台
}else{
// 微信登录失败
NSLog(@"error %@",response.errStr);
}
}
//微信分享 微信回应给第三方应用程序的类
if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
SendMessageToWXResp *response = (SendMessageToWXResp *)resp;
NSLog(@"error code %d error msg %@ lang %@ country %@",response.errCode,response.errStr,response.lang,response.country);
if (response.errCode == 0) {
// 分享成功
}else{
// 分享失败
}
}
//QQ分享回调
if ([resp isKindOfClass: [SendMessageToQQResp class]]) {
SendMessageToQQResp * tmpResp = (SendMessageToQQResp *)resp;
if (tmpResp.type == ESENDMESSAGETOQQRESPTYPE && [tmpResp.result integerValue] == 0) {
// 分享成功
}else {
// 分享失败
}
}
}
// 处理来自微博的响应
- (void)didReceiveWeiboResponse:(WBBaseResponse *)response {
//用户登录的回调
if ([response isKindOfClass:WBAuthorizeResponse.class]) {
NSLog(@"用户登录的回调 = 微博 userInfo = %@",response.userInfo);
if (response.statusCode == WeiboSDKResponseStatusCodeSuccess) {
NSDictionary *userInfo = response.userInfo;
NSString *accessToken=[userInfo objectForKey:@"access_token"];
//@TODO 微博返回的access_token需要保存下来给后台
}else {
//登录失败
}
}
//微博分享的回调
if ([response isKindOfClass:WBSendMessageToWeiboResponse.class]) {
WBSendMessageToWeiboResponse *res = (WBSendMessageToWeiboResponse *)response;
NSLog(@"weibo response %ld",(long)res.statusCode);
}
}
// 处理来自QQ的请求(貌似用不到)
- (void)onReq:(QQBaseReq *)req {
NSLog(@"%@",req);
}
/* 处理来自QQ的响应 方法名冲突 与微信合并
- (void)onResp:(QQBaseResp *)resp {
}
*/
// 处理QQ在线状态的回调(貌似用不到)
- (void)isOnlineResponse:(NSDictionary *)response {
}
// 处理来自微博的请求(貌似用不到)
- (void)didReceiveWeiboRequest:(WBBaseRequest *)request {
}
===========登录==========
#import
#import "WXApi.h"
#import "WeiboSDK.h"
@interface LoginVC ()
{
TencentOAuth *_tencentOAuth;
NSMutableArray *_permissionArray; //权限列表
}
@implementation LoginVC
#pragma mark -------- 第三方登录 --------
// 微信登录
- (IBAction)weixinLoginAct:(id)sender {
if ([WXApi isWXAppInstalled]) {
//构造SendAuthReq结构体
SendAuthReq* req =[[SendAuthReq alloc] init] ;
req.scope = @"snsapi_userinfo,snsapi_base";
req.state = @"0744";
//第三方向微信终端发送一个SendAuthReq消息结构
[WXApi sendReq:req];
}else {
[MBProgressHUD showErrorMsg:@"未安装微信"];
}
}
//QQ登录
- (IBAction)qqLoginAct:(id)sender {
if ([TencentOAuth iphoneQQInstalled]) {
_tencentOAuth = [[TencentOAuth alloc] initWithAppId:kQQ_APP_ID andDelegate:self];
//设置权限
_permissionArray = [NSMutableArray arrayWithObjects:kOPEN_PERMISSION_GET_USER_INFO, nil];
_tencentOAuth.redirectURI=@"www.qq.com";
// 登录操作
[_tencentOAuth authorize:_permissionArray inSafari:YES];
}else {
[MBProgressHUD showErrorMsg:@"未安装QQ"];
}
}
//微博登录
- (IBAction)sinaLoginAct:(id)sender {
if ([WeiboSDK isWeiboAppInstalled]) {
WBAuthorizeRequest *request = [WBAuthorizeRequest request];
request.redirectURI = kWB_REDIRECT_URL;
request.scope = @"all";
request.userInfo = @{@"SSO_From": @"LoginVC",
@"Other_Info_1": [NSNumber numberWithInt:123],
@"Other_Info_2": @[@"obj1", @"obj2"],
@"Other_Info_3": @{@"key1": @"obj1", @"key2": @"obj2"}};
[WeiboSDK sendRequest:request];
}else {
[MBProgressHUD showErrorMsg:@"未安装微博"];
}
}
#pragma mark -------- 登录回调 --------
//success 回调
- (void)tencentDidLogin {
/* Access Token凭证,用于后续访问各开放接口*/
if (_tencentOAuth.accessToken) {
NSLog(@"accessToken is %@---openId:%@",_tencentOAuth.accessToken,_tencentOAuth.openId);
// 获取用户信息。调用这个方法,qq的sdk会自动调用
// - (void)getUserInfoResponse:(APIResponse *)response
// 这个方法就是用户信息的回调方法
[_tencentOAuth getUserInfo];
//@TODO 走自己服务器的登录流程
}else {
NSLog(@"accessToken 没有获取成功");
}
}
//fail
- (void)tencentDidNotLogin:(BOOL)cancelled {
if (cancelled) {
NSLog(@"用户点击取消按钮,主动退出登录");
}else {
NSLog(@"其他原因,导致登录失败");
}
}
//登录时网络有问题的回调
- (void)tencentDidNotNetWork {
NSLog(@"没有网络啦啦啦啦啦");
}
/**
获取用户信息的回调
@param response .jsonResponse里面是用户详细
nickname 昵称
gender 性别
figureurl 头像
*/
- (void)getUserInfoResponse:(APIResponse *)response {
NSLog(@"user info is %@", response.jsonResponse);
}
@end
这里讲一下我们项目里的登录流程
1.分别调用三方SDK,登录成功后在能在回调里得到所需要的东西。微博会返回一个access_Token,微信返回一个code,QQ要返回一个code和openId。
2.把以上获得的字段通过自己服务器的登录接口传给后台,后台再去调用各个平台获取用户信息的接口并和自己服务器的账户体系绑定。
===========分享==========
一般我们分享都是采用文字+图片+url链接,微信和QQ都比较简单,但是微博规定多媒体(url链接)与图片不可以同时存在,下面会提到在这种情况下如何实现链接分享。
导入以下头文件,并声明tencentOAuth
.h
#import
#import
#import
#import "weiboSDK.h"
#import "WXApi.h"
@property (nonatomic, strong) TencentOAuth *tencentOAuth;
.m
#pragma mark -------- wx share --------
- (void)shareToWeChatFriend:(UIButton *)btn {
if ([WXApi isWXAppInstalled] && [WXApi isWXAppSupportApi]) {
SendMessageToWXReq *sendReq = [[SendMessageToWXReq alloc] init];
sendReq.bText = NO;//不使用文本信息
sendReq.scene = 0;//0 = 好友列表; 1 = 朋友圈 ;2 = 收藏
//创建分享内容对象
WXMediaMessage *urlMessage = [WXMediaMessage message];
urlMessage.title = @"分享的标题";//分享标题
urlMessage.description = @"分享的内容";//分享描述
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"分享的图片url"]];
[urlMessage setThumbImage:[UIImage imageWithData:data]];//分享图片,使用SDK的setThumbImage方法可压缩图片大小
//创建多媒体对象
WXWebpageObject *webObj = [WXWebpageObject object];
webObj.webpageUrl = @"分享链接url";//分享链接
//完成发送对象实例
urlMessage.mediaObject = webObj;
sendReq.message = urlMessage;
[WXApi sendReq:sendReq];
}else {
[MBProgressHUD showErrorMsg:@"未安装微信"];
}
}
#pragma mark -------- qq share --------
- (void)shareToQQ:(UIButton *)btn {
if ([TencentOAuth iphoneQQInstalled]) {
self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:kQQ_APP_ID andDelegate:nil];
NSURL *pageURL = [NSURL URLWithString:@"分享链接url"];
NSURL *previewURL = [NSURL URLWithString:@"分享的图片url"];
QQApiNewsObject *newsObjc = [QQApiNewsObject objectWithURL: pageURL title:@"分享的标题" description:@"分享的内容" previewImageURL:previewURL];
[newsObjc setCflag:kQQAPICtrlFlagQQShare];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObjc];
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
[self handleSendResult:sent];
}else {
[MBProgressHUD showErrorMsg:@"未安装QQ"];
}
}
- (void)shareToQZone:(UIButton *)btn {
if ([TencentOAuth iphoneQQInstalled]) {
self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:kQQ_APP_ID andDelegate:nil];
NSURL *pageURL = [NSURL URLWithString:@"分享链接url"];
NSURL *imgURL = [NSURL URLWithString:@"分享的图片url"];
QQApiNewsObject *objc = [QQApiNewsObject objectWithURL:pageURL title:@"分享的标题" description:@"分享的内容" previewImageURL:imgURL];
[objc setCflag:kQQAPICtrlFlagQZoneShareOnStart];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:objc];
QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
[self handleSendResult:sent];
}else {
[MBProgressHUD showErrorMsg:@"未安装QQ"];
}
}
#pragma mark -------- weibo share --------
- (void)shareToWeibo:(UIButton *)btn {
if ([WeiboSDK isWeiboAppInstalled]) {
WBMessageObject *message = [WBMessageObject message];
// 把网页链接拼接在标题里,微博会自动识别
message.text = [NSString stringWithFormat:@"%@%@",分享的标题,分享链接url];
WBImageObject *imgObject = [WBImageObject object];
imgObject.imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:_imgURLStr]];
message.imageObject = imgObject;
WBAuthorizeRequest *authRequest = [WBAuthorizeRequest request];
authRequest.redirectURI = kWB_REDIRECT_URL;
authRequest.scope = @"all";
WBSendMessageToWeiboRequest *request = [WBSendMessageToWeiboRequest requestWithMessage:message authInfo:authRequest access_token:nil];
request.userInfo = @{@"ShareMessageFrom": @"ShareManager",
@"Other_Info_1": [NSNumber numberWithInt:123],
@"Other_Info_2": @[@"obj1", @"obj2"],
@"Other_Info_3": @{@"key1": @"obj1", @"key2": @"obj2"}};
// request.shouldOpenWeiboAppInstallPageIfNotInstalled = NO;
[WeiboSDK sendRequest:request];
}else {
[MBProgressHUD showErrorMsg:@"未安装微博"];
}
}
#pragma mark -------- privite method --------
- (void)handleSendResult:(QQApiSendResultCode)sendResult {
if (sendResult == EQQAPISENDSUCESS) {
NSLog(@"分享成功--- %d",sendResult);
}else {
NSLog(@"分享失败--- %d",sendResult);
}
}