iOS UIWebview 接收 JS callback(JSON)配置(OC)

Web端主要靠Runtime来设置相应的触发。

iOS部分主要是需要在项目中放入如下几个文件 1 NSString+JSON NSString+JSON.h

#import <Foundation/Foundation.h>

@interface NSString (JSON)

- (id)JSONValue;

@end
复制代码

NSString+JSON.m

#import "NSString+JSON.h"

@implementation NSString (JSON)

- (id)JSONValue {
    id obj = [NSJSONSerialization JSONObjectWithData:[self dataUsingEncoding:NSUTF8StringEncoding]
                                             options:NSJSONReadingMutableContainers
                                               error:nil];
    return obj;
}

@end
复制代码

2 NSString+Addition

NSString+Addition.h

#import <Foundation/Foundation.h>

@interface NSString (Addition)

/**
 * 验证字符串长度
 * @param str   待验证字符串
 * @param min   字符串长度最小值
 * @param max   字符串长度最大值
 * @return BOOL 是否满足长度要求,满足返回true/YES,不满足返回false/No
 */
+ (BOOL)lengthValidate:(NSString *)str
                   min:(NSUInteger)min
                   max:(NSUInteger)max;
/**
 * 验证字符串是否符合正则表达式
 * @param str 待验证字符串
 * @param regex 正则表达式字符串
 */
+ (BOOL)regexValidate:(NSString *)str withRegex:(NSString *)regex;

/**
 * 验证字符串是否是正确的email格式
 * @param str   待验证字符串
 * @return BOOL 是否是正确的email格式,格式正确返回true/YES,格式错误返回false/No
 */
+ (BOOL)IsEmail:(NSString *)str;

+ (NSUInteger)NumOfMatches:(NSString *)str regexString:(NSString *)regexString;

/**
 * 验证字符串是否为空
 * @param str   待验证字符串
 * @return BOOL 字符串是否为空,为空或者str不是字符串类型返回true/YES,不为空返回false/No
 */
+ (BOOL)IsNilOrEmpty:(NSString *)str;

/**
 * 验证字符串是否为电话号码
 * @param str   待验证字符串
 * @return BOOL 是否是正确的电话号码,格式正确返回true/YES,格式错误返回false/No
 */
+ (BOOL)IsPhone:(NSString *)str;

/**
 * 对字符串进行url编码
 * @return NSString 编码后的字符串
 */
- (NSString*)stringByURLEncodingStringParameter;

/**
 * 解析NVP格式的字符串(Name Value Pair / 名值对)
 * @param separator     间隔符(=)
 * @param delimiter     定界符(&)
 * @return NSDictionary 解析后的字典(Key-Value)
 */
- (NSDictionary *)parametersWithSeparator:(NSString *)separator
                                delimiter:(NSString *)delimiter;

+ (NSString *)htmlEncode:(NSString *)str;
+ (NSString *)htmlDecode:(NSString *)str;
+ (NSString *)replaceHTMLTag:(NSString *)str;

- (NSString*)stringByRemovingHTMLTags;

- (NSString *)stringByReplacingSnakeCaseWithCamelCase;
- (NSString *)stringByReplacingCamelCaseWithSnakeCase;

@end
复制代码

NSString+Addition.m

#import "NSString+Addition.h"

@implementation NSString (Addition)

/**
* 验证字符串是否为空
* @param str   待验证字符串
* @return BOOL 字符串是否为空,为空或者str不是字符串类型返回true/YES,不为空返回false/No
*/
+ (BOOL)IsNilOrEmpty:(NSString *)str {
    if (![str isKindOfClass:[NSString class]]) {
        return YES;
    }

    if (str == nil) {
        return YES;
    }

    NSMutableString *string = [[NSMutableString alloc] init];
    [string setString:str];
    CFStringTrimWhitespace((__bridge CFMutableStringRef)string);
    if ([string length] == 0) {
        return YES;
    }
    return NO;
}

/**
* 验证字符串是否是正确的email格式
* @param str   待验证字符串
* @return BOOL 是否是正确的email格式,格式正确返回true/YES,格式错误返回false/No
*/
+ (BOOL)IsEmail:(NSString *)str {
    NSString *strRegex = @"^[a-zA-Z0-9_\\.]+@[a-zA-Z0-9-]+[\\.a-zA-Z]+$";
    return [NSString NumOfMatches:str regexString:strRegex];
}

