Skip to content
This repository has been archived by the owner on Jun 3, 2021. It is now read-only.

+ [ios] ios support prerender #342

Merged
merged 11 commits into from
May 16, 2017
4 changes: 4 additions & 0 deletions ios/playground/WeexDemo/AppDelegate.m
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
#import <WeexSDK/WeexSDK.h>
#import <AVFoundation/AVFoundation.h>
#import <ATSDK/ATManager.h>
#import "WXConfigCenterProtocol.h"
#import "WXConfigCenterDefaultImpl.h"

@interface AppDelegate ()
@end
Expand Down Expand Up @@ -111,6 +113,8 @@ - (void)initWeexSDK

[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
[WXSDKEngine registerHandler:[WXEventModule new] withProtocol:@protocol(WXEventModuleProtocol)];
[WXSDKEngine registerHandler:[WXConfigCenterDefaultImpl new] withProtocol:@protocol(WXConfigCenterProtocol)];


[WXSDKEngine registerComponent:@"select" withClass:NSClassFromString(@"WXSelectComponent")];
[WXSDKEngine registerModule:@"event" withClass:[WXEventModule class]];
Expand Down
25 changes: 25 additions & 0 deletions ios/playground/WeexDemo/WXConfigCenterDefaultImpl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#import <Foundation/Foundation.h>
#import "WXConfigCenterProtocol.h"

@interface WXConfigCenterDefaultImpl : NSObject<WXConfigCenterProtocol>

@end
45 changes: 45 additions & 0 deletions ios/playground/WeexDemo/WXConfigCenterDefaultImpl.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

#import "WXConfigCenterDefaultImpl.h"

@implementation WXConfigCenterDefaultImpl

- (id)configForKey:(NSString *)key defaultValue:(id)defaultValue isDefault:(BOOL *)isDefault
{
NSArray<NSString*>* keys = [key componentsSeparatedByString:@"."];
if ([keys[0] isEqualToString:@"iOS_weex_ext_config"] && [keys[1] isEqualToString:@"text_render_useCoreText"]){
return @YES;
}
if ([keys[0] isEqualToString:@"iOS_weex_ext_config"] && [keys[1] isEqualToString:@"slider_class_name"]){
return @"WXCycleSliderComponent";
}
if ([keys[0] isEqualToString:@"weex_prerender_config"] && [keys[1] isEqualToString:@"is_switch_on"]){
return @YES;
}
if ([keys[0] isEqualToString:@"weex_prerender_config"] && [keys[1] isEqualToString:@"cacheTime"]){
return @300000;
}
if ([keys[0] isEqualToString:@"weex_prerender_config"] && [keys[1] isEqualToString:@"max_cache_num"]){
return @2;
}
return nil;
}

@end
22 changes: 21 additions & 1 deletion ios/playground/WeexDemo/WXDemoViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
#import <WeexSDK/WXSDKManager.h>
#import "UIViewController+WXDemoNaviBar.h"
#import "DemoDefine.h"
#import "WXPrerenderManager.h"
#import "WXMonitor.h"


@interface WXDemoViewController () <UIScrollViewDelegate, UIWebViewDelegate>
Expand Down Expand Up @@ -104,8 +106,8 @@ - (void)didReceiveMemoryWarning {

- (void)dealloc
{
[_instance destroyInstance];

[_instance destroyInstance];
#ifdef DEBUG
[_instance forceGarbageCollection];
#endif
Expand All @@ -118,6 +120,10 @@ - (void)render
CGFloat width = self.view.frame.size.width;
[_instance destroyInstance];
_instance = [[WXSDKInstance alloc] init];
if([WXPrerenderManager isTaskExist:[self.url absoluteString]]){
_instance = [WXPrerenderManager instanceFromUrl:self.url.absoluteString];
}

_instance.viewController = self;
_instance.frame = CGRectMake(self.view.frame.size.width-width, 0, width, _weexHeight);

Expand Down Expand Up @@ -156,6 +162,20 @@ - (void)render
WXLogError(@"error: render url is nil");
return;
}
if([WXPrerenderManager isTaskExist:[self.url absoluteString]]){
WX_MONITOR_INSTANCE_PERF_START(WXPTJSDownload, _instance);
WX_MONITOR_INSTANCE_PERF_END(WXPTJSDownload, _instance);
WX_MONITOR_INSTANCE_PERF_START(WXPTFirstScreenRender, _instance);
WX_MONITOR_INSTANCE_PERF_START(WXPTAllRender, _instance);
UIView *view = [WXPrerenderManager viewFromUrl:self.url.absoluteString];
_instance.onCreate(view);
NSError *error = [WXPrerenderManager errorFromUrl:self.url.absoluteString];
if(error){
_instance.onFailed(error);
}
[WXPrerenderManager renderFromCache:[self.url absoluteString]];
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];
Expand Down
8 changes: 8 additions & 0 deletions ios/sdk/WeexSDK.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,8 @@
C401945E1E344E8300D19C31 /* WXFloatCompareTests.m in Sources */ = {isa = PBXBuildFile; fileRef = C401945D1E344E8300D19C31 /* WXFloatCompareTests.m */; };
C41E1A971DC1FD15009C7F90 /* WXDatePickerManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C41E1A951DC1FD15009C7F90 /* WXDatePickerManager.h */; };
C41E1A981DC1FD15009C7F90 /* WXDatePickerManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C41E1A961DC1FD15009C7F90 /* WXDatePickerManager.m */; };
C43C03E81EC8ACA40044C7FF /* WXPrerenderManager.h in Headers */ = {isa = PBXBuildFile; fileRef = C43C03E41EC8ACA40044C7FF /* WXPrerenderManager.h */; };
C43C03E91EC8ACA40044C7FF /* WXPrerenderManager.m in Sources */ = {isa = PBXBuildFile; fileRef = C43C03E51EC8ACA40044C7FF /* WXPrerenderManager.m */; };
C4B3D6D41E6954300013F38D /* WXEditComponent.h in Headers */ = {isa = PBXBuildFile; fileRef = C4B3D6D21E6954300013F38D /* WXEditComponent.h */; };
C4B3D6D51E6954300013F38D /* WXEditComponent.m in Sources */ = {isa = PBXBuildFile; fileRef = C4B3D6D31E6954300013F38D /* WXEditComponent.m */; };
C4B834271DE69B09007AD27E /* WXPickerModule.m in Sources */ = {isa = PBXBuildFile; fileRef = C4B834251DE69B09007AD27E /* WXPickerModule.m */; };
Expand Down Expand Up @@ -553,6 +555,8 @@
C401945D1E344E8300D19C31 /* WXFloatCompareTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXFloatCompareTests.m; sourceTree = "<group>"; };
C41E1A951DC1FD15009C7F90 /* WXDatePickerManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXDatePickerManager.h; sourceTree = "<group>"; };
C41E1A961DC1FD15009C7F90 /* WXDatePickerManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXDatePickerManager.m; sourceTree = "<group>"; };
C43C03E41EC8ACA40044C7FF /* WXPrerenderManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXPrerenderManager.h; sourceTree = "<group>"; };
C43C03E51EC8ACA40044C7FF /* WXPrerenderManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXPrerenderManager.m; sourceTree = "<group>"; };
C4B3D6D21E6954300013F38D /* WXEditComponent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WXEditComponent.h; sourceTree = "<group>"; };
C4B3D6D31E6954300013F38D /* WXEditComponent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXEditComponent.m; sourceTree = "<group>"; };
C4B834251DE69B09007AD27E /* WXPickerModule.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WXPickerModule.m; sourceTree = "<group>"; };
Expand Down Expand Up @@ -1058,6 +1062,8 @@
77E659D71C07F585008B8775 /* Module */ = {
isa = PBXGroup;
children = (
C43C03E41EC8ACA40044C7FF /* WXPrerenderManager.h */,
C43C03E51EC8ACA40044C7FF /* WXPrerenderManager.m */,
C4F012801E1502E9003378D0 /* WXWebSocketModule.h */,
C4F012811E1502E9003378D0 /* WXWebSocketModule.m */,
C4B834251DE69B09007AD27E /* WXPickerModule.m */,
Expand Down Expand Up @@ -1299,6 +1305,7 @@
59A582D41CF481110081FD3E /* WXAppMonitorProtocol.h in Headers */,
2A44AB111C1AD5B00067A7EA /* WXSliderComponent.h in Headers */,
2A837AB61CD9DE9200AEDF03 /* WXRefreshComponent.h in Headers */,
C43C03E81EC8ACA40044C7FF /* WXPrerenderManager.h in Headers */,
74B232D21D2A2BA4006322EA /* WXLayoutDefine.h in Headers */,
C4B834281DE69B09007AD27E /* WXPickerModule.h in Headers */,
59A596311CB632050012CD52 /* WXRootViewController.h in Headers */,
Expand Down Expand Up @@ -1546,6 +1553,7 @@
77E65A1A1C155F25008B8775 /* WXScrollerComponent.m in Sources */,
747A787D1D1BAAC900DED9D0 /* WXComponent+ViewManagement.m in Sources */,
C4E375371E5FCBD3009B2D9C /* WXComponent+BoxShadow.m in Sources */,
C43C03E91EC8ACA40044C7FF /* WXPrerenderManager.m in Sources */,
2A837AB51CD9DE9200AEDF03 /* WXLoadingIndicator.m in Sources */,
C4F012831E1502E9003378D0 /* WXWebSocketModule.m in Sources */,
59D3CA401CF9ED57008835DC /* Layout.c in Sources */,
Expand Down
5 changes: 5 additions & 0 deletions ios/sdk/WeexSDK/Sources/Bridge/WXBridgeContext.m
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#import "WXModuleMethod.h"
#import "WXCallJSMethod.h"
#import "WXSDKInstance_private.h"
#import "WXPrerenderManager.h"

#define SuppressPerformSelectorLeakWarning(Stuff) \
do { \
Expand Down Expand Up @@ -140,6 +141,10 @@ - (void)registerGlobalFunctions
}

WXModuleMethod *method = [[WXModuleMethod alloc] initWithModuleName:moduleName methodName:methodName arguments:arguments instance:instance];
if(![moduleName isEqualToString:@"dom"] && instance.needPrerender){
[WXPrerenderManager storePrerenderModuleTasks:method forUrl:instance.scriptURL.absoluteString];
return nil;
}
return [method invoke];
}];

