html ,js ,oc交互

1、html ,js ,oc交互

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

html代码:

<div class="editCaptcha">
     <img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>

js代码:

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

oc代码:

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

html代码:

<div class="editCaptcha">
     <img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>

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代码:

<div class="editCaptcha">
     <input type="number" id="captcha" placeholder="captcha" value="" style="display: inline-block;">
     <img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>

<div class="btn">
     <input type="button" id="confirmBtn" value="submit" onClick="onConfirmCaptcha()" >
    </div>

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代码:

<div class="editCaptcha">
     <input type="number" id="captcha" placeholder="captcha" value="" style="display: inline-block;">
     <img id="captchaImg" src="" onClick="refreshCaptcha()">
</div>

<div class="btn">
     <input type="button" id="confirmBtn" value="submit" onClick="onConfirmCaptcha()" >
    </div>

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 ()<IMYWebViewDelegate, UIGestureRecognizerDelegate, UIScrollViewDelegate>{
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 ()<IMYWebViewDelegate, UIGestureRecognizerDelegate, UIScrollViewDelegate>{
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;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,194评论 6 490
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,058评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,780评论 0 346
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,388评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,430评论 5 384
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,764评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,907评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,679评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,122评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,459评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,605评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,270评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,867评论 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,734评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,961评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,297评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,472评论 2 348

推荐阅读更多精彩内容