1. 程式人生 > >weex-自定義module,實現weex在iOS的本地化,js之間互相跳轉,互動,傳值(iOS接入weex的最佳方式)

weex-自定義module,實現weex在iOS的本地化,js之間互相跳轉,互動,傳值(iOS接入weex的最佳方式)

博主學習weex也有一段日子了,以前寫的Demo都是屬於純weex的,最多就是把所有的js檔案引入Xcode專案中,通過載入本地的js檔案的方式來實現專案,但也僅僅只存在一個VC,相當於是內嵌了網頁的app,當然,weex的效能要好很多。
那麼接下來,博主將向大家展示怎麼通過weex的js檔案實現不同的VC之間的互動,以及Xcode和weex的互動:
1.自定義module,實現push方法(在這樣的專案環境,navagator肯定是不能用的)

#import <Foundation/Foundation.h>
#import <WeexSDK/WeexSDK.h>
@interface WXEventModule : NSObject <WXModuleProtocol> @end #import "WXEventModule.h" #import "HomeBigViewController.h" @implementation WXEventModule @synthesize weexInstance; WX_EXPORT_METHOD(@selector(push:)) //WX_EXPORT_METHOD(@selector(pop)) //WX_EXPORT_METHOD(@selector(present:)) //WX_EXPORT_METHOD(@selector(dismiss))
// //WX_EXPORT_METHOD(@selector(postGlobalEvent::)) - (void)anotherOpenURL:(NSString *)url callback:(WXKeepAliveCallback)callback { callback(url,false); NSLog(@"call me"); } - (void)openURL:(NSString *)url { NSString *newURL = url; if ([url hasPrefix:@"//"]) { newURL = [NSString
stringWithFormat:@"http:%@", url]; } else if (![url hasPrefix:@"http"]) { // relative path newURL = [NSURL URLWithString:url relativeToURL:weexInstance.scriptURL].absoluteString; } UIViewController *controller = [[HomeBigViewController alloc] init]; ((HomeBigViewController *)controller).url = [NSURL URLWithString:newURL]; [[weexInstance.viewController navigationController] pushViewController:controller animated:YES]; } - (void)push:(NSString *)url { [self openURL:url]; }

2.如上,push方法已經定義完畢,你可以在weex裡面來直接使用了,但是在此之前需要在Xcode的Appdelegate中註冊module:

//第一個名字你可以隨便取,總之用的時候需要一樣,後面的類名要和類名一致
    [WXSDKEngine registerModule:@"WXEventModule" withClass:NSClassFromString(@"WXEventModule")];

3.如何在weex中使用這個push方法

//這是weex裡的一個方法,WXEventModule是我們註冊的名字,然後直接拉起push方法
bigAction(index){
   console.log('will jump')
   weex.requireModule("WXEventModule").push("homeBig.js");
},

也許你已經注意到了,push裡是一個js檔案的名字,沒錯,這裡直接穿入你要跳轉的js的檔名,路徑不需要了,在Xcode裡面做處理;同時引數只有一個,如果需要傳遞引數有兩種辦法:
!)storage;
!!)在push中增加引數,比如:

//需要變動的地方
WX_EXPORT_METHOD(@selector(push:ids:))


- (void)push:(NSString *)url ids:(NSString *)ID
{
    [self openURL:url ];
}
//這裡要提出的是如果還有其他原生需求的話這樣的互動是沒問題的,但是如果全是這樣的js載入的介面,還是用storage的好,傳過來資料會對VC造成影響,具體看下面;

4.這是重頭戲,VC怎麼來寫?不可能我們一個js對應一個單獨的VC,當然,這樣寫也可以,但是會很麻煩,這裡分為兩種情況:
!)全是js檔案載入的介面;
!!)有weex的js介面,也有原生的介面;
如果有些功能需要用原生介面實現,並傳遞到原生介面,上面寫到的傳值就是最合適的方法,但是如果都是js介面則這樣的傳值毫無意義,因為你把從js拿到的值在新的VC再把值傳給已經寫好的js介面,且不說實現的問題,繞了一圈又把資料傳給weex是不是很麻煩,所以weex之間傳值建議storage,即使在Xcode中,因為集成了weex環境,依然支援storage,但僅限於weex的js之間。

