统一Ping++支付回调代码的着陆点

最近在给公司的产品做第三方支付用到了Ping++,阅读ping++的 SDK 文档后发现对于不同的支付方式、不同的软件环境,支付结果的回调点并不一样。

Ping++发起支付请求是用这个方法:

[Pingpp createPayment:charge
       viewController:viewController
         appURLScheme:kUrlScheme
       withCompletion:^(NSString *result, PingppError *error) {
    if ([result isEqualToString:@"success"]) {
        // 支付成功
    } else {
        // 支付失败或取消
        NSLog(@"Error: code=%lu msg=%@", error.code, [error getMsg]);
    }
}];

然而这个Completion块并不一定执行,文档中提到:

渠道为银联、百度钱包或者渠道为支付宝但未安装支付宝钱包时,交易结果会在调起插件时的 Completion 中返回。 渠道为微信、支付宝且安装了支付宝钱包或者测试模式时,请实现 UIApplicationDelegate 的 - application:openURL:sourceApplication:annotation: 方法

于是,我们需要把回调代码的着陆点统一一下,不然你相同的代码就要在两处复制粘贴了,俗话说,同样的代码写两遍就是罪过。

这里,我新建一个类用于处理回调。因为Ping++的回调块只有(NSString *result, PingppError *error)这两个参数,而考虑到处理支付结果回调时我们一般还要知道用户是在哪一个 ViewController 发起支付请求,因此给回调方法增加一个参数 vc:

@interface HandlePingPPBehaviour : NSObject

- (void)handleResult:(NSString *)str error:(PingppError *)error currentViewController:(UIViewController *)viewController;

@end

@implementation HandlePingPPBehaviour

- (void)handleResult:(NSString *)result error:(PingppError *)error currentViewController:(UIViewController *)targetViewController {
    // result : success, fail, cancel, invalid
    NSString *msg;
    if (error == nil) {
        NSLog(@"PingppError is nil");
        msg = result;
    } else {
        NSLog(@"PingppError: code=%lu msg=%@", (unsigned long)error.code, [error getMsg]);
        msg = [NSString stringWithFormat:@"result=%@ PingppError: code=%lu msg=%@", result, (unsigned long)error.code, [error getMsg]];
    }

    if ([result isEqualToString:@"success"]) {
        if([targetViewController isKindOfClass:[Foo class]]){
        // 这里根据不同的vc做不同的操作
}
    } else if ([result isEqualToString:@"cancel"]) {
// handle cancel
    } else if ([result isEqualToString:@"fail"]) {
// handle fail
    }
}

@end

然后在使用时, AppDelegate这样做

- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation
{
    [Pingpp handleOpenURL:url withCompletion:^(NSString *result, PingppError *error) {
        UIViewController *targetViewController = ...;//获取到targetViewController

        HandlePingPPBehaviour *handlePingPPBehaviour = [HandlePingPPBehaviour new];
        [handlePingPPBehaviour handleResult:result error:error currentViewController:targetViewController];
    }];

    return  YES;
}

发起支付的那个块回调

completion:^(NSString *result, PingppError *error) {  
                    HandlePingPPBehaviour *handlePingPPBehaviour = [HandlePingPPBehaviour new];
                    [handlePingPPBehaviour handleResult:result error:error currentViewController:self];
                }

其实我不喜欢讨论什么设计模式的,不过这种方法据我所知应该是叫做 Strategy Pattern

comments powered by Disqus