小工具      在线工具  汉语词典  dos游戏  css  js  c++  java

IOS 原生界面和Weex容器互相跳转实践 附部分js和原生代码

React Native&Weex 额外说明

收录于:52天前

weex相关原理,请看官方网站

这个IOS Weex demo实现的功能是从原生界面跳转到Weex容器页面,然后点击Weex容器页面上的按钮(js)跳转到另一个原生界面。

1. 一、效果图

2. 实施

1、weex容器渲染的js代码如下,上面第二张图的代码

启动本地Node环境,可以通过浏览器访问,也可以通过Weex容器渲染到上图二的界面中。

import { createElement, Component } from 'rax';
import View from 'rax-view';
import Text from 'rax-text';
import Button from 'rax-button';

import { setTitle, openUrl, getAppStoken } from 'lib/jsbridge';
import styles from './app.css';

class APP extends Component {
  constructor(props) {
    super(props);
    this.state = {
      timesPressed1: 0,
      list: [],
    };
  }
  componentDidMount() {
    // alert('请求错误'); // eslint-disable-line
  }

  handlePress = () => {
    this.setState({
      timesPressed1: this.state.timesPressed1 + 1,
    });
   // alert('弹框测试!!!'); // eslint-disable-line

    openUrl({
      // url: 'weex://go/scan',
      url: 'weex://go/ljDetail?orderId=123',
    });
  };

  render() {
    return (
      <View style={styles.body}>
        <Text style={styles.loadingText}>当前页面是个weex容器</Text>
        <Text style={styles.loadingText}>加载的是个weex页面</Text>
        <Button style={styles.button} onPress={this.handlePress}>点击我从weex页面跳转到原生</Button>
      </View>
    );
  }
}

export default APP;

2. 原生 Weex 容器

NSString *url = @"http://10.50.62.53:9999/wxTest/index.html?lj_weexurl=http://10.50.62.53:9999/wxTest/index.js";

这个容器的设计是为了当 Weex 加载失败时,可以将当前页面显示为 html 页面,并加载 wxTest/index.html 页面,不影响使用。

当 Weex 加载成功后,会渲染 wxTest/index.js 的代码。

#import "WXViewController.h"
#import <WeexSDK/WXSDKInstance.h>
#import <WeexSDK/WXSDKEngine.h>
#import <WeexSDK/WXUtility.h>
#import <WeexSDK/WXDebugTool.h>
#import <WeexSDK/WXSDKManager.h>
#import "UIViewController+WXDemoNaviBar.h"
#import "WXPrerenderManager.h"
#import "WXMonitor.h"
#import "WXTracingManager.h"

#import "LJWKWebView.h"
#import "LJWKWebViewUtils.h"

#define kNavAndStatuesHeight  64
#define kUseWeexFlag @"lj_weexurl"

@interface WXViewController ()

@property (nonatomic, strong) WXSDKInstance *instance;
@property (nonatomic, strong) UIView *weexView;
@property (nonatomic, assign) BOOL isUseWeexRender; //是否使用weex渲染
@property (nonatomic, strong) LJWKWebView *webView;

@end

@implementation WXViewController

#pragma mark -- dealloc
- (void)dealloc
{
    [_instance destroyInstance];
    [[NSNotificationCenter defaultCenter] removeObserver:self];
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        NSAssert(NO, @"请使用initWithUrl初始化");
    }
    return self;
}

- (instancetype)initWithUrl:(NSURL *)url useWeexEnv:(BOOL)useWeexEnv
{
    self = [super init];
    if (self) {
        _url = url;
        _isUseWeexRender = useWeexEnv && ([url.absoluteString rangeOfString:kUseWeexFlag].location != NSNotFound);
    }
    return self;
}

