iOS-QQ分享功能实现

更新时间:2017-12-18

相关网址

QQ开发文档
QQ互联开放平台

吐槽

腾讯开发文档简直一言难尽,没见过这么随意的开放平台。里面充斥着一堆错误和疏漏,足以让专心于其文档的开发者大吃一惊。
至于腾讯开放平台,创建应用显示需要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 LibrariesTencentOpenApi_iOS_Bundle.bundle还未,故而此处手动加入

环境配置

修改必要的工程配置属性

在工程配置中的“Build Settings”一栏中找到“Linking”配置区,给“Other Linker Flags”配置项添加属性值“-fobjc-arc”。

Other Linker Flags
修改工程配置文件

在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>
QQ相关白名单-LSApplicationQueriesSchemes

代码设置

  • 分享相关代码使用前都需引入头文件:#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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,898评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,401评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 143,058评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,539评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,382评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,319评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,706评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,370评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,664评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,715评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,476评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,326评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,730评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,003评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,275评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,683评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,877评论 2 335

推荐阅读更多精彩内容