diff --git a/Limelight/ViewControllers/MainFrameViewController.m b/Limelight/ViewControllers/MainFrameViewController.m
index beada0b..de72e18 100644
--- a/Limelight/ViewControllers/MainFrameViewController.m
+++ b/Limelight/ViewControllers/MainFrameViewController.m
@@ -62,7 +62,7 @@ static NSMutableSet* hostList;
[self->_pairAlert addAction:[UIAlertAction actionWithTitle:@"Cancel" style:UIAlertActionStyleDestructive handler:^(UIAlertAction* action) {
self->_pairAlert = nil;
[self->_discMan startDiscovery];
- [self hideLoadingFrame];
+ [self hideLoadingFrame: nil];
}]];
[[self activeViewController] presentViewController:self->_pairAlert animated:YES completion:nil];
});
@@ -76,10 +76,12 @@ static NSMutableSet* hostList;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"]];
}]];
[failedDialog addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
- [[self activeViewController] presentViewController:failedDialog animated:YES completion:nil];
+
+ [self hideLoadingFrame: ^{
+ [[self activeViewController] presentViewController:failedDialog animated:YES completion:nil];
+ }];
[_discMan startDiscovery];
- [self hideLoadingFrame];
}
- (void)pairFailed:(NSString *)message {
@@ -124,7 +126,7 @@ static NSMutableSet* hostList;
[self.navigationController.navigationBar setNeedsLayout];
[self updateAppsForHost:host];
- [self hideLoadingFrame];
+ [self hideLoadingFrame: nil];
});
}
Log(LOG_I, @"Using cached app list: %d", usingCachedAppList);
@@ -139,8 +141,6 @@ static NSMutableSet* hostList;
if (appListResp == nil || ![appListResp isStatusOk] || [appListResp getAppList] == nil) {
Log(LOG_W, @"Failed to get applist: %@", appListResp.statusMessage);
dispatch_async(dispatch_get_main_queue(), ^{
- [self hideLoadingFrame];
-
if (host != self->_selectedHost) {
return;
}
@@ -152,7 +152,9 @@ static NSMutableSet* hostList;
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://github.com/moonlight-stream/moonlight-docs/wiki/Troubleshooting"]];
}]];
[applistAlert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
- [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil];
+ [self hideLoadingFrame: ^{
+ [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil];
+ }];
host.online = NO;
[self showHostSelectionView];
});
@@ -170,7 +172,7 @@ static NSMutableSet* hostList;
[self updateAppsForHost:host];
[self->_appManager stopRetrieving];
[self->_appManager retrieveAssetsFromHost:host];
- [self hideLoadingFrame];
+ [self hideLoadingFrame: nil];
});
}
});
@@ -298,8 +300,6 @@ static NSMutableSet* hostList;
if (serverInfoResp == nil || ![serverInfoResp isStatusOk]) {
Log(LOG_W, @"Failed to get server info: %@", serverInfoResp.statusMessage);
dispatch_async(dispatch_get_main_queue(), ^{
- [self hideLoadingFrame];
-
if (host != self->_selectedHost) {
return;
}
@@ -315,7 +315,9 @@ static NSMutableSet* hostList;
if (view != nil) {
// Only display an alert if this was the result of a real
// user action, not just passively entering the foreground again
- [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil];
+ [self hideLoadingFrame: ^{
+ [[self activeViewController] presentViewController:applistAlert animated:YES completion:nil];
+ }];
}
host.online = NO;
@@ -338,8 +340,9 @@ static NSMutableSet* hostList;
else {
// Not user action, so just return to host screen
dispatch_async(dispatch_get_main_queue(), ^{
- [self hideLoadingFrame];
- [self showHostSelectionView];
+ [self hideLoadingFrame:^{
+ [self showHostSelectionView];
+ }];
});
}
}
@@ -430,8 +433,9 @@ static NSMutableSet* hostList;
}];});
}]];
[alertController addTextFieldWithConfigurationHandler:nil];
- [self hideLoadingFrame];
- [[self activeViewController] presentViewController:alertController animated:YES completion:nil];
+ [self hideLoadingFrame: ^{
+ [[self activeViewController] presentViewController:alertController animated:YES completion:nil];
+ }];
}
- (void) prepareToStreamApp:(TemporaryApp *)app {
@@ -538,9 +542,10 @@ static NSMutableSet* hostList;
dispatch_async(dispatch_get_main_queue(), ^{
[self updateAppsForHost:app.host];
- [self hideLoadingFrame];
[self prepareToStreamApp:app];
- [self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
+ [self hideLoadingFrame: ^{
+ [self performSegueWithIdentifier:@"createStreamFrame" sender:nil];
+ }];
});
return;
@@ -557,8 +562,9 @@ static NSMutableSet* hostList;
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
dispatch_async(dispatch_get_main_queue(), ^{
[self updateAppsForHost:app.host];
- [self hideLoadingFrame];
- [[self activeViewController] presentViewController:alert animated:YES completion:nil];
+ [self hideLoadingFrame: ^{
+ [[self activeViewController] presentViewController:alert animated:YES completion:nil];
+ }];
});
});
}]];
@@ -628,17 +634,15 @@ static NSMutableSet* hostList;
}
- (void) showLoadingFrame {
- _loadingFrame = [self.storyboard instantiateViewControllerWithIdentifier:@"loadingFrame"];
-
// Avoid animating this as it significantly prolongs the loading frame's
// time on screen and can lead to warnings about dismissing while it's
// still animating.
[[self activeViewController] presentViewController:_loadingFrame animated:NO completion:nil];
}
-- (void) hideLoadingFrame {
+- (void) hideLoadingFrame:(void (^)(void))completion {
// See comment above in showLoadingFrame about why we don't animate this
- [_loadingFrame dismissViewControllerAnimated:NO completion:nil];
+ [_loadingFrame dismissViewControllerAnimated:NO completion:completion];
[self enableNavigation];
}
@@ -661,6 +665,8 @@ static NSMutableSet* hostList;
[self.revealViewController setDelegate:self];
#endif
+ _loadingFrame = [self.storyboard instantiateViewControllerWithIdentifier:@"loadingFrame"];
+
// Set the current position to the center
currentPosition = FrontViewPositionLeft;
@@ -765,6 +771,11 @@ static NSMutableSet* hostList;
selector: @selector(handleEnterBackground)
name: UIApplicationWillResignActiveNotification
object: nil];
+}
+
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
// We can get here on home press while streaming
// since the stream view segues to us just before
@@ -777,7 +788,14 @@ static NSMutableSet* hostList;
// this view via an error dialog from the stream
// view, so we won't get a return to active notification
// for that which would normally fire beginForegroundRefresh.
- [self beginForegroundRefresh];
+ //
+ // On tvOS, we'll get a viewWillAppear when returning from the
+ // loading frame which will cause an infinite loop by starting
+ // another loading frame. To avoid this, just don't refresh
+ // if we're coming back from a loading frame view.
+ if (![[self activeViewController] isKindOfClass:[LoadingFrameViewController class]]) {
+ [self beginForegroundRefresh];
+ }
}
- (void)viewDidDisappear:(BOOL)animated
diff --git a/Moonlight TV/Base.lproj/Main.storyboard b/Moonlight TV/Base.lproj/Main.storyboard
index a25d862..d8bac58 100644
--- a/Moonlight TV/Base.lproj/Main.storyboard
+++ b/Moonlight TV/Base.lproj/Main.storyboard
@@ -102,7 +102,7 @@
-
+