#pragma mark -- life cycle
- (void)viewDidLoad
{
    [super viewDidLoad];
    
//    [self setTopNavBarTitle:@"Weex Container"];
    [self setGrayTopBarBg];
    
    if (_isUseWeexRender) {
        [self.view setClipsToBounds:YES];
        [self renderWeex];
    }else{
        [self setDeafaultTopBarBg];
        [self setTopNavBackButton];
        [self setTopNavBarTitle:@"加载中..."];
        [self loadWebViewWithUrl:self.url.absoluteString];
    }
}

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    if (_isUseWeexRender) {
        [self updateInstanceState:WeexInstanceAppear];
    }
}

- (void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    if (_isUseWeexRender) {
        [self updateInstanceState:WeexInstanceDisappear];
    }
}

应用程序代理代码

#import "AppDelegate.h"
#import "WXViewController.h"
#import "UIViewController+WXDemoNaviBar.h"
#import "WXLJCustomeEventModule.h"
#import "WXImgLoaderDefaultImpl.h"
#import "WXScannerVC.h"
#import "UIView+UIThreadCheck.h"
#import <WeexSDK/WeexSDK.h>
#import <AVFoundation/AVFoundation.h>
#import <ATSDK/ATManager.h>
#import "WXNavigationHandlerImpl.h"

#import "ViewController.h"
//#import "WXAnalyzerCenter.h"


#ifdef DEBUG
#import "DebugAnalyzer.h"
#endif

@interface AppDelegate ()
@end

@implementation AppDelegate

#pragma mark
#pragma mark application

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    self.window.backgroundColor = [UIColor whiteColor];
    
    [self initWeexSDK];
    
    ViewController *vc = [[ViewController alloc]init];
    UINavigationController *nav = [[UINavigationController alloc]initWithRootViewController:vc];
    self.window.rootViewController = nav;
    [self.window makeKeyAndVisible];
    
    [self startSplashScreen];
    
#if DEBUG
    // check if there are any UI changes on main thread.
    [UIView wx_checkUIThread];
#endif
    
    return YES;
}

- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler
{
    if ([shortcutItem.type isEqualToString:QRSCAN]) {
        WXScannerVC * scanViewController = [[WXScannerVC alloc] init];
        [(WXRootViewController*)self.window.rootViewController pushViewController:scanViewController animated:YES];
    }
    if ([shortcutItem.type isEqualToString:QRSCAN_HISTORY]) {
//        WXScannerHistoryVC *scannerHistoryVC = [WXScannerHistoryVC new];
//        [(WXRootViewController*)self.window.rootViewController pushViewController:scannerHistoryVC animated:YES];
    }
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    
#ifdef UITEST
#if !TARGET_IPHONE_SIMULATOR
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSString *documentsDirectory = [paths objectAtIndex:0];
    setenv("GCOV_PREFIX", [documentsDirectory cStringUsingEncoding:NSUTF8StringEncoding], 1);
    setenv("GCOV_PREFIX_STRIP", "6", 1);
#endif
    extern void __gcov_flush(void);
    __gcov_flush();
#endif
}

- (BOOL)application:(UIApplication *)application handleOpenURL:(NSURL *)url
{
    NSString *newUrlStr = url.absoluteString;
    if([url.scheme isEqualToString:@"wxpage"]) {
        newUrlStr = [newUrlStr stringByReplacingOccurrencesOfString:@"wxpage://" withString:@"http://"];
    }
    UIViewController * viewController = [self demoController:newUrlStr];
//    ((WXViewController*)viewController).url = [NSURL URLWithString:newUrlStr];
    [(WXRootViewController*)self.window.rootViewController pushViewController:viewController animated:YES];
    return YES;
}

