混合开发_混合开发框架 - CSDN
精华内容
参与话题
  • 混合开发

    2020-05-15 15:32:47
    混合开发三类App: 一. NativeApp(原生APP) ​ 纯工具类APP ​ 特点? ​ 开发:由Native人员进行开发的 安卓(Android) 苹果(IOS) ​ 语言:Android(Java+XML) IOS(Objective-c / Swift + XML) ​ 更新...

    混合开发三类App:

    • 1、Native App (原生App)
    • 2、Web App
    • 3、Hybrid App

    一. NativeApp(原生APP)

    纯工具类APP  
    
    ​		特点?
    		开发:Android、IOS工程师开发,
    	        Android:java,xml  配置 java jdk  , Android sdk   eclipse编辑器
    	        IOS:xml,Objective-C/swift,  mac,Imac机上    XCODE
    
    ​			更新维护:版本更新、打补丁包   都得需要用户从app store里面进行下载
    
    ​			使用:必须去app-store里面进行下载更新才能使用软件
    	特点和优势:
    			1、流畅度较高
    			2、对网络的依赖性不强,在没有网络的情况下也可能使用部分功能
    			3、可以调用设备的原生功能
    ​	缺点:
    			不能跨平台开发   必须开发两套代码(Android+IOS)
    
    
    			开发成本
    			        开发成本较高,因为需要分开开发,不能跨平台开发,而且开发周期长,
    			        使用成本较高,因为需要下载安装,话费流量,并长期占用手机的内存
    			        更新维护成本高
    			
    		
    

    二. WebApp(移动M站)

    特点:(凡是可以在移动端浏览器里面打开的网站都称之为WebApp)
    使用:无需下载  直接通过用户的手机浏览器打开使用即可
    更新维护:直接无痕更新(需要注意浏览器缓存问题   缓存的产生是基于文件的路径)
    开发: web前端开发工程师
          使用HTML5+CSS3+js,mac、pc上开发
          更新维护成本低
    
    开发成本:
            开发成本较低,可以实现跨域平台,开发周期短(比较于原生)
            使用成本低,不需要下载安装,通过浏览器空间
    
    特点和优势
            1、用户粘度低
            2、流畅度较低
            3、对网络的依赖性强
            4、不能访问设备的原生功能!因为浏览器的安装级别限制
            (同源策略、不能调用设备的原生功能及文件系统)
    缺点:不稳定 流畅度低  用户体验差   不能调用原生设备 
    

    三. Hybrid App(混合App)

    混合开发的app其实从根本上的技术就是在原生的壳子、界面里嵌入H5页面来实现功能
    
    先决技术:H5页面是可以嵌入到原生的webview中的
    开发模式:
    
    1、原生主导
    
        这是最主流的一种方式,也就是说其实现在市场上的应用已经很少有春原生的了而是大多采用了混合开发的模式,一般都是原生主导的,也就是在某个界面中去嵌入h5页面
    
        区分方式:
                    1.长按文字看是否被选中,如果能选中肯定是嵌入的H5页面
                    
                    2.安卓打开开发模式,手机上就会出现很多的线条,线条包裹起来的就是原生的元素
    
                 为什么要这么做:
                    借助H5页面的跨平台属性来降低开发成本。而且,因为内嵌应用电影、外卖,他们的webapp已经存在了,所以可以直接将webapp的页面嵌入进来
    
                什么样的页面适合去嵌入H5页面
                    布局复杂,逻辑简单,经常更新卫华的,比如详情、部分列表等等都适合嵌入H5页面的方式
    
            1.js判断操作系统
                 html中的window.navigator.userAng   
                    
                    
            2.js与native通信
                   native与js交互
                        1.ios可以调用window下面的方法
                                
                                当跳转详情的时候,详情界面就可以调用里面H5页面的JSBridge的方法来传递参数
                        2.页面中发送所有的网络请求,webview
    
                                一把都是用用iframe标签来发送请求,也就是,事先定义号一个url,作为通信的地址,然后创建iframe去发送这个请求 
                        
    
    2、H5主导的模式
    
    
            纯H5开发工程师借助一些工具去搭建native的外壳,这个应用的内部都是H5页面构成
    
        这种开发模式主要以来的是工具,(打包应用、调用设备原生功能的能力)
                        现有的技术栈
                            1、phoneggap(打包调试) + cordova(调用设备原生功能)
                
                            2、DCLOUD/APICLOUD
                                    
                            3、ReactNative/weex(使用类似H5技术开发,但是开发出来的native app)
    
                        
    
                使用DCLOUD产品开发混合APP
                        
                        HBUILDER可以进行应用的开发、调试、打包
                        MUI是一个高效的前端框架,里面继承了很多native的效果
    
    
                  H5+RUNTIE  用到调用设备原生功能的工具
    
                  1、Hbuilder可以创建移动APP(hybrid app)
    
                    2、在真机上进行应用的调试,必须保证手机能够连接上电脑
        
                    Andriod:
                    IOS:itunes   itools
                    
                    依靠基座来运行,第一次会给手机安装一个基座
    
    

    
    是一个app壳内嵌一个html兼容各种设备,减少发版频率,节约开发成本
    通过jsBright操作底层操作权限
    Hybrid一般分为两类,
        1)放在远程,应用变得非常小,服务器更新及时更新,使用必须联网
        2)打包放在自己app内,使用不需要了联网,下载包变大,不能立即更新
    

    混合应用开发:

    • 1.微信公众号:通过jssdk连接native和web

    • 2.微信小程序:内置框架连接native和web

    • 3.普通原生和web交互:jsBridge

    意义:更好地使用第三方平台,更灵活的技术方案选型,具备搭建平台和输出服务的能力

    • jsbridge是实现native端和web端的双向通信的一种机制,通过约定进行通信
      混合开发主流框架
    1.web渲染:cordova(前身phoneGap)
    2.原生渲染:react native .weex
    3.混合开发:微信小程序
    
    • jsbrige实现原理
      将native端的原生接口封装成javascript接口,将web端的javascript接口封装成原生的接口,实现双向通信
      web调用native的方式有两种:
      1.拦截webview请求中的URL schema
      2.向webview注入jsAPI

    • 方式一:兼容性好,但是不直观,url长度有限制

    //实现:native调用web的时候,web端的方法定义:
    window.方法名=参数=>{方法体}
    //web端调用native的时候,web端的代码:
    window.alert('jsbridge://原生方法?参数="xxx')
    document.location="jsbridge://原生方法?参数=xxx"
    
    • 方式二:简单直观,但是在低版本的手机可能会有兼容性的问题
      web端通过调用注入到js中的原生方法调用native
      native通过注入js调用web
    window.注入到webview的方法.原生方法(参数);
    
    • 支持回调的jsbridge
      webview调用原生的时候会有一个callbackid,返回的时候原生会把callbackid返回找到对应的回调.反之原生调用webview也是类似的
      比如:web调用native时候,web端代码实现如下
    window.JSSDK={
    	getNativeValue(callback){
    		const callID=id++;
    		callbackmap[callID]=callback;
    		nativeBridge.原生方法(callID);
    	}
    	receiveMassage(callID,value){//原生返回值的时候出发的方法
    		if(callbackmap[callID]){
    			callbackmap[callID](value)
    		}
    	}
    }
    调用:
    	widow.getNativeValue(value=>{
    		方法体处理返回值数据
    	})
    
    • native调用web的时候,web端的代码实现:
    widow.JSSDK={
    	getwebText(callbackid){
    		nativeBridge.原生方法(callbackid,'web端的值')
    	}
    }
    
    • jsbridge的开源实现
    DSBridge,可以查看官方文档.原理一样
    
    展开全文
  • 混合 APP 开发(Hybrid App)

    千次阅读 2019-04-20 21:18:37
    混合 App Html5简介 UIWebView 和 WKWebView UIWebView 和 JS 交互 WKWebView 和 JS 交互 JS 调用 Native 相机 一. 混合 APP Hybrid Mobile App 可以理解为通过 Web 网络技术(如 HTML,CSS 和 JavaScript)...

    目录

    • 混合 App
    • Html5简介
    • UIWebView 和 WKWebView
    • UIWebView 和 JS 交互
    • WKWebView 和 JS 交互
    • JS 调用 Native 相机

     

    一. 混合 APP

    Hybrid Mobile App 可以理解为通过 Web 网络技术(如 HTML,CSS 和 JavaScript)与 Native 相结合的混合移动应用程序。

    H5用于大体界面的编写,如:需要一些基本的输入框、单选按钮、普通按钮、以及下拉选择框等。

    CSS3则是主要用于对整体界面细节化的修饰。比如:一个普通按钮,输入框边角默认是直角,那我们可以用CSS来改变其形状。

    还可以用来设置不同的样式。

    JS主要是要跟服务端打交道,实现数据交互。JS中的数据交互,主要以JSON格式跟XML格式这两种格式实现。

    总体来说,H5+CSS3负责界面的搭建,JS负责数据的交互。

     

     

    二. HTML5简介

     

    下面简述一下 Hybrid 的发展史:

     

    1.H5 发布

     

    Html5 是在 2014 年 9 月份正式发布的,这一次的发布做了一个最大的改变就是“从以前的 XML 子集升级成为一个独立集合”。

     

     

     

    2.H5 渗入 Mobile App 开发

     

    Native APP 开发中有一个 webview 的组件(Android 中是 webview,iOS 有 UIWebview和 WKWebview),这个组件可以加载 Html 文件。

    在 H5 大行其道之前,webview 加载的 web 页面很单调(因为只能加载一些静态资源),自从 H5 火了之后,前端猿们开发的 H5 页面在 webview 中的表现不俗使得 H5 开发慢慢渗透到了 Mobile App 开发中来。

     

     

    3.Hybrid 现状

     

    虽然目前已经出现了 RN 和 Weex 这些使用 JS 写 Native App 的技术,但是 Hybrid 仍然没有被淘汰,市面上大多数应用都不同程度的引入了 Web 页面。

     

    三. UIWebView 和 WKWebView

    做浏览器首先要选个好的基础。iOS8提供两类浏览组件:UIWebViewWKWebView

    UIWebView是iOS传统的浏览控件,绝大多数浏览器都采用这个控件作为基础, 如Chrome,Firefox,Safari。UIWebView比较封闭,很多API都不开放,但却一度是唯一的选择。好处是,这个控件使用时间比较长,有很多方案可以参考。

    WKWebView是苹果在iOS8和 OS X Yosemite 中新推出的WebKit中的一个组件。

    它代替了 UIKit 中的UIWebView和AppKit中的WebView,提供了统一的跨双平台 API。支持HTML5的特性, 占用内存可能只有UIWebView的1/3 ~ 1/4, 拥有 60fps 滚动刷新率、内置手势、高效的app和web信息交换通道、和Safari相同的JavaScript引擎, 增加了加载进度属性, 比UIWebView性能更加强大。

    但WKWebView也不是那么完美:如没有控制Cookie的API,  对读取本地html文件的支持也不好等。

     

    四. UIWebView 和 JS 交互

     

    JavaScriptCore介绍

     

    JavaScriptCore 这个库是 Apple 在 iOS 7 之后加入到标准库的,它对 iOS Native 与 JS 做交互调用产生了划时代的影响。

    JavaScriptCore 大体是由 4 个类以及 1 个协议组成的:

     

     

    • JSContext JS 执行上下文,你可以把它理解成 JavaScriptCore 包装出来的 JS 运行的环境。
    • JSValue 是对 JavaScript 值的引用,任何 JS 中的值都可以被包装为一个 JSValue
    • JSManagedValue 是对 JSValue 的包装,加入了“conditional retain”
    • JSVirtualMachine 可以理解为JS 虚拟机JSVirtualMachine中可以创建多个 JSContext 实例他们都是可以独立运行的 JavaScript 执行环境。
    • JSExport 协议:我们可以使用这个协议暴露原生对象,实例方法,类方法,和属性给JavaScript,这样JavaScript就可以调用相关暴露的方法和属性。

     

    Native 调用 JS:

     

    • WebView 直接注入 JS 并执行
    • JavaScriptCore 方法
    WebView 直接注入 JS 并执行
    
    self.webView.stringByEvaluatingJavaScript(from: “jsFuncName()”)
    
    注意:
    这个方法会返回运行 JS 的结果(nullable NSString *),它是一个同步方法,会阻塞当前线程!尽管此方法不被弃用,但最佳做法是使用 WKWebView 类的 evaluateJavaScript:completionHandler:method。注意:
    这个方法会返回运行 JS 的结果(nullable NSString *),它是一个同步方法,会阻塞当前线程!尽管此方法不被弃用,但最佳做法是使用 WKWebView 类的 evaluateJavaScript:completionHandler:method。

     

    JavaScriptCore 方法
    // 导入 JavaScriptCore 库
    
    JavaScriptCore 库提供的 JSValue 类,是对 JavaScript 值的引用。 您可以使用 JSValue 类来转换 JavaScript 和 Objective-C 或 Swift 之间的基本值(如数字和字符串),以便在本机代码和 JavaScript 代码之间传递数据。
    
    Native 代码: 
    self.context = webView.value(forKeyPath: “documentView.webView.mainFrame.javaScriptContext")
    
    let jsValue: JSValue = self.context.objectForKeyedSubscript(“jsFuncName()”)
            jsValue.call(withArguments: ["param1" ,"param2"])
    
    JS 代码: 
    function jsFuncName(param1, param2){
    
    }
    

     

     

     

    JS 调用 Native :

     

    • 拦截 URL 请求
    • Block 方法
    • 模型注入(JavaScriptCore 的 JSExport 协议)
    拦截 URL 请求
    
    用JS 发起一个假的 URL 请求, 然后在 shouldStartLoadWith 代理方法中拦截这次请求, 做出相应处理.
    注意: 
    这里在JS 中自定义一个loadURL 方法发起请求,而不是直接使用 window.location.href
    如果要传递参数, 可以拼接在 URL 上
    
    Native 代码:
    func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
            if request.url?.scheme == "haleyAction" {
                // to do something
                return false
            }
           return true
     }
            
    JS 代码:
    function loadURL(url) {
        var iFrame;
        iFrame = document.createElement("iframe");
                iFrame.setAttribute("src", url);
                iFrame.setAttribute("style", "display:none;");
                iFrame.setAttribute("height", "0px");
                iFrame.setAttribute("width", "0px");
                iFrame.setAttribute("frameborder", "0");
                document.body.appendChild(iFrame);
                // 发起请求后这个 iFrame 就没用了,所以把它从 dom 上移除掉
                iFrame.parentNode.removeChild(iFrame);
                iFrame = null;
            }
        
            function firstClick() {
                //要传递参数时, 可以拼接在url上
                loadURL("haleyAction://shareClick?title=测试分享的标题&content=测试分享的内容&url=http://www.baidu.com");
            }

     

    Block 方法
    
    使用 block 在js中运行原生代码, 将自动与JavaScript方法建立桥梁
    注意: 这种方法仅仅适用于 OC 的 block, 并不适用于swift中的闭包, 为了公开闭包,      
    我们将进行如下两步操作:
    (1)使用 @convention(block) 属性标记闭包,来建立桥梁成为 OC 中的 block
    (2)在映射 block 到 JavaScript方法调用之前,我们需要 unsafeBitCast 函数将block 转成为 AnyObject
    
    Native 代码:
    // JS调用了无参数swift方法
    let closure1: @convention(block) () ->() = {
                
    }
    self.context.setObject(unsafeBitCast(closure1, to: AnyObject.self),   
    forKeyedSubscript: "test1" as NSCopying & NSObjectProtocol)
    
    // JS调用了有参数swift方法
    let closure2: @convention(block) () ->() = {
                
    }
    self.context.setObject(unsafeBitCast(closure2, to: AnyObject.self), 
    forKeyedSubscript: "test2" as NSCopying & NSObjectProtocol)
    
    JS 代码:
    function JS_Swift1(){
        test1();
    }
    function JS_Swift2(){
        test2('oc','swift');
    }注意: 这种方法仅仅适用于 OC 的 block, 并不适用于swift中的闭包, 为了公开闭包,      
    我们将进行如下两步操作:
    (1)使用 @convention(block) 属性标记闭包,来建立桥梁成为 OC 中的 block
    (2)在映射 block 到 JavaScript方法调用之前,我们需要 unsafeBitCast 函数将block 转成为 AnyObject
    
    Native 代码:
    // JS调用了无参数swift方法
    let closure1: @convention(block) () ->() = {
                
    }
    self.context.setObject(unsafeBitCast(closure1, to: AnyObject.self),   
    forKeyedSubscript: "test1" as NSCopying & NSObjectProtocol)
    
    // JS调用了有参数swift方法
    let closure2: @convention(block) () ->() = {
                
    }
    self.context.setObject(unsafeBitCast(closure2, to: AnyObject.self), 
    forKeyedSubscript: "test2" as NSCopying & NSObjectProtocol)
    
    JS 代码:
    function JS_Swift1(){
        test1();
    }
    function JS_Swift2(){
        test2('oc','swift');
    }

     

     

    模型注入(JavaScriptCore  JSExport 协议)
    
    步骤一: 自定义协议服从 JSExport协议
    可以使用该协议暴露原生对象,实例方法,类方法,和属性给JavaScript,这样JavaScript就可以调用相关暴露的方法和属性。遵守JSExport协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来
    
    注意:
    如果js是多个参数的话  我们代理方法的所有变量前的名字连起来要和js的方法名字一样比如: js方法为  OCModel.showAlertMsg('js title', 'js message’),他有两个参数 那么我们的代理方法 就是把js的方法名 showAlertMsg 任意拆分成两段作为代理方法名
    
    第一个参数的 argumentLabel 用 "_" 隐藏
    @objc protocol JavaScriptSwiftDelegate: JSExport {
    
        func callNoParam()
        
        func showAlert(_ title: String, msg: String)
    }
    
    步骤二: 自定义模型服从自定义协议, 实现协议方法
    
    @objc class JSObjCModel: NSObject, JavaScriptSwiftDelegate {
        weak var controller: UIViewController?
        weak var jsContext: JSContext?
        
        func callNoParam() {
            let jsFunc = self.jsContext?.objectForKeyedSubscript("jsFunc");
            _ = jsFunc?.call(withArguments: []);
        }
        
        func showAlert(_ title: String, msg: String) {
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil))
            self.controller?.present(alert, animated: true, completion: nil)
        }
    }
    
    步骤三: 将模型对象注入 JS
    
    // 模型注入
    let model = JSObjCModel()
    model.controller = self
    model.jsContext = context
    // 这一步是将OCModel这个模型注入到JS中,在JS就可以通过OCModel调用我们暴露的方法了
    context.setObject(model, forKeyedSubscript: "OCModel" as NSCopying & NSObjectProtocol)
    let url = Bundle.main.url(forResource: "WebView", withExtension: "html")
    context.evaluateScript(try? String.init(contentsOf: url!, encoding: .utf8))
    context.exceptionHandler = { [unowned self](con, except) in
                self.context.exception = except
    }
    
    JS 代码:
    <div class='btn-button' onclick="OCModel.callNoParam()">JS调用Native方式三无参</div>
    <div class='btn-button' onclick="OCModel.showAlertMsg('js title', 'js message’)">JS调用Native方式三有参</div>(JavaScriptCore  JSExport 协议)
    
    步骤一: 自定义协议服从 JSExport协议
    可以使用该协议暴露原生对象,实例方法,类方法,和属性给JavaScript,这样JavaScript就可以调用相关暴露的方法和属性。遵守JSExport协议,就可以定义我们自己的协议,在协议中声明的API都会在JS中暴露出来
    
    注意:
    如果js是多个参数的话  我们代理方法的所有变量前的名字连起来要和js的方法名字一样比如: js方法为  OCModel.showAlertMsg('js title', 'js message’),他有两个参数 那么我们的代理方法 就是把js的方法名 showAlertMsg 任意拆分成两段作为代理方法名
    
    第一个参数的 argumentLabel 用 "_" 隐藏
    @objc protocol JavaScriptSwiftDelegate: JSExport {
    
        func callNoParam()
        
        func showAlert(_ title: String, msg: String)
    }
    
    步骤二: 自定义模型服从自定义协议, 实现协议方法
    
    @objc class JSObjCModel: NSObject, JavaScriptSwiftDelegate {
        weak var controller: UIViewController?
        weak var jsContext: JSContext?
        
        func callNoParam() {
            let jsFunc = self.jsContext?.objectForKeyedSubscript("jsFunc");
            _ = jsFunc?.call(withArguments: []);
        }
        
        func showAlert(_ title: String, msg: String) {
            let alert = UIAlertController(title: title, message: msg, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "确定", style: .default, handler: nil))
            self.controller?.present(alert, animated: true, completion: nil)
        }
    }
    
    步骤三: 将模型对象注入 JS
    
    // 模型注入
    let model = JSObjCModel()
    model.controller = self
    model.jsContext = context
    // 这一步是将OCModel这个模型注入到JS中,在JS就可以通过OCModel调用我们暴露的方法了
    context.setObject(model, forKeyedSubscript: "OCModel" as NSCopying & NSObjectProtocol)
    let url = Bundle.main.url(forResource: "WebView", withExtension: "html")
    context.evaluateScript(try? String.init(contentsOf: url!, encoding: .utf8))
    context.exceptionHandler = { [unowned self](con, except) in
                self.context.exception = except
    }
    
    JS 代码:
    <div class='btn-button' οnclick="OCModel.callNoParam()">JS调用Native方式三无参</div>
    <div class='btn-button' οnclick="OCModel.showAlertMsg('js title', 'js message’)">JS调用Native方式三有参</div>

     

    五. WKWebView JS 交互

     

    WKWebView 的配置
    
    //导入 WebKit
    //创建配置类
    let confirgure = WKWebViewConfiguration()
                 
    //WKUserContentController: 内容交互控制器
    confirgure.userContentController = WKUserContentController()
            
    //创建WKWebView
    wkWebView = WKWebView(frame: CGRect(x: 0, y: 0, width: view.frame.width, height: view.frame.height), configuration: confirgure)
            
    //配置代理
    wkWebView.navigationDelegate = self as WKNavigationDelegate
    wkWebView.uiDelegate = self as WKUIDelegate

     

    Native 调用 JS

     

    • WebView 直接注入 JS 并执行

     

    不同于 UIWebView,WKWebView 注入并执行 JS 的方法不会阻塞当前线程。因为考虑到 webview 加载的 web content 内 JS 代码不一定经过验证,如果阻塞线程可能会挂起 App。
    
    self.wkWebView.evaluateJavaScript(“jsFuncName()") { (result, error) in
                print(result, error)
    }
    
    注意: 
    方法不会阻塞线程,而且它的回调代码块总是在主线程中运行。注意: 
    方法不会阻塞线程,而且它的回调代码块总是在主线程中运行。

     

    JS 调用 Native 

     

    • 拦截 URL 请求
    • Webkit 的 WKUIDelegate协议
    • 模型注入(Webkit 的 WKScriptMessageHandler协议)
       
    拦截 URL 请求
    拦截请求的代理方法为 WebKit 中 WKNavigationDelegate 协议的
    
     func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: ) 方法
    
    , 其它同 WebView

     

    Webkit 的 WKUIDelegate协议
    
    WKUIDelegate 协议包含一些函数用来监听 web JS 想要显示 alert 或 confirm 时触发。我们如果在 WKWebView 中加载一个 web 并且想要 web JS 的 alert 或 confirm 正常弹出,就需要实现对应的代理方法。
    
    以JS 弹出Confirm 为例, 下面是在 WKUIDelegate 监听 web 要显示 confirm 的代理方法中用 Native UIAlertController 替代 JS 中的 confirm 显示的 例子: 
    
    //通过 message 得到JS 端所传的数据,在 ios 端显示原生 alert 得到 true/false 后通过 completionHandler 回调给 JS
    
    Native 代码:
    func webView(_ webView: WKWebView, runJavaScriptConfirmPanelWithMessage message: String, initiatedByFrame frame: WKFrameInfo, completionHandler: @escaping (Bool) -> Void) {
            let alert = UIAlertController(title: "Confirm", message: message, preferredStyle: .alert)
            alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) -> Void in
                completionHandler(true)
            }))
            alert.addAction(UIAlertAction(title: "cancel", style: .cancel, handler: { (_) -> Void in
                completionHandler(false)
            }))
            self.present(alert, animated: true, completion: nil)
    }
    
    JS 代码:
    function callJsConfirm() {
            if (confirm('confirm', 'Objective-C call js to show confirm')) {
                d ocument.getElementById('jsParamFuncSpan').innerHTML = 'true';
            }else {
                 document.getElementById('jsParamFuncSpan').innerHTML = 'false';
            }
    }
    

     

    模型注入(Webkit 的 WKScriptMessageHandler协议)
    
    注意: 
    对象注入写在 viewWillAppear 中, 防止循环引用
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            //注入对象名称 APPModel, 当 JS 通过 APPModel 调用时, 可以在 WKScriptMessageHandler 代理方法中接收到
            wkWebView.configuration.userContentController.add(self, name: "APPModel")
        }
        
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "APPModel")
              }
    
    JS 通过 AppModel 给 Native 发送数据,会在该方法中收到
    JS调用iOS的部分, 都只能在此处使用, 我们也可以注入多个名称(JS对象), 用于区分功能
    
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "APPModel" {
                //传递的参数只支持NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull类型
                let alert = UIAlertController(title: "MessageHandler", message: message.name, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) -> Void in
                    
                }))
                self.present(alert, animated: true, completion: nil)
            }
        }
    
    JS 代码:
    function messageHandlers() {
            //APPModel 是我们注入的对象
            window.webkit.messageHandlers.APPModel.postMessage({body: 'messageHandlers'});
    }
    注意: 
    对象注入写在 viewWillAppear 中, 防止循环引用
    
        override func viewWillAppear(_ animated: Bool) {
            super.viewWillAppear(animated)
            //注入对象名称 APPModel, 当 JS 通过 APPModel 调用时, 可以在 WKScriptMessageHandler 代理方法中接收到
            wkWebView.configuration.userContentController.add(self, name: "APPModel")
        }
        
        override func viewWillDisappear(_ animated: Bool) {
            super.viewWillDisappear(animated)
            wkWebView.configuration.userContentController.removeScriptMessageHandler(forName: "APPModel")
              }
    
    JS 通过 AppModel 给 Native 发送数据,会在该方法中收到
    JS调用iOS的部分, 都只能在此处使用, 我们也可以注入多个名称(JS对象), 用于区分功能
    
        func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage) {
            if message.name == "APPModel" {
                //传递的参数只支持NSNumber, NSString, NSDate, NSArray,NSDictionary, and NSNull类型
                let alert = UIAlertController(title: "MessageHandler", message: message.name, preferredStyle: .alert)
                alert.addAction(UIAlertAction(title: "Ok", style: .default, handler: { (_) -> Void in
                    
                }))
                self.present(alert, animated: true, completion: nil)
            }
        }
    
    JS 代码:
    function messageHandlers() {
            //APPModel 是我们注入的对象
            window.webkit.messageHandlers.APPModel.postMessage({body: 'messageHandlers'});
    }
    

     

    六. JS 通过 Native 调用iOS 硬件(相机)

    JS 调用 iOS 硬件, 本质上还是通过以上介绍的 JS 调用 Native 方法调用 Native接口,

    再由 Native 调用本地硬件, 具体实现看 demo , 这里不再赘述.

     

     

    参考链接:

     

    拦截 URL:

    https://www.jianshu.com/p/d19689e0ed83

    https://blog.csdn.net/wanglei0918/article/details/78141890

    WKWebView 和 JS 交互:

    https://github.com/marcuswestin/WebViewJavascriptBridge

    http://www.cocoachina.com/ios/20171024/20895.html

    https://blog.csdn.net/baihuaxiu123/article/details/51674726

    WebView 和 JS 交互:

    https://www.jianshu.com/p/c11f9766f8d5

    https://www.jianshu.com/p/8f3c47c24e29

    https://blog.csdn.net/longshihua/article/details/51645575

     

    Github地址: 点击打开链接

    https://github.com/LeeJoey77/WebView_H5Demo.git
    
     
    https://github.com/LeeJoey77/WebView_H5Demo.gi

     

     

     

     

     

     

     

     

    展开全文
  • 移动端混合开发

    千次阅读 2019-10-14 19:10:45
    到现在做移动混合开发一年多了,做了3个项目,也算是个老手了。虽然只干了一年,但花了很多时间研究,所以感觉至少有2年多的经验。 框架选择:综合上手难度、普及率、资料查询难度等选择了ionic(框架自带整合...

    到现在做移动混合开发一年多了,做了3个项目,也算是个老手了。虽然只干了一年,但花了很多时间研究,所以感觉至少有2年多的经验。

    框架选择:综合上手难度、普及率、资料查询难度等选择了ionic(框架自带整合angularjs+cordova)。官方地址:https://ionicframework.com/docs/

    个人觉得ionic做的页面非常美,没图你说个什么?下面先看看效果

    花了7天做的一个演示demo,地址是http://renrenxiuka.whty.com.cn/app/ICBC/index.html

    是不是被惊艳到了?

    ionic优点:

    1.节约成本、页面好维护

       这是混合开发的共同特点,原生开发ios开发ios的,android开发android的,即耗人力,页面做的也会有差异。混合开发一个人就可以开发跨平台且共用的页面

    2.控件多

      常用的控件官网上都可以查询到,使用方便,比如广告轮播、日期选择等控件。如果控件没有,也可以使用html+css+js的方式实现。如何引用自定义js?后面的博客我会写到。

    3.便捷的插件

     什么是插件?我的理解,插件就是一些封装好的原生功能,在页面上调用。

     ionic采用了cordova来调用原生的功能,自身提供了很多写好的插件,也可以自定义插件,非常方便。

     4.资料查询

      百度搜到关于ionic的资料寥寥无几,要在github上去搜索,在官网上也可查询。

      当需要调整某个控件的颜色或宽度时,在官网上查不到或者觉得慢怎么办?在浏览器上打开调试模式即可看到各种html元素和css样式,找到那个样式再修改即可。

     5.上手简单

      从一个html小白到上手只需几天的时间即可

     6.开发速度快

      用原生写一个list列表,要activity+adapter+viewholder+xml,明明很简单的东西要写一大堆代码,数据请求到了还要notify刷新页面

      现在recyleListview的item分割线甚至还要手动写代码。

      用ionic几分钟可以搞定,页面与ts文件(类似js)数据双向绑定

    ps:还有好多优点,比如丰富的图标库等等

     

    缺点

    1.兼容性

     这是所有混合开发的通病吧,毕竟是基于html

     如ion-list分割线某些机型不显示、某些机型不支持var关键字等,这些都要靠自己慢慢积累。

     2.好像没啥缺点了。。

     

    扫码关注我吧,获取学习视频

    展开全文
  • 前端混合开发总结

    千次阅读 2018-12-07 10:52:04
    名称 React Native Weex Flutter uni-app 支持 Facebook Alibaba Google ... 需针对iOS、Android编写2份代码(需要会Java,oc) 只需要编写一份代码,即可运行在Web、iOS、Android上 ...

            

    名称 React  Native Weex Flutter uni-app
    支持 Facebook Alibaba Google Dcloud
    编写方式 需针对iOS、Android编写2份代码(需要会Java,oc) 只需要编写一份代码,即可运行在Web、iOS、Android上 只需要编写一份代码,即可运行在iOS、Android上

    vue  框架开发即可编译出

    安卓 ,ios,H5,小程序跨平台

    JS引擎 JSCore V8 未知 APP基于Weex,小程序基于mpvue,H5基于vue框架
    框架 React.js组件化,数据绑定  Virtual DOM JSX模板学习使用有一定成本 Vue.JS 组件化,数据绑定 Virtual DOM 模板就是普通的html,数据绑定使用mustache风格,样式直接使用css 代码风格和java比较接近,个人感觉和前端标签也很像,有人说喜欢XML布局的对于Dart会比较难受 vue
    异步 提供了Promise 只支持 callback Dart 的 Event-Queue的模型 提供了Promise
    扩展 不同平台可自由扩展 为了保证各平台的一致性,一次扩展得在各个平台都实现 可扩展 可扩展
    组件 除了自带的,还有js.coach上社区贡献的,比较丰富 基本靠平台提供 依赖ReactiveX库 和weex基本一样
    性能 优秀 android 原生在内存、CPU 资源占用方面要低于 flutter,并且安装包的体积也要小于 flutter   (优) 一般
    社区 非常成熟和活跃 开源较晚,社区处于成长期 活跃 新框架,社区处于成长期
    上手难度 困难 容易 一般 容易

     

                 

              React Native

            

              优点:

    •  跨平台开发
    •   跳过App Store审核,远程更新代码,提高迭代频率和效率,既有Native的体验,又保留React的开发效率。

    缺点:

    • 对于不熟悉前端开发的人员上手比较慢;
    • 不能真正意义上做到跨平台;
    • app包体积增大明显

     

     

     

     

    H5     vue

     

    小程序

       wepy mpvue taro

     

       

    • WEPY https://tencent.github.io/wepy/document.html

      腾讯团队开源的一款类vue语法规范的小程序框架,借鉴了Vue的语法风格和功能特性,支持了Vue的诸多特征,比如父子组件、组件之间的通信、computed属性计算、wathcer监听器、props传值、slot槽分发,还有很多高级的特征支持:Mixin混合、拦截器等;WePY发布的第一个版本是2016年12月份,也就是小程序刚刚推出的时候,到目前为止,WePY已经发布了52个版本, 最新版本为1.7.2; 

      

    • MpVue http://mpvue.com/mpvue/#-html

      美团团队开源的一款使用 Vue.js 开发微信小程序的前端框架。使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力。mpvue在发布后的几天间获得2.7k的star,上升速度飞起,截至目前为止已经有13.7k的star;

    • Taro https://taro.aotu.io/

       京东凹凸实验室开源的一款使用 React.js 开发微信小程序的前端框架。它采用与 React 一致的组件化思想,组件生命周期与 React 保持一致,同时支持使用 JSX 语法,让代码具有更丰富的表现力,使用 Taro 进行开发可以获得和 React 一致的开发体验。,同时因为使用了react的原因所以除了能编译h5, 小程序外还可以编译为ReactNative;

     

        

    展开全文
  • 谈谈App混合开发

    千次阅读 2019-05-24 10:56:07
    混合开发的App(Hybrid App)就是在一个App中内嵌一个轻量级的浏览器,一部分原生的功能改为Html 5来开发,这部分功能不仅能够在不升级App的情况下动态更新,而且可以在Android或iOS的App上同时运行,让用户的体验更...
  • 混合开发(APP)

    2019-03-04 00:30:35
    1.由于混合开发,(登录app负责),那么在页面完成后对接接口的时候需要传一个token值,都知道token是登录时生成的,此时就需要APP将该值传给我,app大佬表示在url中有给传,截取token传值后token为null,绑到input...
  • 关于混合开发

    2020-10-08 14:02:19
    app原生开发与app混合开发有什么区别? 一、app原生开发 原生开发(Native App开发),在Android、IOS等移动平台上利用提供的开发语言、开发类库、开发工具进行App软件开发,比如Android是利用Java、Eclipse、...
  • Hybrid APP混合开发的一些经验和总结

    万次阅读 多人点赞 2017-03-31 11:14:30
    由于业务需要,接触到一个Hybrid APP混合开发的项目。当时是第一次接触混合开发,有一些经验和总结,欢迎各位一起交流学习~ 1、混合开发概述 Hybrid App主要以JS+Native两者相互调用为主,从开发层面实现“一次...
  • App混合开发(英文名:Hybrid App),是指在开发一款App产品的时候为了提高效率、节省成本即利用了原生的开发技术还应用了HTML5开发技术,是原生和HTML5技术的混合应用。目前App的开发主要包含三种方式:原生开发、...
  • Vue+原生App混合开发

    千次阅读 2019-01-25 15:58:32
    转载一篇 Vue+原生App混合开发 源地址 : https://www.cnblogs.com/undefined000/p/vue-nativeApp-development.html  
  • Hybrid App 开发快速指南

    万次阅读 2018-08-14 00:42:57
    关于混合应用是什么、为什么使用的问题,相信大家都有自己的答案,但如何开发混合应用,从现有资料中却很难找到一个系统、全面的回答。 刚上手或准备上手混合应用的开发者,经常苦于没有一套经过验证的最佳实践来...
  • vue与原生混合开发

    万次阅读 2018-07-06 10:09:08
    前段时间,做了一个混合开发的项目,主要是以vue框架开发h5页面,使用cordova作为中间沟通桥梁,实现了h5与安卓、iOS的混合开发,由于从事iOS开发,h5也是刚接触不久,很多深入原理还不太清楚,只说下我们这个个项目...
  • 不过对于移动开发者来说更关心的问题是如何低成本、周期短开发出体验效果好的App,所以当下用html5远比赌html5更现实,因此跨平台开发至关重要...今天小编就给大家推荐5个好用的html5混合式App开发工具。1、Appceler...
  • 移动开发-混合App介绍

    万次阅读 2018-06-25 08:56:38
    3种开发类型的原理和对比 什么是混合App(Hybrid App) Hybrid App是指介于web-app(网页APP,如京东web)、native-app(原生应用,如手机上面的APP应用)这两者之间的app,它虽然看上去是一个Native App,但...
  • 移动端app开发,原生开发与混合开发的区别

    千次阅读 多人点赞 2019-09-26 18:47:16
    目前市场上主流的APP分为三种:原生APP、Web APP(即HTML5)和混合APP三种,相对应的定制开发就是原生开发、H5开发和混合开发。那么这三种开发模式究竟有何不同呢?下面我们就分别从这三者各自的优劣势来区分比较吧...
  • 最简单的混合开发教程:APICloud.

    千次阅读 2016-09-26 00:25:44
    现在react-native越来越火了,阿里也推出了weex,微信的应用号也开始内测了,未来的世界将会是混合开发的天下。 所以现在还没有接触过混合开发的前端朋友们就要看过来了,这是个最简单的混合开发框架 。 那些已经在做...
  • 移动端的混合开发是什么意思?我是学H5的我想知道,我们H5做的移动端的页面如何转化成APP?
  • Hybird APP (混合开发)简介

    万次阅读 2019-03-07 11:26:45
    写了几个 APP,最初是打算用纯 Native 的,可是我自身的 Android...还好有前辈指点了一下,可以采用 Hybrid APP(混合开发),一路磕磕绊绊的完成了项目。看了不少资料,从菜鸟的角度来总结下 Hybrid APP(混合开发)。
  • Web应用本质上是为移动浏览器设计的基于Web的应用,它们是用普通Web开发语言开发的,可以在各种智能手机浏览器上运行。 优点: 支持设备广泛;较低的开发成本;可即时上线;无内容限制;用户可以直接使用最新...
  • 5个好用的混合式App开发工具

    千次阅读 2015-09-08 17:11:10
    在残酷的移动互联网竞争环境下, HTML5技术一直受到各方关注,“HTML5颠覆原生 App”的争论也从未...于是,一个一直被提及但是从没有占据过统治地位的概念又一次走进了移动开发者们的视野,那就是跨平台开发。 AD:
1 2 3 4 5 ... 20
收藏数 235,900
精华内容 94,360
关键字:

混合开发