zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    android开发我的新浪微博客户端-用户授权页面UI篇(3.1)
    android开发我的新浪微博客户端-OAuth篇(2.1)
    android开发我的新浪微博客户端-载入页面sqlite篇(1.2)
    android开发我的新浪微博客户端-载入页面UI篇(1.1)
    android 强制设置横屏 判断是横屏还是竖屏
    android 各种进度条(ProgressBar)
    android:百度地图-给地图添加标注物
    android应用与服务的通信之学生查询系统案例源码
    android手机多线程断点续传下载器案例源码
    android外拨电话拦截器,完整源码
  • 原文地址:https://www.cnblogs.com/xgao/p/6497012.html
Copyright © 2011-2022 走看看