close
当前位置: 物联网在线 > 技术文库 > ios >

Weex 是如何在 iOS 客户端上跑起来的(14)

一个Weex界面的主动渲染的过程如下:

- (void)render { CGFloat width = self.view.frame.size.width; [_instance destroyInstance]; _instance = [[WXSDKInstance alloc] init]; _instance.viewController = self; _instance.frame = CGRectMake(self.view.frame.size.width-width, 0, 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) { }; _instance.renderFinish = ^(UIView *view) { [weakSelf updateInstanceState:WeexInstanceAppear]; }; _instance.updateFinish = ^(UIView *view) { }; if (!self.url) { WXLogError(@"error: render url is nil"); return; } NSURL *URL = [self testURL: [self.url absoluteString]]; NSString *randomURL = [NSString stringWithFormat:@"%@%@random=%d",URL.absoluteString,URL.query?@"&":@"?",arc4random()]; [_instance renderWithURL:[NSURL URLWithString:randomURL] options:@{@"bundleUrl":URL.absoluteString} data:nil]; }

由于WXSDKInstance是支持实时刷新,所以在创建的时候需要先销毁掉原来的,再创建一个新的。

WXSDKInstance支持设置各种状态时候的回调callback函数,具体支持哪些状态,可以看上面WXSDKInstance的定义。

Weex支持从本地加载JS,也支持从服务器加载JS。如果从本地加载,那么可以用下面的方法,从本地加载一个JSBundle。

