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中主要是组件的引用,大体页面布局。类似于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、组件的使用



协议的实现(handler)

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

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

#pragma mark - WXImgLoaderProtocol
- (id)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)[[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;

你可能感兴趣的:(Weex开发 [iOS])