'NSUnknownKeyException' with UIWebview - ios

I'm trying to create an app that starts from a main page with three buttons on it. Each button pressed will switch to another view. Each view is just a blank view with a UIWebView on it. Transitioning to each page works fine when there's nothing on it. However, when I add the UIWebview and all the correct code, the transition to the page causes the app to crash with this error message:
* Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key viewWeb.'
* First throw call stack:
(0x1c94012 0x10d1e7e 0x1d1cfb1 0xb7de41 0xaff5f8 0xaff0e7 0xb29b58 0x233019 0x10e5663 0x1c8f45a 0x231b1c 0xf67e7 0xf6dc8 0xf6ff8 0xf7232 0x259b 0x10e5705 0x192c0 0x19258 0xda021 0xda57f 0xd96e8 0x48cef 0x48f02 0x26d4a 0x18698 0x1befdf9 0x1befad0 0x1c09bf5 0x1c09962 0x1c3abb6 0x1c39f44 0x1c39e1b 0x1bee7e3 0x1bee668 0x15ffc 0x1e92 0x1dc5)
libc++abi.dylib: terminate called throwing an exception
I'm positive all the UIWebView code is correct since I tested the exact same code in a new app that just runs on a single view and has no transitions. But here's the code I'm using for the transition:
- (IBAction)floorCatalog:(id)sender {
UIViewController* floorLampsViewController = [[UIViewController alloc] initWithNibName:#"floorLampsViewController" bundle:[NSBundle mainBundle]];
[self.view addSubview:floorLampsViewController.view];
}
- (void)dealloc {
[_floorLampsButton release];
[_tableLampsButton release];
[_wallLampsButton release];
[super dealloc];
}
- (void)viewDidUnload {
[self setFloorLampsButton:nil];
[self setTableLampsButton:nil];
[self setWallLampsButton:nil];
[super viewDidUnload];
}
And here's the code I'm using for the web views:
#property (retain, nonatomic) IBOutlet UIWebView *viewWeb;
[self.viewWeb loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"http://www.bing.com"]]];
Any reason why this keeps happening? Thanks!

Is viewWeb hooked up to the UIWebView in Interface Builder? It looks like viewWeb wasn't initialized or something, and seeing you're using an IBOutlet it makes me think it's in your nib.

Related

Loading url on UIWebView crashes with "unrecognized selector" exception

I have built a view controller in my app whose only element is a UIWebView. I am trying to load a webpage on this uiwebview element with the following code, right after its view controller loads:
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
NetworkHelper *networkHelper = [NetworkHelper getInstance];
NSString *tocsUrl = [NSString stringWithFormat:#"%#%#", networkHelper.clientConfiguration[#"hdv_production_uri"],
#"/tocs?device=iOS"];
NSURL *url = [NSURL URLWithString:tocsUrl];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
[self.webView loadRequest:urlRequest];
}
String tocsUrl is a valid http string (http://192.168.1.12:3000/tocs?device=iOS).
However, the line [self.webView loadRequest:urlRequest]; is crashing the app with the following exception:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UIView loadRequest:]: unrecognized selector sent to instance 0x170188fd0'
*** First throw call stack:
(0x186d86530 0x197d640e4 0x186d8d5f4 0x186d8a3ac 0x186c8ec4c 0x1000b5d18 0x18b594958 0x18b594668 0x18bc881d0 0x18b88f790 0x18b8aab50 0x18b8acf68 0x18b681c4c 0x18b5c8a14 0x18b5b1d08 0x18b5c83b0 0x18b587ec8 0x186d3ed98 0x186d3bd24 0x186d3c104 0x186c691f4 0x19008b6fc 0x18b5fa10c 0x1000e0ad8 0x1983e2a08)
libc++abi.dylib: terminating with uncaught exception of type NSException
self.webView is defined in the .h file as:
#property (strong, nonatomic) IBOutlet UIWebView *webView;
Any pointers on how to solve this crash will be highly appreciated.
Check your webView, you have assigned it to UIView instead of your UIWebView. You can also remove and re add the connection to your UIWebView and Interface Builder. You can use shift+option+right click to make sure that you're choosing right controller in IB

[_UIWebViewScrollViewDelegateForwarder scrollViewWasRemoved:]: unrecognized selector sent to instance

