Weex开发 [iOS]

[TOC]

初始化Weex环境

  • WXSDKEngine:SDK开放的绝大多数接口都在此有声明。
  • WXLog: 控制Log输出的级别,包括Verbose、Debug、Info、Warning、Error,开发者可以按需来设置输出级别。
  • WXDebugTool: weex提供的对外调试工具。
  • WXAppConfiguration: 使用weex开发的业务性配置。

在AppDelegate的didFinishLaunchingWithOptions方法中进行初始化设置

// 业务配置,非必需
[WXAppConfiguration setAppGroup:@"itheimaApp"];
[WXAppConfiguration setAppName:@"WeexDemo"];
[WXAppConfiguration setAppVersion:@"3.2.0"];
// 初始化`WeexSDK`环境
[WXSDKEngine initSDKEnviroment];
// 注册自定义组件和模型,非必需 [如果有就注册如果没有就不注册]
[WXSDKEngine registerComponent:@"YourView" withClass:[MyViewComponent class]];
[WXSDKEngine registerModule:@"YourModule" withClass:[YourModule class]];
// 注册协议的实现类,非必需
[WXSDKEngine registerHandler:[WXNavigationDefaultImpl new] withProtocol:@protocol(WXNavigationProtocol)];
//设置Log输出等级:调试环境默认为Debug,正式发布会自动关闭。
[WXLog setLogLevel:WXLogLevelDebug];

渲染Weex实例

  1. 声明属性instance
// WXSDKInstance属性
@property (nonatomic, strong) WXSDKInstance *weexInstance;
// Weex视图
@property (weak, nonatomic) UIView *weexView;
  1. 创建WXSDKInstance 对象,并进行相关设置。
    WXSDKInstance,就是weex渲染的实例对象。它提供给开发者诸多跟页面渲染相关的接口,包括renderWithURL、refreshInstance以及destroyInstance等,提供了几个比较重要的回调接口,方便开发者根据不同的业务场景去处理他们的逻辑,如onfailed,还提供了性能监控相关的接口。
- (void)renderWeexWithURL:(NSString *)url 
{
// 创建WXSDKInstance对象
 _weexInstance = [[WXSDKInstance alloc] init];
 // 设置weexInstance所在的控制器
 _weexInstance.viewController = self;
 //设置weexInstance的frame
 _weexInstance.frame = self.view.frame;
 __weak typeof(self) weakSelf = self;
 //设置weexInstance创建完毕回调
 _weexInstance.onCreate = ^(UIView *view) {
      weakSelf.weexView = view;
     [weakSelf.weexView removeFromSuperview];
     [weakSelf.view addSubview:weakSelf.weexView];
 };
 // 设置weexInstance出错的回调
 _weexInstance.onFailed = ^(NSError *error) {
     //process failure
     NSLog(@"处理失败:%@",error);
 };
 //设置渲染完成的回调
 _weexInstance.renderFinish = ^ (UIView *view) {
     //process renderFinish
     NSLog(@"渲染完成");
 };
  //设置weexInstance用于渲染的`js`的URL路径
 [_weexInstance renderWithURL:url options:@{@"bundleUrl":[self.url absoluteString]} data:nil];
}

// 需要在控制器的dealloc方法中销毁WeexInstance否则会导致内存泄露
- (void)dealloc {
//  销毁WXSDKInstance实例
    [self.instance destroyInstance];
}

加载Weex的js文件

weex的js文件一般都是从服务器上加载,如果你不想从服务器上加载weex的js文件,你可以把这些js文件拷贝到工程目录中。

  1. 使用.we文件生成weex的js文件
    终端cd 到 .we文件所在的目录,然后执行
weex  list.we -o list.js

其中list.we 是你的页面对应的weex文件. 在开发中index.we一般指的使用整个App的入口文件. 我们这里使用list.we 文件,生成一个list.js文件

  1. js文件的URL
// 加载本地资源目录中的js文件
[_instance renderWithURL:[[NSBundle mainBundle] URLForResource:@"list"   withExtension:@"js"]];
// 从服务器加载js文件
[_instance renderWithURL:[NSURL URLWithString:@"http://10.0.100.139:8081/weex.js"]];

Weex开发的组件骨架和生命周期

<template>
</template>

<style>
</style>

<script>
  module.exports = {
    data: {},
    methods: {},

    init: function () {
      console.log('在初始化内部变量,并且添加了事件功能后被触发');
    },
    created: function () {
      console.log('完成数据绑定之后,模板编译之前被触发');
    },
    ready: function () {
      console.log('模板已经编译并且生成了 Virtual DOM 之后被触发');
    },
    destroyed: function () {
      console.log('在页面被销毁时调用');
    }
  }
