Weex開發(fā) [iOS]

[TOC]

初始化Weex環(huán)境

  • WXSDKEngine:SDK開放的絕大多數(shù)接口都在此有聲明。
  • WXLog: 控制Log輸出的級(jí)別,包括Verbose、Debug娃惯、Info、Warning肥败、Error趾浅,開發(fā)者可以按需來設(shè)置輸出級(jí)別。
  • WXDebugTool: weex提供的對外調(diào)試工具馒稍。
  • WXAppConfiguration: 使用weex開發(fā)的業(yè)務(wù)性配置皿哨。

在AppDelegate的didFinishLaunchingWithOptions方法中進(jìn)行初始化設(shè)置

// 業(yè)務(wù)配置,非必需
[WXAppConfiguration setAppGroup:@"itheimaApp"];
[WXAppConfiguration setAppName:@"WeexDemo"];
[WXAppConfiguration setAppVersion:@"3.2.0"];
// 初始化`WeexSDK`環(huán)境
[WXSDKEngine initSDKEnviroment];
// 注冊自定義組件和模型纽谒,非必需 [如果有就注冊如果沒有就不注冊]
[WXSDKEngine registerComponent:@"YourView" withClass:[MyViewComponent class]];
[WXSDKEngine registerModule:@"YourModule" withClass:[YourModule class]];
// 注冊協(xié)議的實(shí)現(xiàn)類证膨,非必需
[WXSDKEngine registerHandler:[WXNavigationDefaultImpl new] withProtocol:@protocol(WXNavigationProtocol)];
//設(shè)置Log輸出等級(jí):調(diào)試環(huán)境默認(rèn)為Debug,正式發(fā)布會(huì)自動(dòng)關(guān)閉鼓黔。
[WXLog setLogLevel:WXLogLevelDebug];

渲染W(wǎng)eex實(shí)例

  1. 聲明屬性instance
// WXSDKInstance屬性
@property (nonatomic, strong) WXSDKInstance *weexInstance;
// Weex視圖
@property (weak, nonatomic) UIView *weexView;
  1. 創(chuàng)建WXSDKInstance 對象,并進(jìn)行相關(guān)設(shè)置央勒。
    WXSDKInstance酱吝,就是weex渲染的實(shí)例對象喻圃。它提供給開發(fā)者諸多跟頁面渲染相關(guān)的接口,包括renderWithURL娱俺、refreshInstance以及destroyInstance等缎谷,提供了幾個(gè)比較重要的回調(diào)接口井濒,方便開發(fā)者根據(jù)不同的業(yè)務(wù)場景去處理他們的邏輯,如onfailed慎陵,還提供了性能監(jiān)控相關(guān)的接口眼虱。
- (void)renderWeexWithURL:(NSString *)url 
{
// 創(chuàng)建WXSDKInstance對象
 _weexInstance = [[WXSDKInstance alloc] init];
 // 設(shè)置weexInstance所在的控制器
 _weexInstance.viewController = self;
 //設(shè)置weexInstance的frame
 _weexInstance.frame = self.view.frame;
 __weak typeof(self) weakSelf = self;
 //設(shè)置weexInstance創(chuàng)建完畢回調(diào)
 _weexInstance.onCreate = ^(UIView *view) {
      weakSelf.weexView = view;
     [weakSelf.weexView removeFromSuperview];
     [weakSelf.view addSubview:weakSelf.weexView];
 };
 // 設(shè)置weexInstance出錯(cuò)的回調(diào)
 _weexInstance.onFailed = ^(NSError *error) {
     //process failure
     NSLog(@"處理失敗:%@",error);
 };
 //設(shè)置渲染完成的回調(diào)
 _weexInstance.renderFinish = ^ (UIView *view) {
     //process renderFinish
     NSLog(@"渲染完成");
 };
  //設(shè)置weexInstance用于渲染的`js`的URL路徑
 [_weexInstance renderWithURL:url options:@{@"bundleUrl":[self.url absoluteString]} data:nil];
}

