Weex在iOS端的加載流程與一些問題

開篇

年后換工作開始接手Weex,開貼記錄下Weex相關(guān)的知識。本篇文章主要介紹一下WeexSDK在原生項(xiàng)目中大致的加載順序,從項(xiàng)目的啟動到界面渲染結(jié)束所走的主要流程。后續(xù)會放上項(xiàng)目中遇到的更多問題。
項(xiàng)目的啟動順序

AppDelegate 在
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

中設(shè)置入口頁
比如:ActiveViewController
在ActiveViewController中 根據(jù)APP是否初次安裝,判斷安裝引導(dǎo)頁、啟動頁

啟動頁結(jié)束后 啟動WeexSDK
[WeexSDKManager setup];

之后根據(jù)是否有手勢密碼和登陸狀態(tài)判斷是否顯示密碼驗(yàn)證頁面。
WeexSDKManager 啟動頁面的設(shè)置

初始化WeexSDK handler、module、componet組件的注冊。(在這里暴露自己封裝的相關(guān)的=module、componet組件名稱供Weex調(diào)用)

項(xiàng)目入口WXRootViewController

根據(jù)自己的調(diào)試需要設(shè)置.js文件的加載路徑,然后傳入加載需要的url進(jìn)入設(shè)置的Controller,在這里進(jìn)行頁面的適配,url的渲染進(jìn)行加載拿到的url,以此為真正的入口進(jìn)入到WeexSDK源碼中。

    [[UIApplication sharedApplication] delegate].window.rootViewController = [[WXRootViewController alloc] initWithRootViewController:demo];

設(shè)置WXRootViewController 在WXRootViewController加載url時設(shè)置

- (id)initWithSourceURL:(NSURL *)sourceURL
{
    WXBaseViewController *baseViewController = [[WXBaseViewController alloc]initWithSourceURL:sourceURL];
    
    return [super initWithRootViewController:baseViewController];
}
WXBaseViewController

作為BaseViewController 每次頁面渲染都會進(jìn)入到當(dāng)前頁面,我們在頁面中設(shè)置iPhone X的適配等,并且根據(jù)不同的需要手動對特定的頁面進(jìn)行刷新渲染(舉例:以通知的形式刷新頁面,或者根據(jù)某個.js文件的名稱對刷新操作做處理)。
并由此對 進(jìn)行 _instance = [[WXSDKInstance alloc] init];進(jìn)入具體的網(wǎng)址渲染操作。

WXSDKInstance 加載與源碼修改設(shè)置

WXSDKInstance的加載與設(shè)置主要通過下列三個方法進(jìn)行,拿到的url進(jìn)行加載然后對url根據(jù)我們不同的需要進(jìn)行設(shè)置,渲染成功之后,根據(jù)需要添加我們需要的操作