+ (NSUInteger)NumOfMatches:(NSString *)str
               regexString:(NSString *)regexString {
    NSRegularExpression *regexExp = [NSRegularExpression regularExpressionWithPattern:regexString options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger numberOfMatches = [regexExp numberOfMatchesInString:str options:0 range:NSMakeRange(0, [str length])];
    //[@"" stringByReplacingOccurrencesOfString:@"" withString:@""];
    return numberOfMatches;

}

/**
* 验证字符串长度
* @param str   待验证字符串
* @param min   字符串长度最小值
* @param max   字符串长度最大值
* @return BOOL 是否满足长度要求,满足返回true/YES,不满足返回false/No
*/
+ (BOOL)lengthValidate:(NSString *)string
                   min:(NSUInteger)min
                   max:(NSUInteger)max {
    if (string) {
        string = [string stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
        if ([string length] >= min && [string length] <= max) {
            return YES;
        }
    }
    return NO;
}

/**
* 验证字符串是否符合正则表达式
* @param str 待验证字符串
* @param regex 正则表达式字符串
* @return BOOL
*/
+ (BOOL)regexValidate:(NSString *)str withRegex:(NSString *)regex {
    if ([NSString IsNilOrEmpty:regex]) {
        return YES;
    }

    NSRegularExpression *regexExppression = [NSRegularExpression regularExpressionWithPattern:regex options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger numberOfMatches = [regexExppression numberOfMatchesInString:str options:0 range:NSMakeRange(0, [str length])];
    return numberOfMatches;
}


/**
* 验证字符串是否为电话号码
* @param str   待验证字符串
* @return BOOL 是否是正确的电话号码,格式正确返回true/YES,格式错误返回false/No
*/
+ (BOOL)IsPhone:(NSString *)str {
    //电话号码正则表达式(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号)
    //NSString *strPhoneRegex = @"((\\d{11})|^((\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})|(\\d{4}|\\d{3})-(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1})|(\\d{7,8})-(\\d{4}|\\d{3}|\\d{2}|\\d{1}))$)";
    //电话号码正则表达式 ()
    NSString *strPhoneRegex = @"^[0-9+\\s\\-\\,\\(\\)]{0,45}$";
    NSRegularExpression *regexPhone = [NSRegularExpression regularExpressionWithPattern:strPhoneRegex options:NSRegularExpressionCaseInsensitive error:nil];
    NSUInteger numberOfMatches = [regexPhone numberOfMatchesInString:str options:0 range:NSMakeRange(0, [str length])];
    return numberOfMatches;
}

/**
* 对字符串进行url编码
* @return NSString 编码后的字符串
*/
- (NSString *)stringByURLEncodingStringParameter {
    // NSURL's stringByAddingPercentEscapesUsingEncoding: does not escape
    // some characters that should be escaped in URL parameters, like / and ?; 
    // we'll use CFURL to force the encoding of those
    //
    // We'll explicitly leave spaces unescaped now, and replace them with +'s
    //
    // Reference: [url]http://www.ietf.org/rfc/rfc3986.txt[/url]

    NSString *resultStr = self;

    CFStringRef originalString = (__bridge CFStringRef)self;
    CFStringRef leaveUnescaped = CFSTR(" ");
    CFStringRef forceEscaped = CFSTR("!*'();:@&=+$,/?%#[]");

    CFStringRef escapedStr;
    escapedStr = CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
            originalString,
            leaveUnescaped,
            forceEscaped,
            kCFStringEncodingUTF8);

    if (escapedStr) {
        NSMutableString *mutableStr = [NSMutableString stringWithString:(__bridge NSString *)escapedStr];
        CFRelease(escapedStr);

        // replace spaces with plusses
        [mutableStr replaceOccurrencesOfString:@" "
                                    withString:@"%20"
                                       options:0
                                         range:NSMakeRange(0, [mutableStr length])];
        resultStr = mutableStr;
    }
    return resultStr;
}

/**
* 解析NVP格式的字符串(Name Value Pair / 名值对)
* @param separator     间隔符(=)
* @param delimiter     定界符(&)
* @return NSDictionary 解析后的字典(Key-Value)
*/
- (NSDictionary *)parametersWithSeparator:(NSString *)separator
                                delimiter:(NSString *)delimiter {
    NSArray *parameterPairs = [self componentsSeparatedByString:delimiter];
    NSMutableDictionary *parameters = [NSMutableDictionary dictionaryWithCapacity:[parameterPairs count]];
    for (NSString *currentPair in parameterPairs) {
        NSRange range = [currentPair rangeOfString:separator];
        if (range.location == NSNotFound)
            continue;
        NSString *key = [currentPair substringToIndex:range.location];
        NSString *value = [currentPair substringFromIndex:range.location + 1];
        [parameters setObject:[value stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding] forKey:key];
    }
    return parameters;
}

+ (NSString *)htmlEncode:(NSString *)str {
    str = [str stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
    str = [str stringByReplacingOccurrencesOfString:@"'" withString:@"''"];
    str = [str stringByReplacingOccurrencesOfString:@"\"" withString:@"""];
    str = [str stringByReplacingOccurrencesOfString:@" " withString:@" "];
    str = [str stringByReplacingOccurrencesOfString:@"<" withString:@"<"];
    str = [str stringByReplacingOccurrencesOfString:@">" withString:@">"];
    str = [str stringByReplacingOccurrencesOfString:@"\n" withString:@"<br />"];
    return str;
}

+ (NSString *)htmlDecode:(NSString *)str {
    str = [str stringByReplacingOccurrencesOfString:@"<br />" withString:@"\n"];
    str = [str stringByReplacingOccurrencesOfString:@"<br>" withString:@"\n"];
    str = [str stringByReplacingOccurrencesOfString:@"<br/>" withString:@"\n"];
    str = [str stringByReplacingOccurrencesOfString:@"<BR />" withString:@"\n"];
    str = [str stringByReplacingOccurrencesOfString:@"<BR>" withString:@"\n"];
    str = [str stringByReplacingOccurrencesOfString:@"<BR/>" withString:@"\n"];

    str = [str stringByReplacingOccurrencesOfString:@"&" withString:@"&"];
    str = [str stringByReplacingOccurrencesOfString:@"''" withString:@"'"];
    str = [str stringByReplacingOccurrencesOfString:@""" withString:@"\""];
    str = [str stringByReplacingOccurrencesOfString:@" " withString:@" "];
    str = [str stringByReplacingOccurrencesOfString:@"<" withString:@"<"];
    str = [str stringByReplacingOccurrencesOfString:@">" withString:@">"];
    str = [str stringByReplacingOccurrencesOfString:@"“" withString:@"\""];
    str = [str stringByReplacingOccurrencesOfString:@"”" withString:@"\""];
    str = [str stringByReplacingOccurrencesOfString:@"‘" withString:@"'"];
    str = [str stringByReplacingOccurrencesOfString:@"" withString:@"'"];
    return str;
}

+ (NSString *)replaceHTMLTag:(NSString *)str {
    NSError *error = NULL;
    NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"<[^>]+>"
                                                                           options:0
                                                                             error:&error];
    return [regex stringByReplacingMatchesInString:str
                                           options:0
                                             range:NSMakeRange(0, str.length)
                                      withTemplate:@""];
}

- (NSString *)stringByRemovingHTMLTags {
//    MarkupStripper* stripper = [[[MarkupStripper alloc] init] autorelease];
//    return [stripper parse:self];
    return nil;
}

- (NSString *)stringByReplacingSnakeCaseWithCamelCase {
    NSArray *components = [self componentsSeparatedByString:@"_"];
    NSMutableString *camelCaseString = [NSMutableString string];
    [components enumerateObjectsUsingBlock:^(NSString *component, NSUInteger idx, BOOL *stop) {
        if (idx > 0) {
            [camelCaseString appendString:[component capitalizedString]];
        } else {
            [camelCaseString appendString:component];
        }
    }];
    return [camelCaseString copy];
}

- (NSString *)stringByReplacingCamelCaseWithSnakeCase {
    NSUInteger index = 1;
    NSMutableString *snakeCaseString = [NSMutableString stringWithString:self];
    NSUInteger length = snakeCaseString.length;
    NSCharacterSet *characterSet = [NSCharacterSet uppercaseLetterCharacterSet];
    while (index < length) {
        if ([characterSet characterIsMember:[snakeCaseString characterAtIndex:index]]) {
            [snakeCaseString insertString:@"_" atIndex:index];
            index++;
        }
        index++;
    }
    return [snakeCaseString copy];
}

@end
复制代码

3 UIWebView+JavaScriptAlert UIWebView+JavaScriptAlert.h

#import <UIKit/UIKit.h>
#import "WebViewController.h"

@interface UIWebView (JavaScriptAlert)

- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame;

- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame;

- (NSString *)webView:(UIWebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(id)frame;

- (void)setOwner:(WebViewController *)controller;

- (WebViewController *)owner;

@end
复制代码

UIWebView+JavaScriptAlert.m

#import "UIWebView+JavaScriptAlert.h"
#import "NSString+JSON.h"
#import <objc/runtime.h>

static const void *WebViewOwnerKey = &WebViewOwnerKey;

@implementation UIWebView (JavaScriptAlert)
static BOOL status = NO;
static BOOL isEnd = NO;

- (void)setOwner:(WebViewController *)controller {
    objc_setAssociatedObject(self, WebViewOwnerKey, controller, OBJC_ASSOCIATION_ASSIGN);
}

- (WebViewController *)owner {
    WebViewController *controller = objc_getAssociatedObject(self, WebViewOwnerKey);
    return controller;
}

- (void)webView:(UIWebView *)sender runJavaScriptAlertPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame {
    
    UIAlertView* customAlert = [[UIAlertView alloc] initWithTitle:nil
                                                          message:message
                                                         delegate:nil
                                                cancelButtonTitle:@"确定"
                                                otherButtonTitles:nil];
    [customAlert show];
}

- (NSString *) webView:(UIWebView *)view runJavaScriptTextInputPanelWithPrompt:(NSString *)prompt defaultText:(NSString *)text initiatedByFrame:(id)frame {
    if ([prompt isEqualToString:@"callback"]) {
        [self.owner webViewCallback:[text JSONValue]];
        return @"";
    }
    
    UIAlertView *promptDiag = [[UIAlertView init] initWithTitle:nil message:prompt delegate:nil cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
    promptDiag.alertViewStyle = UIAlertViewStylePlainTextInput;
    [promptDiag show];

    CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (version >= 7.) {
        while (isEnd == NO) {
            [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
        }
    } else {
        while (isEnd == NO && promptDiag.superview != nil) {
            [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1f]];
        }
    }
    isEnd = NO;
    return [promptDiag textFieldAtIndex:0].text;
}

- (BOOL)webView:(UIWebView *)sender runJavaScriptConfirmPanelWithMessage:(NSString *)message initiatedByFrame:(id)frame {
    UIAlertView *confirmDiag = [[UIAlertView alloc] initWithTitle:nil
                                                          message:message
                                                         delegate:self
                                                cancelButtonTitle:@"取消"
                                                otherButtonTitles:@"确定", nil];
    
    [confirmDiag show];
    
    CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue];
    if (version >= 7.) {
        while (isEnd == NO) {
            [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];
        }
    } else {
        while (isEnd == NO && confirmDiag.superview != nil) {
            [[NSRunLoop mainRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01f]];
        }
    }
    isEnd = NO;
    return status;
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    status = buttonIndex;
    isEnd = YES;
}

@end
复制代码

4 WebViewController WebViewController.h 中

//接收callback字段方法
- (void)webViewCallback:(NSDictionary *)params;
复制代码

WebViewController.m 中

//viewDidLoad方法中加入
self.webView.owner = self;

//添加Params接收转化方法
- (NSDictionary *)getRequestParams:(NSURLRequest *)request {
    return [request.URL.query parametersWithSeparator:@"=" delimiter:@"&"];
}

//实现webViewCallback方法
- (void)webViewCallback:(NSDictionary *)params {
    //略
}

//对webView开始加载时的请求做拦截处理(可根据实际需求修改或添加URL判断)
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    self.urlRequest = request;
    if (self.loading == nil) {
        self.loading = @"True";
    }
    if ([request.URL.description hasSuffix:@"#"]) {
        return NO;
    }
    if ([request.URL.scheme isEqualToString:@"tel"]) {
        return YES;
    }
//    NSLog(@"%@",request.URL.scheme);
    NSDictionary *params = [self getRequestParams:request];
    if ([request.URL.scheme isEqualToString:@"callback"]) {
        NSString *dictStr = params[@"data"];
        NSDictionary *dict = [dictStr JSONValue];
        [self webViewCallback:dict];
    }
    if ([request.URL.absoluteString rangeOfString:@"isAuthSuccessful=true"].location != NSNotFound) {
        NSLog(@"ebay auth success");
        [[NSNotificationCenter defaultCenter] postNotificationName:@"ebayAuthSuccess" object:nil];
        [self.navigationController popViewControllerAnimated:YES];
        WebViewController *rootViewController = [self.navigationController.viewControllers firstObject];
        [rootViewController.webView stringByEvaluatingJavaScriptFromString:@"bindSuccessCallback()"];
        return NO;
    }
    return YES;
}
复制代码

以上

转载于:https://juejin.im/post/5a30f6c55188257dd239a4ae

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值