background
The project uses the login, sharing and payment functions of some third-party platforms, including login and sharing on wechat, Weibo and QQ platforms and payment on Alipay and wechat platforms. The original access configuration integration is used, and the function can be successfully integrated basically according to the development documents of SDK. Behind but the problem is also gradually exposed, third-party platform login, share, pay function different platform SDK implemented or there’s a big difference, including the input parameters and callback methods have difference is very big, if simply integration according to the document, so will meet code calls the structure is a mess, the callback clutter is not uniform, What is more serious is that if a third platform is added and deleted later, the modification becomes very difficult and difficult to maintain, which violates the open and closed principle in software development, so WE considered to reconstruct this part of the code.
The results of
The project realized the extensibility of adding and deleting third-party platforms. To add or delete third-party platforms, you only need to add or remove corresponding classes and configurations, without involving existing codes and without affecting client calls.
I’m code, welcome to 👉👉YTThirdPlatformManager
The sequel of this article introduces the features of using POD library on the basis of this architecture, further modularization and decoupling, the business code of each third-party platform is separate sub-module of pod library, which can be imported into one or more third-party platforms as required.
The code that was called by the previous client code
[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) {
}];
}];
Copy the code
Problem analysis
Firstly, from the perspective of clients, the input and output of platform function calls are basically fixed for login, sharing and payment functions:
The input | The output | |
---|---|---|
The login | Third platform type | User information of the third platform (UID, user name…) |
share | Content shared (images, titles, text, hyperlinks) | Third send platform type, share result |
pay | Third platform type, payment information (order information, signature information… | Third platform type, payment results |
Having identified the input-output relationship, the next thing to do is to unify the input-output, which is the key to this code architecture.
Architecture design
Based on the above analysis, corresponding interfaces are designed to isolate the requests and responses of SDK of different platforms. The design of this part is similar to abstract factories. In order to manage factories, the management factories of different third-generation platforms realize a common interface. Different platforms (login operation, share, pay operation can be thought of as the product) abstract in order to a common interface to invoke (here is different from the abstract factory, no packages for these operations as the object and then using the object to operate, mainly in order to keep the code simple, prevent excessive design) a single platform for WeChat platform (for example) the class diagram:
- Interface PTAbsThirdPlatformManager abstract the client configuration and request the third platform
- Interface PTAbsThirdPlatformRequestHandler abstracts the request of the third party platform
- Interface response by PTAbsThirdPlatformRespManagerDelegate PTAbsThirdPlatformRespManager abstract the third-party platform to unify data correction to PTAbsThirdPlatformManager subclasses
- Class PTWXManager PTAbsThirdPlatformManager concrete realization, WeChat third-party platform login, share, and payment processing
- Class PTWXRequestHandler PTAbsThirdPlatformRequestHandler implementation, here working with WeChat API
- Class PTWXRespManager PTAbsThirdPlatformRespManager implementation, handle WeChat SDK callback here, And through the PTAbsThirdPlatformRespManagerDelegate add data correction to the PTWXManager such other platforms, Add three classes: PT Platform Manager, PT platform RequestHandler and PT platform RespManager
The structure of different platforms is good, and then there needs to be a unified management of different platforms, unified configuration management, request management:
Code implementation
Abstract interface part
Abstract interfaces for function calls of third-party platforms on the client side. These interfaces are the combination of interfaces needed by the third platform. Some platforms need to use all of them, and some only need part of them, such as wechat login, sharing and payment. Alipay is only used to pay different platforms according to the different functions, to achieve the corresponding method.
//
// 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;
/** third-party platforms handle urls */
- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation;
/** Third party login @param thirdPlatformType third party platform @param viewController from which page to call the share @param callback login callback */
- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType
fromViewController:(UIViewController *)viewController
callback:(void (^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback;
/** Third-party sharing @param Platform Third-party sharing platform @param image Shared image @param imageUrlString Shared image address @param title shared title @param text shared text @param urlString Share URL @param fromViewController share from which page @param shareResultBlock share result callback */
- (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;
/** third party payment @Param payMethodType payment platform @Param Order Payment order model @Param paymentBlock payment result callback */
- (void)payWithPlateform:(PTPaymentMethodType)payMethodType
order:(PTOrderModel*)order
paymentBlock:(void(^) (BOOL result))paymentBlock;
@end
Copy the code
The third platform calls the SDK interface abstraction. Considering the functional clarity of the code, the request and the corresponding part of the SDK interface call are separated separately. Although the number of classes and codes is increased, the separation of code responsibilities is clearer.
//
// 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
// Third party authorization
+ (BOOL)sendAuthInViewController:(UIViewController *)viewController;
/ / pay
+ (BOOL)payWithOrder:(PTOrderModel*)order;
/ / share
+ (BOOL)sendMessageWithImage:(UIImage*)image
imageUrlString:(NSString*)imageUrlString
urlString:(NSString*)urlString
title:(NSString*)title
text:(NSString*)text
shareType:(PTShareType)shareType;
@end
Copy the code
Third platform part of response and callback interface, this part is mainly responsible for the SDK of different correction method and the callback method for callback, through the method of defining PTAbsThirdPlatformRespManagerDelegate callback to the 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
Subclasses need to set getters/setters
@property (nonatomic.weak) id<PTAbsThirdPlatformRespManagerDelegate> delegate;
@end
Copy the code
Interface implementation class section
First defines PTBaseThirdPlatformManager classes are used to deal with the public portion of the different platforms, such as the callback block set, receiving PTAbsThirdPlatformRespManagerDelegate callback and then back to client block. In addition, there is the unified processing of shared images. After the unified processing of images, they are handed to subclasses for processing. Here, the template mode is used.
//
// 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 *);
/** subclass overrides this method, The shareToPlateform method of the parent class calls the method of the subclass @param Platform @param image shared image @param imageUrlString Shared image address @param title Share title @param text Share text @param urlString Share URL @param fromViewController share from which page @param shareResultBlock Share result callback */
- (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 {
// Subclass implementation
NSAssert(YES."Dude, you forgot to implement this.");
}
/** third-party platforms handle urls */
- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
// Subclass implementation
NSAssert(YES."Dude, you forgot to implement this.");
return NO;
}
/** Third-party sharing @param Platform Third-party sharing platform @param image Shared image @param imageUrlString Shared image address @param title shared title @param text shared text @param urlString Share URL @param fromViewController share from which page @param shareResultBlock share result callback */
- (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"];
[selfdoShareToPlateform: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 {
// Empty implementation, subclass implementation of this method
}
/** Third party login @param thirdPlatformType third party platform @param viewController from which page to call the share @param callback login callback */
- (void)signInWithType:(PTThirdPlatformType)thirdPlatformType fromViewController:(UIViewController *)viewController callback:(void (^)(ThirdPlatformUserInfo* userInfo, NSError* err))callback {
// Empty implementation, subclass implementation of this method
}
/** third party payment @Param payMethodType payment platform @Param Order Payment order model @Param paymentBlock payment result callback */
- (void)payWithPlateform:(PTPaymentMethodType)payMethodType order:(PTOrderModel*)order paymentBlock:(void(^) (BOOL result))paymentBlock {
// Empty implementation, subclass implementation of this method
}
#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
Copy the code
The realization of the specific platform, taking wechat as an example, PTWXManager deals with the initial configuration of the SDK of wechat platform; The proxy class that sets the URL callback of wechat client, namely the singleton object of PTWXRespManager. It then overwrites the specific business function methods, including login, sharing, and payment, which are handled by the PTWXRequestHandler class, and then sets the delegate of the PTWXRespManager singleton object as itself. In the parent class PTBaseThirdPlatformManager unified handling callback.
//
// 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 {
// Subclass implementation
// Register with wechat
[WXApi registerApp:kWXAppID];
}
/** third-party platforms handle urls */
- (BOOL)thirdPlatCanOpenUrlWithApplication:(UIApplication *)application
openURL:(NSURL *)url
sourceApplication:(NSString *)sourceApplication
annotation:(id)annotation {
/ / WeChat
if ([WXApi handleOpenURL:url delegate:[PTWXRespManager sharedInstance]]) {
return YES;
}
return NO;
}
/** Third party login @param thirdPlatformType third party platform @param fromViewController from which page to call the share @param callback login 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];
}
/** subclass overrides this method, The shareToPlateform method of the parent class calls the method of the subclass @param Platform @param image shared image @param imageUrlString Shared image address @param title Share title @param text Share text @param urlString Share URL @param fromViewController share from which page @param shareResultBlock Share result callback */
- (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); }}/** third party payment @Param payMethodType payment platform @Param Order Payment order model @Param paymentBlock payment result callback */
- (void)payWithPlateform:(PTPaymentMethodType)payMethodType order:(PTOrderModel*)order paymentBlock:(void(^) (BOOL result))paymentBlock {
self.paymentBlock = paymentBlock;
// Use Alipay to pay
[PTWXRespManager sharedInstance].delegate = self;
[PTWXRequestHandler payWithOrder:order];
}
@end
Copy the code
PTWXRequestHandler implements specific SDK calls and other operations
//
// 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 {
// Activate wechat Pay
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;
}
/ / share
+ (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) {
returnscaledImage; }}return oriImage;
}
@end
Copy the code
PTWXRespManager processing WeChat SDK callback and PTAbsThirdPlatformRespManagerDelegate proxy to unify the callback is passed to the 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:NOplatform:PTShareTypeWechat]; }}}else if ([resp isKindOfClass:[SendAuthResp class]]) {
if (resp.errCode == WXSuccess) {
// wx requests 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:nilplatform:PTThirdPlatformTypeWechat]; }}}else if([resp isKindOfClass:[PayResp class]]) {// Return result of payment. The actual payment result needs to be queried on wechat server
if (self.delegate
&& [self.delegate respondsToSelector:@selector(respManagerDidRecvPayResponse:platform:)]) {
[self.delegate respManagerDidRecvPayResponse:(resp.errCode == WXSuccess) platform:PaymentMethodTypeWechat]; }}}//wx obtains user information
- (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
Copy the code
Different platform management class, this part is the third send users unified handling client platform function calls, because different third party platform has the same interface, in order to coupled with specific third-party platform, using the class name string configure different platform, the client just use this class can interact with the specific third party platform.
//
// 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
/** Third-party platform configuration */
- (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]; }}}/** third-party platforms handle urls */
- (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;
}
/** Third party login @param thirdPlatformType third party platform @param fromViewController from which page to call the share @param callback login 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];
}
/** Third-party sharing @param Platform Third-party sharing platform @param image Shared image @param imageUrlString Shared image address @param title shared title @param text shared text @param urlString Share URL @param fromViewController share from which page @param shareResultBlock share result callback */
- (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];
}
/** third party payment @Param payMethodType payment platform @Param Order Payment order model @Param paymentBlock payment result callback */
- (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
Copy the code
One More Thing
Just learn the design mode, there are omissions in the place please do not hesitate to give advice