iOS第三方平台集成组件化

背景

项目使用到了一些第三方平台的登录、分享、支付功能,包括了微信、微博、QQ平台登录分享和支付宝、微信平台的支付,使用的是原生的接入配置集成的,功能上基本上对照着SDK的开发文档就能够成功的集成了。但是问题也后面也渐渐的暴露出来了,第三方平台的登录、分享、支付功能不同平台的的SDK实现方式还是有很大的差别的,包括了输入的参数以及回调方式都有差别很大,如果只是简单的按照文档集成,那么一定会遇到代码调用结构很乱,回调杂乱不统一的问题,更为严重的是,后面如果添加删除一个第三发平台,那么修改变得很困难和难以维护,这违反了软件开发中的开闭原则,所以考虑到了把这部分代码做一个重构。

结果

项目实现了添加和删除第三方平台的可扩展,添加或者删除第三发平台只要增加或者移除对应的类和配置即可,不会涉及到已有的代码,客户端的调用也不影响。

先上一个客户端代码调用的代码

[self addActionWithName:@"QQ Login"callback:^{

[[PTThirdPlatformConfigManager sharedInstance] signInWithType:PTThirdPlatformTypeTencentQQ fromViewController:weakSelf callback:^(ThirdPlatformUserInfo *userInfo, NSError *err) {

}];

}];

[self addActionWithName:@"Wechat Login"callback:^{

[[PTThirdPlatformConfigManager sharedInstance] signInWithType:PTThirdPlatformTypeWechat fromViewController:weakSelf callback:^(ThirdPlatformUserInfo *userInfo, NSError *err) {

}];

}];

问题分析

首先从客户端的角度分析,对于登录、分享、支付功能,基本上我们的输入是固定的:

确定了输入输出关系,接下来的事情就是统一输入输出,这也是这次代码重构的关键。

结构设计

基于以上的分析,对不同平台的SDK的请求和响应设计了对应的接口进行隔离,这部分的设计类似于抽象工厂,不同的第三发平台抽象为了管理工厂,管理工厂实现了一个共同的接口,不同平台的操作(登录、分享、支付的操作可以认为是产品)抽象为了共同的接口调用(这里和抽象工厂不同,没有对这些操作封装为对象然后使用对象再去操作,主要是为了保持代码的简单,防止设计过度)

单个平台(以微信平台为例)的类结构图: 结构图

结构说明:

接口PTAbsThirdPlatformManager抽象了客户端对第三发平台的配置和请求

接口PTAbsThirdPlatformRequestHandler抽象了第三方平台的请求

接口PTAbsThirdPlatformRespManager抽象了第三方平台的响应通过PTAbsThirdPlatformRespManagerDelegate把数据统一回调到PTAbsThirdPlatformManager子类中

类PTWXManager是PTAbsThirdPlatformManager的具体实现,进行微信第三方平台的登录、分享和支付处理

类PTWXRequestHandler是PTAbsThirdPlatformRequestHandler的实现,这里和微信的API打交道

类PTWXRespManager是PTAbsThirdPlatformRespManager的实现,在这里处理微信SDK的回调,并通过PTAbsThirdPlatformRespManagerDelegate把数据回调到PTWXManager

这样添加其他平台,只要对应的添加 【PT平台Manager】、【PT平台RequestHandler】、【PT平台RespManager】这三个类就好了

不同平台的结构好了,接下来需要有一个地方统一管理不同平台,进行统一的配置管理、请求管理:

PTThirdPlatformConfigManager也是PTAbsThirdPlatformManager实现,里面配置了不同的平台对应的管理器,客户端只要传递不同平台的类型以及需要对应的操作,就可以调用对应平台的功能了。现在客户端可以直接和PTThirdPlatformConfigManager打交道了,而不用去和具体的比如PTWXManager、PTWeiboManager等管理器打交道了。

如果客户添加了新的平台,需要再PTThirdPlatformConfigManager进行配置就行了,然后客户端调用的逻辑保持不变。

代码实现

抽象接口部分

客户端第三方平台功能调用的抽象接口,这些接口是第三发平台需要使用到了接口的并集,有的平台需要用到全部,有的只需要部分即可,比如微信到了登录、分享、支付;支付宝用到了只有支付不同的平台根据功能的不同,实现对应的方法即可。

//

//  PTAbsThirdPlatformManager.h

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import

#import

#import"PTThirdPlatformDefine.h"

#import"PTThirdPlatformObject.h"