</script>
  • template中主要是组件的引用,大体页面布局。类似于HTML。
  • style中主要是组件的CSS样式引用
  • script中主要就是js的调用。- data属于绑定的数据,init、created、ready是Weex的生命周期方法。
  • methods中存放用户定义的一些js事件。
  • computed中主要是对绑定数据data部分进行预处理。
  • init内一般用于初始化一些内部变量,绑定一些自定义事件,这时还没有数据绑定,没有创建vdom,所以不能通过this获取到data和methods,也不能获取vdom的节点
  • created 完成了数据绑定 ,但还未开始编译模板,可以通过this获取data和methods,但不能获取vdom的节点
  • ready表示渲染完成 ,从子组件往上触发
  • destroyed 组件销毁,比如页面跳转,从子组件开始往上触发

模板(Module)扩展

1、自定义Module

  1. 自定义的module类 必须实现 WXModuleProtocol
  2. 必须添加宏WX_EXPORT_METHO, 这样它才可以被weex识别,它的参数是==JavaScript调用 module指定方法的参数==
  3. 添加@synthesized weexInstance,每个moudle对象被绑定到一个指定的实例上
  4. Module 方法会在UI线程中被调用,所以不要做太多耗时的任务在这里,如果要在其他线程执行整个module 方法,需要实现WXModuleProtocol中- (NSThread *)targetExecuteThread的方法,这样,分发到这个module的任务会在指定的线程中运行
  5. Weex 的参数可以是 String 或者Map
  6. Module 支持返回值给 JavaScript中的回调,回调的类型是WXModuleCallback,回调的参数可以是String或者Map
@implementation WXEventModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(openTLDURL:callback))
- (void)openTLDURL:(NSString *)url callback:(WXModuleCallback)callback {
    NSString *newURL = url;
    if ([url hasPrefix:@"//"]) {
        newURL = [NSString stringWithFormat:@"http:%@", url];
    } else if (![url hasPrefix:@"http"]) {
       newURL = [NSURL URLWithString:url relativeToURL:weexInstance.scriptURL].absoluteString;
    }
    UIViewController *controller = [[WXDemoViewController alloc] init];
    ((WXDemoViewController *)controller).url = [NSURL URLWithString:newURL];
    [[weexInstance.viewController navigationController] pushViewController:controller animated:YES];
    callback(@{@"result":@"success"});
}
@end

2、注册这个Module

通过调用 WXSDKEngine 中的 registerModule:withClass方法来注册自己的module

[WXSDKEngine registerModule:@"tldevent" withClass:[WXEventModule class]];

3、使用这个Module

这里的 require 里面的tldevent 就是在 上一步调用registerModule: 注册module 时候的name

var eventModule = weex.requireModule('tldevent'); 
eventModule.openTLDURL('url',function(ret) {   
    nativeLog(ret);
});

组件(Components)扩展

虽然 WeexSDK 中有很多的 native 的 Component,但这有可能并不能满足需求。如果在之前已经写了一些很酷炫 native 的组件,想包装一下,导入到 Weex 中,可以实现自己的 native Component。(参考官方源码中的WeexPlayGround中的WXSelectComponent)

1、自定义组件

@implementation WXMyComponent
WX_EXPORT_METHOD(@selector(tldfocus)) // 暴露该方法给js
- (instancetype)initWithRef:(NSString *)ref type:(NSString *)type styles:(NSDictionary *)styles attributes:(NSDictionary *)attributes events:(NSArray *)events weexInstance:(WXSDKInstance *)weexInstance
{
    if (self = [super initWithRef:ref type:type styles:styles attributes:attributes events:events weexInstance:weexInstance]) {
        // handle your attributes
        // handle your styles
    }
    
    return self;
}
- (void)tldfocus
{
    NSLog(@"you got it");
}
@end

2、注册组件

[WXSDKEngine registerComponent:@"mycomponent" withClass:[WXMyComponent class]]

3、组件的使用

<template>
  <mycomponent id='mycomponent'></mycomponent>
</template>
<script>
  module.exports = {
    created:function() {
      this.$el('mycomponent').tldfocus();
    }
  }
</script>

协议的实现(handler)

Weex SDK没有图片下载navigation 操作的能力,需要自己实现这些 protocol

1、实现协议(以WXImgLoaderProtocol为例)

#pragma mark - WXImgLoaderProtocol
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image,  NSError *error, BOOL finished))completedBlock
{
    if ([url hasPrefix:@"//"]) {
        url = [@"http:" stringByAppendingString:url];
    }
    return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] downloadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize) {     
    } completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
    if (completedBlock) {
        completedBlock(image, error, finished);
    }
    }];
}

2、handler注册

[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)]

Tips

  1. Weex渲染的时候是按照宽度为750像素标准来渲染的,然后根据屏幕的实际宽度来进行等比例缩放高度,所以会导致Plus系列会高度变大、显示不开,5系列会高度变小、底部有空白。我是根据屏幕实际宽度和scale来计算缩放倍数,然后设置实际的高度的,不知道还有没有其他好的处理方法。(字体也会是这种情况,在5系列上偏小,在Plus系列上偏大)
    var config  = this.$getConfig();
    var env = config.env;
    var scale = env.scale;
    this.realScale = 750/2*scale/env.deviceWidth
    this.rowHeight = this.rowHeight * this.realScale;
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容