// 需要在控制器的dealloc方法中銷毀WeexInstance否則會(huì)導(dǎo)致內(nèi)存泄露
- (void)dealloc {
//  銷毀WXSDKInstance實(shí)例
    [self.instance destroyInstance];
}

加載Weex的js文件

weex的js文件一般都是從服務(wù)器上加載,如果你不想從服務(wù)器上加載weex的js文件,你可以把這些js文件拷貝到工程目錄中。

  1. 使用.we文件生成weex的js文件
    終端cd 到 .we文件所在的目錄,然后執(zhí)行
weex  list.we -o list.js

其中l(wèi)ist.we 是你的頁面對應(yīng)的weex文件. 在開發(fā)中index.we一般指的使用整個(gè)App的入口文件. 我們這里使用list.we 文件,生成一個(gè)list.js文件

  1. js文件的URL
// 加載本地資源目錄中的js文件
[_instance renderWithURL:[[NSBundle mainBundle] URLForResource:@"list"   withExtension:@"js"]];
// 從服務(wù)器加載js文件
[_instance renderWithURL:[NSURL URLWithString:@"http://10.0.100.139:8081/weex.js"]];

Weex開發(fā)的組件骨架和生命周期

<template>
</template>

<style>
</style>

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

    init: function () {
      console.log('在初始化內(nèi)部變量席纽,并且添加了事件功能后被觸發(fā)');
    },
    created: function () {
      console.log('完成數(shù)據(jù)綁定之后,模板編譯之前被觸發(fā)');
    },
    ready: function () {
      console.log('模板已經(jīng)編譯并且生成了 Virtual DOM 之后被觸發(fā)');
    },
    destroyed: function () {
      console.log('在頁面被銷毀時(shí)調(diào)用');
    }
  }
</script>
  • template中主要是組件的引用撞蚕,大體頁面布局润梯。類似于HTML。
  • style中主要是組件的CSS樣式引用
  • script中主要就是js的調(diào)用甥厦。- data屬于綁定的數(shù)據(jù)纺铭,init、created刀疙、ready是Weex的生命周期方法舶赔。
  • methods中存放用戶定義的一些js事件。
  • computed中主要是對綁定數(shù)據(jù)data部分進(jìn)行預(yù)處理谦秧。
  • init內(nèi)一般用于初始化一些內(nèi)部變量竟纳,綁定一些自定義事件撵溃,這時(shí)還沒有數(shù)據(jù)綁定,沒有創(chuàng)建vdom锥累,所以不能通過this獲取到data和methods缘挑,也不能獲取vdom的節(jié)點(diǎn)
  • created 完成了數(shù)據(jù)綁定 ,但還未開始編譯模板桶略,可以通過this獲取data和methods语淘,但不能獲取vdom的節(jié)點(diǎn)
  • ready表示渲染完成 ,從子組件往上觸發(fā)
  • destroyed 組件銷毀际歼,比如頁面跳轉(zhuǎn)惶翻,從子組件開始往上觸發(fā)

模板(Module)擴(kuò)展

1、自定義Module

  1. 自定義的module類 必須實(shí)現(xiàn) WXModuleProtocol
  2. 必須添加宏WX_EXPORT_METHO, 這樣它才可以被weex識(shí)別鹅心,它的參數(shù)是==JavaScript調(diào)用 module指定方法的參數(shù)==
  3. 添加@synthesized weexInstance吕粗,每個(gè)moudle對象被綁定到一個(gè)指定的實(shí)例上
  4. Module 方法會(huì)在UI線程中被調(diào)用,所以不要做太多耗時(shí)的任務(wù)在這里巴帮,如果要在其他線程執(zhí)行整個(gè)module 方法溯泣,需要實(shí)現(xiàn)WXModuleProtocol中- (NSThread *)targetExecuteThread的方法,這樣榕茧,分發(fā)到這個(gè)module的任務(wù)會(huì)在指定的線程中運(yùn)行
  5. Weex 的參數(shù)可以是 String 或者M(jìn)ap
  6. Module 支持返回值給 JavaScript中的回調(diào)垃沦,回調(diào)的類型是WXModuleCallback,回調(diào)的參數(shù)可以是String或者M(jìn)ap