#import"UtilMacro.h"

@classPTOrderModel;

@protocol PTAbsThirdPlatformManager

@optional

- (void)thirdPlatConfigWithApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions;

/**

第三方平台处理URL

*/

- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application

openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation;

/**

第三方登录

@param thirdPlatformType 第三方平台

@param viewController 从哪个页面调用的分享

@param callback 登录回调

*/

- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType

fromViewController:(UIViewController *)viewController

callback:(void(^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback;

/**

第三方分享

@param platform 第三方分享平台

@param image 分享的图片

@param imageUrlString 分享的图片地址

@param title 分享的标题

@param text 分享的文字

@param urlString 分享的URL

@param fromViewController 从哪个页面调用的分享

@param shareResultBlock 分享结果回调

*/

- (void)shareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock;

/**

第三方支付

@param payMethodType 支付平台

@param order 支付订单模型

@param paymentBlock 支付结果回调

*/

- (void)payWithPlateform:(PTPaymentMethodType)payMethodType

order:(PTOrderModel*)order

paymentBlock:(void(^)(BOOL result))paymentBlock;

@end

具体的第三发平台调用SDK接口的抽象,因为考虑到考虑到代码的功能清晰性,所以把SDK接口调用的请求和相应部分单独出来,虽然增加了类和代码量,但在代码的职责分离上更清晰。

//

//  PTAbsThirdPlatformRequestHandler.h

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import

#import

#import"PTThirdPlatformDefine.h"

@classPTOrderModel;

@protocol PTAbsThirdPlatformRequestHandler

@optional

// 第三方授权

+ (BOOL)sendAuthInViewController:(UIViewController *)viewController;

// 支付

+ (BOOL)payWithOrder:(PTOrderModel*)order;

// 分享

+ (BOOL)sendMessageWithImage:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

urlString:(NSString*)urlString

title:(NSString*)title

text:(NSString*)text

shareType:(PTShareType)shareType;

@end

第三发平台响应和回调部分的接口,这部分主要负责把不同SDK的不同回调方式和回调方法统一进行回调,通过PTAbsThirdPlatformRespManagerDelegate定义的方法回调到具体的Manager。

//

//  PTAbsThirdPlatformRespManager.h

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import

#import"PTThirdPlatformDefine.h"

#import"PTThirdPlatformObject.h"

#import"UtilMacro.h"

// RespManagerDelegate

@protocol PTAbsThirdPlatformRespManagerDelegate

@optional

- (void)respManagerDidRecvPayResponse:(BOOL)result platform:(PTPaymentMethodType)platform;

- (void)respManagerDidRecvAuthResponse:(ThirdPlatformUserInfo *)response platform:(PTThirdPlatformType)platform;

- (void)respManagerDidRecvMessageResponse:(BOOL)result platform:(PTShareType)platform;

@end

@protocol PTAbsThirdPlatformRespManager

@optional

// 代理,子类需要设置getter/setter

@property (nonatomic, weak) iddelegate;

@end

接口实现类部分

首先定义了PTBaseThirdPlatformManager类用于处理不同平台的公共部分,比如说回调block的设置,接收到PTAbsThirdPlatformRespManagerDelegate的回调然后进行客户端的block回调。此外还有分享图片的统一处理,图片统一处理好了之后交给子类进行处理,这里使用到了是模板模式。

//

//  PTBaseThirdPlatformManager.h

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import

#import"PTAbsThirdPlatformManager.h"

@interfacePTBaseThirdPlatformManager : NSObject

@property (nonatomic, copy) void(^paymentBlock)(BOOL result);

@property (nonatomic, copy) void(^callback)(ThirdPlatformUserInfo* userInfo, NSError* err);

@property (nonatomic, copy) void(^shareResultBlock)(PTShareType, PTShareResult, NSError *);

/**

第三方分享,子类重写这个方法,由父类的shareToPlateform方法调用子类的该方法

@param platform 第三方分享平台

@param image 分享的图片

@param imageUrlString 分享的图片地址

@param title 分享的标题

@param text 分享的文字

@param urlString 分享的URL

@param fromViewController 从哪个页面调用的分享

@param shareResultBlock 分享结果回调

*/

- (void)doShareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock;

@end

//

//  PTBaseThirdPlatformManager.m

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import"PTBaseThirdPlatformManager.h"

#import

@implementation PTBaseThirdPlatformManager

- (void)thirdPlatConfigWithApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 子类实现

NSAssert(YES, @"哥么,这里你忘记实现了");

}

/**

第三方平台处理URL

*/

- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application

openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation {

// 子类实现

NSAssert(YES, @"哥么,这里你忘记实现了");

returnNO;

}

/**

第三方分享

@param platform 第三方分享平台

@param image 分享的图片

@param imageUrlString 分享的图片地址

@param title 分享的标题

@param text 分享的文字

@param urlString 分享的URL

@param fromViewController 从哪个页面调用的分享

@param shareResultBlock 分享结果回调

*/

- (void)shareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock {

__block UIImage* sharedImage = nil;

if(image) {

sharedImage = image;

[self doShareToPlateform:platform image:sharedImage imageUrlString:imageUrlString title:title text:text urlString:urlString fromViewController:fromViewController shareResultBlock:shareResultBlock];

} elseif(imageUrlString != nil) {

[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:imageUrlString] options:0progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {

if(image) {

sharedImage = image;

} else{

sharedImage = [UIImage imageNamed:@"app_icon"];

}

[self doShareToPlateform:platform image:sharedImage imageUrlString:imageUrlString title:title text:text urlString:urlString fromViewController:fromViewController shareResultBlock:shareResultBlock];

}];

} else{

sharedImage = [UIImage imageNamed:@"signin_logo"];

[self doShareToPlateform:platform image:sharedImage imageUrlString:imageUrlString title:title text:text urlString:urlString fromViewController:fromViewController shareResultBlock:shareResultBlock];

}

}

