Unrecognized selector sent to instance, pushViewController:animated - ios

I don't know how to solve this problem:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ViewController pushViewController:animated:]: unrecognized selector sent to instance 0x8e5fc70'
This problem is connected to screen timeout. After 30 seconds of no activity, my App have to back to the login screen, and if the user come back he have to login again. And this is my code:
AppDelegate.h:
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>
#property (strong, nonatomic) UIWindow *window;
#end
AppDelegate.m:
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(applicationDidTimeout:) name:kApplicationDidTimeoutNotification object:nil];
return YES;
}
-(void)applicationDidTimeout:(NSNotification *) notif
{
NSLog (#"time exceeded!!");
UIViewController *controller = [[UIStoryboard storyboardWithName:#"Main" bundle:NULL] instantiateViewControllerWithIdentifier:#"mainView"];
[(UINavigationController *)self.window.rootViewController pushViewController:controller animated:YES];
As you can see the problem is in the last line of this code. This part of the code which I used has been taken from:
iOS perform action after period of inactivity (no user interaction)

The pushViewController:animated: method is a method of UINavigationController.
But your root view controller is of type ViewController which is most likely a UIViewController.
You need to change your setup so your main view controller is inside a UINavigationController and you need to make the navigation controller the window's root view controller.

This means in storyboard the rootViewController is a navigationController

Related

How do I access a view controller from AppDelegate.m during a background refresh

I am trying to implement background refresh in my app. I have a method refreshMessages that is inside one of my UIViewControllers (I am using a UINavigationController). I need to access this controller from AppDelegate.m.
Usually I would do something like this:
UINavigationController *navigationController = [self.window.rootViewController navigationController];
to get the navigation controller and I can then access them from there. But surely this won't work now. The app is in the BACKGROUND and no window is showing. Any thoughts on how to get around this? Thanks!
Here is my background refresh:
-(void)application:(UIApplication *)application
performFetchWithCompletionHandler:
(void (^)(UIBackgroundFetchResult))completionHandler {
NSLog(#"Doing the background refresh");
UINavigationController *navigationController = [self.window.rootViewController navigationController];
NSLog(#"Number of controllers is %d", [[navigationController viewControllers] count]);
//There are zero controllers?!!! Must be because no window is showing
completionHandler(UIBackgroundFetchResultNewData);
}
Yes, you are right. The window will be nil since it will no longer be in the view hierarchy.
A cheeky solution would be to hold the reference of the view controller in the AppDelegate by creating a property in it. You can assign this when the application goes to the background by subscribing to the relevant notification in the view controller.
Edit: Code added
In your AppDelegate.h
#property (nonatomic, weak) YourViewController *yourViewController;
In YourViewController.m, somewhere in viewDidLoad
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(appWillResignActive:) name:UIApplicationWillResignActiveNotification object:nil];
appWillResignActive's implementation
-(void)appWillResignActive:(id)sender {
YourAppDelegate *delegate = [UIApplication sharedApplication].delegate;
delegate.yourViewController = self;
}
In your completion handler
[self.yourViewController refreshMessages]
Also, make sure you remove the observer once the view controller is deallocated.

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];

Unrecognized selector sent to instance. NSInvalidArgumentExpection

i have a loginviewcontroller class that has a button 'login'.
The login class is connected to my mainmenuviewcontroller to a uiview. This i connected as follows
(mainmenuviewcontroller.h)
import <UIKit/UIKit.h>
#interface ViewController : UIViewController
#property (strong) IBOutlet UIView *loginView;
#end
(mainmenuviewcontroller.m)
- (void)viewDidLoad
{
[super viewDidLoad];
LogInViewController *logIn = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
[self.loginView addSubview:logIn.view];
[self.loginView setClipsToBounds:YES];
}
At this point, everything is fine. My loginViewcontroller is showing up niceley inside its own view in my main menu.
When pressing the login button on the loginviewcontroller(showing in a uiview on the main menu), it then calls the method below located in its loginviewcontroller class.
(loginviewcontroller.h)
#import <UIKit/UIKit.h>
#interface LogInViewController : UIViewController
- (IBAction)loginButtonPressed;
#end
(loginviewcontroller.m)
- (IBAction)loginButtonPressed
{
NSLog(#"login Button Pressed");
}
However an exception occurs and i dont know why: i have ensured the touchup inside sent action from the button has the correct name. And i am using Arc. HELP! :)
2013-10-28 13:57:46.367 Headache Mbl[1593:60b] -[NSConcreteMapTable loginButtonPressed]: unrecognized selector sent to instance 0x17d4fa20
2013-10-28 13:57:46.370 Headache Mbl[1593:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteMapTable loginButtonPressed]: unrecognized selector sent to instance 0x17d4fa20'
*** First throw call stack:
(0x2de2fe8b 0x385826c7 0x2de337b7 0x2de320b7 0x2dd80e98 0x305ea55f 0x305ea4fb 0x305ea4cb 0x305d60f3 0x305e9f13 0x305e9bdd 0x305e4c09 0x305b9f59 0x305b8747 0x2ddfaf27 0x2ddfa3ef 0x2ddf8bdf 0x2dd63541 0x2dd63323 0x32a742eb 0x3061a1e5 0x60bdd 0x38a7bab7)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
I am still a quite new to this, a possible solution was suggested that the class needs to be a property. How is this done? Thanks
If you have connected the IBoutlet properly,
Make the LogInViewController as a ivar or property. The object loses its value on viewDidLoad's return.
#interface ViewController : UIViewController
{
LogInViewController *logIn;
}
#property (strong) IBOutlet UIView *loginView;
#end
- (void)viewDidLoad
{
[super viewDidLoad];
logIn = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
[self.loginView addSubview:logIn.view];
[self.loginView setClipsToBounds:YES];
}
when the viewDidLoad ends the logIn object will be released, only his view will survive because you are adding it to the main view controller view, so when you tap the button, will send a message to an object that doesn't exist anymore.
Let me say that it's conceptually wrong what you are trying to do, the login view controller should be added to a hierarchy, presenting it, pushing it, or containing in another view controller, but not creating it just to get his view and add it to another viewcontroller.
LogInViewController *logIn = [[LogInViewController alloc] initWithNibName:#"LogInViewController" bundle:nil];
[self addChildViewController:logIn];
[self.loginView addSubview:logIn.view];
[self.loginView setClipsToBounds:YES];
turns out i needed to add the view as a a child view controller. Once loaded it removes it from memory but still shows it. so its needs to be added as a child.
:)

Change initial View Controller of Master-Detail-Application

I created a new iPhone project on a Master-Detail-Application. As I need a login before, I added at the storyboard a new ViewController, checkmarked "is initial View Controller" and assigned the new created class LoginViewController to this ViewController.
Furthermore but not relevant (in my opinion), i created a segue and connected it from the ViewController to the NavigationController (of the Master-Detail-Template).
The AppDelegate.m was changed to launch the new controller at startup:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
/* // Old Master-Detail-View-Controller
UINavigationController *navigationController = (UINavigationController *)self.window.rootViewController;
MasterViewController *controller = (MasterViewController *)navigationController.topViewController;
controller.managedObjectContext = self.managedObjectContext;
*/
(LoginViewController *)self.window.rootViewController;
return YES;
}
This will end up in the error:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '-[UICollectionViewController loadView] loaded the "Qn5-Rj-iPA-view-IRE-eP
-ILZ" nib but didn't get a UICollectionView.'
I have as well tried this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
LoginViewController *loginViewController = [[LoginViewController alloc] init];
self.window.rootViewController = loginViewController; //Set the view controller
[self.window makeKeyAndVisible];
return YES;
}
Resulting in a similar error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException',
reason: 'UICollectionView must be initialized with a non-nil layout parameter'
Where is my mistake?
What I do not get is, where the hell the UICollectionView in the error message comes from. I did never create one or add one??
My LoginViewController inherits by mistake form UICollectionViewController instead of UIViewController. I fixed that and it works.
This explained the strange errormessage which i did not understood in the first place. As always the truth is in the sourcecode. Rechecking helps.
You don't have to do anything to load view controllers in the AppDelegate. As long as your stroyboard is the one that is loaded in project settings, it should load automatically.

this class is not key value coding-compliant for the key view.'

I have a problem in AppDelegate, when run the app I get this error:
Terminating app due to uncaught exception 'NSUnknownKeyException', reason:
'[<UIApplication 0x856c820> setValue:forUndefinedKey:]:
this class is not key value coding-compliant for the key view.'
This is the code of AppDelegate.h
#import <UIKit/UIKit.h>
#class ViewController;
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
//UINavigationController *navigationController;
}
#property (strong, nonatomic) UIWindow *window;
#property (copy, nonatomic) ViewController * viewController;
#property (copy, nonatomic) UINavigationController * navigationController;
#end
This is the code of AppDelegate.m
#import "AppDelegate.h"
#import "RootViewController.h"
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions: (NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
RootViewController *rootMenu;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone) {
rootMenu= [[RootViewController alloc] initWithNibName:#"ViewController_iPhone" bundle:nil];
} else {
rootMenu = [[RootViewController alloc]initWithNibName:#"ViewController_iPad" bundle:nil];
}
self.navigationController =[[UINavigationController alloc]initWithRootViewController:rootMenu];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
What can I do to resolve this error? I have rewritten the RootViewController, throwing in the trash the old one, but the problem remains the same.Thanks in advance
This usually happens when an Interface Builder or Storyboard connection hasn't properly been made. Sometimes you'll make a connection, and then delete the code that the connection was made to. Interface Builder still has a reference to the code, which causes the key/value compliant run time error. You can also get this error if you haven't assigned the proper class to a view controller. If you've written code for a particular view controller, be sure to set the class appropriately in Interface Builder for that View Controller.
I know this question is a bit old, but I was running into the same problem and the article below helped a lot. Basically it illustrates step-by-step how to fix the problem #bgolson described.
http://www.tech-recipes.com/rx/52021/how-do-i-fix-the-issue-this-class-is-not-key-value-coding-compliant-for-the-key-in-xcode-6/

Resources