Skip to content

Commit 9d2dd45

Browse files
committed
Update RootViewController.
1 parent 088f85b commit 9d2dd45

File tree

1 file changed

+218
-2
lines changed

1 file changed

+218
-2
lines changed

WebAppWrapper/RootViewController.m

Lines changed: 218 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,113 @@
77
//
88

99
#import "RootViewController.h"
10+
#import "RWebViewController.h"
1011

11-
@interface RootViewController ()
12+
NSString * const kWebAppStartLink = @"http://v2ex.com/";
13+
NSString * const kWebAppHost = @"v2ex.com";
14+
NSUInteger const kWebAppMaxFailRefreshCount = 3;
15+
16+
@interface RootViewController () <UIWebViewDelegate, UIAlertViewDelegate>
17+
18+
@property (nonatomic, strong) NSURL *startURL;
19+
@property (nonatomic, strong) NSString *webAppHost;
20+
@property (nonatomic, strong) NSArray *otherInternalHosts;
21+
@property (nonatomic, strong) NSArray *blockedHosts;
22+
23+
@property (nonatomic, assign) BOOL shouldCheckAuthenticity;
24+
@property (nonatomic, strong) NSString *authenticityCheckQueryJavaScript;
25+
@property (nonatomic, strong) NSString *authenticityCheckResult;
26+
27+
@property (nonatomic, assign) NSUInteger currentFailRefreshCount;
28+
@property (nonatomic, assign) NSUInteger maxFailRefreshCount;
29+
@property (nonatomic, weak) UIAlertView *failLoadAlertView;
30+
31+
@property (nonatomic, strong) UIWebView *webView;
32+
33+
- (void)showFailLoadWarning;
34+
35+
- (void)loadStartPage;
36+
- (void)refresh;
37+
- (void)failRefresh;
38+
39+
- (void)configure;
1240

1341
@end
1442

1543
@implementation RootViewController
1644

45+
#pragma mark - View control
46+
47+
- (void)showFailLoadWarning
48+
{
49+
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", nil)
50+
message:NSLocalizedString(@"An error occurred on loading.", nil)
51+
delegate:self
52+
cancelButtonTitle:NSLocalizedString(@"Quit", nil)
53+
otherButtonTitles:NSLocalizedString(@"Retry", nil), nil];
54+
alertView.delegate = self;
55+
self.failLoadAlertView = alertView;
56+
[alertView show];
57+
}
58+
59+
#pragma mark - Web view control
60+
61+
- (void)loadStartPage
62+
{
63+
NSURLRequest *request = [NSURLRequest requestWithURL:self.startURL];
64+
[self.webView loadRequest:request];
65+
}
66+
67+
- (void)refresh
68+
{
69+
[self.webView reload];
70+
}
71+
72+
- (void)failRefresh
73+
{
74+
if (self.currentFailRefreshCount) {
75+
[self refresh];
76+
self.currentFailRefreshCount--;
77+
} else {
78+
[self showFailLoadWarning];
79+
}
80+
}
81+
82+
- (void)resetFailRefreshCount
83+
{
84+
self.currentFailRefreshCount = self.maxFailRefreshCount;
85+
}
86+
87+
#pragma mark - Life cycle
88+
89+
- (void)configure
90+
{
91+
// Init start URL.
92+
93+
self.startURL = [NSURL URLWithString:kWebAppStartLink];
94+
95+
// Set web app host.
96+
97+
self.webAppHost = kWebAppHost;
98+
99+
// Set other internal hosts.
100+
101+
self.otherInternalHosts = @[
102+
@"about:blank",
103+
@"googleads.g.doubleclick.net"
104+
];
105+
106+
// Set blocked hosts.
107+
108+
self.blockedHosts = @[
109+
];
110+
111+
// Set max fail refresh count.
112+
113+
self.maxFailRefreshCount = kWebAppMaxFailRefreshCount;
114+
[self resetFailRefreshCount];
115+
}
116+
17117
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
18118
{
19119
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
@@ -26,7 +126,24 @@ - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
26126
- (void)viewDidLoad
27127
{
28128
[super viewDidLoad];
29-
// Do any additional setup after loading the view.
129+
130+
[self configure];
131+
132+
// Init & add web view.
133+
134+
self.webView = [[UIWebView alloc] initWithFrame:self.view.bounds];
135+
self.webView.delegate = self;
136+
self.webView.scalesPageToFit = YES;
137+
[self.view addSubview:self.webView];
138+
}
139+
140+
- (void)viewDidAppear:(BOOL)animated
141+
{
142+
[super viewDidAppear:animated];
143+
144+
if (!self.webView.request) {
145+
[self loadStartPage];
146+
}
30147
}
31148

32149
- (void)didReceiveMemoryWarning
@@ -35,4 +152,103 @@ - (void)didReceiveMemoryWarning
35152
// Dispose of any resources that can be recreated.
36153
}
37154