I've a really strange error, and I cannot find the problem.
In my iPad APP I've a UINavigationController, a UITableViewController as master and a UIViewController containing a UIWebView as detail.
I launch the APP, the UITableViewController is shown. By segue I open the detail as usual. Then I have a back button in my detailviewcontroller that calls this method
[self.contentWebView setDelegate:nil];
[self.contentWebView stopLoading];
[self.navigationController popViewControllerAnimated:YES];
It gets poped and the master is shown again. Its
- (void)viewWillAppear:(BOOL)animated
gets called, but then I get the following error:
2014-06-06 15:56:58.156 Knowledge[356:60b] -[_UIWebViewScrollViewDelegateForwarder scrollViewWasRemoved:]: unrecognized selector sent to instance 0x170429f60
2014-06-06 15:56:58.159 Knowledge[356:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIWebViewScrollViewDelegateForwarder scrollViewWasRemoved:]: unrecognized selector sent to instance 0x170429f60'
*** First throw call stack:
(0x189582f50 [...] 0x196553aa0)
libc++abi.dylib: terminating with uncaught exception of type NSException
BUT, this happens only on the iPad Air... older iPads work as expected
UPDATE:
I added now the command [self.contentWebView removeFromSuperview]; after "stopLoading" and now the error is happing right up there.
Please ignore this answer if you are not touching scroll view's (of the web view) delegate reference.
I was facing the same strange error. After some investigation, I found that it was happening because scroll view's (of the web view) delegate was altered in controller's viewDidLoad method:
[self webView].scrollView.delegate = self;
In some cases, scroll view invokes delegate method(s) even after your view controller is destroyed. This should be prevented by weak delegate reference, but for some reason scroll view calls delegate method on deallocated (zombie) object anyway. I assume this is a bug in the framework.
So here what you can do: set delegate reference to nil in your controller's dealloc method:
- (void)dealloc
{
[self webView].scrollView.delegate = nil;
}
After deallocation, scroll view will be prevented from calling any method on no longer existing controller.

SIGABRT Error on my TabBarController when selecting the second tab