#pragma mark weex
- (void)initWeexSDK
{
    [WXAppConfiguration setAppGroup:@"AliApp"];
    [WXAppConfiguration setAppName:@"WeexDemo"];
    [WXAppConfiguration setExternalUserAgent:@"ExternalUA"];
    
    [WXSDKEngine initSDKEnvironment];
    
    [WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
    [WXSDKEngine registerHandler:[WXNavigationHandlerImpl new] withProtocol:@protocol(WXNavigationProtocol)];
    
    // 注册自定义的JS回调原生方法的事件方法
    [WXSDKEngine registerHandler:[WXLJCustomeEventModule new] withProtocol:@protocol(WXModuleProtocol)];
    [WXSDKEngine registerModule:@"actionBridge" withClass:[WXLJCustomeEventModule class]];
    // 注册自定义的JS回调原生方法的事件方法
    
#ifdef DEBUG
    [WXAnalyzerCenter addWxAnalyzer:[DebugAnalyzer new]];
#endif
    
#if !(TARGET_IPHONE_SIMULATOR)
    [self checkUpdate];
#endif
    
#ifdef DEBUG
    [self atAddPlugin];
    [WXDebugTool setDebug:YES];
    [WXLog setLogLevel:WXLogLevelLog];
    
#ifndef UITEST
    [[ATManager shareInstance] show];
#endif
#else
    [WXDebugTool setDebug:NO];
    [WXLog setLogLevel:WXLogLevelError];
#endif
}

- (UIViewController *)demoController:(NSString*)url
{
//    NSString *url = @"http://10.50.62.53:9999/wxTest/index.js";
    //    NSString *url = @"http://10.50.62.53:9999/wxTableview/index.js";
    //    NSString *url = @"https://www.baidu.com/";
    UIViewController *demo = [[WXViewController alloc] initWithUrl:[NSURL URLWithString:url] useWeexEnv:YES];
    return demo;
}

#pragma mark
#pragma mark animation when startup

- (void)startSplashScreen
{
    UIView* splashView = [[UIView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    splashView.backgroundColor = WEEX_COLOR;
    
    UIImageView *iconImageView = [UIImageView new];
    UIImage *icon = [UIImage imageWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"weex-icon" ofType:@"png"]];
    if ([icon respondsToSelector:@selector(imageWithRenderingMode:)]) {
        iconImageView.image = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
        iconImageView.tintColor = [UIColor whiteColor];
    } else {
        iconImageView.image = icon;
    }
    iconImageView.frame = CGRectMake(0, 0, 320, 320);
    iconImageView.contentMode = UIViewContentModeScaleAspectFit;
    iconImageView.center = splashView.center;
    [splashView addSubview:iconImageView];
    
    [self.window addSubview:splashView];
    
    float animationDuration = 1.4;
    CGFloat shrinkDuration = animationDuration * 0.3;
    CGFloat growDuration = animationDuration * 0.7;
    
    if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7.0) {
        [UIView animateWithDuration:shrinkDuration delay:1.0 usingSpringWithDamping:0.7f initialSpringVelocity:10 options:UIViewAnimationOptionCurveEaseInOut animations:^{
            CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.75, 0.75);
            iconImageView.transform = scaleTransform;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:growDuration animations:^{
                CGAffineTransform scaleTransform = CGAffineTransformMakeScale(20, 20);
                iconImageView.transform = scaleTransform;
                splashView.alpha = 0;
            } completion:^(BOOL finished) {
                [splashView removeFromSuperview];
            }];
        }];
    } else {
        [UIView animateWithDuration:shrinkDuration delay:1.0 options:0 animations:^{
            CGAffineTransform scaleTransform = CGAffineTransformMakeScale(0.75, 0.75);
            iconImageView.transform = scaleTransform;
        } completion:^(BOOL finished) {
            [UIView animateWithDuration:growDuration animations:^{
                CGAffineTransform scaleTransform = CGAffineTransformMakeScale(20, 20);
                iconImageView.transform = scaleTransform;
                splashView.alpha = 0;
            } completion:^(BOOL finished) {
                [splashView removeFromSuperview];
            }];
        }];
    }
}

#pragma mark

