更新时间:2017-12-18
相关网址
吐槽
腾讯开发文档简直一言难尽,没见过这么随意的开放平台。里面充斥着一堆错误和疏漏,足以让专心于其文档的开发者大吃一惊。
至于腾讯开放平台,创建应用显示需要App Store ID,不填无法创建应用,但是未上架应用没有App Store ID。此处无需在意,随便填写就行了,我当时填写的是App开发中
。
腾讯开发文档有更新,本文档亦已更新。
流程
创建应用
进入QQ互联开放平台注册开发者,填写相关信息
并创建iOS应用,填写应用相关信息并提交审核即可。
注意点:
- 应用还未上架App Store时没有App Store ID,此处随便填写(我是填写App开发中,然后过审核的)
- app schema可以填写
QQ
+转化成十六进制的App ID
(附上一个转换网址),转换后的App ID不足八位则前面补0凑齐。此处以APPID:1108611为例。
注意,此处的app schema与工程里(Xcode)设置的URL Schemes不一致,工程里的前缀为tencent
,而QQ互联开放平台上的则以QQ开头
SDK下载及添加
SDK下载
下载链接:
SDK下载
iOS SDK目录结构
iOS SDK包中带有两个文件:
TencentOpenAPI.framework
打包了iOS SDK的头文件定义和具体实现。TencentOpenApi_iOS_Bundle.bundle
打包了iOS SDK需要的资源文件。
将iOS SDK文件添加到工程中
将iOS SDK中的TencentOpenAPI.framework和TencentOpenApi_IOS_Bundle.bundle文件拷贝到应用开发的目录下。然后将TencentOpenAPI.framework从SDK的保存目录拖拽到工程导航视图(project navigator)中。
注意TencentOpenAPI.framework和TencentOpenApi_IOS_Bundle.bundle必须放到应用的资源的根目录下,否则会出现资源无法加载的问题。在弹出的对话框中勾选“Create groups”,去掉“copy items if needed”,在Add to targets中选择要加入SDK的target之后点击finish。完成之后就将iOS SDK的framework文件加入了开发工程中。(我也不知道为什么要去掉“copy items if needed”)
添加SDK依赖的系统库文件。分别为:
“Security.framework”,“libiconv.dylib”,“SystemConfiguration.framework”,“CoreGraphics.Framework”、“libsqlite3.dylib”、“CoreTelephony.framework”、“libstdc++.dylib”、“libz.dylib”。
文档里写得是dylib,现在已经改用tbd
添加方法为:进入Build Phases
->Link Binary With Libraries
点+
直接搜索添加进入
Build Phases
->Link Binary With Libraries
,选择“Add Other…”,进入iOS SDK文件所在目录,选择TencentOpenApi_IOS_Bundle.bundle,点击回车或者点击“Open”,将其也添加进Link Binary With Libraries
。
TencentOpenAPI.framework
在拖拽的时候已经添加进入Link Binary With Libraries
而TencentOpenApi_iOS_Bundle.bundle
还未,故而此处手动加入
环境配置
修改必要的工程配置属性
在工程配置中的“Build Settings”一栏中找到“Linking”配置区,给“Other Linker Flags”配置项添加属性值“-fobjc-arc”。
修改工程配置文件
在XCode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type”添加一条新的“URL scheme”,其identifier为:tencentApiIdentifier
,URL Schemes为:tencent
+AppID
(QQ互联开放平台所注册应用的App ID)。如:tencent1108611
.
注意,此处的URL Schemes与QQ互联开放平台设置的App Schema不一致,工程里的前缀为tencent
,而QQ互联开放平台上的则以QQ开头
添加QQ的Scheme进xcode白名单
- 在info.plist增加key:LSApplicationQueriesSchemes,类型为NSArray
- 添加需要支持的白名单,类型为String
QQ相关Scheme:(该部分QQ互联开放平台上并未列出,腾讯官方SDK被人吐槽不是没有理由的)
mqqapi
mqq
mqqOpensdkSSoLogin
mqqconnect
mqqopensdkdataline
mqqopensdkgrouptribeshare
mqqopensdkfriend
mqqopensdkapi
mqqopensdkapiV2
mqqopensdkapiV3
mqzoneopensdk
wtloginmqq
wtloginmqq2
mqqwpa
mqzone
mqzonev2
mqzoneshare
wtloginqzone
mqzonewx
mqzoneopensdkapiV2
mqzoneopensdkapi19
mqzoneopensdkapi
mqzoneopensdk
还可以通过另一种方法添加,还是在plist文件里面配置(下方白名单列表不止QQ还包含其他应用的白名单,自行按需要增减)
<key>LSApplicationQueriesSchemes</key>
<array>
<!-- 微信 URL Scheme 白名单-->
<string>wechat</string>
<string>weixin</string>
<!-- 新浪微博 URL Scheme 白名单-->
<string>sinaweibohd</string>
<string>sinaweibo</string>
<string>sinaweibosso</string>
<string>weibosdk</string>
<string>weibosdk2.5</string>
<!-- QQ、Qzone URL Scheme 白名单-->
<string>mqqapi</string>
<string>mqq</string>
<string>mqqOpensdkSSoLogin</string>
<string>mqqconnect</string>
<string>mqqopensdkdataline</string>
<string>mqqopensdkgrouptribeshare</string>
<string>mqqopensdkfriend</string>
<string>mqqopensdkapi</string>
<string>mqqopensdkapiV2</string>
<string>mqqopensdkapiV3</string>
<string>mqzoneopensdk</string>
<string>wtloginmqq</string>
<string>wtloginmqq2</string>
<string>mqqwpa</string>
<string>mqzone</string>
<string>mqzonev2</string>
<string>mqzoneshare</string>
<string>wtloginqzone</string>
<string>mqzonewx</string>
<string>mqzoneopensdkapiV2</string>
<string>mqzoneopensdkapi19</string>
<string>mqzoneopensdkapi</string>
<string>mqzoneopensdk</string>
<!-- 支付宝 URL Scheme 白名单-->
<string>alipay</string>
<string>alipayshare</string>
</array>
代码设置
- 分享相关代码使用前都需引入头文件:#import <TencentOpenAPI/TencentOAuth.h>
- AppDelegate部分,未声明默认写在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
重写AppDelegate 的handleOpenURL和openURL方法
openURL:
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation{
return [TencentOAuth HandleOpenURL:url];
}
handleOpenURL:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url{
return [TencentOAuth HandleOpenURL:url];
}
初始化iOS SDK API数据对象TencentOAuth
创建TencentOAuth并初始化其AppID(直接在- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
初始化即可),此处以1108611为例。delegate为实现TencentSessionDelegate的对象:
_tencentOAuth = [[TencentOAuth alloc] initWithAppId:@"1108611" andDelegate:self];
- 此处腾讯官方文档在方法内部加了个
,
,腾讯你开心就好== -
andDelegate
需要<TencentSessionDelegate>
协议才能执行 - 执行
<TencentSessionDelegate>
协议需要添加QQ登录回调:
//登录功能没添加,但调用TencentOAuth相关方法进行分享必须添加<TencentSessionDelegate>,则以下方法必须实现,尽管并不需要实际使用它们
//登录成功
- (void)tencentDidLogin
{
// _labelTitle.text = @"登录完成";
if (_tencentOAuth.accessToken && 0 != [_tencentOAuth.accessToken length])
{
// 记录登录用户的OpenID、Token以及过期时间
// _labelAccessToken.text = _tencentOAuth.accessToken;
}
else
{
// _labelAccessToken.text = @"登录不成功 没有获取accesstoken";
}
}
//非网络错误导致登录失败
-(void)tencentDidNotLogin:(BOOL)cancelled
{
if (cancelled)
{
// _labelTitle.text = @"用户取消登录";
}
else
{
// _labelTitle.text = @"登录失败";
}
}
//网络错误导致登录失败
-(void)tencentDidNotNetWork
{
// _labelTitle.text=@"无网络连接,请设置网络";
}
初始化redirectURI(这里需要填写注册APP时填写的域名。默认可以不用填写。建议不用填写。demo中注册时的地址是“www.qq.com”):
_tencentOAuth.redirectURI = @"www.qq.com";
设置应用需要用户授权的API列表。 (建议如果授权过多的话,可能会造成用户不愿意授权。这里最好只授权应用需要用户赋予的授权。):
_permissions = [[NSArray arrayWithObjects:@"get_user_info",@"get_simple_userinfo", @"add_t", nil] retain];
//QQ第三方授权登录,此处不需要。该方法执行后会直接跳转QQ进行快捷登录
//[_tencentOAuth authorize:_permissions inSafari:NO];
QQ登录相关内容不再本文范围之内。略过
QQ分享相关代码
分享到QQ好友
分享到QQ好友支持发送:
- 纯文本消息(QQApiTextObject)
- 纯图片消息(QQApiImageObject)
- 新闻类消息(QQApiNewsObject)
- 音频类消息(QQApiImageObject)
- 视频类消息(QQApiVideoObject)
在用户安装了手机QQ时通过手机QQ进行分享,否则调用浏览器页面进行分享。其中文本消息,图文消息和音频消息的title是必须的,summary可以不填,具体调用请参考分享示例代码。使用分享到QQ好友功能需要设置QQ业务回调,请参考处理QQ业务的回调。
分享示例代码
- 添加以下三个头文件:
//QQ分享
#import <TencentOpenAPI/TencentOAuth.h>
#import <TencentOpenAPI/QQApiInterface.h>
#import <TencentOpenAPI/QQApiInterfaceObject.h>
纯文本分享:
QQApiTextObject *txtObj = [QQApiTextObject objectWithText:@"QQ互联测试"];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:txtObj];
//将内容分享到qq
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
纯图片分享:
NSString *imgPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"test.gif"];
NSData *imgData = [NSData dataWithContentsOfFile:imgPath];
QQApiImageObject *imgObj = [QQApiImageObject objectWithData:imgData
previewImageData:imgData
title:@"QQ互联测试"
description:@"QQ互联测试分享"];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:imgObj];
//将内容分享到qq
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
新闻分享:(常用分享类型)
NSString *utf8String = @"http://www.163.com";
NSString *title = @"新闻标题";
NSString *description = @"新闻描述";
NSString *previewImageUrl = @"http://cdni.wired.co.uk/620x413/k_n/NewsForecast%20copy_620x413.jpg";
QQApiNewsObject *newsObj = [QQApiNewsObject
objectWithURL:[NSURL URLWithString:utf8String]
title:title
description:description
previewImageURL:[NSURL URLWithString:previewImageUrl]];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:newsObj];
//将内容分享到qq
//QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//将内容分享到qzone
QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
音乐分享:
NSString *utf8String = @"http://y.qq.com/i/song.html?songid=432451&source=mobileQQ%23wechat_redirect";
NSString *title = @"歌曲名:不要说话";
NSString *descriotion = @"专辑名:不想放手歌手名:陈奕迅";
NSString *previewImageUrl = @"http://imgcache.qq.com/music/photo/mid_album_300/V/E/000J1pJ50cDCVE.jpg";
NSString *flashURL = @"http://10.136.9.109/fcgi-bin/fcg_music_get_playurl.fcg?song_id=1234&redirect=0&filetype=mp3&qqmusic_fromtag=15&app_id=100311325&app_key=b233c8c2c8a0fbee4f83781b4a04c595&device_id=1234";
QQApiAudioObject *audioObj =
[QQApiAudioObject objectWithURL:[NSURL URLWithString:utf8String]
title:title
description:descriotion
previewImageURL:[NSURL URLWithString:previewImageUrl]];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:audioObj]
//将内容分享到qq
//QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//将被容分享到qzone
QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
视频分享:
NSString *previewPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"video.jpg"];
NSData* previewData = [NSData dataWithContentsOfFile:previewPath];
NSString *utf8String = @"http://www.163.com";
QQApiVideoObject *videoObj = [QQApiVideoObject objectWithURL:[NSURL URLWithString:utf8String ? : @""]
title:@"QQ互联测试"
description:@"QQ互联测试分享"
previewImageData:previewData];
[videoObj setFlashURL:[NSURL URLWithString:@"http://v.qq.com/cover/5/53x6bbyb07ebl3s/n0013r8esy6.html"]];
SendMessageToQQReq *req = [SendMessageToQQReq reqWithContent:videoObj];
//将内容分享到qq
//QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//将被容分享到qzone
QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
备注:该代码必须在主线程执行,当其出现在子线程则需要将其加入主线程才行:
dispatch_async(dispatch_get_main_queue(), ^{
//回调或者说是通知主线程刷新,
QQApiSendResultCode sent = [QQApiInterface sendReq:req];
//QQApiSendResultCode sent = [QQApiInterface SendReqToQZone:req];
});
注意:
分享到QQ空间接口暂时不支持发送多张图片的能力,若开发者传入多张图片,则会自动选入第一张图片作为预览图。多图的能力将在以后支持。
处理QQ业务的回调
在使用QQApiInterface 的方法时需要设置回调才能正确调用。设置方法如下:
- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
#if __QQAPI_ENABLE__
[QQApiInterface handleOpenURL:url delegate:(id)[QQAPIDemoEntry class]];
#endif
if (YES == [TencentOAuth CanHandleOpenURL:url])
{
return [TencentOAuth HandleOpenURL:url];
}
return YES;
}
在handleOpenURL 中添加[QQApiInterface handleOpenURL:url delegate:(id)[QQAPIDemoEntry class]]代码,可以在QQAPIDemoEntry类中实现QQApiInterfaceDelegate的回调方法。更完整的示例请参考SDKDemo。
以上为QQ分享功能,其余QQ相关功能请参照腾讯
坑爹开发文档
相关链接:iOS9之后 开发-- 白名单配置
最后还是附上一份demo:QQShare