html ,js ,oc交互

作者: 慧惠 | 来源:发表于2016-03-02 11:21 被阅读593次

    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;
    }
    

    相关文章

      网友评论

        本文标题:html ,js ,oc交互

        本文链接:https://www.haomeiwen.com/subject/pgxnkttx.html