iOS第三方平台集成组件化

来源:互联网 发布:ubuntu修改镜像源 编辑:程序博客网 时间:2024/05/16 16:13

背景  

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

结果

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

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

1
2
3
4
5
6
7
8
9
10
11
   [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) {
             
        }];
    }];

问题分析

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

QQ截图20171109131750.png

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

结构设计

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

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

29171639_u3qj.png

结构说明:

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

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

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

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

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

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

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

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

29174014_vXLy.png29174014_vXLy.png

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

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

代码实现

抽象接口部分

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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
//
//  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"
 
@class PTOrderModel;
 
@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接口调用的请求和相应部分单独出来,虽然增加了类和代码量,但在代码的职责分离上更清晰。

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
30
31
32
33
//
//  PTAbsThirdPlatformRequestHandler.h
//  YTThirdPlatformManager
//
//  Created by aron on 2017/10/26.
//  Copyright © 2017年 aron. All rights reserved.
//
 
#import
#import
#import "PTThirdPlatformDefine.h"
 
@class PTOrderModel;
 
@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。

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
30
31
32
//
//  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回调。此外还有分享图片的统一处理,图片统一处理好了之后交给子类进行处理,这里使用到了是模板模式。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
//
//  PTBaseThirdPlatformManager.h
//  YTThirdPlatformManager
//
//  Created by aron on 2017/10/26.
//  Copyright © 2017年 aron. All rights reserved.
//
 
#import
#import "PTAbsThirdPlatformManager.h"
 
@interface PTBaseThirdPlatformManager : 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, @"哥么,这里你忘记实现了");
    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 {
    // 空实现,子类实现该方法
}
 
/**
 第三方支付
 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统一的处理回调。

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
//
//  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</ptabsthirdplatformrespmanagerdelegate></wxapi.h>

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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//
//  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;
    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];
    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</wxapi.h>

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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
//  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

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

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
//
//  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) {
                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)];
    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) {
        return nil;
    }
    Class clz = NSClassFromString(classString);
    SEL sharedInstanceSelector = @selector(sharedInstance);
    idmanager = 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

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


原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 饿了么入职查不到学历怎么办 高中没考上家人让打工怎么办 一建证书丢了怎么办 自考大专证书丢了怎么办 护士学分卡丢了怎么办 公司电脑只能用内网怎么办 遇见素质低的人怎么办 被素质低的人骂怎么办 对素质差的人怎么办 碰到素质低的人怎么办 和韩国人结婚后工作怎么办 大连明珠卡坏了怎么办 护肤品酒精含量太高怎么办 父母出国三年想孩子怎么办 孩子高考不理想想出国怎么办 交大附中创新班剩余孩子怎么办 棋牌开发公司倒闭了怎么办 7月1日本地流量怎么办 装电池的弹簧生锈了怎么办 电器被电池碱了怎么办 车辆被交警拖走怎么办 香烟熏的眼睛疼怎么办 想在中牟住5天怎么办 腰弯了直不了怎么办 自考科目停考了怎么办 把wlan密码忘了怎么办 滕州不给报新婚怎么办 体内锁水能力差怎么办 别人说你人品差怎么办 面对没素质的人怎么办 遇到很坏的室友怎么办 餐饮员工与顾客发生矛盾怎么办 新员工老员工出现矛盾怎么办 手机移动4g网慢怎么办 碰到素质低的老公怎么办 小孩做事拖拉 没时间观念怎么办 execl表中日期加3.5怎么办 狗狗喜欢咬人怎么办 烧烤一顿吃多了怎么办 派派背包食物不足怎么办 未转变者下不了怎么办