Expand Down
23 changes: 22 additions & 1 deletion ios/sdk/WeexSDK/Sources/Controller/WXBaseViewController.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
#import "WXSDKEngine.h"
#import "WXSDKManager.h"
#import "WXUtility.h"
#import "WXPrerenderManager.h"
#import "WXMonitor.h"

@interface WXBaseViewController ()

Expand Down Expand Up @@ -122,8 +124,12 @@ - (void)_renderWithURL:(NSURL *)sourceURL
if (!sourceURL) {
return;
}

[_instance destroyInstance];
if([WXPrerenderManager isTaskExist:[self.sourceURL absoluteString]]){
_instance = [WXPrerenderManager instanceFromUrl:self.sourceURL.absoluteString];
}

_instance = [[WXSDKInstance alloc] init];
_instance.frame = CGRectMake(0.0f, 0.0f, self.view.bounds.size.width, self.view.bounds.size.height);
_instance.pageObject = self;
Expand Down Expand Up @@ -153,6 +159,21 @@ - (void)_renderWithURL:(NSURL *)sourceURL
_instance.renderFinish = ^(UIView *view) {
[weakSelf _updateInstanceState:WeexInstanceAppear];
};

if([WXPrerenderManager isTaskExist:[self.sourceURL absoluteString]]){
WX_MONITOR_INSTANCE_PERF_START(WXPTJSDownload, _instance);
WX_MONITOR_INSTANCE_PERF_END(WXPTJSDownload, _instance);
WX_MONITOR_INSTANCE_PERF_START(WXPTFirstScreenRender, _instance);
WX_MONITOR_INSTANCE_PERF_START(WXPTAllRender, _instance);
UIView *view = [WXPrerenderManager viewFromUrl:self.sourceURL.absoluteString];
_instance.onCreate(view);
NSError *error = [WXPrerenderManager errorFromUrl:self.sourceURL.absoluteString];
if(error){
_instance.onFailed(error);
}
[WXPrerenderManager renderFromCache:[self.sourceURL absoluteString]];
return;
}
}