155+
#pragma mark - Web view delegate
156+
157+
- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
158+
{
159+
if (webView == self.webView) {
160+
NSString *host = request.URL.host;
161+
162+
// Determine if the URL is blocked.
163+
164+
__block BOOL isBlocked = NO;
165+
[self.blockedHosts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
166+
NSString *blockedHost = obj;
167+
if (NSMaxRange([host rangeOfString:blockedHost options:(NSCaseInsensitiveSearch | NSBackwardsSearch)]) == host.length) {
168+
isBlocked = YES;
169+
*stop = YES;
170+
}
171+
}];
172+
173+
// Determine if the URL is external.
174+
175+
__block BOOL isExternal = NO;
176+
if (!isBlocked) {
177+
if (NSMaxRange([host rangeOfString:self.webAppHost options:(NSCaseInsensitiveSearch | NSBackwardsSearch)]) != host.length) {
178+
isExternal = YES;
179+
[self.otherInternalHosts enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
180+
NSString *internalHost = obj;
181+
if (NSMaxRange([host rangeOfString:internalHost options:(NSCaseInsensitiveSearch | NSBackwardsSearch)]) == host.length) {
182+
isExternal = NO;
183+
*stop = YES;
184+
}
185+
}];
186+
}
187+
}
188+
189+
// Open in external web view controller if the URL is external.
190+
191+
if (isExternal) {
192+
RWebViewController *externalWebViewController = [[RWebViewController alloc] init];
193+
externalWebViewController.startURL = request.URL;
194+
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:externalWebViewController];
195+
[self presentViewController:navigationController animated:YES completion:nil];
196+
}
197+
198+
return !(isExternal | isBlocked);
199+
}
200+
return YES;
201+
}
202+
203+
- (void)webViewDidFinishLoad:(UIWebView *)webView
204+
{
205+
if (webView == self.webView) {
206+
BOOL success = NO;
207+
208+
// Check authenticity.
209+
210+
if (self.shouldCheckAuthenticity) {
211+
if ([[self.webView stringByEvaluatingJavaScriptFromString:self.authenticityCheckQueryJavaScript] isEqualToString:self.authenticityCheckResult]) {
212+
success = YES;
213+
}
214+
} else {
215+
success = YES;
216+
}
217+
218+
// Refresh on fail.
219+
220+
if (success) {
221+
[self resetFailRefreshCount];
222+
} else {
223+
[self failRefresh];
224+
}
225+
}
226+
}
227+
228+
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
229+
{
230+
if (webView == self.webView) {
231+
[self failRefresh];
232+
}
233+
}
234+
235+
#pragma mark - Alert view delegate
236+
237+
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
238+
{
239+
if (alertView == self.failLoadAlertView) {
240+
switch (buttonIndex) {
241+
case 0: // Quit
242+
abort();
243+
break;
244+
case 1: // Retry
245+
[self resetFailRefreshCount];
246+
[self failRefresh];
247+
break;
248+
default:
249+
break;
250+
}
251+
}
252+
}
253+
38254
@end

0 commit comments

Comments
 (0)