- (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data;
- (void)_renderWithRequest:(WXResourceRequest *)request options:(NSDictionary *)options data:(id)data{
/*******  這里進(jìn)行加載方式的路徑切換  ******/
//    //如果加載的是本地包
//    NSURL *url;
//    if ([request.URL.absoluteString containsString:[NSBundle mainBundle].bundlePath]) {
//        url = request.URL;
//    }else{
//        url = [NSURL URLWithString:[self fileWithString:request.URL.absoluteString]];
//    }
//    request.URL = url;
    
    //如果加載的是線上的
        NSURL *url = request.URL;

...

}

- (void)_renderWithMainBundleString:(NSString *)mainBundleString{

...

   [WXSDKEngine registerDefaults];
   [[NSNotificationCenter defaultCenter] postNotificationName:WX_SDKINSTANCE_WILL_RENDER object:self];//渲染即將完成的標(biāo)識
....
//需要在加載完成之后進(jìn)行個人操作
....


}

至于 自定義 module與Component 擴(kuò)展 官方給了詳細(xì)的介紹

項(xiàng)目中的問題:

1.APP殺死軟件收到url形式的通知,點(diǎn)擊無法打開對應(yīng)的網(wǎng)址

收到推送消息之后以通知的形式發(fā)送給Weex前端,來用來控制頁面的跳轉(zhuǎn)。

    省略代碼...
   if (userInfo[@"url"]) {
        NSDictionary * item = @{
                                @"param":userInfo
                                };
        [[NSNotificationCenter defaultCenter] postNotificationName:@"push_moudle" object:self userInfo:item];
    }

當(dāng)軟件是啟動狀態(tài)是,收到推送發(fā)送通知,頁面正常跳轉(zhuǎn),APP殺死的情況下,由于打開APP直接走AppDelegate中的

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

進(jìn)行發(fā)送通知,此時WeexSDK尚未啟動成功,所以Weex尚未注冊通知成功,無法進(jìn)行對應(yīng)的跳轉(zhuǎn)。
解決方案:在WXSDKInstance渲染加載結(jié)束之后,做2-3秒的延遲,拿到收到的遠(yuǎn)程推送發(fā)送推送消息,此時WeexSDK已啟動成功收到推送消息

2.由Weex頁面進(jìn)入到H5頁面或原生界面,返回之后Weex頁面不刷新

在WXBaseViewController中進(jìn)行設(shè)置根據(jù)不同的需求設(shè)置方式大致分為兩種

  • 在生命周期將要出現(xiàn)的時候判斷如果包含某個特定的.js文件對當(dāng)前頁面進(jìn)行刷新
-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    if ([self.navigationController isKindOfClass:[WXRootViewController class]]) {
        [self.navigationController setNavigationBarHidden:YES animated:YES];
    }
    if ([_sourceURL.absoluteString containsString:@"myWeb.js"]) {
        [self _renderWithURL:_sourceURL];
    }
}
  • 通知方式刷新界面,收到通知重新渲染界面調(diào)用如下方法
[self _renderWithURL:_sourceURL];

3.線上打包與本地打包

線上打包:包括測試環(huán)境下的本地起服務(wù)加載與正式的線上加載,主要特點(diǎn)是不依賴本地的Views文件,實(shí)現(xiàn)熱更新,加載的內(nèi)容由線上網(wǎng)址返回的.js文件決定。主要入口是本地bundlejs文件下的index.js文件。頁面的顯示的前提是必須有線上服務(wù)或者有本地服務(wù)在運(yùn)行。
在WXSDKInstance中

- (void)_renderWithRequest:(WXResourceRequest *)request options:(NSDictionary *)options data:(id)data;
  //直接渲染網(wǎng)絡(luò)url
    request.URL = url;
    .....
}

本地打包:不依賴于線上的網(wǎng)址,將項(xiàng)目中用到的.js文件所在的Views文件夾放到項(xiàng)目中,對文件的加載路徑進(jìn)行處理,直接由index.js作為入口訪問,本地Views文件夾下的.js文件實(shí)現(xiàn)頁面的加載。不需要起本地服務(wù)于線上服務(wù)的運(yùn)行。
在WXSDKInstance中

- (void)_renderWithRequest:(WXResourceRequest *)request options:(NSDictionary *)options data:(id)data;
方法中 

  //如果加載的是本地包
    NSURL *url;
    if ([request.URL.absoluteString containsString:[NSBundle mainBundle].bundlePath]) {
        url = request.URL;
    }else{
        url = [NSURL URLWithString:[self fileWithString:request.URL.absoluteString]];
    }
    request.URL = url;
    .....
}
//路徑處理
-(NSString*)fileWithString:(NSString*)str{
    str = [str componentsSeparatedByString:@"?"].firstObject;
    NSString* string = [NSString stringWithFormat:@"file://%@%@",[NSBundle mainBundle].bundlePath,str];
    if ([string containsString:@"dist/"]) {
        string = [string stringByReplacingOccurrencesOfString:@"dist" withString:@"bundlejs"];
    }
    return string;
}

后記

Weex一定程度上減少了原生的開發(fā)工作量,但是也有許多需要與原生交互的東西,作為第一篇記錄一下,以后有時間持續(xù)更新,希望分享更多Weex相關(guān)的內(nèi)容。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容