- (void)_updateInstanceState:(WXState)state
Expand Down
2 changes: 2 additions & 0 deletions ios/sdk/WeexSDK/Sources/Manager/WXBridgeManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
@class WXBridgeMethod;
@class WXSDKInstance;

extern void WXPerformBlockOnBridgeThread(void (^block)());

@interface WXBridgeManager : NSObject

/**
Expand Down
2 changes: 1 addition & 1 deletion ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -177,5 +177,5 @@ extern void WXPerformBlockOnComponentThread(void (^block)());

- (void)_addUITask:(void (^)())block;


- (void)excutePrerenderUITask:(NSString *)url;
@end
28 changes: 26 additions & 2 deletions ios/sdk/WeexSDK/Sources/Manager/WXComponentManager.m
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#import "WXInvocationConfig.h"
#import "WXHandlerFactory.h"
#import "WXValidateProtocol.h"
#import "WXPrerenderManager.h"

static NSThread *WXComponentThread;

Expand All @@ -49,7 +50,8 @@ @implementation WXComponentManager
// access only on component thread
NSMapTable<NSString *, WXComponent *> *_indexDict;
NSMutableArray<dispatch_block_t> *_uiTaskQueue;

NSMutableDictionary *_uiPrerenderTaskQueue;

WXComponent *_rootComponent;
NSMutableArray *_fixedComponents;

Expand Down Expand Up @@ -165,7 +167,29 @@ - (void)_applyRootFrame:(CGRect)rootFrame toRootCSSNode:(css_node_t *)rootCSSNod

- (void)_addUITask:(void (^)())block
{
[_uiTaskQueue addObject:block];
if(!_uiPrerenderTaskQueue){
_uiPrerenderTaskQueue = [NSMutableDictionary new];
}
if(self.weexInstance.needPrerender){
NSMutableArray<dispatch_block_t> *tasks = [_uiPrerenderTaskQueue objectForKey:self.weexInstance.scriptURL.absoluteString];
if(!tasks){
tasks = [NSMutableArray new];
}
[tasks addObject:block];
[_uiPrerenderTaskQueue setObject:tasks forKey:self.weexInstance.scriptURL.absoluteString];
}else{
[_uiTaskQueue addObject:block];
}
}

- (void)excutePrerenderUITask:(NSString *)url
{
NSMutableArray *tasks = [_uiPrerenderTaskQueue objectForKey:self.weexInstance.scriptURL.absoluteString];
for (id block in tasks) {
[_uiTaskQueue addObject:block];
}
tasks = [NSMutableArray new];
[_uiPrerenderTaskQueue setObject:tasks forKey:self.weexInstance.scriptURL.absoluteString];
}

#pragma mark Component Tree Building
Expand Down
5 changes: 5 additions & 0 deletions ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ extern NSString *const bundleUrlOptionKey;
**/
@property (nonatomic, strong) NSString *instanceId;

/**
* Which indicates current instance needs to be prerender or not,default value is false.
**/
@property (nonatomic, assign) BOOL needPrerender;

/**
* The state of current instance.
**/
Expand Down
6 changes: 6 additions & 0 deletions ios/sdk/WeexSDK/Sources/Model/WXSDKInstance.m
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#import "WXConfigCenterProtocol.h"
#import "WXTextComponent.h"
#import "WXConvert.h"
#import "WXPrerenderManager.h"

NSString *const bundleUrlOptionKey = @"bundleUrl";

Expand Down Expand Up @@ -317,11 +318,16 @@ - (void)refreshInstance:(id)data

- (void)destroyInstance
{
if([WXPrerenderManager isTaskExist:[self.scriptURL absoluteString]]) {
return;
}
if (!self.instanceId) {
WXLogError(@"Fail to find instance!");
return;
}

[WXPrerenderManager destroyTask:self.instanceId];

[[WXSDKManager bridgeMgr] destroyInstance:self.instanceId];

if (_componentManager) {
Expand Down
Loading