@implementation WXEventModule
@synthesize weexInstance;
WX_EXPORT_METHOD(@selector(openTLDURL:callback))
- (void)openTLDURL:(NSString *)url callback:(WXModuleCallback)callback {
    NSString *newURL = url;
    if ([url hasPrefix:@"http://"]) {
        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、注冊這個(gè)Module

通過調(diào)用 WXSDKEngine 中的 registerModule:withClass方法來注冊自己的module

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

3用押、使用這個(gè)Module

這里的 require 里面的tldevent 就是在 上一步調(diào)用registerModule: 注冊module 時(shí)候的name

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

組件(Components)擴(kuò)展

雖然 WeexSDK 中有很多的 native 的 Component肢簿,但這有可能并不能滿足需求。如果在之前已經(jīng)寫了一些很酷炫 native 的組件蜻拨,想包裝一下池充,導(dǎo)入到 Weex 中,可以實(shí)現(xiàn)自己的 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>

協(xié)議的實(shí)現(xiàn)(handler)

Weex SDK沒有圖片下載卧惜,navigation 操作的能力,需要自己實(shí)現(xiàn)這些 protocol

1夹纫、實(shí)現(xiàn)協(xié)議(以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:@"http://"]) {
        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渲染的時(shí)候是按照寬度為750像素標(biāo)準(zhǔn)來渲染的,然后根據(jù)屏幕的實(shí)際寬度來進(jìn)行等比例縮放高度舰讹,所以會(huì)導(dǎo)致Plus系列會(huì)高度變大茅姜、顯示不開,5系列會(huì)高度變小月匣、底部有空白钻洒。我是根據(jù)屏幕實(shí)際寬度和scale來計(jì)算縮放倍數(shù)奋姿,然后設(shè)置實(shí)際的高度的,不知道還有沒有其他好的處理方法航唆。(字體也會(huì)是這種情況胀蛮,在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;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糯钙,一起剝皮案震驚了整個(gè)濱河市粪狼,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌任岸,老刑警劉巖再榄,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異享潜,居然都是意外死亡困鸥,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門剑按,熙熙樓的掌柜王于貴愁眉苦臉地迎上來疾就,“玉大人,你說我怎么就攤上這事艺蝴♀” “怎么了?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵猜敢,是天一觀的道長姑荷。 經(jīng)常有香客問我,道長缩擂,這世上最難降的妖魔是什么鼠冕? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮胯盯,結(jié)果婚禮上懈费,老公的妹妹穿的比我還像新娘。我一直安慰自己博脑,他們只是感情好楞捂,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著趋厉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪胶坠。 梳的紋絲不亂的頭發(fā)上君账,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天,我揣著相機(jī)與錄音沈善,去河邊找鬼乡数。 笑死椭蹄,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的净赴。 我是一名探鬼主播绳矩,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼玖翅!你這毒婦竟也來了翼馆?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤金度,失蹤者是張志新(化名)和其女友劉穎应媚,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體猜极,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡中姜,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了跟伏。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片丢胚。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖受扳,靈堂內(nèi)的尸體忽然破棺而出携龟,到底是詐尸還是另有隱情,我是刑警寧澤辞色,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布骨宠,位于F島的核電站,受9級(jí)特大地震影響相满,放射性物質(zhì)發(fā)生泄漏层亿。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一立美、第九天 我趴在偏房一處隱蔽的房頂上張望匿又。 院中可真熱鬧,春花似錦建蹄、人聲如沸碌更。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽痛单。三九已至,卻和暖如春劲腿,著一層夾襖步出監(jiān)牢的瞬間旭绒,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留挥吵,地道東北人重父。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像忽匈,于是被迫代替她去往敵國和親房午。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容