- (void)doShareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock {

// 空实现,子类实现该方法

}

/**

第三方登录

@param thirdPlatformType 第三方平台

@param viewController 从哪个页面调用的分享

@param callback 登录回调

*/

- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType fromViewController:(UIViewController *)viewController callback:(void(^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback {

// 空实现,子类实现该方法

}

/**

第三方支付

5

@param payMethodType 支付平台

@param order 支付订单模型

@param paymentBlock 支付结果回调

*/

- (void)payWithPlateform:(PTPaymentMethodType)payMethodType order:(PTOrderModel*)order paymentBlock:(void(^)(BOOL result))paymentBlock {

// 空实现,子类实现该方法

}

#pragma mark - ......::::::: PTAbsThirdPlatformRespManagerDelegate :::::::......

- (void)respManagerDidRecvAuthResponse:(ThirdPlatformUserInfo *)response platform:(PTThirdPlatformType)platform {

PTOnMainThreadAsync(^{

!_callback ?: _callback(response, nil);

});

}

- (void)respManagerDidRecvMessageResponse:(BOOL)result platform:(PTShareType)platform {

PTOnMainThreadAsync(^{

if(result) {

!self.shareResultBlock ?: self.shareResultBlock(platform, PTShareResultSuccess, nil);

} else{

!self.shareResultBlock ?: self.shareResultBlock(platform, PTShareResultFailed, nil);

}

});

}

- (void)respManagerDidRecvPayResponse:(BOOL)result platform:(PTPaymentMethodType)platform {

PTOnMainThreadAsync(^{

!self.paymentBlock ?: self.paymentBlock(result);

});

}

@end

具体平台的实现,以微信为例,PTWXManager处理微信平台的SDK初始化配置;设置微信客户端的URL回调的的代理类,即PTWXRespManager的单例对象。然后就是具体的业务功能方法的重写,包含了登录、分享、支付,具体的功能则是交给PTWXRequestHandler类处理,然后设置PTWXRespManager单例对象的delegate为自身,会在父类PTBaseThirdPlatformManager统一的处理回调。

//

//  PTWXManager.m

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import"PTWXManager.h"

#import"PTWXRespManager.h"

#import"PTWXRequestHandler.h"

#import

#import"PTThirdPlatformConfigConst.h"

@interfacePTWXManager ()

@end

@implementation PTWXManager

DEF_SINGLETON

- (void)thirdPlatConfigWithApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

// 子类实现

//向微信注册

[WXApi registerApp:kWXAppID];

}

/**

第三方平台处理URL

*/

- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application

openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation {

// 微信

if([WXApi handleOpenURL:url delegate:[PTWXRespManager sharedInstance]]) {

returnYES;

}

returnNO;

}

/**

第三方登录

@param thirdPlatformType 第三方平台

@param fromViewController 从哪个页面调用的分享

@param callback 登录回调

*/

- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType fromViewController:(UIViewController *)viewController callback:(void(^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback {

self.callback = callback;

[PTWXRespManager sharedInstance].delegate = self;

[PTWXRequestHandler sendAuthInViewController:viewController];

}

/**

第三方分享,子类重写这个方法,由父类的shareToPlateform方法调用子类的该方法

@param platform 第三方分享平台

@param image 分享的图片

@param imageUrlString 分享的图片地址

@param title 分享的标题

@param text 分享的文字

@param urlString 分享的URL

@param fromViewController 从哪个页面调用的分享

@param shareResultBlock 分享结果回调

*/

- (void)doShareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock {

self.shareResultBlock = shareResultBlock;

[self doWechatShareWithImage:image urlString:urlString title:title text:text platform:platform fromViewController:fromViewController];

}

- (void)doWechatShareWithImage:(UIImage*)image

urlString:(NSString*)urlString

title:(NSString*)title

text:(NSString*)text

platform:(PTShareType)platform

fromViewController:(UIViewController*)fromViewController {

[PTWXRespManager sharedInstance].delegate = self;

BOOL shareResult = [PTWXRequestHandler sendMessageWithImage:image imageUrlString:nil urlString:urlString title:title text:text shareType:platform];

if(shareResult == NO) {

!self.shareResultBlock ?: self.shareResultBlock(PTShareTypeWechat, PTShareResultFailed, nil);

}

}

/**

第三方支付

@param payMethodType 支付平台

@param order 支付订单模型

@param paymentBlock 支付结果回调

*/

- (void)payWithPlateform:(PTPaymentMethodType)payMethodType order:(PTOrderModel*)order paymentBlock:(void(^)(BOOL result))paymentBlock {

self.paymentBlock = paymentBlock;

// 使用支付宝支付

[PTWXRespManager sharedInstance].delegate = self;

[PTWXRequestHandler payWithOrder:order];

}

@end

PTWXRequestHandler实现了具体的SDK调用以及其他的一些操作

//

//  PTWXRequestHandler.m

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import"PTWXRequestHandler.h"

#import

#import"PTWXRespManager.h"

#import"PTOrderModel.h"

#import"PTThirdPlatformConfigConst.h"

#import"UIImage+Util.h"

@implementation PTWXRequestHandler

+ (BOOL)sendAuthInViewController:(UIViewController *)viewController {

SendAuthReq* req = [[SendAuthReq alloc] init];

req.scope = kAuthScope;

req.state = kAuthOpenID;

req.openID = kAuthOpenID;

4

return[WXApi sendAuthReq:req

viewController:viewController

delegate:[PTWXRespManager sharedInstance]];

}

+ (BOOL)payWithOrder:(PTOrderModel *)order {

//调起微信支付

PayReq* req            = [[PayReq alloc] init];

req.partnerId          = order.partnerid;

req.prepayId            = order.prepayid;

req.nonceStr            = order.noncestr;

req.timeStamp          = order.timestamp;

req.package= order.package;

req.sign                = order.sign;

BOOL result = [WXApi sendReq:req];

returnresult;

}

// 分享

+ (BOOL)sendMessageWithImage:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

urlString:(NSString*)urlString

title:(NSString*)title

text:(NSString*)text

shareType:(PTShareType)shareType {

enum WXScene wxScene = 0;

if(PTShareTypeWechat == shareType) {

wxScene = WXSceneSession;

} elseif(PTShareTypeWechatLine == shareType) {

wxScene = WXSceneTimeline;

}

SendMessageToWXReq* req = [[SendMessageToWXReq alloc] init];

req.scene = wxScene;

req.bText = NO;

WXMediaMessage* msg = [[WXMediaMessage alloc] init];

msg.title = title;

msg.description = text;

[msg setThumbImage:[self scaledImageWithOriImage:image]];

if(urlString && urlString.length>0) {

WXWebpageObject* webPageObj = [[WXWebpageObject alloc] init];

webPageObj.webpageUrl = urlString;

msg.mediaObject = webPageObj;

}

req.message = msg;

BOOL result = [WXApi sendReq:req];

returnresult;

}

+ (UIImage*)scaledImageWithOriImage:(UIImage*)oriImage {

NSInteger maxSharedImageBytes = 32*1000;//32K

NSInteger oriImageBytes = UIImageJPEGRepresentation(oriImage, 1.0).length;

if(oriImageBytes > maxSharedImageBytes) {

CGFloat scaleFactor = maxSharedImageBytes * 1.0f / oriImageBytes * 1.0f;

UIImage* scaledImage = [oriImage scaletoScale:scaleFactor];

if(scaledImage) {

returnscaledImage;

}

}

returnoriImage;

}

@end

PTWXRespManager处理微信SDK的回调,并PTAbsThirdPlatformRespManagerDelegate代理把回调统一的传递给PTWXManager

//

//  PTWXRespManager.m

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import"PTWXRespManager.h"

#import"WXApi.h"

#import"NSData+NSJSON.h"

#import"PTThirdPlatformConfigConst.h"

#import"NetworkRequestUtil.h"

@implementation PTWXRespManager

DEF_SINGLETON

#pragma mark - WXApiDelegate

- (void)onResp:(BaseResp *)resp {

if([resp isKindOfClass:[SendMessageToWXResp class]]) {

if(self.delegate

&& [self.delegate respondsToSelector:@selector(respManagerDidRecvMessageResponse:platform:)]) {

if(resp.errCode == WXSuccess) {

[self.delegate respManagerDidRecvMessageResponse:YES platform:PTShareTypeWechat];

} else{

[self.delegate respManagerDidRecvMessageResponse:NO platform:PTShareTypeWechat];

}

}

} elseif([resp isKindOfClass:[SendAuthResp class]]) {

if(resp.errCode == WXSuccess) {

// wx请求accessToken & openId

NSString *urlString = [NSString stringWithFormat:@"https://api.weixin.qq.com/sns/oauth2/access_token?appid=%@&secret=%@&code=%@&grant_type=authorization_code", kWXAppID, kWXAppSecret, ((SendAuthResp*)resp).code];

[NetworkRequestUtil requestWithURLString:urlString completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

NSDictionary *resultDict = [data nsjsonObject];

[self getUserInfoWithAccessToken:[resultDict objectForKey:@"access_token"] andOpenId:[resultDict objectForKey:@"openid"]];

}];

} else{

if(self.delegate

&& [self.delegate respondsToSelector:@selector(respManagerDidRecvAuthResponse:platform:)]) {

[self.delegate respManagerDidRecvAuthResponse:nil platform:PTThirdPlatformTypeWechat];

}

}

} elseif([resp isKindOfClass:[PayResp class]]){

//支付返回结果,实际支付结果需要去微信服务器端查询

if(self.delegate

&& [self.delegate respondsToSelector:@selector(respManagerDidRecvPayResponse:platform:)]) {

[self.delegate respManagerDidRecvPayResponse:(resp.errCode == WXSuccess) platform:PaymentMethodTypeWechat];

}

}

}

//wx获取用户信息

- (void)getUserInfoWithAccessToken:(NSString *)accessToken andOpenId:(NSString *)openId{

NSString *urlString =[NSString stringWithFormat:@"https://api.weixin.qq.com/sns/userinfo?access_token=%@&openid=%@", accessToken, openId];

[NetworkRequestUtil requestWithURLString:urlString completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {

NSDictionary *resultDict = [data nsjsonObject];

ThirdPlatformUserInfo* userInfo = [ThirdPlatformUserInfo new];

userInfo.userId = [resultDict objectForKey:@"unionid"];

userInfo.username = [resultDict objectForKey:@"nickname"];

userInfo.head = [resultDict objectForKey:@"headimgurl"];

userInfo.tokenString = accessToken;

PTOnMainThreadAsync(^{

if(self.delegate

&& [self.delegate respondsToSelector:@selector(respManagerDidRecvAuthResponse:platform:)]) {

[self.delegate respManagerDidRecvAuthResponse:userInfo platform:PTThirdPlatformTypeWechat];

}

});

}];

}

@end

不同平台的管理类,这部分是用户统一处理客户端的第三发平台功能调用的,因为不同的第三方平台有相同的接口,为了不和具体的第三方平台耦合,使用了类名字符串进行配置不同的平台,客户端只要使用这个类就可以和具体的第三方平台交互了。

//

//  PTThirdPlatformConfigManager.m

//  YTThirdPlatformManager

//

//  Created by aron on 2017/10/26.

//  Copyright © 2017年 aron. All rights reserved.

//

#import"PTThirdPlatformConfigManager.h"

#import"PTAbsThirdPlatformManager.h"

@implementation PTThirdPlatformConfigManager

DEF_SINGLETON

/**

第三方平台配置

*/

- (void)thirdPlatConfigWithApplication:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

for(NSString* classString in[self thirdPlatformManagerClasses]) {

idmanager = [self managerFromClassString:classString];

if(manager && [manager conformsToProtocol:@protocol(PTAbsThirdPlatformManager)]) {

[manager thirdPlatConfigWithApplication:application didFinishLaunchingWithOptions:launchOptions];

}

}

}

/**

第三方平台处理URL

*/

- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application

openURL:(NSURL *)url

sourceApplication:(NSString *)sourceApplication

annotation:(id)annotation {

for(NSString* classString in[self thirdPlatformManagerClasses]) {

idmanager = [self managerFromClassString:classString];

if(manager && [manager conformsToProtocol:@protocol(PTAbsThirdPlatformManager)]) {

BOOL result = [manager thirdPlatCanOpenUrlWithApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];

if(result) {

returnYES;

}

}

}

returnNO;

}

/**

第三方登录

@param thirdPlatformType 第三方平台

@param fromViewController 从哪个页面调用的分享

@param callback 登录回调

*/

- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType

fromViewController:(UIViewController *)viewController

callback:(void(^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback {

NSString* classString = [[self thirdPlatformSigninManagerConfig] objectForKey:@(thirdPlatformType)];

idmanager = [self managerFromClassString:classString];

[manager signInWithType:thirdPlatformType

fromViewController:viewController

callback:callback];

}

/**

第三方分享

@param platform 第三方分享平台

@param image 分享的图片

@param imageUrlString 分享的图片地址

@param title 分享的标题

@param text 分享的文字

@param urlString 分享的URL

@param fromViewController 从哪个页面调用的分享

@param shareResultBlock 分享结果回调

*/

- (void)shareToPlateform:(PTShareType)platform

image:(UIImage*)image

imageUrlString:(NSString*)imageUrlString

title:(NSString*)title

text:(NSString*)text

urlString:(NSString*)urlString

fromViewController:(UIViewController*)fromViewController

shareResultBlock:(void(^) (PTShareType platform, PTShareResult shareResult, NSError* error))shareResultBlock {

NSString* classString = [[self thirdPlatformShareManagerConfig] objectForKey:@(platform)];

idmanager = [self managerFromClassString:classString];

[manager shareToPlateform:platform

image:image

imageUrlString:imageUrlString

title:title

text:text

urlString:urlString

fromViewController:fromViewController

shareResultBlock:shareResultBlock];

}

/**

第三方支付

@param payMethodType 支付平台

@param order 支付订单模型

@param paymentBlock 支付结果回调

*/

- (void)payWithPlateform:(PTPaymentMethodType)payMethodType order:(PTOrderModel*)order paymentBlock:(void(^)(BOOL result))paymentBlock {

NSString* classString = [[self thirdPlatformPayManagerConfig] objectForKey:@(payMethodType)];

idmanager = [self managerFromClassString:classString];

[manager payWithPlateform:payMethodType

order:order

paymentBlock:paymentBlock];

}

- (id)managerFromClassString:(NSString*)classString {

if(classString == nil || classString.length == 0) {

returnnil;

}

Class clz = NSClassFromString(classString);

SEL sharedInstanceSelector = @selector(sharedInstance);

idmanager = nil;

if(clz && [clz respondsToSelector:sharedInstanceSelector]){

manager = [clz performSelector:sharedInstanceSelector];

}

returnmanager;

}

- (NSArray*)thirdPlatformManagerClasses {

return@[@"PTAlipayManager",

@"PTTencentManager",

@"PTWeiboManager",

@"PTWXManager",

];

}

- (NSDictionary*)thirdPlatformSigninManagerConfig {

return@{

@(PTThirdPlatformTypeWechat): @"PTWXManager",

@(PTThirdPlatformTypeTencentQQ): @"PTTencentManager",

@(PTThirdPlatformTypeWeibo): @"PTWeiboManager"

};

}

- (NSDictionary*)thirdPlatformPayManagerConfig {

return@{

@(PaymentMethodTypeWechat): @"PTWXManager",

@(PaymentMethodTypeAlipay): @"PTAlipayManager"

};

}

- (NSDictionary*)thirdPlatformShareManagerConfig {

return@{

@(PaymentMethodTypeWechat): @"PTWXManager",

@(PTShareTypeWechatLine): @"PTWXManager",

@(PTShareTypeQQ): @"PTTencentManager",

@(PTShareTypeQQZone): @"PTTencentManager",

@(PTShareTypeWeibo): @"PTWeiboManager",

};

}

@end

One More Thing

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

推荐阅读更多精彩内容