热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

iOSHybrid开发演进

Web技术相对于Native来说有很多优势,比如:跨端(浏览器、Android、iOS)、排版更灵活、实时生效等。所以,在开发中我们经常会采用一些Web页面嵌入到APP中。这样,就引入了web与Native的交互,往往也就是JavaScript与Native的交互。Native调用JS比较简单

Web技术相对于Native来说有很多优势,比如:跨端(浏览器、Android、iOS)、排版更灵活、实时生效等。所以,在开发中我们经常会采用一些Web页面嵌入到APP中。

这样,就引入了web与Native的交互,往往也就是Javascript与Native的交互。

JS与Native的交互,可以大致分为:Native调用JS、JS调用Native。

Native调用JS

Native调用JS比较简单

//UIWebView
- (nullable NSString *)stringByEvaluatingJavascriptFromString:(NSString *)script;

//WKWebView
- (void)evaluateJavascript:(NSString *)JavascriptString completionHandler:(void (^ _Nullable)(_Nullable id, NSError * _Nullable error))completionHandler;

注意:

  • UIWebView执行JS是同步的,在WKWebView中是异步的。
  • UIWebView返回值只支持可String化的基本类型,并不支持集合类型(Array、Dictionary)和对象。
  • WKWebView执行JS的回调Block中支持集合类型和对象,也支持可String化的基本类型。

h5代码



	
    
	
    




Native代码

//UIWebView
NSString *str = [self.webView stringByEvaluatingJavascriptFromString:@"methodA('zhangsan', '123456')"];
NSLog(@"str");

//WKWebView
[self.webView evaluateJavascript:@"methodA('zhangsan', '123456')" completionHandler:^(id _Nullable value, NSError * _Nullable error) {
    if (error) {
        NSLog(@"%@", error);
        return ;
    }
    NSLog(@"%@", value);
}];

JS调用Native

其实,JS调用Native的交互经历过几个阶段。

iOS7之前

iOS7之前,JS想要调用Native时主动触发加载一个新的url。我们通过拦截URL通过提前约定的协议来判断是否为调用原生功能,用这种方式来处理JS对Native的调用。

JS端主要通过 window.location.assign 来触发新的加载。

iOS中在 - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType 中针对URL做判断。

JS代码



	
	
	


	


OC代码

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType {
    NSString *urlPath = [request.URL absoluteString];
    /*
     * 与Web端协商定义交互协议 scheme://function_name?para1=value1¶2=value2¶3=value3&callback=callback_value
     *  scheme为native时,是要与原生进行交互。
     *  function_name指定要调用原生的什么功能。
     *  para1是参数名称,value1是参数值
     *  callback是原生执行完后对js的回调
     */
    if ([urlPath hasPrefix:@"native://"]) {
        urlPath = [urlPath substringFromIndex:@"native://".length];
        NSArray *questiOnMarkArray= [urlPath componentsSeparatedByString:@"?"];
        NSString *funcName;
        NSArray *paraArray;
        if (questionMarkArray.count > 0) {
            funcName = [questionMarkArray firstObject];
            if (questionMarkArray.count > 1) {
                // 从问号后还是都认定为参数
                NSString *paraStr =  [urlPath substringFromIndex:funcName.length + 1];
                paraArray = [paraStr componentsSeparatedByString:@"&"];
            }
        }
        
        // funcname 匹配
        if ([funcName isEqualToString:@"func1"]) {
            
        } else if ([funcName isEqualToString:@"func2"]) {
            
        } else if ([funcName isEqualToString:@"func3"]) {
            
        } else {
            
        }
        
        return NO;
    } else {
        return YES;
    }
}

iOS7

iOS7开始,系统公开了JavascriptCore框架,我们可以基于此来进行JS与Natvie的交互。

插播Javascript的调试方法(我们可以在Mac上调试JS代码)。

Safari的 偏好设置 中勾选底部的 在菜单栏中显示“开发”菜单 ,然后Safari的菜单栏中就多出了 开发 菜单,当webview加载完h5后就可以选择对应的模拟器下对应的应用进行web调试。详细步骤和真机的调试方法请自行Google。

