diff --git a/src/ios/CDVWKWebViewEngine.m b/src/ios/CDVWKWebViewEngine.m
index e7e05122..2c1936fc 100644
--- a/src/ios/CDVWKWebViewEngine.m
+++ b/src/ios/CDVWKWebViewEngine.m
@@ -107,6 +107,7 @@ @interface CDVWKWebViewEngine ()
@property (nonatomic, readwrite) CGRect frame;
@property (nonatomic, strong) NSString *userAgentCreds;
@property (nonatomic, assign) BOOL internalConnectionsOnly;
+
@property (nonatomic, readwrite) NSString *CDV_LOCAL_SERVER;
@end
@@ -353,6 +354,14 @@ - (void)pluginInitialize
addObserver:self
selector:@selector(onAppWillEnterForeground:)
name:UIApplicationWillEnterForegroundNotification object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(onSocketError:)
+ name:@"socketUnknownError" object:nil];
+ [[NSNotificationCenter defaultCenter]
+ addObserver:self
+ selector:@selector(onSocketError:)
+ name:@"socketInUseError" object:nil];
NSLog(@"Using Ionic WKWebView");
@@ -417,7 +426,11 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
if (context == KVOContext) {
if (object == [self webView] && [keyPath isEqualToString: @"URL"] && [object valueForKeyPath:keyPath] == nil){
NSLog(@"URL is nil. Reloading WKWebView");
- [(WKWebView*)_engineWebView reload];
+ if ([self.webServer isRunning]) {
+ [(WKWebView*)_engineWebView reload];
+ } else {
+ [self loadErrorPage:nil];
+ }
}
} else {
[super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
@@ -426,11 +439,19 @@ - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(N
- (void)onAppWillEnterForeground:(NSNotification *)notification {
if ([self shouldReloadWebView]) {
- NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
- [(WKWebView*)_engineWebView reload];
+ if ([self.webServer isRunning]) {
+ NSLog(@"%@", @"CDVWKWebViewEngine reloading!");
+ [(WKWebView*)_engineWebView reload];
+ } else {
+ [self loadErrorPage:nil];
+ }
}
}
+- (void)onSocketError:(NSNotification *)notification {
+ [self loadErrorPage:nil];
+}
+
- (BOOL)shouldReloadWebView
{
WKWebView* wkWebView = (WKWebView*)_engineWebView;
@@ -475,17 +496,25 @@ - (id)loadRequest:(NSURLRequest *)request
if ([self.webServer isRunning]) {
return [(WKWebView*)_engineWebView loadRequest:request];
} else {
- NSString* errorHtml = [NSString stringWithFormat:
- @""
- @"
Error"
- @" "
- @"
The App Server is not running.
"
- @"
Close other apps and try again.
"
- @"
"
- @""
- ];
- return [self loadHTMLString:errorHtml baseURL:request.URL];
+ return [self loadErrorPage:request];
+ }
+}
+
+- (id)loadErrorPage:(NSURLRequest *)request
+{
+ if (!request) {
+ request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
}
+ NSString* errorHtml = [NSString stringWithFormat:
+ @""
+ @"Error"
+ @" "
+ @"
Error
"
+ @"
Unable to load app.
"
+ @"
"
+ @""
+ ];
+ return [self loadHTMLString:errorHtml baseURL:request.URL];
}
- (id)loadHTMLString:(NSString *)string baseURL:(NSURL*)baseURL
@@ -744,7 +773,11 @@ - (void)webView:(WKWebView*)theWebView didFailNavigation:(WKNavigation*)navigati
- (void)webViewWebContentProcessDidTerminate:(WKWebView *)webView
{
- [webView reload];
+ if ([self.webServer isRunning]) {
+ [webView reload];
+ } else {
+ [self loadErrorPage:nil];
+ }
}
- (BOOL)defaultResourcePolicyForURL:(NSURL*)url
@@ -815,14 +848,19 @@ - (void) webView:(WKWebView *)webView decidePolicyForNavigationAction:(WKNavigat
-(void)getServerBasePath:(CDVInvokedUrlCommand*)command
{
- [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
+ [self.commandDelegate sendPluginResult:[CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:self.basePath] callbackId:command.callbackId];
}
-(void)setServerBasePath:(CDVInvokedUrlCommand*)command
{
- NSString * path = [command argumentAtIndex:0];
- [self setServerPath:path];
- [(WKWebView*)_engineWebView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]]];
+ NSString * path = [command argumentAtIndex:0];
+ [self setServerPath:path];
+ NSURLRequest * request = [NSURLRequest requestWithURL:[NSURL URLWithString:self.CDV_LOCAL_SERVER]];
+ if ([self.webServer isRunning]) {
+ [(WKWebView*)_engineWebView loadRequest:request];
+ } else {
+ [self loadErrorPage:request];
+ }
}
-(void)setServerPath:(NSString *) path
diff --git a/src/ios/GCDWebServer/Core/GCDWebServer.m b/src/ios/GCDWebServer/Core/GCDWebServer.m
index 4e8f306f..ebb83268 100644
--- a/src/ios/GCDWebServer/Core/GCDWebServer.m
+++ b/src/ios/GCDWebServer/Core/GCDWebServer.m
@@ -461,6 +461,7 @@ - (int)_createListeningSocket:(BOOL)useIPv6
*error = GCDWebServerMakePosixError(errno);
}
GWS_LOG_ERROR(@"Failed binding %s listening socket: %s (%i)", useIPv6 ? "IPv6" : "IPv4", strerror(errno), errno);
+ [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketInUseError" object:nil]];
close(listeningSocket);
}
@@ -713,13 +714,13 @@ - (BOOL)hasSocketError:(int)socket {
int error = 0;
socklen_t len = sizeof(error);
int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
-
+
if (retval != 0 ) {
/* there was a problem getting the error code */
GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
return YES;
}
-
+
if (error != 0) {
GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
return YES;
@@ -727,6 +728,24 @@ - (BOOL)hasSocketError:(int)socket {
return NO;
}
+- (int)socketError:(int)socket {
+ int error = 0;
+ socklen_t len = sizeof(error);
+ int retval = getsockopt(socket, SOL_SOCKET, SO_ERROR, &error, &len);
+
+ if (retval != 0 ) {
+ /* there was a problem getting the error code */
+ GWS_LOG_ERROR(@"error getting socket error code: %s\n", strerror(retval));
+ return retval;
+ }
+
+ if (error != 0) {
+ GWS_LOG_INFO(@"Socket error: %s on socket %d\n", strerror(error), socket);
+ return error;
+ }
+ return 0;
+}
+
- (void)_didEnterBackground:(NSNotification*)notification {
GWS_DCHECK([NSThread isMainThread]);
GWS_LOG_DEBUG(@"Did enter background");
@@ -744,8 +763,14 @@ - (void)_willEnterForeground:(NSNotification*)notification {
}
if ([self isRunning] && ([self hasSocketError:ipv4ListeningSocket] || [self hasSocketError:ipv6ListeningSocket])) {
- [self _stop];
- [self _start:nil];
+ // If error is -1 (unknown) its probably because of port being used by other app, so don't restart in this case as it will fail
+ if ([self socketError:ipv4ListeningSocket] != -1 && [self socketError:ipv6ListeningSocket] != -1) {
+ [self _stop];
+ [self _start:nil];
+ } else {
+ _options = nil;
+ [[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:@"socketUnknownError" object:nil]];
+ }
}
}