8

I have a multi-view application with the following hierarchy:

splash -> navigation controller -> table view controller -> settings view controller

Splash is the application entry point and therefore becomes the root view controller. When I try to add a tile to the band via an action on the settings view controller, I get a debugger warning:

application[1929:1000746] Warning: Attempt to present <MSBAddTileDialogViewController_iOS: 0x15f0575b0> on <SplashViewController: 0x15dd597b0> whose view is not in the window hierarchy!

This happens immediately after the call to MSBClient.tileManager addTile:completionHandler:. The call never returns, no error is generated.

Any suggestions on how to get around this?

SwiftArchitect
  • 47,376
  • 28
  • 140
  • 179
chortik
  • 81
  • 1
  • 6
  • 1
    I only dabble in iOS development so I likely can't answer your question directly. When you add a Tile using the Band SDK it will attempt to show a confirmation dialog to the user. It may be that your stack of controllers doesn't mesh well with how the Band SDK locates the proper controller on which to add its own view controller. You may need to provide more snippets of your settings view controller to see how/when in its load/appear process you're attempting to add the tile. – Phil Hoff -- MSFT Dec 20 '15 at 19:02
  • @phil-hoff-msft, thanks for looking at it. Here's [a sample](http://mikeradin.com/ModifiedBandTileEvent.zip). I modified the example included with the iOS SDK download to include an interim view thus making the user interface not the root view controller. Same issue exists. – chortik Dec 20 '15 at 21:00
  • This is a known issue as the SDK is trying to present the confirmation dialog on the root view controller even when it is not part of the view hierarchy. The only workaround for now is to make sure that the root view controller is presenting when making the addTile: call. – Manjit Riat Dec 21 '15 at 19:44
  • Thanks Manjit, is there a plan to fix this? My rootviewcontroller is defined by the storyboard, it happens to be a splash view with a logo and such. The application is not written exclusively for the Band but I want to give the users an option to send notifications and some other information to the Band of they have one they way it already does for the Apple Watch. This would be controlled from a settings view as described in hierarchy in the original question. I don't see how in this use case I can add the tile from the rootviewcontroller. – chortik Dec 21 '15 at 20:05
  • @ManjitRiat, I wrapped the call to `MSBClient.tileManager addTile:completionHandler:` inside of a `dispatch_async(dispatch_get_main_queue(), ^{})` block and received the same warning from the debugger. The call never returns, the operation doesn't complete and there is no error. – chortik Dec 22 '15 at 02:17
  • @chortik dispatch_async() will just execute your code on the main_queue and does not have any effect on the view hierarchy so the original issue still remains. – Manjit Riat Dec 22 '15 at 19:07
  • 1
    @chortik Please download the latest SDK and let us know if you still run into issues. – Manjit Riat Dec 22 '15 at 22:38
  • @ManjitRiat, that works. Thank you very much. – chortik Dec 23 '15 at 02:51
  • is this MSBClient visible by the time you try to change its title? – Duck Jul 10 '16 at 00:09

1 Answers1

3

You will need to get the root view controller and perform a segue from that view controller. This can be quite frustrating to debug but there are some answers on here about this topic.

Here is some code that I have used to perform a segue from the root view controller to a screen when the app receives a push notification.

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"YourStoryboard" bundle:nil];

YourViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:@"viewcontrolleridentifier"];

UIViewController *top = [UIApplication sharedApplication].keyWindow.rootViewController;

[top presentViewController:viewController animated:YES completion: nil];

Heres the same code in swift:

let storyboard = UIStoryboard.init(name: "YourStoryboard", bundle: nil)

let viewController = storyboard.instantiateViewController(withIdentifier: "viewcontrolleridentifier")

let top = UIApplication.shared.keyWindow?.rootViewController

top?.present(viewController, animated: true, completion: nil)

Make sure you set the view controllers identifier in your storyboard.

EDIT* If the view controller you are accessing is embedded within a navigation controller you will need to amend the above code,

Objective C:

UIViewController *top = [self topMostController];

UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:viewController];

[top presentViewController:navigationController animated:YES completion: nil];

Swift:

let top = UIApplication.shared.keyWindow?.rootViewController

let navigationController = UINavigationController.init(rootViewController: viewController)

top?.present(navigationController, animated: true, completion: nil)
Axemasta
  • 763
  • 1
  • 9
  • 24