- (void)atAddPlugin {
#if DEBUG
    [[ATManager shareInstance] addPluginWithId:@"weex" andName:@"weex" andIconName:@"../weex" andEntry:@"" andArgs:@[@""]];
    [[ATManager shareInstance] addSubPluginWithParentId:@"weex" andSubId:@"logger" andName:@"logger" andIconName:@"log" andEntry:@"WXATLoggerPlugin" andArgs:@[@""]];
    //    [[ATManager shareInstance] addSubPluginWithParentId:@"weex" andSubId:@"viewHierarchy" andName:@"hierarchy" andIconName:@"log" andEntry:@"WXATViewHierarchyPlugin" andArgs:@[@""]];
    [[ATManager shareInstance] addSubPluginWithParentId:@"weex" andSubId:@"test2" andName:@"test" andIconName:@"at_arr_refresh" andEntry:@"" andArgs:@[]];
    [[ATManager shareInstance] addSubPluginWithParentId:@"weex" andSubId:@"test3" andName:@"test" andIconName:@"at_arr_refresh" andEntry:@"" andArgs:@[]];
#endif
}

- (void)checkUpdate {
    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSDictionary *infoDic = [[NSBundle mainBundle] infoDictionary];
        NSString *currentVersion = [infoDic objectForKey:@"CFBundleShortVersionString"];
        NSString *URL = @"http://itunes.apple.com/lookup?id=1130862662";
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:URL]];
        [request setHTTPMethod:@"POST"];
        
        NSHTTPURLResponse *urlResponse = nil;
        NSError *error = nil;
        NSData *recervedData = [NSURLConnection sendSynchronousRequest:request returningResponse:&urlResponse error:&error];
        NSString *results = [[NSString alloc] initWithBytes:[recervedData bytes] length:[recervedData length] encoding:NSUTF8StringEncoding];
        
        NSDictionary *dic = [WXUtility objectFromJSON:results];
        NSArray *infoArray = [dic objectForKey:@"results"];
        
        if ([infoArray count]) {
            NSDictionary *releaseInfo = [infoArray objectAtIndex:0];
            weakSelf.latestVer = [releaseInfo objectForKey:@"version"];
            if ([weakSelf.latestVer floatValue] > [currentVersion floatValue]) {
                if (![[NSUserDefaults standardUserDefaults] boolForKey: weakSelf.latestVer]) {
                    [[NSUserDefaults standardUserDefaults] setBool:FALSE forKey:weakSelf.latestVer];
                    dispatch_async(dispatch_get_main_queue(), ^{
                        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"New Version" message:@"Will update to a new version" delegate:self cancelButtonTitle:@"cancel" otherButtonTitles:@"update", nil];
                        [alert show];
                    });
                }
            }
        }
    });
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
    switch (buttonIndex) {
        case 0:
            [[NSUserDefaults standardUserDefaults] setBool:TRUE forKey:self.latestVer];
            break;
        case 1:
            [[UIApplication sharedApplication]openURL:[NSURL URLWithString:@"itms-apps://itunes.apple.com/cn/app/weex-playground/id1130862662?mt=8"]];
        default:
            break;
    }
    [alertView dismissWithClickedButtonIndex:buttonIndex animated:YES];
}

@end

定制的weex组件--------专门与js交互的文件

#import "WXLJCustomeEventModule.h"
#import <WeexSDK/WeexSDK.h>
#import "WXViewController.h"
#import "HomeViewController.h"

@interface WXLJCustomeEventModule()

@property (nonatomic, copy) WXModuleKeepAliveCallback loginSuccessCallBack;

@end

@implementation WXLJCustomeEventModule

@synthesize weexInstance;

WX_EXPORT_METHOD(@selector(openUrl:callback:))
WX_EXPORT_METHOD(@selector(close:callback:))
WX_EXPORT_METHOD(@selector(setNavBarTitle:callback:))

