Osheep

时光不回头,当下最重要。

iOS接入QQSDK实现分享的一点经验

QQ分享SDK的接入(iOS端)

一.准备工作

  • 1.在腾讯开放平台申请分享需要使用的APPID。
  • 2.在腾讯开放平台下载官方最新版本的SDK。(官方可能会改接口)
  • 3.在腾讯开放平台下载官方接入文档和API文档(虽然写的不好,但仍然有参考价值)。
  • 4.0按照官方接入文档,接入SDK的.a和.framework包。
  • 4.1如果是使用Cocoapod进行的第三方库接入,需要对接入位置的.podspec文件进行以下修改,也可以参看文档《使用CocoaPods打包framework,并创建framework的私有podspec》

     sh.vendored_frameworks = "Pod/Classes/Share/**/*.framework"
  • 5.接入官方要求的SDK依赖系统库文件。(具体要求见接入文档)

二.环境配置

* 下面的操作全部在工程当中

* 1.向腾讯注册本App。

  • 1.1 (2种方法)在AppDelegate.m中的didFinishLaunchingWithOptions向腾讯注册。

      [[TencentOAuth alloc] initWithAppId:QQKey andDelegate:nil];
  • 1.2 也可以在具体实现的位置,使用

      self.tencentOAuth = [[TencentOAuth alloc] initWithAppId:APPID andDelegate:self];

    注意,self使用的代理为TencentSessionDelegate,请注意引入头文件

  • 1.3在工程的buildSetting中的URLtype进行腾讯的设置,URLschemes=tencent+appid.
  • 1.4参看iOS单独集成QQ分享功能的苦逼经验
    可以帮助理解上面的操作。

* 2.使用handleOpenURL和openURL识别当前接入的是哪个第三方APP。

  • 2.1重写APPDelegate的handleOpenURL方法。如果有其他分享方式需要先判断URL是否等于tencent+APPID,如果相等,添加下面语句:

       return [TencentOAuth HandleOpenURL:url];
  • 2.2重写APPDelegate的openURL方法。同样如果有其他分享方式需要先判断URL是否等于tencent+APPID,如果相等,添加下面语句:

       return [TencentOAuth HandleOpenURL:url];
  • 2.3在文档的plist中添加QQ专用的白名单,具体白名单可以在SDK提供的demo里面拖。

* 3.设置Bundle display name属性值

  • 3.1如果创建工程是Xcode 6.0以上版本,创建工程时默认不设置Bundle display name属性值。但是QQSDK需要用到Bundle display name的值,所以务必请检查确保这个属性存在,如果没有请添加上。可以设置成与Bundle name一致。

三.实现分享的API接口调用

* 1.在实现的类中添加头文件

  • 1.1注意,QQ添加头文件时使用下面格式,要在引用的类前面添加TencentOpenAPI

       #import  <TencentOpenAPI/QQApi.h>

* 2.以新闻类分享为例,给出代码参考,其他类型具体分享代码参看官方API文档

//申请一个新闻类对象
QQApiNewsObject *msgContentObj = 
[QQApiNewsObject objectWithURL:  _shareURL 
                 title:_shareTitle 
                 description:_shareDescription        
                 previewImageData:imageData];

//从contentObj中传入数据,生成一个QQReq
SendMessageToQQReq *req = [SendMessageToQQReq 
                           reqWithContent:contentObj];

//向QQ发送消息,查看是否可以发送
QQApiSendResultCode sent = [QQApiInterface sendReq:req];

3.QQ消息的回调

  • 2.1注意,sendReq取到的值只能在判断发送前的状态,不能判断是否放弃发送或者发送成功。判断放弃发送的方法是截取openURL中的URL,发送失败的URL含有一个叫error_description的字段,当字段中的内容为dGhlIHVzZXIgZ2l2ZSB1cCB0aGUgY3VycmVudCBvcGVyYXRpb24=时,表示用户放弃了发送,可以以此来判断当前回调情况。

  • 2.2由于QQ和微信都是腾讯的,所以有两个回调方法是相同的onReq,onResp(本文中使用的不是这个方法),为了避免产生问题,可以在声明代理的位置使用下面方法进行区别。

       [WXApi handleOpenURL:url delegate:(id<WXApiDelegate>)self];

四.iPhone4S的兼容

1.iPhone4S不兼容的原因是新版本的SDK不再支持i386,解决方法是不直接调用QQSDK中提供的接口。

2.不含参数、含有1个参数、含有2个参数的方法

  • 2.1使用NSClassFromString调用不含参的方法:

      [NSClassFromString(@"WBImageObject") 
      performSelector:NSSelectorFromString(@"object")]
  • 2.2使用NSClassFromString调用含一个参数的方法:

      [NSClassFromString(@"TencentOAuth")   
      performSelector:NSSelectorFromString(@"HandleOpenURL:")
       withObject:url]
  • 2.2使用NSClassFromString调用含两个参数的方法:

      [tencent 
      performSelector:NSSelectorFromString(@"initWithAppId:andDelegate:")
      withObject:qqString 
      withObject:(id<TencentSessionDelegate>)self];

3.含有大于等于3个参数的方法

  • 3.1定义多参数动态加载方法,假设叫MethodQQ

      这里涉及到公司代码,就不给例子了,

    说明一下使用的原理是NSMethodSignature和NSInvocation的消息转发,
    封装QQ的方法,调用后把参数转发给QQ的Api,执行后再传回来。

关于NSMethodSignature和NSInvocation的使用,可以参考一下这篇文章NSMethodSignature和NSInvocation使用

  • 3.2如果存在两次释放的问题,则在调用位置使用下面格式的代码,使得msgContentObj不能自动release.如果没有这个问题,不需要修改。

       CFTypeRef msgContentObj;
      // 调用MethodQQ,取得返回值,使得msgContentObj = 返回值;
      // 类型强转
      msgContentObj = (__bridge CFTypeRef)((__bridge QQApiNewsObject *)msgContentObj);
      // 发送请求时,调整msgContentObj类型
      isSuccess = [self doSendQQRequestWithContentObj:(__bridge id)(msgContentObj) isSendToQzone:YES];
点赞