既然知道了我们可以自己构造scheme url打开其他App,并完成对应的业务操作。那么我们来试试,不适用SDK的情况下,完成分享信息到QQ和QZone.
首先,假设我们做成一个标准,任何遵循我们这个标准都可以被我们直接拿来使用,将数据分享到对应的平台。Ok,我们先定义一个分享的标准Api接口。
/**
* 所有分享平台必须实现的规范
*/
@protocol ShareInterface <NSObject>
@required
//分享平台的关键字
- (NSString *)platformName;
//分享平台的类型
- (XZHSharePlatform)platformType;
//secret是可选
- (void)registWithAppIdOrAppKey:(NSString *)keyOrId
AppSecret:(NSString *)secret;
//分享
- (void)startShare:(XZHMessage *)message Type:(XZHShareType)shareType;
- (BOOL)handleOpenURL;
@optional
//授权
- (void)oauth;
- (BOOL)isInstalled;
@end
定义完接口后,我们开始做一个分享到腾讯平台的接口实现。
//.h
#import <Foundation/Foundation.h>
#import "XZHShareBase.h"
//注: XZHShareBase类默认实现了接口,并提供了一些基础代码
@interface XZHShareToQQ : XZHShareBase
@end
- (NSString *)platformName {
return @"QQ";
}
- (XZHSharePlatform)platformType {
return XZHShareQQ;
}
/**
* 把传入的appKey和appSecret使用单例对象保存起来,方便后面使用
*/
- (void)registWithAppIdOrAppKey:(NSString *)keyOrId AppSecret:(NSString *)secret {
//保存参数
NSDictionary *options = @{
@"appid" : keyOrId,
@"callback_name" : [NSString stringWithFormat:@"QQ%02llx",[keyOrId longLongValue]]
};
[self saveOptions:options];
}
/**
* 分享信息的核心方法:
* 1. 根据不同的分享Api,构造不同的scheme url
* 2. 构造完scheme url后,openURL打开url,掉起QQ
*/
- (void)startShare:(XZHMessage *)message Type:(XZHShareType)shareType
{
NSString *url = @"";
if (shareType == XZHShareToQZone) {
url = [self _genShareUrl:message to:XZHTencentQZone];
} else if (shareType == XZHShareToQQFriend) {
url = [self _genShareUrl:message to:XZHTencentMobileQQ];
} else if (shareType == XZHShareToQQFavirate) {
url = [self _genShareUrl:message to:XZHTencentQQShareFavorites];
} else if (shareType == XZHShareToQQDataLine) {
url = [self _genShareUrl:message to:XZHTencentQQShareDataline];
}
[[self class] openURL:url];
}
/**
* 根据不同分享Api,生成不同的分享schme url
*/
- (NSString*)_genShareUrl:(XZHMessage *)msg to:(XZHTencentPlatform)shareTo {
NSString *url = [[NSString alloc] initWithString:ShareSchema];
NSString *boundleName = [XZHShareManager base64Encode:[XZHShareManager CFBundleDisplayName]];
NSString *callback_name = [[self optionDict] objectForKey:@"callback_name"];
NSMutableDictionary *params = [@{
@"thirdAppDisplayName" : boundleName,
@"version" : @"1",
@"cflag" : [NSString stringWithFormat:@"%ld", shareTo],
@"callback_type" : @"scheme",
@"generalpastboard" : @"1",
@"callback_name" : callback_name,
@"src_type" : @"app",
@"shareType" : @"0",
} mutableCopy];
//如果未给当前message对象设置 分享消息类型,则默认为 news类型
if (msg.link && !msg.messageType) {
msg.messageType = XZHMessageNews;
}
NSDictionary *subParams = nil;
if ([msg computeMessageType] == XZHMessageText) {
NSString *fileData = [XZHShareManager base64AndUrlEncode:msg.title];
subParams = @{
@"file_type" : @"text",
@"file_data" : fileData
};
} else if ([msg computeMessageType] == XZHMessageImage) {
//将message保存到剪贴板
NSDictionary *data=@{
@"file_data":msg.imageData,
@"previewimagedata":msg.thumbImageData?:msg.imageData
};
[[XZHShareManager manager] clipBoardSave:data
ForKey:SaveObjectForQQPlatformKey
Encoding:XZHClipBoardNSKeyedArchiver];
NSString *title = [XZHShareManager base64AndUrlEncode:msg.title];
NSString *desc = [XZHShareManager base64AndUrlEncode:msg.desc];
subParams = @{
@"file_type" : @"img",
@"title" : title,
@"objectlocation" : @"pasteboard",
@"description" : desc,
};
}else if ([msg computeMessageType] == XZHMessageNews) {
NSDictionary *data=@{@"previewimagedata":msg.imageData};
//图片保存到剪贴板
[[XZHShareManager manager] clipBoardSave:data
ForKey:SaveObjectForQQPlatformKey
Encoding:XZHClipBoardNSKeyedArchiver];
NSString *title = [XZHShareManager base64AndUrlEncode:msg.title];
NSString *url = [XZHShareManager base64AndUrlEncode:msg.link];
NSString *desc = [XZHShareManager base64AndUrlEncode:msg.desc];
NSString *msgType=@"news";
if (msg.messageType == XZHMessageNews) {
msgType = @"news";
} else if (msg.messageType == XZHMessageAudio) {
msgType = @"audio";
}
subParams = @{
@"file_type" : msgType,
@"title" : title,
@"url" : url,
@"description" : desc,
@"objectlocation" : @"pasteboard",
};
}
//得到最后字典
[params addEntriesFromDictionary:subParams];
//构造最后的scheme url
url = [XZHShareManager urlStringWithOriginUrlString:url appendParameters:params];
return url;
}
//QQ处理完毕后,回调我们的App,执行Appdelegate回调函数
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
//其他应用掉起当前应用时,传回的参数,如果传入的url能够处理
if ([[XZHShareManager manager] handleOpenURL:url]) {
return YES;
}
//不能处理的App调起
return YES;
}
//XZHShareManager.m 所有我们管理的分享平台的回调函数,统一有这个类来分发,轮训所有的分享平台,看哪个能处理
- (BOOL)handleOpenURL:(NSURL *)url {
self.returnURL = url;
//轮训所有分享平台,看哪个能处理
for (id<XZHShareInterface> impl in self.platforms) {
if ([impl handleOpenURL]) {
return YES;
}
}
return NO;
}
//ShareToQQ.m 处理App回调时,QQ回传的参数
- (BOOL)handleOpenURL {
XZHShareManager *manager = [XZHShareManager manager];
NSString *returnURL = [manager.returnURL absoluteString];
if ([returnURL hasPrefix:ShareCallbackSchemePrix]) {
NSDictionary *dict = [XZHShareManager parseUrl:[XZHShareManager manager].returnURL];
if ([dict hasKey:@"error_description"]) {
[dict setValue:[XZHShareManager base64Decode:dict[@"error_description"]] forKey:@"error_description"];
}
if ([dict hasKey:@"error"]) {
NSInteger code = [dict[@"error"] integerValue];
if (code != 0) {
NSError *error = [NSError errorWithDomain:@"response_from_qq" code:code userInfo:dict];
if (manager.onShareFail) {
manager.onShareFail(manager.shareMessage, error);
}
}else {
if (manager.onShareSuccess) {
manager.onShareSuccess(manager.shareMessage);
}
}
}
[manager clearCompletions];
return YES;
} else if ([returnURL hasPrefix:OauthCallbackSchemePrix]) {
return YES;
} else {
return NO;
}
}