- (void)openUrl:(id)paramsJSON callback:(WXModuleKeepAliveCallback)callback
{
     NSDictionary *paramsDic = [CHUtil dictionaryWithJsonString:paramsJSON];
//    url: 'weex://go/ljDetail?orderId=123',
    if (paramsDic) {
        NSString *url = paramsDic[@"url"];
        NSDictionary *queryDic = [CHUtil getParamsDicWithUrl: url];
        
        if ([url hasPrefix:@"http"]) {
            WXViewController *vc = [[WXViewController alloc] initWithUrl:[NSURL URLWithString:url] useWeexEnv:YES];
            [[weexInstance.viewController navigationController] pushViewController:vc animated:YES];
        } else if ([url hasPrefix:@"weex"] && [url rangeOfString:@"ljDetail"].location != NSNotFound){
            
            HomeViewController *vc = [HomeViewController new ];
            vc.orderId = queryDic[@"orderId"];
            [[weexInstance.viewController navigationController] pushViewController:vc animated:YES];
            NSLog(@"url:%@", url);
            return;
        }
    }
    
}

- (void)close:(id)paramsJSON callback:(WXModuleKeepAliveCallback)callback
{
    [weexInstance.viewController.navigationController popViewControllerAnimated:YES];
    if (callback) {
        callback(@"", NO);
    }
}

. . .

相关推荐

额外说明

计算机网络体系结构思维导图

计算机网络 https://www.aliyundrive.com/s/9rVggaxJVoN 点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。

额外说明

Java Web常见漏洞分析

Java vs PHP Java Web的常见概念 Java Web项目的目录结构 Servlet JSP(Java Server Pages) JDBC(Java Database Connectivity) Java Bean Java Web常见漏

额外说明

day18_管理系统综合案例

今日内容 综合练习 简单的功能 列表查询 登录 添加 删除 修改 复杂的功能 删除选中 分页查询 好处: 减轻服务器服务器内存的开销 提升用户的体验 复杂的条件查询 2. 登录 调整页面,加入验证码功能

额外说明

【Unity3D开发小游戏】《愤怒的小鸟》Unity开发教程

《愤怒的小鸟》开发教程 一、前言 二、源码 三、正文 项目版本 1.设置相机 2.地面设置 3.边界设置 4.云彩设置 5.弹弓设计 6.鸟的设置 7.木片 8.石头 9.冰 10.绿猪 11.橡胶 12.总结 一、前言 “愤怒的小鸟”在2009年12月

额外说明

HNU-计算机网络-讨论课1

题目: 有关网络系统结构的讨论 一、必选问题(每组平均每人1个) 1、分层结构其实是世界演进形成的普遍系统结构,不管是自然领域还是社会领域,请举例说说你的理解。 2、有人说通信网络的核心技术在物理层,难度要远远大于上层技术,所以上层技术并不重要。说说你的

额外说明

《项目实战》构建SpringCloud alibaba项目(三、构建服务方子工程store-user-service)

系列文章目录 构建SpringCloud alibaba项目(一、构建父工程、公共库、网关) 构建SpringCloud alibaba项目(二、构建微服务鉴权子工程store-authority-service) 构建SpringCloud aliba

额外说明

《MapboxGL 基础知识点》- 地图监听事件

添加地图监听事件 使用方法 map.on map.on(type, layerIds, listener) 例如 map.on('mouseup', onMouseup); function onMouseup(e) { // mouseup

额外说明

关于 http 或 https 协议的获取与设置

在实际生产环境下,不要写死 http 或 https。否则当站点在集成时如果变更了协议,那就麻烦了。。。获取当前站点协议 // 注意,返回的字符串是带冒号的 : window.location.protocol  如上图和示例,可以看出从 window.

额外说明

路径规划 | 图解动态A*(D*)算法(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍 1 什么是D*算法? 2 D*算法核心概念一览 3 D*算法流程图 4 步步图解:算法实例 5 算法仿真与实现 5.1 ROS C++实现 5.2 Python实现 0 专栏介绍 -附C++/Python/Matlab全套代码-课程设

ads via 小工具