So I am making a card playing game where I have a UITabBarController and I have two tabs. Now the first tab is working perfectly fine but when I click on the other tab I receive this error
"Thread 1: signal SIGABRT" and on the debugger panel I have "argc = (int 1)" and argv = (char **) 0xbffff38c. I am using a story board for this project.
Below is my View Controller for the tab that throws me the error above.
If you need anymore code let me know but I was thinking it was probably a problem with my View since it won't even load.
#import "GameResultsViewController.h"
#import "GameResult.h"
#interface GameResultsViewController ()
#property (weak, nonatomic) IBOutlet UITextView *textResults;
#end
#implementation GameResultsViewController
- (void) updateUI
{
NSString* displayText = #"";
for (GameResult* gameResult in [GameResult allGameResults])
{
displayText = [displayText stringByAppendingFormat:#"Score: %d %# %0g\n",gameResult.score, gameResult.end, round(gameResult.duration)];
}
self.textResults.text = displayText;
}
- (void) setup
{
}
- (void) awakeFromNib
{
[self setup];
}
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
[self setup];
return self;
}
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[self updateUI];
}
#end
this was also in the debugger window
2013-07-25 20:38:46.360 Matchismo[1119:c07] *** Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<GameResultsViewController 0x758cce0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key display.'
*** First throw call stack:
(0x1c9b012 0x10d8e7e 0x1d23fb1 0xb84e41 0xb065f8 0xb060e7 0xb30b58 0x23a019 0x10ec663 0x1c9645a 0x238b1c 0xfd7e7 0xfddc8 0xfdff8 0xfe232 0x11f8c9 0x11f704 0x11dbda 0x11da5c 0x11f647 0x10ec705 0x202c0 0x20258 0x242ff4 0x10ec705 0x202c0 0x20258 0xe1021 0xe157f 0xe1056 0x246af9 0x10ec705 0x202c0 0x20258 0xe1021 0xe157f 0xe06e8 0x4fcef 0x4ff02 0x2dd4a 0x1f698 0x1bf6df9 0x1bf6ad0 0x1c10bf5 0x1c10962 0x1c41bb6 0x1c40f44 0x1c40e1b 0x1bf57e3 0x1bf5668 0x1cffc 0x297d 0x28a5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
This part of your console log tells you what's going on:
[<GameResultsViewController 0x758cce0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key display.'
*** First throw call stack:
At some point in your app, an object is trying to set the 'display' property on an object of the GameResultsViewController class - but that class does not have this property.
It might be a stray outlet in Interface Builder if you've renamed a property - the old connection still exists in Interface Builder, so when the NIB loads the runtime tries to connect the outlet and fails with this error. Or you have a line of code somewhere where you have something like gameResultsViewController.display = ... and the display property is incorrect (either incorrectly named, or you haven't added to the GameResultsViewController class yet).
My 5c is on a renamed property being left in Interface Builder. Check out the outlet view on your ViewController to see if there's anything grayed out - usually indicates a broken property. Example here I renamed the button property to myButton - so you see the unconnected myButton property, and the warning on the button property.

About #selector and MVC

What I have:
four TableViewController(A, B, C, D) - which would show four category
of content.
fake TabBarController based on UITabBarController, it
works fine.
What I want to do:
Add a button on ATableView, and it will use a method on my FakeTabBarController (because I want to share the method so I can use it on BTableViewController, CTableViewController rather than duplicate it two or three times)
So I just make the method public (on the .h file), and included the .h file in my ATableViewController. Then,
addTarget:action:forControlEvents: as always, but.. it doesn't work, please help!
Error:
[ATableViewController assisitantButtonPressed:]: unrecognized selector sent to instance 0x715a8d0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[ATableViewController assisitantButtonPressed:]: unrecognized selector sent to instance 0x715a8d0'
*** First throw call stack:
(0x1ca1012 0x10dee7e 0x1d2c4bd 0x1c90bbc 0x1c9094e 0x10f2705 0x262c0 0x26258 0xe7021 0xe757f 0xe66e8 0x2ea1d3 0x1c69afe 0x1c69a3d 0x1c477c2 0x1c46f44 0x1c46e1b 0x1bfb7e3 0x1bfb668 0x22ffc 0x1c8d 0x1bb5)
libc++abi.dylib: terminate called throwing an exception
FakeTabBarController.h:
#import <UIKit/UIKit.h>
#interface CustomTabBarController : UITabBarController
- (IBAction)assisitantButtonPressed:(UIButton *)sender;
#end
FakeTabBarController.m:
...
- (IBAction)assisitantButtonPressed:(UIButton *)sender
{
switch ([sender tag]) {
case 0: // AA
NSLog(#"AA");
break;
case 1: // BB
NSLog(#"BB");
break;
default:
break;
}
}
...
ATableViewController.m:
#import "ATableViewController.h"
#import "ATableCell.h"
#import "FakeTabBarController.h"
...
- (void)viewDidLoad
{
[super viewDidLoad];
UIImage *AAImage = [UIImage imageNamed:#"search.png"];
UIButton *AAButton = [[UIButton alloc] initWithFrame:CGRectMake(self.view.frame.size.width * 0.73, 0, AAImage.size.width, AAImage.size.height)];
[AAButton setTag:0];
[AAButton setImage:searchImage forState:UIControlStateNormal];
[AAButton addTarget:self action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:AAButton];
}
This line
[AAButton addTarget:self action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
sets the target to method assisitantButtonPressed: of self, which is ATableViewController. It throws exception because ATableViewController doesn't have that method. The correct way is to add a weak property to ATableViewController to keep a reference to CustomTabBarController and addTarget to that TabBar, rather than self
#interface ATableViewController
#property (weak, nonatomic) CustomTabBarController* tabBar;
...
#end
#implementation ATableViewController
-(void)viewDidLoad {
[super viewDidLoad];
self.tabBar = <you must somehow obtain the tab bar reference, either here or in init>
...
[AAButton addTarget:self.tabBar action:#selector(assisitantButtonPressed:) forControlEvents:UIControlEventTouchUpInside];
...
}
#end
It's good that you're trying to avoid code duplication. However since ATableViewController, BTableViewController, ... are very similar (judging from your question and their naming), you may want to use just one single TableViewController but with different actual data. Besides, if the method assisitantButtonPressed: really belongs to the table view controller and you moved it to the navBar just to avoid code duplication, it is a very bad practice.

Crasher in a custom view as UINavigationControllers navigationItem.titleView

I have an UIViewController with several subviews in its view property (UISearchbar and several UIButtons). The UIButtons hooked up to typical IBActions like -(IBAction)buttonPressed:(id)sender for the UIControlEventTouchUpInside state - it doesn't matter if I do it in IB or programmatically.
- (void)viewDidLoad {
MUZTitleViewController *title = [[MUZTitleViewController alloc]
initWithNibName:nil bundle:nil];
self.navigationItem.titleView = title.view;
}
In my project there's also an UINavigationController. When I set the navigationItem.titleView of the UINavigationBar to the view of my UIViewControllers view I get an EXC_BAD_ACCESS exception, as soon as I tap one of the button. I don't know why this is.
I uploaded a small sample project to illustrate my problem: Test010.xcodeproj (it's ARC enabled)
More and more I come to the conclusion that it's not a good idea to use the UIViewControllers view and assign it to the titleView but I don't see any alternative here.
Edit: Sorry, the sample project commented out the call which causes the exception. I reuploaded the linked project file.
Edit^2: As PengOne pointed out I've skipped the exact error message I got:
2011-09-10 23:09:50.621 Test010[78639:f803] -[CALayer buttonPressed:]: unrecognized selector sent to instance 0x9254ae0
2011-09-10 23:09:50.623 Test010[78639:f803] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[CALayer buttonPressed:]: unrecognized selector sent to instance 0x9254ae0'
Have you tried setting NSZombieEnabled to YES? If I do this, the console shows the following output:
2011-09-10 22:56:23.329 Test010[6481:ef03] *** -[MUZTitleViewController
performSelector:withObject:withObject:]: message sent to deallocated
instance 0x7a7ff70
As the project is ARC enabled, the controller seems to get deallocated some time after this line:
MUZTitleViewController *title = [[MUZTitleViewController alloc] initWithNibName:nil bundle:nil];
I am not sure what the best solution is, but a property definitely helps to prevent the exception like so:
// MUZDetailViewController.h
#property (strong, nonatomic) MUZTitleViewController *title;
// MUZDetailViewController.m
#synthesize title;
self.title = [[MUZTitleViewController alloc] initWithNibName:nil bundle:nil];
self.navigationItem.titleView = title.view;
The problem that you were having with ARC can also be resolved by setting the initial view controller of your application as your main window's rootViewController property instead of using addSubview.
Doing this avoids the need to add each custom view controller as a property.

Resources