Is it possible to check whether an identifier exists in a storyboard before instantiating the object?
As Tom said, the best solution to this problem is the try-catch block:
@try {
UIViewController *newViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"identifier"];
}
@catch (NSException *exception) {
UIAlertView *catchView;
catchView = [[UIAlertView alloc]
initWithTitle: NSLocalizedString(@"Error", @"Error")
message: NSLocalizedString(@"Identifier not found on SB".", @"Error")
delegate: self
cancelButtonTitle: NSLocalizedString(@"OK", @"Error") otherButtonTitles: nil];
[catchView show];
}
I hope it helps! even though the answer is really late.
You can use valueForKey:
on UIStoryboard
s. UIStoryboard
s have a key called "identifierToNibNameMap", its value is an NSDictionary
with the UIViewController
s in that storyboard. This inner NSDictionary
uses the viewcontroller's names as keys so you can actually check if a viewcontroller exists in a storyboard with the following code:
if ([[storyboard valueForKey:@"identifierToNibNameMap"] objectForKey:myViewControllerName]) {
// the view controller exists, instantiate it here
UIViewController* myViewController = [storyboard instantiateViewControllerWithIdentifier:myViewControllerName];
} else {
//the view controller doesn't exist, do fallback here
}
Note: Apple has been known to reject apps that query the underlying properties of cocoa classes using valueForKey:
. These underlying properties could change at any time in the future, breaking app functionality without warning. There is no deprecation process for these things.
@Kevin's solution works. Here is a pretty the same piece of code for Swift 3 as function, that I am using in my code:
func instantiateViewController(fromStoryboardName storyboardName: String, withIdentifier identifier: String) -> UIViewController? {
let mainStoryboard = UIStoryboard(name: storyboardName, bundle: nil)
if let availableIdentifiers = mainStoryboard.value(forKey: "identifierToNibNameMap") as? [String: Any] {
if availableIdentifiers[identifier] != nil {
if let poiInformationViewController = mainStoryboard.instantiateViewController(withIdentifier: identifier) as? UIViewController {
return viewController
}
}
}
return nil
}
Use this function as follows:
if let viewController = self.instantiateViewController(fromStoryboardName: "YourStoryboardName", withIdentifier: "YourViewControllerStoryboardID") {
// Here you are sure your viewController is available in the Storyboard
} else {
print("Error: The Storyboard with the name YourStoryboardName or the Storyboard identifier YourViewControllerStoryboardID is not available")
}