• IOS中Hybird实现


    现在Hybird这块,网上也有很多文章,最近研究了下,分享给大家。

    什么是Hybird技术?

    1、一般是指WebView和Native技术混合而成的一套技术方案

    2、也可以理解成,非Native技术与Native技术的混合开发

    现在的Hybird有几种实现方式:

    1、UIWebView、WKWebView 直接使用的是网页与OC交互(cordova与phonegap是使用该方案)(本文没有对该方案进行讲解)

    2、数据驱动、脚本驱动(RN、微信小程序用的好像都是这种原理)

    现在对于使用了webView实现的hybird技术大家都知道它的优势与劣势

    优势是 可以热更新,直接WEB前端人员也能开发,擅长复杂的内容排版

    劣势是 体验没有原生应用流畅

    本文重点是说 数据驱动、脚本驱动,好处是能热更新,体验也更好,因为它都是生成原生应用,和WebView完全不一样

    什么是数据驱动?

    数据驱动说的是 我们App通过下载服务器端的json文件(里面定义了我们的UI布局样式,简单的业务功能)然后本地解析动态创建相应的UI。

    什么是脚本驱动?

    脚本驱动说的是 通过OC中的JavaScriptCore实现JS与OC的交互,一些简单的功能能放到JS中处理。

    效果演示

    默认打开效果:

    点击测试1按钮的效果:

    点击测试2按钮的效果:

    以上的这些UI布局及功能都是动态写在 json与js 文件里面的 

    具体代码演示

    因为我们为了方便演示,我这里没有搭建WEB服务器,所以json文件就直接放在APP里面,我们先创建 page.json 和 page.js 文件 

    分别如下:

    可以看得出来,我们这个json文件里面的数据定义了一些UI的相关属性,注意button里面的那个onClicked,对应的是下面page.js里面的js方法

    这里面的 updateLabelText 方法是我们App里面定义好的,下面我们来看App里

    //
    //  ViewController.m
    //  hybirdDemo
    //
    //  Created by xgao on 17/3/3.
    //  Copyright © 2017年 xgao. All rights reserved.
    //
    
    #import "ViewController.h"
    //@import JavaScriptCore;
    #import <JavaScriptCore/JavaScriptCore.h>
    
    // 数据驱动、脚本驱动
    @interface ViewController ()
    
    // 用于执行JS的上下文
    @property (nonatomic,strong) JSContext* jsContext;
    // 保存按钮的点击事件的方法名
    @property (nonatomic,retain) NSMutableDictionary* functionDic;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        [self initDataUI];
        [self initJSContext];
    }
    
    - (NSMutableDictionary*)functionDic{
        if (!_functionDic) {
            _functionDic = [NSMutableDictionary dictionary];
        }
        return _functionDic;
    }
    
    - (void)initDataUI{
        
        // 加载JSON数据
        NSString* pageJsonPath = [[NSBundle mainBundle] pathForResource:@"page" ofType:@"json"];
        NSData* pageJsonData = [NSData dataWithContentsOfFile:pageJsonPath];
        NSDictionary* pageJsonDic = [NSJSONSerialization JSONObjectWithData:pageJsonData options:NSJSONReadingAllowFragments error:nil];
        
        NSArray<NSDictionary*>* views = pageJsonDic[@"views"];
        for (NSDictionary* view in views) {
            // 解析UI
            if ([view[@"class"] isEqualToString:@"label"]) {    // UILabel
               
                UILabel* label = [[UILabel alloc]initWithFrame:[self CGRectWithDic:view]];
                label.text = view[@"text"];
                label.tag = [view[@"tag"] intValue];
                [self.view addSubview:label];
            }else if([view[@"class"] isEqualToString:@"button"]){   // UIButton
                
                UIButton* button = [[UIButton alloc]initWithFrame:[self CGRectWithDic:view]];
                [button setTitle:view[@"title"] forState:UIControlStateNormal];
                button.tag = [view[@"tag"] intValue];
                [button setTitleColor:[UIColor greenColor] forState:UIControlStateNormal];
                [button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
                // 添加到事件字典中,btnClick
                [self.functionDic setObject:button forKey:view[@"onClicked"]];
                [self.view addSubview:button];
            }
        }
    }
    
    // 初始化JSContext
    - (void)initJSContext{
        
        self.jsContext = [[JSContext alloc]init];
        
        // 加载 page.js 脚本文件
        NSString* pageJsPath = [[NSBundle mainBundle] pathForResource:@"page" ofType:@"js"];
        NSString* pageJs = [NSString stringWithContentsOfFile:pageJsPath encoding:NSUTF8StringEncoding error:nil];
        // 执行JS脚本,将JS代码注入到 上下文中
        [self.jsContext evaluateScript:pageJs];
        
        // 定义updateLabelText方法,用于JS调用OC
        __weak ViewController* weakSelf = self;
        self.jsContext[@"updateLabelText"] = ^(NSString* text,NSInteger tag){
            UILabel* label = [weakSelf.view viewWithTag:tag];
            label.text = text;
        };
    }
    
    // button按钮点击通用事件
    - (void)buttonClick:(UIButton*)button{
        
        for (NSString* func in self.functionDic.allKeys) {
            UIButton* btn = self.functionDic[func];
            if ([btn isEqual:button]) {
                // OC 调用 JS 方法,这里就是 OC调用JS定义的那两个 btnClick 和 btnClick2
                [self.jsContext[func] callWithArguments:nil];
                break;
            }
        }
        
    }
    
    #pragma mark - Private
    
    - (CGRect)CGRectWithDic:(NSDictionary*)dic{
        
        CGFloat x = [dic[@"x"] floatValue];
        CGFloat y = [dic[@"y"] floatValue];
        CGFloat width = [dic[@"width"] floatValue];
        CGFloat height = [dic[@"height"] floatValue];
        return CGRectMake(x, y, width, height);
    }
    
    @end
  • 相关阅读:
    【漏洞】【Druid】Druid未授权访问漏洞,修复方案。springboot
    linux shell 获取java版本号
    SpringBoot 通过配置禁用swagger
    string.format()详解
    Linux 下杀毒软件 clamav 0.104.2 离线安装及测试(CentOS7)
    MySQL密码复杂度策略
    Tcpdump抓包命令
    狄尔沃斯定理(Dilworth's theorem)
    docker容器安装TensorFlow_gpu 版本遇到的坑。。。
    C++ 11 make_shared
  • 原文地址:https://www.cnblogs.com/xgao/p/6497012.html
Copyright © 2020-2023  润新知