html ,js ,oc交互

1、html ,js ,oc交互

1.1、点击html页面上的button,调用oc的方法

html代码:

js代码:

function refreshCaptcha(){
    window.location.href = "huihui://refreshCaptchas/";
}

oc代码:

- (void)refreshCaptchas
{
    [self getVerifyCode];
}
1.2、通过oc方法,传值给js,从而改变html页面

html代码:

js代码:

function setCaptchaImg(url){
 document.getElementById('captchaImg').src = url + '&_=' + new Date().getTime();
}

oc代码:

- (void)getVerifyCode
{
    NSMutableDictionary* params = [[NSMutableDictionary alloc]init];
    [params safeSetObject:_passport forKey:@"passportId"];
    [params safeSetObject:@"58" forKey:@"width"];
    [params safeSetObject:@"30" forKey:@"height"];

    NSString *url =[XGSDKAuthServer getRequestUrl:@"getCaptcha" withParams:params] ;
    [self evaluatingscript:[NSString stringWithFormat:@"setCaptchaImg('%@')", url]];
}
1.3、点击html页面上的button,调用oc的方法并传参给oc方法。

html代码:

js代码:

function onConfirmCaptcha(){
 var captcha = getValueById('captcha');
 window.location.href = "huihui://onConfirm/?captcha=" + captcha;
}

oc代码:

- (void)onConfirm:(NSArray *)param
{
    NSAssert(param.count == 1, @"传入的参数不符合预期");
//获取从html页面传过来的参数
   NSString *code = [param safeObjectAtIndex:0];
}
1.4、在oc的方法中获取html页面上的输入框中的值

html代码:

js代码:

function onConfirmCaptcha(){
 var captcha = getValueById('captcha');
 window.location.href = "kingsoft://onConfirm/?captcha=" + captcha;
}

oc代码:

-(void)ocCall{
  NSString *code=[self evaluatingscript:@"onConfirmCaptcha()"];
}

- (NSString *)onConfirm:(NSArray *)param
{
    NSAssert(param.count == 1, @"传入的参数不符合预期");
//获取从html页面传过来的参数
   NSString *code = [param safeObjectAtIndex:0];
   return code;
}

2、html ,js ,oc交互实现原理

js代码:

//获取html的触摸事件
function pageLoad(){
    document.ontouchend = function(){
        window.location.href = "huihui://documentclick/";
    };
}

oc代码:

- (void)documentclick{
    NSLog(@"documentclick");
}
@interface XGSDKBaseViewController (){
IMYWebView *_webview;
}

- (NSString *)evaluatingscript:(NSString *)script
{
    return [_webview stringByEvaluatingJavaScriptFromString:script];
}

#pragma mark - UIWebView delegate

