blob: 45847c629e1d58573d8501aa37015fc204a4b87f [file] [log] [blame]
/*
* 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 "WXBaseViewController.h"
#import "WXRootViewController.h"
#import "WXSDKInstance.h"
#import "WXSDKInstance_private.h"
#import "WXSDKEngine.h"
#import "WXSDKManager.h"
#import "WXUtility.h"
#import "WXPrerenderManager.h"
#import "WXMonitor.h"
@interface WXBaseViewController ()
@property (nonatomic, strong) WXSDKInstance *instance;
@property (nonatomic, strong) UIView *weexView;
@property (nonatomic, strong) NSURL *sourceURL;
@end
@implementation WXBaseViewController
- (void)dealloc
{
[_instance destroyInstance];
[self _removeObservers];
}
- (instancetype)initWithSourceURL:(NSURL *)sourceURL
{
if ((self = [super init])) {
self.sourceURL = sourceURL;
self.hidesBottomBarWhenPushed = YES;
[self _addObservers];
}
return self;
}
/**
* After setting the navbar hidden status , this function will be called automatically. In this function, we
* set the height of mainView equal to screen height, because there is something wrong with the layout of
* page content.
*/
- (void)viewWillLayoutSubviews
{
[super viewWillLayoutSubviews];
if ([self.navigationController isKindOfClass:[WXRootViewController class]]) {
CGRect frame = self.view.frame;
frame.origin.y = 0;
frame.size.height = [UIScreen mainScreen].bounds.size.height;
self.view.frame = frame;
}
}
/**
* We assume that the initial state of viewController's navigtionBar is hidden. By setting the attribute of
* 'dataRole' equal to 'navbar', the navigationBar hidden will be NO.
*/
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
self.automaticallyAdjustsScrollViewInsets = NO;
[self _renderWithURL:_sourceURL];
if ([self.navigationController isKindOfClass:[WXRootViewController class]]) {
[self.navigationController setNavigationBarHidden:YES animated:YES];
}
}
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self _updateInstanceState:WeexInstanceAppear];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self _updateInstanceState:WeexInstanceDisappear];
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
[self _updateInstanceState:WeexInstanceMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)refreshWeex
{
[self _renderWithURL:_sourceURL];
}
- (void)addEdgePop
{
self.navigationController.interactivePopGestureRecognizer.delegate = self;
}
- (void)_renderWithURL:(NSURL *)sourceURL
{
if (!sourceURL) {
return;
}
[_instance destroyInstance];
_instance = [[WXSDKInstance alloc] init];
if([WXPrerenderManager isTaskReady:[self.sourceURL absoluteString]]){
_instance = [WXPrerenderManager instanceFromUrl:self.sourceURL.absoluteString];
}
_instance.frame = CGRectMake(0.0f, 0.0f, self.view.bounds.size.width, self.view.bounds.size.height);
_instance.pageObject = self;
_instance.pageName = sourceURL.absoluteString;
_instance.viewController = self;
NSString *newURL = nil;
if ([sourceURL.absoluteString rangeOfString:@"?"].location != NSNotFound) {
newURL = [NSString stringWithFormat:@"%@&random=%d", sourceURL.absoluteString, arc4random()];
} else {
newURL = [NSString stringWithFormat:@"%@?random=%d", sourceURL.absoluteString, arc4random()];
}
__weak typeof(self) weakSelf = self;
_instance.onCreate = ^(UIView *view) {
[weakSelf.weexView removeFromSuperview];
weakSelf.weexView = view;
[weakSelf.view addSubview:weakSelf.weexView];
};
_instance.onFailed = ^(NSError *error) {
};
_instance.renderFinish = ^(UIView *view) {
[weakSelf _updateInstanceState:WeexInstanceAppear];
};
[_instance renderWithURL:[NSURL URLWithString:newURL] options:@{@"bundleUrl":sourceURL.absoluteString} data:nil];
if([WXPrerenderManager isTaskReady:[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);
[WXPrerenderManager renderFromCache:[self.sourceURL absoluteString]];
return;
}
}
- (void)_updateInstanceState:(WXState)state
{
if (_instance && _instance.state != state) {
_instance.state = state;
if (state == WeexInstanceAppear) {
[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewappear" params:nil domChanges:nil];
} else if (state == WeexInstanceDisappear) {
[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewdisappear" params:nil domChanges:nil];
}
}
}
- (void)_appStateDidChange:(NSNotification *)notify
{
if ([notify.name isEqualToString:@"UIApplicationDidBecomeActiveNotification"]) {
[self _updateInstanceState:WeexInstanceForeground];
} else if([notify.name isEqualToString:@"UIApplicationDidEnterBackgroundNotification"]) {
[self _updateInstanceState:WeexInstanceBackground]; ;
}
}
- (void)_addObservers
{
for (NSString *name in @[UIApplicationDidBecomeActiveNotification,
UIApplicationDidEnterBackgroundNotification]) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(_appStateDidChange:)
name:name
object:nil];
}
}
- (void)_removeObservers
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
@end