iOS-QQ分享功能实现

原文链接:https://www.jianshu.com/p/581edba36b5b

 

相关网址

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

吐槽

腾讯开发文档简直一言难尽,没见过这么随意的开放平台。里面充斥着一堆错误和疏漏,足以让专心于其文档的开发者大吃一惊。
至于腾讯开放平台,创建应用显示需要App Store ID,不填无法创建应用,但是未上架应用没有App Store ID。此处无需在意,随便填写就行了,我当时填写的是App开发中
腾讯开发文档有更新,本文档亦已更新。


流程

创建应用

进入QQ互联开放平台注册开发者,填写相关信息

iOS-QQ分享功能实现_第1张图片

初注册需要填写开发者资料

并创建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”。

iOS-QQ分享功能实现_第2张图片

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还包含其他应用的白名单,自行按需要增减)


LSApplicationQueriesSchemes 
    
    
wechat    
weixin   
    
sinaweibohd   
sinaweibo   
sinaweibosso   
weibosdk   
weibosdk2.5   
    
mqqapi   
mqq    
mqqOpensdkSSoLogin   
mqqconnect  
mqqopensdkdataline  
mqqopensdkgrouptribeshare  
mqqopensdkfriend  
mqqopensdkapi   
mqqopensdkapiV2  
mqqopensdkapiV3  
mqzoneopensdk  
wtloginmqq   
wtloginmqq2   
mqqwpa   
mqzone   
mqzonev2   
mqzoneshare   
wtloginqzone   
mqzonewx   
mqzoneopensdkapiV2   
mqzoneopensdkapi19  
mqzoneopensdkapi  
mqzoneopensdk  
   
alipay 
alipayshare

iOS-QQ分享功能实现_第3张图片

QQ相关白名单-LSApplicationQueriesSchemes

代码设置

  • 分享相关代码使用前都需引入头文件:#import
  • 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需要协议才能执行
  • 执行协议需要添加QQ登录回调:

//登录功能没添加,但调用TencentOAuth相关方法进行分享必须添加,则以下方法必须实现,尽管并不需要实际使用它们
//登录成功
- (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 
#import 
#import 

纯文本分享:

    
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

 

你可能感兴趣的:(收藏)