iOS7中通常采用的方式是拿到JSContext,然后将OC的方法或对象注入到JS中。

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    self.jsCOntext= [self.webView valueForKeyPath:@"documentView.webView.mainFrame.JavascriptContext"];
    
    // JS的异常回调
    self.jsContext.exceptiOnHandler= ^(JSContext *context, JSValue *exception) {
        NSLog(@"%@", exception);
    };
    
    // 注入方法
    self.jsContext[@"addNum"] = ^(int a, int b) {
        return a + b;
    };
    
    // 注入对象
    NSDictionary *dict = @{@"aaa" : @"aaa", @"bbb" : @"bbb"};
    self.jsContext[@"dict"] = [JSValue valueWithObject:dict inContext:self.jsContext];
}

然后在JS中就可以调用相应的对象和方法,调用方式和调用原生的方法或对象一致。

function callByContext() {
    
    var num = addNum(5, 8);
    console.log(num);
    
    console.log(dict);
}

iOS8 WKWebView

UIWebView有很多的性能问题,所以苹果在iOS8中引入了新的浏览器组件WKWebView。

并且在iOS12后苹果废弃了UIWebView,所以请同学们务必赶紧升级到WKWebView!!!

在WKWebView的交互中,要使用WKUserContentController。在WKWebView构建的时候,需要传入WKWebViewConfiguration,而WKWebViewConfiguration可以添加WKUserContentController为ScriptMessageHandler。

WKUserContentController *userCOntent= [[WKUserContentController alloc] init];
[userContent addScriptMessageHandler:id name:@"MyNative"];
    
WKWebViewConfiguration *cOnfig= [[WKWebViewConfiguration alloc] init];
config.userCOntentController= userContent;
    
WKWebView *webView = [[WKWebView alloc] initWithFrame:CGRectZero configuration:config];

handler 对象需要实现指定协议,实现指定的协议方法,当 JS 端通过 window.webkit.messageHandlers 发送 Native 消息时,handler 对象的协议方法被调用,通过协议方法的相关参数传值。

#pragma mark - WKScriptMessageHandler
- (void)userContentController:(WKUserContentController *)userContentController didReceiveScriptMessage:(WKScriptMessage *)message {}

JS调用iOS的方法

// Javascript
function callNative() {
  window.webkit.messageHandlers.MyNative.postMessage('body');
}

相关的JS和iOS代码已上传至GitHub( github.com/NewFarmer21… ),可自行下载和调试。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 我们


推荐阅读
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 移动端常用单位——rem的使用方法和注意事项
    本文介绍了移动端常用的单位rem的使用方法和注意事项,包括px、%、em、vw、vh等其他常用单位的比较。同时还介绍了如何通过JS获取视口宽度并动态调整rem的值,以适应不同设备的屏幕大小。此外,还提到了rem目前在移动端的主流地位。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 如何在HTML中获取鼠标的当前位置
    本文介绍了在HTML中获取鼠标当前位置的三种方法,分别是相对于屏幕的位置、相对于窗口的位置以及考虑了页面滚动因素的位置。通过这些方法可以准确获取鼠标的坐标信息。 ... [详细]
  • webui之常用js操作(webui界面是什么)
    本文目录一览:1、web前端开发需要掌握的几个必备技术 ... [详细]
  • 篇首语:本文由编程笔记#小编为大家整理,主要介绍了预加载多个本地WebView相关的知识,希望对你有一定的参考价值。 ... [详细]
  • remote 移除_remote模块的使用(四)
    微信公众号:[猫十二的日常],欢迎留言和指出问题a在electron中的一些模块,它是区分进程的,有些模块只能是主进程可以使 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 本文介绍了使用AJAX的POST请求实现数据修改功能的方法。通过ajax-post技术,可以实现在输入某个id后,通过ajax技术调用post.jsp修改具有该id记录的姓名的值。文章还提到了AJAX的概念和作用,以及使用async参数和open()方法的注意事项。同时强调了不推荐使用async=false的情况,并解释了JavaScript等待服务器响应的机制。 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 来自微信官方:微信支付跨平台软件架构首次曝光
    大纲背景线上效果指标什么是软件架构为什么需要软件架构从零到一构建支付跨平台软件架构1.抽象业务流程2.加入路由机制3.管理网络请求4.规范数据传递总结背景作为一个重要业务ÿ ... [详细]
  • 安卓开发入门!BAT大厂面试基础题集合,顺利通过阿里Android岗面试
    其实不是Android不行了,而是你跟不上了我的很多读者都在反馈说,现在一个岗位可以收到的简历数,是前几年的几倍。我们必须承认ÿ ... [详细]
author-avatar
桃花救赎
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有