iOS第三方平台集成组件化


声明:本文转载自https://my.oschina.net/u/1242477/blog/1557875,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

背景

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

结果

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

   [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) {                      }];     }]; 

问题分析

首先从客户端的角度分析,对于登录、分享、支付功能,基本上我们的输入是固定的:
** 登录: **
输入:
第三发平台类型
输出:
第三发平台的用户信息(UID、用户名...)

** 分享: **
输入:
第三发平台类型
分享的内容(图片、标题、文字、超链接) 输出:
第三发平台类型
分享的结果

** 支付: **
输入:
第三发平台类型
支付信息(订单信息、签名信息...) 输出:
第三发平台类型
支付的结果

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

结构设计

基于以上的分析,对不同平台的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 <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "PTThirdPlatformDefine.h" #import "PTThirdPlatformObject.h" #import "UtilMacro.h"  @class PTOrderModel;  @protocol PTAbsThirdPlatformManager <NSObject>  @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 <Foundation/Foundation.h> #import <UIKit/UIKit.h> #import "PTThirdPlatformDefine.h"  @class PTOrderModel;  @protocol PTAbsThirdPlatformRequestHandler <NSObject>  @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 <Foundation/Foundation.h> #import "PTThirdPlatformDefine.h" #import "PTThirdPlatformObject.h" #import "UtilMacro.h"  // RespManagerDelegate @protocol PTAbsThirdPlatformRespManagerDelegate <NSObject>  @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 <NSObject>  @optional  // 代理,子类需要设置getter/setter @property (nonatomic, weak) id<PTAbsThirdPlatformRespManagerDelegate> delegate;  @end 

接口实现类部分

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

// //  PTBaseThirdPlatformManager.h //  YTThirdPlatformManager // //  Created by aron on 2017/10/26. //  Copyright © 2017年 aron. All rights reserved. //  #import <Foundation/Foundation.h> #import "PTAbsThirdPlatformManager.h"  @interface PTBaseThirdPlatformManager : NSObject <PTAbsThirdPlatformManager>  @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 <SDWebImage/SDWebImageManager.h>   @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, @"哥么,这里你忘记实现了");     return NO; }  /**  第三方分享    @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];     } else if (imageUrlString != nil) {         [[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:imageUrlString] options:0 progress: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 {     // 空实现,子类实现该方法 }  /**  第三方支付    @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 <WXApi.h> #import "PTThirdPlatformConfigConst.h"  @interface PTWXManager () <PTAbsThirdPlatformRespManagerDelegate> @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]]) {         return YES;     }     return NO; }  /**  第三方登录    @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 <WXApi.h> #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;          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];     return result; }  // 分享 + (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;     } else if (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];     return result; }  + (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) {             return scaledImage;         }     }     return oriImage; }  @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];             }         }     } else if ([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];             }         }              } else if([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]) {         id<PTAbsThirdPlatformManager> manager = [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]) {         id<PTAbsThirdPlatformManager> manager = [self managerFromClassString:classString];         if (manager && [manager conformsToProtocol:@protocol(PTAbsThirdPlatformManager)]) {             BOOL result = [manager thirdPlatCanOpenUrlWithApplication:application openURL:url sourceApplication:sourceApplication annotation:annotation];             if (result) {                 return YES;             }         }     }     return NO; }  /**  第三方登录    @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)];     id<PTAbsThirdPlatformManager> manager = [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)];     id<PTAbsThirdPlatformManager> manager = [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)];     id<PTAbsThirdPlatformManager> manager = [self managerFromClassString:classString];     [manager payWithPlateform:payMethodType                         order:order                  paymentBlock:paymentBlock]; }  - (id)managerFromClassString:(NSString*)classString {     if (classString == nil || classString.length == 0) {         return nil;     }     Class clz = NSClassFromString(classString);     SEL sharedInstanceSelector = @selector(sharedInstance);     id<PTAbsThirdPlatformManager> manager = nil;     if(clz && [clz respondsToSelector:sharedInstanceSelector]){         manager = [clz performSelector:sharedInstanceSelector];     }     return manager; }  - (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

刚刚学设计模式,有疏漏的地方请各位看官不吝赐教

本文发表于2017年10月30日 08:38
(c)注:本文转载自https://my.oschina.net/u/1242477/blog/1557875,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2670 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

万稳万当,不如一默。任何一句话,你不说出来便是那句话的主人,你说了出来,便是那句话的奴隶。

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1