• iOS WKWebView H5微信、支付宝支付跳转


    iOS客户端实现嵌入H5进行支付跳转到客户端,支付完成后再跳转回自己的App时,解决WKWebView无法跳转回APP的BUG.

    一、支付宝

    1. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    2. NSURLRequest *request = navigationAction.request;
    3. NSString *scheme = [request.URL scheme];
    4. // decode for all URL to avoid url contains some special character so that it wasn't load.
    5. NSString *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    6. NSLog(@"Current URL is %@",absoluteString);
    7. static NSString *endPayRedirectURL = nil;
    8. // 跳转到本地某宝App
    9. if ([absoluteString hasPrefix:@"alipays://"] || [absoluteString hasPrefix:@"alipay://"])
    10. {
    11. NSURL *openedURL = navigationAction.request.URL;
    12. NSString *prefixString = @"alipay://alipayclient/?";
    13. NSString *urlString = [[self xh_URLDecodedString:absoluteString] stringByReplacingOccurrencesOfString:@"alipays" withString:@"自定义scheme"];
    14. ;
    15. if ([urlString hasPrefix:prefixString]) {
    16. NSRange rang = [urlString rangeOfString:prefixString];
    17. NSString *subString = [urlString substringFromIndex:rang.length];
    18. NSString *encodedString = [prefixString stringByAppendingString:[self xh_URLEncodedString:subString]];
    19. openedURL = [NSURL URLWithString:encodedString];
    20. }
    21. BOOL isSucc = [[UIApplication sharedApplication] openURL:openedURL];
    22. if (!isSucc) {
    23. NSLog(@"未安装某宝客户端");
    24. }
    25. decisionHandler(WKNavigationActionPolicyCancel);
    26. return;
    27. }
    28. decisionHandler(WKNavigationActionPolicyAllow);
    29. }
    30. - (NSString *)xh_URLDecodedString:(NSString *)urlString
    31. {
    32. NSString *string = urlString;
    33. NSString *decodedString=(__bridge_transfer NSString *)CFURLCreateStringByReplacingPercentEscapesUsingEncoding(NULL, (__bridge CFStringRef)string, CFSTR(""), CFStringConvertNSStringEncodingToEncoding(NSUTF8StringEncoding));
    34. return decodedString;
    35. }
    36. - (NSString *)xh_URLEncodedString:(NSString *)urlString
    37. {
    38. NSString *string = urlString;
    39. NSString *encodedString = (NSString *) CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
    40. (CFStringRef)string,
    41. NULL,
    42. (CFStringRef)@"!*'();:@&=+$,/?%#[]",
    43. kCFStringEncodingUTF8));
    44. return encodedString;
    45. }

    二、微信

    1.在项目的Info.plist中添加一个URL Schemes(用于跳回我们项目),如下图所示

    2.添加WKNavigationDelegate代理,并实现重定向代理方法,通过拦截微信链接以实现跳转

    1. - (void)webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigationAction *)navigationAction decisionHandler:(void (^)(WKNavigationActionPolicy))decisionHandler {
    2. NSURLRequest *request = navigationAction.request;
    3. NSString *scheme = [request.URL scheme];
    4. // decode for all URL to avoid url contains some special character so that it wasn't load.
    5. NSString *absoluteString = [navigationAction.request.URL.absoluteString stringByRemovingPercentEncoding];
    6. NSLog(@"Current URL is %@",absoluteString);
    7. static NSString *endPayRedirectURL = nil;
    8. // Wechat Pay, Note : modify redirect_url to resolve we couldn't return our app from wechat client.
    9. if ([absoluteString hasPrefix:@"https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb"] && ![absoluteString hasSuffix:[NSString stringWithFormat:@"redirect_url=%@%@://",kSchemePrefix,CompanyFirstDomainByWeChatRegister]]) {
    10. decisionHandler(WKNavigationActionPolicyCancel);
    11. #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.
    12. // 1. If the url contain "redirect_url" : We need to remember it to use our scheme replace it.
    13. // 2. If the url not contain "redirect_url" , We should add it so that we will could jump to our app.
    14. // 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.
    15. NSString *redirectUrl = nil;
    16. if ([absoluteString containsString:@"redirect_url="]) {
    17. NSRange redirectRange = [absoluteString rangeOfString:@"redirect_url"];
    18. endPayRedirectURL = [absoluteString substringFromIndex:redirectRange.location+redirectRange.length+1];
    19. redirectUrl = [[absoluteString substringToIndex:redirectRange.location] stringByAppendingString:[NSString stringWithFormat:@"redirect_url=%@%@://",kSchemePrefix,CompanyFirstDomainByWeChatRegister]];
    20. }else {
    21. redirectUrl = [absoluteString stringByAppendingString:[NSString stringWithFormat:@"&redirect_url=%@%@://",kSchemePrefix,CompanyFirstDomainByWeChatRegister]];
    22. }
    23. NSMutableURLRequest *newRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:redirectUrl] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT];
    24. newRequest.allHTTPHeaderFields = request.allHTTPHeaderFields;
    25. newRequest.URL = [NSURL URLWithString:redirectUrl];
    26. [webView loadRequest:newRequest];
    27. return;
    28. }
    29. // Judge is whether to jump to other app.
    30. if (![scheme isEqualToString:@"https"] && ![scheme isEqualToString:@"http"]) {
    31. decisionHandler(WKNavigationActionPolicyCancel);
    32. if ([scheme isEqualToString:@"weixin"]) {
    33. // The var endPayRedirectURL was our saved origin url's redirect address. We need to load it when we return from wechat client.
    34. if (endPayRedirectURL) {
    35. [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:endPayRedirectURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:XDX_URL_TIMEOUT]];
    36. }
    37. }else if ([scheme isEqualToString:[NSString stringWithFormat:@"%@%@",kSchemePrefix,CompanyFirstDomainByWeChatRegister]]) {
    38. }
    39. // BOOL canOpen = [[UIApplication sharedApplication] canOpenURL:request.URL];
    40. // if (canOpen) {
    41. // [[UIApplication sharedApplication] openURL:request.URL];
    42. // }
    43. if ([navigationAction.request.URL.absoluteString hasPrefix:@"weixin://"]) {
    44. [[UIApplication sharedApplication] openURL:navigationAction.request.URL];
    45. }
    46. return;
    47. }
    48. decisionHandler(WKNavigationActionPolicyAllow);
    49. }

    注:kSchemePrefix 自定义前缀,可任意填写
    CompanyFirstDomainByWeChatRegister 微信一级域名
    XDX_URL_TIMEOUT 超时时间

  • 相关阅读:
    qt开发遇到的问题记录
    HBase之Compaction
    CentOS 7 上编译和安装 SQLite 3.9.0
    第二篇 如何选择操作系统
    AI 大框架基于python来实现基带处理之TensorFlow(信道估计和预测模型,信号解调和解码模型)
    【单片机】15-AD和DA转换
    flutter web 中嵌入一个html
    判断两个对象是否不相等operator.ne()
    CleanMyMac X靠谱苹果电脑杀毒软件
    【JS】BMI身体质量指数计算工具
  • 原文地址:https://blog.csdn.net/chuming0311/article/details/134425360