1. SSO安全登录QQ帐号
iOS SDK支持应用跳转到手机QQ进行登录,给用户提供更加安全、快捷的体验 。如果用户没有安装手机QQ,将打开登录页面。
2. 分享到QQ和QQ空间
2.1 分享到QQ好友
分享到QQ好友支持发送:
- – 纯文本消息(QQApiTextObject)
- – 纯图片消息(QQApiImageObject)
- – 新闻类消息(QQApiNewsObject)
- – 音频类消息(QQApiImageObject)
- – 视频类消息(QQApiVideoObject)
在用户安装了手机QQ时通过手机QQ进行分享,否则调用浏览器页面进行分享。
其中文本消息,图文消息和音频消息的title是必须的,summary可以不填,具体调用请参考2.3 分享示例代码。
使用分享到QQ好友功能需要设置QQ业务回调,请参考6. 处理QQ业务的回调。
2.2 分享到QQ空间
分享到QQ空间的接口用于取代老的分享接口addShareWithParams(该接口已经废弃)。
分享到QQ空间支持发送:
– 带有URL的消息
– 新闻类消息(QQApiNewsObject)
– 音频类消息(QQApiImageObject)
– 视频类消息(QQApiVideoObject)
分享时调用浏览器页面进行分享。其中title是必须的,summary可以不填,具体调用请参考2.3 分享示例代码。
使用分享到QQ空间功能需要设置QQ业务回调,请参考6. 处理QQ业务的回调。
2.3 分享示例代码
下面是各种分享消息的实例代码,作为开发者调用QQ好友分享和QQ空间分享的参考:
纯文本分享:
QQApiTextObject*txtObj=[QQApiTextObject objectWithText:@"QQ互联测试"];
SendMessageToQQReq*req=[SendMessageToQQReq reqWithContent:txtObj];
//将内容分享到qq
QQApiSendResultCodesent=[QQApiInterface sendReq:req];
纯图片分享:
NSString*imgPath=[[[NSBundlemainBundle] 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
QQApiSendResultCodesent=[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
QQApiSendResultCodesent=[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
QQApiSendResultCodesent=[QQApiInterface SendReqToQZone:req];
视频分享:
NSString*previewPath=[[[NSBundlemainBundle] 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
QQApiSendResultCodesent=[QQApiInterface SendReqToQZone:req];
注意:
分享到QQ空间接口暂时不支持发送多张图片的能力,若开发者传入多张图片,则会自动选入第一张图片作为预览图。多图的能力将在以后支持。
3. 调用OpenAPI
SDK中具体支持的API种类和每条API的参数说明,请参照API列表。这里用设置用户头像举例说明。
3.1 OpenAPI参数字典封装
在封装各接口的参数字典时,推荐使用为每个接口新增的参数封装辅助类,如:
接口(BOOL)addShareWithParams:(NSMutableDictionary *)params
对应辅助类TCAddShareDic
TCAddShareDic辅助类中属性:
@property (nonatomic, retain) TCRequiredStr paramTitle;
对应于CGI请求中参数”title”
TCRequiredStr 表示这是一个必填参数,类型是字符串
TCOptionalStr 表示这是一个可选参数,类型是字符串
3.2 设置用户头像调用示例
设置QQ头像时,调用TencetnOAuth对象的setUserHeadpic方法:
TCSetUserHeadpic*params=[TCSetUserHeadpicdictionary];
params.paramImage=image;
params.paramFileName=@"make";
UIViewController*headController=nil;
[_tencentOAuth setUserHeadpic:params andViewController:&headController];
UIViewController*rootController=[[[appdelegate] window] rootViewController];
[rootController dismissModalViewControllerAnimated:NO];
[rootController presentModalViewController:headController animated:YES];
设置头像完成后,会调用TencentSessionDelegate中的tencentOAuth:doCloseViewController通知应用界面需要关闭:
@protocolTencentSessionDelegate
-(void)setUserHeadpicResponse:(APIResponse*)response
-(void)tencentOAuth:(TencentOAuth*)tencentOAuth doCloseViewController:(UIViewController*)viewController
{
if(tencentOAuth==_tencentOAuth)
{
UIApplication*app=[UIApplicationsharedApplication];
UIViewController*rootController=[[[appdelegate] window] rootViewController];
[rootController dismissModalViewControllerAnimated:YES];
}
}
设置头像完成后,会调用TencentSessionDelegate中的setUserHeadpicResponse返回调用结果:
@protocolTencentSessionDelegate
-(void)setUserHeadpicResponse:(APIResponse*)response
{
if(nil==response)
{
return;
}
if(URLREQUEST_FAILED==response.retCode
&&kOpenSDKErrorUserHeadPicLarge==response.detailRetCode)
{
UIAlertView*alert=[[UIAlertViewalloc] initWithTitle:@"操作失败" message:[NSString stringWithFormat:@"您的图片大小超标啦,请更换一张试试呢:)"]
delegate:self cancelButtonTitle:@"我知道啦" otherButtonTitles: nil];
[alertshow];
[alertrelease];
}
}
3.3 使用增量授权
当第三方应用调用某个API接口时,如果服务器返回操作未被授权,则会触发增量授权逻辑。第三方应用需自行实现tencentNeedPerformIncrAuth:withPermissions:协议接口才能够进入增量授权逻辑,否则默认第三方应用放弃增量授权。示例如下:
-(BOOL)tencentNeedPerformIncrAuth:(TencentOAuth*)tencentOAuth
withPermissions:(NSArray*)permissions
{
// incrAuthWithPermissions是增量授权时需要调用的登录接口
// permissions是需要增量授权的权限列表
[tencentOAuth incrAuthWithPermissions:permissions];
returnNO;// 返回NO表明不需要再回传未授权API接口的原始请求结果;
// 否则可以返回YES
}
注意:在用户通过增量授权页重新授权登录后,第三方应用需更新自己维护的token及有效期限等信息。
**用户在增量授权时是可以更换帐号进行登录的,强烈要求第三方应用核对增量授权后的用户openid是否一致,以添加必要的处理逻辑(用户帐号变更需重新拉取用户的资料等信息)**
增量授权成功时,会通过tencentDidUpdate:协议接口通知第三方应用:
-(void)tencentDidUpdate:(TencentOAuth*)tencentOAuth
{
_labelTitle.text=@"增量授权完成";
if(tencentOAuth.accessToken
&&0!=[tencentOAuth.accessTokenlength])
{// 在这里第三方应用需要更新自己维护的token及有效期限等信息
// **务必在这里检查用户的openid是否有变更,变更需重新拉取用户的资料等信息**
_labelAccessToken.text=tencentOAuth.accessToken;
}
else
{
_labelAccessToken.text=@"增量授权不成功,没有获取accesstoken";
}
}
增量授权失败时,会通过tencentFailedUpdate:协议接口通知第三方应用:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-(void)tencentFailedUpdate:(UpdateFailType)reason
{
switch(reason)
{
case kUpdateFailNetwork:
{
_labelTitle.text=@"增量授权失败,无网络连接,请设置网络";
break;
}
case kUpdateFailUserCancel:
{
_labelTitle.text=@"增量授权失败,用户取消授权";
break;
}
case kUpdateFailUnknown:
default:
{
_labelTitle.text=@"增量授权失败,未知错误";
break;
}
}
}
3.4 返回数据说明
APIResponse属性:
retCode – 网络请求返回码,主要表示服务器是否成功返回数据
seq – 请求的序列号,依次递增,方便内部管理
errorMsg – 错误消息
jsonResponse – 由服务器返回的json格式字符串转换而来的json字典数据(具体参数字段请参见对应API说明文档)
message – 服务器返回的原始字符串数据
detailRetCode – 新增的详细错误码,以区分不同的错误原因(v1.2以及之前的SDK接口无此参数)
3.5 返回码说明
retCode网络请求返回码说明:
0 表示成功,请求成功发送到服务器,并且服务器返回的数据格式正确
1 表示失败,可能原因有网络异常,或服务器返回的数据格式错误,无法解析
detailRetCode详细错误码说明:
kOpenSDKInvalid -无效的错误码
[公共错误码]
kOpenSDKErrorSuccess – 成功
kOpenSDKErrorUnknown – 未知错误
kOpenSDKErrorUserCancel – 用户取消
kOpenSDKErrorReLogin – token无效或用户未授权相应权限需要重新登录
kOpenSDKErrorOperationDeny – 第三方应用没有该api操作的权限
[网络相关错误码]
kOpenSDKErrorNetwork – 网络错误,网络不通或连接不到服务器
kOpenSDKErrorURL – URL格式或协议错误
kOpenSDKErrorDataParse – 数据解析错误,服务器返回的数据解析出错
kOpenSDKErrorParam – 传入参数错误
kOpenSDKErrorConnTimeout – http连接超时
kOpenSDKErrorSecurity – 安全问题
kOpenSDKErrorIO – 下载和文件IO错误
kOpenSDKErrorServer – 服务器端错误
[webview中特有错误]
kOpenSDKErrorWebPage – 页面错误
[设置头像 自定义错误码段]
kOpenSDKErrorUserHeadPicLarge – 图片过大 设置头像自定义错误码
4. 调用微云接口
iOS SDK支持调用腾讯微云的接口,支持对照片,音频,视频,结构化数据的上传,下载,删除等能力。下面以微云照片上传为例,向开发者介绍如何向腾讯微云上传照片。
4.1创建微云request对象,调用TencentOAuth实例的统一发送接口
-(void)weiyunUpload:(NSNumber*)weiyunType
{
WeiYun_upload_photo_GET*request=[[WeiYun_upload_photo_GETalloc] init];
//data是图片的二进制数据流
request.param_sha=[datadigest];
request.param_md5=[datamd5];
request.param_name=@"test";
request.param_size=[NSString stringWithFormat:@"%u",[datalength]];
request.param_upload_type=@"control";
request.paramUploadData=data;
[_tencentOAuth sendAPIRequest:request callback:self];
}
4.2 实现TCAPIRequestDelegate协议,响应结果
-(void)cgiRquest:didResponse用来响应统一api的调用结果,request是请求的消息,response是响应的结果。
-(void)cgiRequest:(TCAPIRequest*)request didResponse:(APIResponse*)response
{
if(URLREQUEST_SUCCEED==response.retCode&&kOpenSDKErrorSuccess==response.detailRetCode)
{
NSString*str=[self responseDataProcess:request didResponse:response];
UIAlertView*alert=[[UIAlertViewalloc] initWithTitle:@"操作成功"
message:[NSString stringWithFormat:@"%@",str]
delegate:self cancelButtonTitle:@"我知道啦"
otherButtonTitles: nil];
[alertshow];
}
}
注意:
上传图片是两步的过程。需要先获得上传参数,再根据上传参数拼装HTTP协议上传到微云的服务器。两步是分开进行的,所以需要注意两个问题。
1.第三方需要将上传对象进行保存,否则将无法进行默认的大数据上传。
2.iOS SDK 1.8实现了拉取上传参数和数据的上传。但是上传没有实现断点续传,所以对大数据的上传支持有限,可以通过实现 TCAPIRequestUploadDelegate 和 TCAPIRequestDownloadDelegate 来取消内部的自动上传和下载的逻辑,获得上传下载参数后自己拼装请求参数。
TCAPIRequestUploadDelegate 协议:
-(BOOL)cgiUploadRequest:(TCAPIRequest*)uploadRequest shouldBeginUploadingStorageRequest:(NSURLRequest*)storageRequest;
TCAPIRequestDownloadDelegate 协议:
-(BOOL)cgiDownloadRequest:(TCAPIRequest*)downloadRequest shouldBeginDownloadingStorageRequest:(NSURLRequest*)storageRequest;
如果不实现上传、下载协议,则按默认方式进行数据的上传下载。第三方实现协议若返回YES,则默认进行数据的上传下载。返回NO则停止上传下载。由第三方获取当前数据后自己上传下载数据。
其他API统一接口的调用参照上传照片的调用方式。目前统一接口主要支持微云所有API接口的调用和微博上传带有图片微博的调用,具体可以参考WeiyunAPI.h和WeiboAPI.h中有关微云和微博TCAPIRequest对象的定义。
5. WPA临时会话
iOS SDK支持发起QQ临时会话,获取指定QQ帐号在线状态。使用WPA功能需要设置QQ业务回调,请参考6. 处理QQ业务的回调。
5.1 发起QQ临时会话
下面是向指定QQ号码发起临时会话的示例代码:
-(void)onOpenWPA:(QElement*)sender
{
[self.view endEditing:YES];
[self.root fetchValueUsingBindingsIntoObject:self];
QQApiWPAObject*wpaObj=[QQApiWPAObject objectWithUin:self.binding_uin];
SendMessageToQQReq*req=[SendMessageToQQReq reqWithContent:wpaObj];
QQApiSendResultCodesent=[QQApiInterface sendReq:req];
[self handleSendResult:sent];
}
5.2 获取指定QQ号码的在线状态
下面是获取指定QQ号码在线状态的示例代码:
-(void)getQQUinOnlineStatues:(QElement*)sender
{
[self.view endEditing:YES];
[self.root fetchValueUsingBindingsIntoObject:self];
NSArray*ARR=[NSArray arrayWithObjects:self.binding_uin,nil];
[QQApiInterface getQQUinOnlineStatues:ARR delegate:self];
}
6. 处理QQ业务的回调
在使用QQApiInterface 的方法时需要设置回调才能正确调用。设置方法如下:
-(BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url
{
#if __QQAPI_ENABLE__
[QQApiInterface handleOpenURL:url delegate:(id)[QQAPIDemoEntryclass]];
#endif
if(YES==[TencentOAuth CanHandleOpenURL:url])
{
return[TencentOAuth HandleOpenURL:url];
}
returnYES;
}
在handleOpenURL 中添加[QQApiInterface handleOpenURL:url delegate:(id)[QQAPIDemoEntry class]]代码,可以在QQAPIDemoEntry类中实现QQApiInterfaceDelegate的回调方法。更完整的示例请参考SDKDemo。
7. iOS SDK 腾讯平台开放能力
iOS SDK支持第三方应用成为腾讯业务内容的提供商,要想成为腾讯业务内容提供商需要在QQ互联的官网进行注册。
使用SDK响应腾讯业务发起的内容请求可以参考下面的操作:
7.1 修改工程配置文件
在XCode中,选择你的工程设置项,选中“TARGETS”一栏,在“info”标签栏的“URL type”添加一条新的“URL scheme”,新的scheme = tencent + appid+‘.’+ content,identifier“tencentApiIdentifier”为。如果您使用的是XCode3或者更低的版本,则需要在plist文件中添加。Demo中我们注册的appid是222222。如下图
7.2 重写AppDelegate 的handleOpenURL和openURL方法
openURL:
-(BOOL)application:(UIApplication*)application openURL:(NSURL*)url sourceApplication:(NSString*)sourceApplication annotation:(id)annotation
{
if(YES==[TencentApiInterface canOpenURL:url delegate:self])
{
[TencentApiInterface handleOpenURL:url delegate:self];
}
}
handleOpenURL
-(BOOL)application:(UIApplication*)application handleOpenURL:(NSURL*)url
{
if(YES==[TencentApiInterface canOpenURL:url delegate:self])
{
[TencentApiInterface handleOpenURL:url delegate:self];
}
}
7.3 实现TencentApiInterfaceDelegate协议
响应腾讯业务的请求,需要实现TencentApiInterfaceDelegate协议的两个方法:
@protocolTencentApiInterfaceDelegate
//onTencentReq是腾讯业务向第三方应用主动发起请求,要求第三方应用响应提供内容,第三方应用再响应完成后需要调用TencentApiInterface的sendRespMessageToTencentApp返回腾讯业务。
-(BOOL)onTencentReq(TencentApiReq*)req;
//onTencentResp是第三方应用主动向腾讯业务发起请求后,腾讯业务返回请求结果。
可以参考以下代码实现对腾讯业务的请求的响应,或参考我们的sample中的代码实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
-(BOOL)onTencentReq:(TencentApiReq*)req
{
NSArray*array=[reqarrMessage];
for(idobjinarray)
{
if([obj isKindOfClass:[TencentTextMessageObjV1class]])
{
obj=(TencentTextMessageObjV1*)obj;
[obj setSText:@"test"];
}
if([obj isKindOfClass:[TencentImageMessageObjV1class]])
{
obj=(TencentImageMessageObjV1*)obj;
NSString*path=[NSString stringWithFormat:@"%@/qzone0.jpg",
[[NSBundlemainBundle] resourcePath]];
UIImage*image=[[UIImagealloc] initWithContentsOfFile:path];
NSData*data=UIImageJPEGRepresentation(image,1.0f);
[obj setDataImage:data];
}
if([obj isKindOfClass:[TencentVideoMessageV1class]])
{
//请加入一段视频URL
obj=(TencentVideoMessageV1*)obj;
[obj setSUrl:@" http://www.tudou.com/programs/view/_cVM3aAp270/"];
}
}
TencentApiResp*resp=[TencentApiResp respFromReq:req];
[TencentOAuth sendRespMessageToTencentApp:resp];
}