- (void)loadLocalBundle:(NSURL *)url { NSURL * localPath = nil; NSMutableArray * pathComponents = nil; if (self.url) { pathComponents =[NSMutableArray arrayWithArray:[url.absoluteString pathComponents]]; [pathComponents removeObjectsInRange:NSRangeFromString(@"0 3")]; [pathComponents replaceObjectAtIndex:0 withObject:@"bundlejs"]; NSString *filePath = [NSString stringWithFormat:@"%@/%@",[NSBundle mainBundle].bundlePath,[pathComponents componentsJoinedByString:@"/"]]; localPath = [NSURL fileURLWithPath:filePath]; }else { NSString *filePath = [NSString stringWithFormat:@"%@/bundlejs/index.js",[NSBundle mainBundle].bundlePath]; localPath = [NSURL fileURLWithPath:filePath]; } NSString *bundleUrl = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%@/bundlejs/",[NSBundle mainBundle].bundlePath]].absoluteString; [_instance renderWithURL:localPath options:@{@"bundleUrl":bundleUrl} data:nil]; }

最后渲染页面就是通过调用renderWithURL:options:data:做到的。

- (void)renderWithURL:(NSURL *)url options:(NSDictionary *)options data:(id)data { if (!url) { WXLogError(@"Url must be passed if you use renderWithURL"); return; } WXResourceRequest *request = [WXResourceRequest requestWithURL:url resourceType:WXResourceTypeMainBundle referrer:@"" cachePolicy:NSURLRequestUseProtocolCachePolicy]; [self _renderWithRequest:request options:options data:data]; }

在WXSDKInstance调用renderWithURL:options:data:方法的时候,会生成一个WXResourceRequest。NSMutableURLRequest定义如下:

@interface WXResourceRequest : NSMutableURLRequest @property (nonatomic, strong) id taskIdentifier; @property (nonatomic, assign) WXResourceType type; @property (nonatomic, strong) NSString *referrer; @property (nonatomic, strong) NSString *userAgent; @end

WXResourceRequest其实也就是对NSMutableURLRequest的一层封装。

下面来分析一下最核心的函数renderWithURL:options:data:(以下的代码实现在源码的基础上略有删减,源码太长,删减以后并不影响阅读)

- (void)_renderWithRequest:(WXResourceRequest *)request options:(NSDictionary *)options data:(id)data; { NSURL *url = request.URL; _scriptURL = url; _options = options; _jsData = data; NSMutableDictionary *newOptions = [options mutableCopy] ?: [NSMutableDictionary new]; WX_MONITOR_INSTANCE_PERF_START(WXPTJSDownload, self); __weak typeof(self) weakSelf = self; _mainBundleLoader = [[WXResourceLoader alloc] initWithRequest:request]; // 请求完成的回调 _mainBundleLoader.onFinished = ^(WXResourceResponse *response, NSData *data) { __strong typeof(weakSelf) strongSelf = weakSelf; if ([response isKindOfClass:[NSHTTPURLResponse class]] && ((NSHTTPURLResponse *)response).statusCode != 200) { NSError *error = [NSError errorWithDomain:WX_ERROR_DOMAIN code:((NSHTTPURLResponse *)response).statusCode userInfo:@{@"message":@"status code error."}]; if (strongSelf.onFailed) { strongSelf.onFailed(error); } return ; } if (!data) { if (strongSelf.onFailed) { strongSelf.onFailed(error); } return; } NSString *jsBundleString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; if (!jsBundleString) { return; } [strongSelf _renderWithMainBundleString:jsBundleString]; }; // 请求失败的回调 _mainBundleLoader.onFailed = ^(NSError *loadError) { if (weakSelf.onFailed) { weakSelf.onFailed(loadError); } }; [_mainBundleLoader start]; }

上面代码只要就是干了2件事情,第一步,生成了WXResourceLoader,并设置了它的onFinished和onFailed回调。第二步调用了start方法。


(责任编辑:ioter)

用户喜欢...

设计实例 #8:如何在整个热电偶测量范围内检测热电偶并准确检测温度

热电偶参考设计演示了如何在整个热电偶测量范围内检测热电偶并准确检测温度。 该解决方案使用MCP3421 18位模数转换器(ADC)测量热电偶两端的电压。ADC具有内部2.048V基准电压和可编程增益放...


如何在零信任世界中保护医疗保健物联网设备

ISTOCK 目前全球安装了超过1亿台医疗保健物联网设备,到2020年增长到1.61亿,根据Statista的数据,在短短三年内实现了17.2%的复合年增长率(CAGR)。 据埃森哲2017年健康互联网称,医疗保健管理...


如何在便携式设计的电池容量读数中实现更高的准确性

我的狗摩卡(图1)经常喜欢在徒步旅行期间跑到我前面进行一些越野探索。她总是在以后找到我,但有时我开始寻找她很久,所以我想找到一种方法来轻松追踪她的位置。通过Adafruit的展望网站...


数字双胞胎如何在物联网支持的环境中推动创新

动态数字表示或数字双胞胎正在迅速改变行业设计,构建和操作其产品和流程的方式。Gartner预测,到2021年,一半的大型工业公司将使用数字双子机,从而使这些机构的有效性得到10%的提高。...


电动汽车绝缘电阻如何在线检测?

电动汽车是一个复杂的机电一体化产品,其中的许多部件包括动力电池、电机、充电机、能量回收装置、辅助电池充...


对话赛灵思:33年老牌芯片厂如何在AI浪潮里新兴业务年增46%

随着移动互联网红利日渐式微,一个更具备颠覆性、更具备革命性的王朝正悄然来临——人工智能(AI)。在下一个十年里,云计算、机器学习、AI芯片等相关产业将以迅猛的势头持续占领市...


客户投诉器件功耗太大,“元凶”原来是它!

selina 在 周五, 11/24/2017 - 09:48 提交 为什么我的处理器功耗大于数据手册给出的值? 在之前的文章中,我们谈到了一个功耗过小的器件——是的,的确有这种情况——带来麻烦的事情。但这种...


SaaS:从功能、数据到生态以及客户成功的一场变革

不知不觉“终结软件”的呐喊已经走过了近二十年,SaaS已经走进千家万户,人们不再纠结是否要“终结软件”,也没...


华为客户荣获2017全球智慧城市博览会两项大奖两项提名奖

在2017年全球智慧城市博览会上,华为在智慧城市领域的四位客户以他们在提供高质量市民服务、实现可持续发展方面...


迈来芯宣布上线中文官方网站以加速融入中国市场,更好的服务中国客户

全球微电子技术公司——迈来芯(Melexis)宣布,定于2017年11月正式上线中文官方网站。迈来芯电子科技(上海)有限...