App crashes on start - objective-c

Hi I was doing some testing earlier and my app was running just fine. I wanted to do some more testing so I decided to remove the app from my device and then reinstall it by running.
Well now for some reason I get to the stage where my splash screen shows up and then it crashes and I get the error:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
This obviously means theres an array out of bounds correct? But why now and how can I found out where and what view controller this is happening on? How could it run before and now all of a sudden when I try reinstalling the app through running it again I get this error?
Thanks
EDIT
The error is with the array in the following code
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
exploreViewController *view1 = [[exploreViewController alloc] initWithNibName:#"exploreViewController" bundle:nil];
view1.title= #"Explore";
Upcoming *view2 = [[Upcoming alloc] initWithNibName:#"Upcoming" bundle:nil];
view2.title = #"Upcoming";
calcViewController *view3 = [[calcViewController alloc] initWithNibName:#"calcViewController" bundle:nil];
view3.title = #"Calc";
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:view1];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:view2];
UINavigationController *nav3 = [[UINavigationController alloc] initWithRootViewController:view3];
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:nav1,nav2,nav3,nil];
self.tabBarItem = [[[UITabBarItem alloc] init] autorelease];
NSArray *tabBarItems = self.tabBarController.tabBar.items;
UIImage *tab1 = [UIImage imageNamed:#"85-trophy.png"];
UIImage *tab2 = [UIImage imageNamed:#"12-eye.png"];
UIImage *tab3 = [UIImage imageNamed:#"237-key.png"];
NSArray *tabBarImages = [[[NSArray alloc] initWithObjects:tab1, tab2, tab3,nil]autorelease];
NSInteger tabBarItemCounter;
for (tabBarItemCounter = 0; tabBarItemCounter < [tabBarItems count]; tabBarItemCounter++)
{
tabBarItem = [tabBarItems objectAtIndex:tabBarItemCounter];
tabBarItem.image = [tabBarImages objectAtIndex:tabBarItemCounter];
}

Well, the reason for this crash is the following:
You are adding five items to your tabBar (nav1, nav2, nav3, nav4, nav6), but you only have three images for your tabs (tab1, tab2, tab3). So when the for loop reaches the fourth tab it crashes because tabBarImages only contains three objects.
Apart from that your code looks a bit messy - which could be the reason for not seeing the error on first sight.
// edit
You are complicating things - just try the following piece of code
UINavigationController *nav1 = [[UINavigationController alloc] initWithRootViewController:__your_viewController__];
nav1.title = #"Explore";
nav1.tabBarItem.image = [UIImage imageNamed:#"85-trophy.png"];
UINavigationController *nav2 = [[UINavigationController alloc] initWithRootViewController:__your_viewController__];
nav2.title = #"Upcoming";
nav2.tabBarItem.image = [UIImage imageNamed:#"12-eye.png"];
UINavigationController *nav3 = [[UINavigationController alloc] initWithRootViewController:__your_viewController__];
nav3.title = #"Calc";
nav3.tabBarItem.image = [UIImage imageNamed:#"237-key.png"];
UITabBarController *tabBarController = [[UITabBarController alloc] init];
[tabBarController setViewControllers:[NSArray arrayWithObjects:nav1, nav2, nav3, nil]];
[nav1 release];
[nav2 release];
[nav3 release];

Related

Set view controller as the first controller in UITabBarController

I have this code in my appDelegate.m that implements a UINavigationController with a UITabBarController:
FristViewController *primeiro = [[FristViewController alloc] init];
UINavigationController *nav1 = [[UINavigationController alloc] init];
[nav1 pushViewController:primeiro animated:YES];
FilesViewController *segundo = [[FilesViewController alloc] init];
UINavigationController *nav2 = [[UINavigationController alloc] init];
[nav2 pushViewController:segundo animated:YES];
InfoViewController *terceiro = [[InfoViewController alloc] init];
UINavigationController *nav3 = [[UINavigationController alloc] init];
[nav3 pushViewController:terceiro animated:YES];
UITabBarController *tabbar = [[UITabBarController alloc] init];
tabbar.viewControllers = [NSArray arrayWithObjects:nav2, nav1, nav3, nil];
nav1.tabBarItem.image = [UIImage imageNamed:#"tab1.png"];
nav2.tabBarItem.image = [UIImage imageNamed:#"tab2.png"];
nav3.tabBarItem.image = [UIImage imageNamed:#"tab3.png"];
self.window.rootViewController = tab bar;
It's all right with this code, in my case when I beginning my app appearing on the first controller is FilesViewController because it is the first in the order of Tab Bar, but in my case I would like the first controller was the FristViewController without changing the order of items in the tab bar, how can I do this?
Go to your storyboard or xib where you created your TabBar. Drag the First controller to 1st position. Or programmatically you could set tabBar.selectedIndex = 0;

UITabBarItem don't show any icon images?

I have this code:
MeuPrimeiroViewController *primeiro = [[MeuPrimeiroViewController alloc] init];
MeuSegundoViewController *segundo = [[MeuSegundoViewController alloc]init];
UITabBarController *tabbar = [[UITabBarController alloc] init];
tabbar.viewControllers = [NSArray arrayWithObjects:primeiro,segundo, nil];
primeiro.tabBarItem.title = #"Primeiro";
primeiro.tabBarItem.image = [UIImage imageNamed:#"1.jpg"];
segundo.tabBarItem.title = #"Segundo";
segundo.tabBarItem.image = [UIImage imageNamed:#"3.jpg"];
self.window.rootViewController = tabbar;
I don't know why, the images don't show?
You need to use the tabBarItem initWithTitle:image:selectedImage method instead. See the method definition here.

Phonegap/Cordova with Multiple CDVViewController

my Idea is to use Phonegap for the business logic of my app, but use native transitions. So I need CDVWebView in every UIViewController. This works fine with normal UIWebviews, but if I use multiple CDVViewControllers for e.g. a TabBar, the deviceReady event only fires for the first CDVWebView.
Here is what I do in the App Delegate:
- (BOOL) application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
{
NSURL* url = [launchOptions objectForKey:UIApplicationLaunchOptionsURLKey];
NSString* invokeString = nil;
if (url && [url isKindOfClass:[NSURL class]]) {
invokeString = [url absoluteString];
NSLog(#"NativeNavigationTest launchOptions = %#", url);
}
NSLog(#"invokeString = %#", invokeString);
CGRect screenBounds = [[UIScreen mainScreen] bounds];
self.window = [[[UIWindow alloc] initWithFrame:screenBounds] autorelease];
self.window.autoresizesSubviews = YES;
CGRect viewBounds = [[UIScreen mainScreen] applicationFrame];
//4 ViewController, each one inherits from CDVViewController
self.viewController = [[[MainViewController alloc] init] autorelease];
self.viewController.useSplashScreen = YES;
self.viewController.wwwFolderName = #"www";
self.viewController.startPage = #"index.html";
self.viewController.invokeString = invokeString;
self.viewController.view.frame = viewBounds;
self.secondController = [[[SecondController alloc] init] autorelease];
self.secondController.useSplashScreen = YES;
self.secondController.wwwFolderName = #"www";
self.secondController.startPage = #"second.html";
self.secondController.invokeString = invokeString;
self.secondController.view.frame = viewBounds;
self.thirdController = [[[ThirdController alloc] init] autorelease];
self.thirdController.useSplashScreen = YES;
self.thirdController.wwwFolderName = #"www";
self.thirdController.startPage = #"third.html";
self.thirdController.invokeString = invokeString;
self.thirdController.view.frame = viewBounds;
self.fourthController = [[[FourthController alloc] init] autorelease];
self.fourthController.useSplashScreen = YES;
self.fourthController.wwwFolderName = #"www";
self.fourthController.startPage = #"fourth.html";
self.fourthController.invokeString = invokeString;
self.fourthController.view.frame = viewBounds;
//add them in a native ViewController environment like a Tabbar
self.tabBarController = [[[UITabBarController alloc] init] autorelease];
self.tabBarController.viewControllers = [NSArray arrayWithObjects:viewController, secondController, thirdController, fourthController, nil];
self.window.rootViewController = self.tabBarController;
[self.window makeKeyAndVisible];
return YES;
}
This is the error I get for each ViewController except for the first.
Error: executing module function 'setInfo' in module 'cordova/plugin/ios/device'. Have you included the iOS version of the cordova-1.9.0.js
and
ERROR: Attempting to call cordova.exec() before 'deviceready'. Ignoring.
Of course I refer to cordova-1.9.0 in my HTML files, I think Cordova was not designed to use multiple WebViews of it, but does anybody know how to change this?
The Answer is Cordova WebView. Designed to be embedded in native Applications.
edit
with Multiple Cordova Webviews, it has the same errors. I don´t know what´s the point of it when you can still only put one single Phonegap powered Webview in your project.
I confirmed this as a race condition in Cordova - the issue is fixed as of 2.4.0.

NSArray -initWithObjects: does not store objects

I'm getting a really bizarre output from that contructor. It does not actually store any of the objects. I debugged the method and the objects being stored are initialized properly.
I use this array to set the vc's on a UITabBarController and the tab bar is empty. Here's the code
-(void)initBarItemsWithAllFeatures {
/*
Issues
*/
UIImage *issuesImage = [UIImage imageNamed:#"issues_on.png"];
UITabBarItem *issuesTabBarItem = [[UITabBarItem alloc]initWithTitle:NSLocalizedString(#"IssuesTabBarTitle",#"") image:issuesImage tag:0];
[issuesImage release];
issuesNavigationController.tabBarItem =issuesTabBarItem;
[issuesTabBarItem release];
/*
thumbs
*/
ThumbsViewController *thumbsViewController = [[ThumbsViewController alloc]initWithNibName:#"ThumbsViewController" bundle:nil];
UIImage *thumbsImage = [UIImage imageNamed:#"thumbs_on.png"];
UITabBarItem *thumbsTabBarItem = [[UITabBarItem alloc]initWithTitle:NSLocalizedString(#"ThumbsTabBarTitle",#"") image:thumbsImage tag:1];
[thumbsImage release];
thumbsViewController.tabBarItem = thumbsTabBarItem;
[thumbsTabBarItem release];
/*
contents
*/
ContentsViewController *contentsViewController = [[ContentsViewController alloc]initWithNibName:#"ContentsViewController" bundle:nil];
UIImage *contentsImage = [UIImage imageNamed:#"contents_on.png"];
UITabBarItem *contentsTabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString (#"ContentsTabBarTitle",#"") image:contentsImage tag:2];
[contentsImage release];
contentsViewController.tabBarItem = contentsTabBarItem;
[contentsTabBarItem release];
/*
search
*/
SearchViewController *searchViewController = [[SearchViewController alloc]initWithNibName:#"SearchViewController" bundle:nil];
UIImage *searchImage = [UIImage imageNamed:#"search_on.png"];
UITabBarItem *searchTabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString (#"SearchTabBarTitle",#"") image:searchImage tag:3];
[searchImage release];
searchViewController.tabBarItem = searchTabBarItem;
[searchTabBarItem release];
/*
favourites
*/
FavouritesViewController *favouritesViewController = [[FavouritesViewController alloc]initWithNibName:#"FavouritesViewController" bundle:nil];
UIImage *favouritesImage = [UIImage imageNamed:#"favourites_on.png"];
UITabBarItem *favouritesTabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString (#"FavouritesTabBarTitle",#"") image:contentsImage tag:4];
[favouritesImage release];
favouritesViewController.tabBarItem = favouritesTabBarItem;
[favouritesTabBarItem release];
/*
contact
*/
ContactViewController * contactViewController = [[ContactViewController alloc] initWithNibName:#"ContactViewController" bundle:nil];
UIImage *contactImage = [UIImage imageNamed:#"contact_on.png"];
UITabBarItem *contactTabBarItem = [[UITabBarItem alloc] initWithTitle:NSLocalizedString (#"contactTabBarTitle",#"") image:contactImage tag:5];
[contactImage release];
contactViewController.tabBarItem = contactTabBarItem;
[contactTabBarItem release];
/*
add to an array
*/
allFeaturesAvailableTabBarItemArray = [[NSArray alloc] initWithObjects:
issuesNavigationController,
thumbsViewController,
contentsViewController,
searchViewController,
favouritesViewController,
contactViewController, nil];
/*
release objects
*/
[thumbsViewController release];
[contentsViewController release];
[searchViewController release];
[favouritesViewController release];
[contactViewController release];
}
Thanks in advance!
I think you may be over releasing the tab bar images (FWIW).
I ended up removing one by one the objects in the array to see which one was causing issues. the first object added was 0x0 (nil) so it didn't add anything to the array. The strange thing is that
on
issuesNavigationController.tabBarItem =issuesTabBarItem;
I'm calling properties on an nil object and fired no alarms. Is this "expected" or is it kind of a bug I should report?
Thank you very much to all of you for your quick answers.
I'm going to take care of the overrelease as well Thanks!

how to set individual tabbaritem icons in uitabbarcontroller in cocoa

I was answered how to set images in general for a uitabbarcontroller. however my uitabbarcontroller is an array of views that looks like:
tabBarController = [[UITabBarController alloc] init];
viewTab1controller = [[ViewTab1Controller alloc] initWithNibName:#"ViewTab1" bundle:nil];
viewTab1controller.title = #"Schedules";
navigationTab1Controller = [[[UINavigationController alloc] initWithRootViewController:viewTab1controller] autorelease];
[viewTab1controller release];
viewTab2controller = [[ViewTab2Controller alloc] initWithNibName:#"ViewTab2" bundle:nil];
viewTab2controller.title = #"Nearest Stop";
navigationTab2Controller = [[[UINavigationController alloc] initWithRootViewController:viewTab2controller] autorelease];
[viewTab2controller release];
viewTab3controller = [[ViewTab3Controller alloc] initWithNibName:#"ViewTab3" bundle:nil];
viewTab3controller.title = #"Routes";
navigationTab3Controller = [[[UINavigationController alloc] initWithRootViewController:viewTab3controller] autorelease];
[viewTab3controller release];
viewTab4controller = [[ViewTab4Controller alloc] initWithNibName:#"ViewTab4" bundle:nil];
viewTab4controller.title = #"Feedback";
navigationTab4Controller = [[[UINavigationController alloc] initWithRootViewController:viewTab4controller] autorelease];
[viewTab4controller release];
//viewTab5controller = [[ViewTab5Controller alloc] initWithNibName:#"ViewTab5" bundle:nil];
//navigationTab5Controller = [[[UINavigationController alloc] initWithRootViewController:viewTab5controller] autorelease];
//[viewTab5controller release];
tabBarController.viewControllers = [NSArray arrayWithObjects:
navigationTab1Controller,
navigationTab2Controller,
navigationTab3Controller,
navigationTab4Controller,
//navigationTab5Controller,
I was given the code in the previous answer to add an image to a tabbaritem:
viewController.tabBarItem.image = [UIImage imageNamed:#"foo.png"];
However this doesn't specify the specific tabbbaritem.
How do I assign an image to each of these 4 tabs?
Thanks!
nil];
Do it like this for each View Controller that you'll be adding to your Tab Bar:
viewTab1controller = [[ViewTab1Controller alloc] initWithNibName:#"ViewTab1" bundle:nil];
viewTab1controller.title = #"Schedules";
navigationTab1Controller = [[UINavigationController alloc] initWithRootViewController:viewTab1controller];
navigationTab1Controller.tabBarItem.image = [UIImage imageNamed:#"Match.png"];