下面來說這個VC怎麼寫,所有的js都用這個VC來載入:

#import <UIKit/UIKit.h>

@interface HomeBigViewController : UIViewController
@property (nonatomic, strong) NSURL *url;


@end



#import "HomeBigViewController.h"
#import <WeexSDK/WXSDKInstance.h>

@interface HomeBigViewController ()

@property (nonatomic, strong) WXSDKInstance *instance;
@property (nonatomic, strong) UIView *weexView;
@property (nonatomic, assign) CGFloat weexHeight;
@property (nonatomic, assign) CGFloat top;

@end

@implementation HomeBigViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    self.view.backgroundColor = [UIColor whiteColor];
    if (!self.navigationController.navigationBar.hidden) {
        _top = CGRectGetMaxY(self.navigationController.navigationBar.frame);
    } else{
        _top = CGRectGetMaxY([[UIApplication sharedApplication]statusBarFrame]);
    }
    _weexHeight = self.view.frame.size.height - _top;
    [self render];
}

- (void)dealloc
{
    [_instance destroyInstance];
}
- (void)viewWillAppear:(BOOL)animated
{
    [self.navigationController.navigationBar setHidden:YES];
    [UIApplication sharedApplication].statusBarStyle = UIStatusBarStyleDefault;
    self.navigationController.navigationBar.barTintColor = [UIColor whiteColor];
    self.navigationController.navigationBar.titleTextAttributes = @{NSForegroundColorAttributeName:[UIColor blueColor]};
    [self.navigationController.navigationBar setBackgroundImage:[[UIImage alloc] init] forBarMetrics:UIBarMetricsDefault];
}
- (void)render
{
    _instance = [[WXSDKInstance alloc] init];
    _instance.viewController = self;
    CGFloat width = self.view.frame.size.width;
    _instance.frame = CGRectMake(self.view.frame.size.width-width,_top, width, _weexHeight);

    __weak typeof(self) weakSelf = self;
    _instance.onCreate = ^(UIView *view) {
        [weakSelf.weexView removeFromSuperview];
        weakSelf.weexView = view;
        [weakSelf.view addSubview:weakSelf.weexView];
        UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, weakSelf.weexView);
    };
    _instance.onFailed = ^(NSError *error) {
        NSLog(@"failed %@",error);
    };

    _instance.renderFinish = ^(UIView *view) {
        NSLog(@"render finish");
    };

    _instance.updateFinish = ^(UIView *view) {
        NSLog(@"update Finish");
    };
    [_instance renderWithURL:_url options:@{@"bundleUrl": [NSString stringWithFormat:@"file://%@/bundlejs/components/",[NSBundle mainBundle].bundlePath]} data:nil];
}


- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

除了對自定義module的描述,還有一個載入圖片的註冊,使用SDWebImage3.7.5,版本太高找不到方法:

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

以上,學好,基本上weex算是入了個門了,接下來的問題就是封裝,樣式和對ES的瞭解了,到這裡,你寫的weex可以按照這種辦法接入iOS專案裡面了,這只是一種方式,方便做其他的原生處理,如果你自信純weex沒問題也可以直接用純weex的包。

總結:部落格寫到這裡,博主的weex學習道路也算告一段落了,如果你都看完了博主weex方面的部落格,你也已經入門了,恭喜你,可以開始你的weex開發之路了。但這並不是終點,以後還會不定期更新,下一步,博主由於公司業務又要轉戰到華為的快應用開發,也許很快,關於快應用的坑和技術點博主就要開始更新了,歡迎大家閱讀,一起學習。