//拦截js中window.location.href方法发送的字符串
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    //huihui://onCancel/
    NSString *requestString = [[[request URL] absoluteString] stringByReplacingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
    
    if ([requestString hasPrefix:@"ios-log:"]) {
        NSLog(@"requestString = %@",[request.URL resourceSpecifier]);
        return NO;
    }
    
    NSURL *url = [request URL];
    if ( [url.absoluteString rangeOfString:@"itms-app"].location != NSNotFound || [url.absoluteString rangeOfString:@"itunes.apple.com"].location != NSNotFound ){
        [[UIApplication sharedApplication] openURL:url];
        return NO;
    }
    
    if ([[request.URL scheme] isEqual:@"huihui"]) {
        NSMutableString *resourceSpecifier = [[NSMutableString alloc] initWithString:[[request.URL resourceSpecifier] substringFromIndex:2]];
        
        NSArray *arr = [resourceSpecifier componentsSeparatedByString:@"/"];
        NSAssert(arr.count > 0, @"URL参数不符合规范");
        if(arr.count > 0){
            NSString *paramstr = [request.URL query];
            NSArray *paramarr = [paramstr componentsSeparatedByString:@"&"];
            NSString *split = paramarr.count > 0 ? @":" : @"";
            NSString *method = [NSString stringWithFormat:@"%@%@", [arr firstObject], split];
            NSMutableArray *param = nil;
            for(NSInteger i = 0; i < paramarr.count; i++){
                NSString *str = [paramarr safeObjectAtIndex:i];
                if(![str isEmptyOrNull]){
                    if(!param){
                        param = [[NSMutableArray alloc] init];
                    }
                    NSString *value = [[[str componentsSeparatedByString:@"="] lastObject] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
                    if(!value){
                        value = @"";
                    }
                    [param safeAddObject:value];
                }
            }
            SEL selector = NSSelectorFromString(method);
            if([self respondsToSelector:selector]){
                [self performSelectorOnMainThread:selector withObject:param waitUntilDone:YES];
            }else{
                NSAssert(NO, @"传入了不存在的方法名");
            }
            return NO;
        }
    }
    
    return YES;
}

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    NSLog(@"load html webViewDidFinishLoad");
    //执行还原信息
    NSString *htmlInfo = [[XGSDKAuthViewManager sharedManager].htmlInputInfoDic valueForKey:NSStringFromClass([self class])];
    
    if(htmlInfo){
        NSString *toJsInfo = [NSString stringWithFormat:@"convertInputInfo('%@')",htmlInfo];
        [self evaluatingscript:toJsInfo];
    }
    
    [self onload];
    [self evaluatingscript:@"pageLoad()"];
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(nullable NSError *)error
{
    //一个页面没有被完全加载之前收到下一个请求,此时迅速会出现此error,error=-999
    //此时可能已经加载完成,则忽略此error,继续进行加载。
    
    if([error code] == NSURLErrorCancelled)
    {
        NSLog(@"上个页面还没加载完");
        return;
    }
    NSLog(@"load html didFailLoadWithError");

    [self setWebViewWithLocalHtml:@"error"];
}

3、若要刷新html页面,只需点击一下html页面即可,不需要重新运行。

分析:当工程部署到模拟器的时候,工程的资源文件会被打包到一个bundle中。若修改了项目目录下的html文件,让其在模拟器上显示,需要再次编译。但是可以从代码上修改项目寻找html文件的路径,让其在项目目录下寻找html而不是在bundle中寻找,就可以做到实时更新。

@interface XGSDKBaseViewController (){
IMYWebView *_webview;
}
@end

//设置本地html,localHtml(huihui)
- (void)setWebViewWithLocalHtml:(NSString *)localHtml
{
    //js跟css 在不同文件,要baseURL
    NSURL *baseURL = nil;
    NSString* templateStr = nil;
    templateStr = [self getTemplateStr:localHtml];
    //判断加载位置...
#if (TARGET_IPHONE_SIMULATOR && DEBUG)
    baseURL = [NSURL fileURLWithPath:[self getBaseURLInWorkSpace] isDirectory:YES];
    NSLog(@"baseURL=%@",baseURL);
#else
    baseURL = [NSURL fileURLWithPath:[self getBaseURLInBundle] isDirectory:YES];
#endif // #if TARGET_IPHONE_SIMULATOR
//调用
[_webview loadHTMLString:templateStr baseURL:baseURL];
}

//返回整个html页面的代码
- (NSString *)getTemplateStr:(NSString *)localHtml
{
    NSString *templateStr = nil;
#if (TARGET_IPHONE_SIMULATOR && DEBUG)
    templateStr = [self getTemplateInWorkSpaceWithHtml:localHtml];
#else
    templateStr = [self getTemplateInBundleWithHtml:localHtml];
#endif // #if TARGET_IPHONE_SIMULATOR
  return templateStr;
}

- (NSString *)getBaseURLInWorkSpace
{
    NSString *srcDir = [NSString stringWithFormat:@"%@/html/",[SamuraiWatcher sharedInstance].sourcePath];
    return srcDir;
}
- (NSString *)getBaseURLInBundle
{
    NSString *srcDir = [[XGSDKBaseViewController frameworkBundle] bundlePath];
    return srcDir;
}
#pragma mark - 正式环境下的路径
- (NSString *)getTemplateInBundleWithHtml:(NSString *)html
{
    //先看看有没有对应的patch文件,有的话就拿,没有就拿bundle
    NSString *patch = [self getDownloadPath:@"xx.html"];
    NSString *scrPath = nil;
    BOOL enablePatch =  [self checkFileIsExit:patch];
    if(enablePatch){
        scrPath = patch;
    }else{
        scrPath = [self localizedPathForResource:html ofType:@".html" bundle:[self frameworkBundle]];
    }
    return [NSString stringWithContentsOfFile:scrPath encoding:NSUTF8StringEncoding error:nil];
}
#pragma mark - 工程目录下用的路径
- (NSString *)getTemplateInWorkSpaceWithHtml:(NSString *)html
{
    //获取在工程目录下的
    NSString *patch = [self getDownloadPath:@"xx.html"];
    NSString *srcPath;
    BOOL enablePatch =  [self checkFileIsExit:patch];
    if(enablePatch){
        srcPath = patch;
    } else {
        srcPath = [NSString stringWithFormat:@"%@/%@.html",[self getBaseURLInWorkSpace],html];
        NSLog(@"srcPath=%@",srcPath);
    }
    return [NSString stringWithContentsOfFile:srcPath encoding:NSUTF8StringEncoding error:nil];
}

+(NSString *)getDownloadPath:(NSString *)fileName{
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *cachesDirectory = [paths objectAtIndex:0];
    NSString *dirPath = [NSString stringWithFormat:@"%@/%@",cachesDirectory, huihui];
    NSString *filePath = [NSString stringWithFormat:@"%@%@%@",dirPath,@"/",fileName];
    return filePath;
}

+(BOOL)checkFileIsExit:(NSString *)filePath{
    // 创建文件管理器
    NSFileManager *fileMgr = [NSFileManager defaultManager];
    BOOL isFileExist = [fileMgr fileExistsAtPath:filePath];
    if (isFileExist) {
        return YES;
    }
    return NO;
}

- (NSString *)getBaseURLInWorkSpace
{
    NSString *srcDir = [NSString stringWithFormat:@"%@/html/",[SamuraiWatcher sharedInstance].sourcePath];
        return srcDir;
}

#pragma mark - bundle
+ (NSBundle *)frameworkBundle {
    static NSBundle* frameworkBundle = nil;
    static dispatch_once_t predicate;
    NSString *bundle = @"huihui.bundle";
    dispatch_once(&predicate, ^{
        NSString* mainBundlePath = [[NSBundle mainBundle] resourcePath];
        NSString* frameworkBundlePath = [mainBundlePath stringByAppendingPathComponent:bundle];
        frameworkBundle = [NSBundle bundleWithPath:frameworkBundlePath];
    });
    return frameworkBundle;
}

- (NSString *)localizedPathForResource:(NSString *)name ofType:(NSString *)extension bundle:(NSBundle *)bundle {
    NSBundle *searchBundle = bundle ? bundle : [NSBundle mainBundle];
    NSString *path = [searchBundle pathForResource:name ofType:extension inDirectory:nil forLocalization:'en'];
    path = path ? path : [searchBundle pathForResource:name ofType:extension];
    return path;
}

你可能感兴趣的:(html ,js ,oc交互)