Getting exception when calling method on ViewController before Navigating to it - ios

I am trying to setData on a ViewController Instance before navigating to it.
I am navigating from a nib file to a view controller in another story board.
Here is the corresponding code:
- (IBAction)newReferenceButtonPressed {
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"ReferenceStoryboard" bundle:nil];
ReferenceViewController *evc = (ReferenceViewController*)[storyboard instantiateViewControllerWithIdentifier:#"ReferenceViewController"];
ReferenceObject *referenceObject = [[ReferenceObject alloc] initWithReference: self.referenceDetailsDictionary[#"getReferenceDetailsResponse"]];
[evc setClientDetailsWithName:customerNameLabel.text andAddress:address1Label.text];
[evc setReferenceData:referenceObject];
[self.navigationController pushViewController:evc
animated:YES];
}
I am making two method calls on the destination view controller. Strangely, setClientDetailsWithName call has no problems while setReferenceData gives me unrecognized selector exception.
Any help is appreciated.
Thanks.

Related

Call a view controller programatically using storyboard id iOS

What I Want?
In MainViewController I open a view from a xib programmatically. This
xib view contains a UIButton. The xib opens successfully.
On click of that UIButton I want to move FeedBackViewController
My code
This is the code I am using to move FeedBackViewController on click of the UIButton
FeedBackViewController *view=[self.storyboad instantiateViewControllerWithIdentifier:#"FeedBackView"];
[self presentViewController:view animated:YES completion:nil];
But it is crashing and I am receiving the following message:
Terminating app due to uncaught exception 'NSInvalidARgumentException', reason: 'Application tried to present a nil modal view controller on target FutureOrderViewController: 0x199a4a30.
Check these things
Check the identifier of the viewcontroller, if it is the same that you mentioned in storyboard
Make sure that your view object is not nil. Set a breakpoint on that line and on the debug area at the bottom see whether the object is not nil. If it is nil then problem lies in the storyboard connection
If your current viewcontroller is not launched from storyboard then get storyboard object like this :
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
UIViewController * feedbackVC = [storyboard instantiateViewControllerWithIdentifier:#"FeedBackView"] ;
[self presentViewController:feedbackVC animated:YES completion:nil];
whenever you want to load a VC as the way you mentioned, you need two things.
Thing 1: Specific storyboard ID. you will find this by:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Your_Storyboard_Id" bundle:nil];
In my case this is Main
Thing 2:
You need your View Controller id. Just click on the View Controller you want to go from storyboard and give a suitableName there.
Then invoke this like:
UIViewController * yourVC = [storyboard
instantiateViewControllerWithIdentifier:#"YourVC_ID"] ;
And if you want to present it modally you already did this. :)
[self presentViewController:yourVC animated:YES completion:nil];
Try this
UIStoryboard *story = [UIStoryboard storyboardWithName:#"Main" bundle:nil];
FeedBackViewController * feedbackVC = [story instantiateViewControllerWithIdentifier:#"FeedBackView"] ;
[self presentViewController:feedbackVC animated:YES completion:nil];
Where FeedBackView is your storyboard id of FeedBackViewController.

iOS - navigate From AppDelegate to UITableViewController

I try to navigate to certain ViewController after I get remote Notification
It crashes after this code any help please
My storyboard like this
SWRevealViewController -> NavViewController -> UIViewController
I want to reach this UIViewController
- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
UIStoryboard *storyboard =[UIStoryboard storyboardWithName:#"Main" bundle:nil];
// my ViewController I want navigate to UITableViewController call home_tableview
Home_tableView *home =[storyboard instantiateViewControllerWithIdentifier:#"home_view"];
[(UINavigationController *)self.window.rootViewController pushViewController:home animated:NO];
}
The Error I get
2015-01-20 13:04:14.379 SchoolLink[1304:416727] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil'
*** First throw call stack:(0x25bd749f 0x3338dc8b 0x25af30b3 0x2909d06b 0x11d48f 0x29099d0f 0x29099a7d 0x2909f953 0x2910643d 0x111dbd 0x2930286b 0x292fa54d 0x2c3680d1 0x25b9dd7d 0x25b9d041 0x25b9bb7b 0x25ae93c1 0x25ae91d3 0x2cee70a9 0x290f8fa1 0x12b7ad 0x3390daaf)
libc++abi.dylib: terminating with
I suppose you have an UINavigationController in your storyboard which embeds your view controllers.
If that's the case, your code should work without any issues.
I've tested it in a new project with two view controllers and one navigation controller as the initial view and everything is fine.
If you're certain that you have all the storyboard identifiers right, and that your initial View in Interface Builder is an UINavigationController that embeds all of your ViewControllers, then you have some issues elsewhere, not in the code you've pasted in.
Since your error is related to insertObjectAtIndex: I believe there's some data you instantiate your UITableViewController with in the normal workflow of the app (when segueing to it) and when you try to present the UITableView controller in a clean state from a notification, that data is missing, hence the crash.
Check where you try to add an object to an array at a given index.
The problem is either in the class that receives the notification (I guess it's your AppDelegate class), either in the UITableViewController class, somewhere in the initialization.
Try
Home_tableView *home =[storyboard instantiateViewControllerWithIdentifier:#"home_view"];
[self.window setRootViewController:home]
[self.window makeKeyAndVisible];
Please try this:
UIStoryboard *storyboard =[UIStoryboard storyboardWithName:#"Main" bundle:nil];
Home_tableView*svc = [storyboard instantiateViewControllerWithIdentifier:#"home_view"];
// Configure the new view controller here.
[self presentViewController:svc animated:YES completion:nil];

iOS memory warning case crash with error "message sent to deallocated instance"

Pushing my view controller twice to navigation controller and simulating memory warning, lead to application crash with error: "message sent to deallocated instance"
I'm pushing view controller by pressing on button:
-(void)buttonPressed
{
MyViewCOntroller *vc = [[MyViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
I'm using ARC.
Scenario:
[self buttonPressed];
Press back button in vc.
[self buttonPressed];
Press back button in vc
Simulate memory warning
The crash does not happen if pushing only once.
I tried also to move "vc" to be ivar of parent controller, but the effect is the same...
Maybe this will help, but I'm using custom back button and its selector:
-(void)backButtonPressed
{
[self.navigationController popViewControllerAnimated:YES];
}
create this vc object as class member and check if crash exists
#interface ParentViewController()
{
MyViewCOntroller *vc;
}
#end
#implementation PaintingViewController
-(void)buttonPressed
{
vc = [[MyViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
Found a solution to this. Please see my answer to my other question:
[UINavigationController retain]: message sent to deallocated instance

iOS: Call segue from coded UIViewController outside of Storyboard

I have a custom UIVieController class that it's not included in any StoryBoard, I need to call from this class an UIViewController that is included in a StoryBoard, I tried many ways to do this but it doesn't work, always get a NSException because when I try to instance the UIViewController of the StoryBoard and get a nil object.
I don't know why it's happening this, I really appreciate any help with this.
Thank you.
Just to clarify in this code I omitted the pushing of the view to the UINavigationController.
I tried this.
+(void)loadSocialMediaAppSegue:(AXISAppDelegate*)delegate withName:(NSString*)segueId{
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"Main_iPhone" bundle:nil];
AXISWebViewViewController *axisWebView = [storyboard instantiateViewControllerWithIdentifier:segueId];
}
and this
+(void)loadSocialMediaAppSegue:(AXISAppDelegate*)delegate withName:(NSString*)segueId{
AXISWebViewViewController *axisWebView = [delegate.window.rootViewController.storyboard instantiateViewControllerWithIdentifier:segueId];
}
Ok the first thing you need to do is to add a identifier to you view controller at Storyboard, you can do that opening the Storyboard's Identity Inspector and fill the storyboard id field.
Now you are able to call this UIViewController from any place you want like this:
UIStoryboard *sb = [UIStoryboard storyboardWithName:#"the name of your storyboard" bundle:nil];
UIViewController *vc = [sb instantiateViewControllerWithIdentifier:#"the id of your view controller"];
I hope this can help you.
Please post the code you are using to instantiate the VC from the Storyboard.
In general:
To instantiate a View Controller from StoryBoard:
MyViewController *MyVC = [[UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil] instantiateViewControllerWithIdentifier:#"MyViewController"];
Make sure you set the Storyboard ID and Restoration ID and Class name to "MyViewController" or whatever you want to call it and use that as the parameter for instantiateViewControllerWithIdentifier:
Then if you are in a navigation controller, simply push the instantiated view controller onto the navigation stack:
[self.navigationController pushViewController:MyVC animated:YES];
or present it modally:
[self presentViewController:MyVC animated:YES completion:nil];

performSegueWithIdentifier NSInvalidArgumentException after call from AppDelegate

Hey together,
I am calling a void with some parameters from the AppDelegate on my main view.
This is done if a push notification is received:
MainViewController *mainView = [[MainViewController alloc] init];
[mainView showPushView:pushDataObject];
The called void # the MainView doing some data operating stuff and after that it should load the pushView:
- (void)showPushView: (PFObject *)pushDataObject {
NSLog(#"Push Data object transfered %#", pushDataObject);
pushItem = pushDataObject;
//All working fine to this point
[self performSegueWithIdentifier:#"showPushObject" sender:self];
}
Now the problem is that the app is crashing at [self performSegueWithIdentifier:#"showPushObject" sender:self]; with this Error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason:
'Receiver (<MainViewController: 0x145b80e0>) has no segue with identifier 'showPushObject''
*** First throw call stack:
(0x2e51fe83 0x3887c6c7 0x30f656d9 0xbeb11 0xb2a23 0x1745f7 0x38d610c3 0x38d610af 0x38d639a9 0x2e4ea5b1 0x2e4e8e7d 0x2e453471 0x2e453253 0x3318d2eb 0x30d08845 0xafecd 0x38d75ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
I think that there is a problem because I call the void from the AppDelegate, am I right?
Those anyone know a fix for that problem?
Thanks a lot!
Best regards from Germany :)
P.S. If I call [self performSegueWithIdentifier:#"showPushObject" sender:self]; with a button or something on the MainViewController all working fine... :/
In order for the segue to work, you need to have the storyboard loaded in the mainView when you start it that way. Try instead something like this:
self.window = [[UIWindow alloc] initWithFrame:UIScreen.mainScreen.bounds];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:#"MainStoryboard" bundle:nil];
UIViewController *firstViewController = [storyboard instantiateViewControllerWithIdentifier:#"kYourMainViewControllerIdentifier"];
self.window.rootViewController = firstViewController;
[self.window makeKeyAndVisible];
Remember to give an identifier to your root view controller and change it in this piece of code.
Your problem is this line:
MainViewController *mainView = [[MainViewController alloc] init];
because it means that the mainView instance doesn't have a storyboard (so it can't have any segues).
When you run it from a button the controller instance must have been created from a storyboard.
So, to fix, load the storyboard and instantiate mainView from it. Then the segue will work.
UIStoryboard *storyboard4Inch = [UIStoryboard storyboardWithName:#"Storyboard4Inch" bundle:nil];
UIViewController *mainViewController = [storyboard4Inch instantiateViewControllerWithIdentifier:#"MainViewController"];
[mainViewController showPushView:pushDataObject];

Resources