前两天通过H5集成了一款游戏,游戏中集成了微信支付。但是我们的产品对H5跳转微信充值有一定要求,我大致说明一下。
前言:直接使用[[UIApplication sharedApplication] openURL:request.URL];
这句代码只是跳转了safari浏览器,这样不满足我们产品的需求,另外在safari浏览器中还会有一个弹窗,”是否打开微信“。
如果使用SFSafariViewController
也会出现是否打开微信的弹窗。
在这里需要引进一个概念 URL重定向
1、一般情况下服务器端会给一个象征着H5页面调起充值页面的链接。这个链接就是我们所需要的链接,请注意一定要确保这个链接是可用的。
2、在项目的Info.plist中添加一个URL Schemes(用于跳回我们项目),如下图所示这个URL schemes 是跳转到微信支付无论成功失败,要返回本app的依据,当然这个依据要让微信知道,请往下看:
3、流程中最重要的一步 使用webview加载(load)这个url,注意仅仅是load这个url即可,不需要讲webview展示出来,也不需要设置位置什么的,但是要设置代理。
4、直接看代码:
#import "XLLianyunPayWK.h"
#import <WebKit/WebKit.h>
static const NSString *CompanyFirstDomainByWeChatRegister = @"xianlaigame.com";
#define XDX_URL_TIMEOUT 10
@interface XLLianyunPayWK()<WKUIDelegate,WKNavigationDelegate>
@property (nonatomic,strong) WKWebView * wkweb;
@end
@implementation XLLianyunPayWK
//创建webview
- (void)createWKWebView{
WKWebViewConfiguration * configura = [[WKWebViewConfiguration alloc] init];
WKUserContentController * userCont = [[WKUserContentController alloc] init];
configura.userContentController = userCont;
self.wkweb = [[WKWebView alloc] initWithFrame:CGRectZero configuration:configura];
[self.wkweb loadRequest: [NSURLRequest requestWithURL:[NSURL URLWithString:self.targetUrl]]];
self.wkweb.navigationDelegate = self;
self.wkweb.UIDelegate = self;
}
// 开始加载
- (void)webView:(WKWebView *)webView didStartProvisionalNavigation:(WKNavigation *)navigation{
[SVProgressHUD show];
}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation{
NSLog(@"加载完成");
[SVProgressHUD dismiss];
}
#pragma mark - WKNavigation Delegate
- (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
NSLog(@"---- 跳转 ----- ");
NSURLRequest *request = navigationAction.request;
NSString *scheme = [request.URL scheme];
// decode for all URL to avoid url contains some special character so that it wasn't load.
NSString *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
NSLog(@"Current URL is %@",absoluteString);
static NSString *endPayRedirectURL = nil;
// Wechat Pay, Note : modify redirect_url to resolve we couldn't return our app from wechat client.
if ([absoluteString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![absoluteString hasSuffix:[NSString stringWithFormat:@"redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]]) {
decisionHandler(WKNavigationActionPolicyCancel);
#warning Note : The string "xiaodongxie.cn://" must be configured by wechat background. It must be your company first domin. You also should configure "URL types" in the Info.plist file.
// 1. If the url contain "redirect_url" : We need to remember it to use our scheme replace it.
// 2. If the url not contain "redirect_url" , We should add it so that we will could jump to our app.
// Note : 2. if the redirect_url is not last string, you should use correct strategy, because the redirect_url's value may contain some "&" special character so that my cut method may be incorrect.
NSString *redirectUrl = nil;
if ([absoluteString containsString:@"redirect_url="]) {
NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
endPayRedirectURL = [absoluteString substringFromIndex:redirectRange.location+redirectRange.length+1];
redirectUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]];
}else {
redirectUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=XLHY.%@://",CompanyFirstDomainByWeChatRegister]];
}
NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT];
newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
newRequest.URL = [NSURL URLWithString:redirectUrl];
[webView loadRequest:newRequest];
return;
}
// Judge is whether to jump to other app.
if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
decisionHandler(WKNavigationActionPolicyCancel);
if ([scheme isEqualToString:@"weixin"]) {
// The var endPayRedirectURL was our saved origin url's redirect address. We need to load it when we return from wechat client.
if (endPayRedirectURL) {
[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:endPayRedirectURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT]];
}
}else if ([scheme isEqualToString:[NSString stringWithFormat:@"XLHY.%@",CompanyFirstDomainByWeChatRegister]]) {
}
BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:request.URL];
if (canOpen) {
[[UIApplication sharedApplication] openURL:request.URL];
self.openBlock();
}
return;
}
decisionHandler(WKNavigationActionPolicyAllow);
}
5、这个代码是可以直接使用的,但是要注意:static const NSString *CompanyFirstDomainByWeChatRegister = @"xianlaigame.com";
这个静态全局变量要与刚才url scheme 保持一致。注意URL SCHEME 中的那个XLHY可以不写。
6、webview的那个代理方法中所有redirect_url=XLHY
这个位置中的XLHY,可以*替换,但是请和URL scheme 中保持一致。
总结:这个方法中非常重要的一个概念是:url重定向,至于什么是重定向,我将在下篇博客说明;
我是磊怀 2849765859 是我的QQ 欢迎联系我