Read delegate from view controller in tab bar application - iphone

I found several posts online stating that I could access my application delegate object from any view controller through the following call:
[[UIApplication sharedApplicaton] delegate];
(For instance: data between Views UIApplication, iOS - Calling App Delegate method from ViewController)
However, whenever I include this line in a function in one of my view controllers, the application crashes.
This is the first application that I'm writing, and I cannot see the difference between my code and how other posts have said I should be using this sharedApplication call. For completeness, below is an excerpt from my application delegate and view controller.
FirstViewController.h:
#class wStreamAppDelegate;
#define URL_ADDRESS #"http://google.com"
#interface FirstViewController : UIViewController <UIWebViewDelegate>{
IBOutlet UIWebView * webView;
wStreamAppDelegate* appDelegate;
}
#property(nonatomic,retain) wStreamAppDelegate* appDelegate;
#property(nonatomic,retain) IBOutlet UIWebView* webView;
FirstViewController.m:
#import "FirstViewController.h"
#import "wStreamAppDelegate.h"
#implementation FirstViewController
#synthesize webView,appDelegate;
#class wStreamAppDelegate;
- (void)viewDidLoad {
[super viewDidLoad];
NSString* urlAddress = URL_ADDRESS;
NSURL* url = [NSURL URLWithString:urlAddress];
NSURLRequest * requestObj = [NSURLRequest requestWithURL:url];
[webView loadRequest:requestObj];
self.appDelegate = (wStreamAppDelegate*)[[UIApplication sharedApplicaton] delegate];
//This doesn't work either
// wStreamAppDelegate *appDelegate= (wStreamAppDelegate*)[[UIApplication sharedApplicaton] delegate];
wStreamAppDelegate.h:
#interface wStreamAppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#end
If anyone has any thoughts on what may be going wrong, general advice for debugging problems like these, or tips, I'd really appreciate it. Thanks.

Typos get everyone sooner or later... in this case, you wrote "sharedApplicaton" instead of "sharedApplication".

Related

Null value when accessing variable in other classes (Combined Navigation & Tab Controller)

I have a navigation controller residing inside a tab bar controller and whenever I try to access a class from a class within the navigation controller all my values return (null).
This is how I'm trying to do it.
AppDelegate.h
#interface AppDelegate : UIResponder <UIApplicationDelegate, UITabBarControllerDelegate> {
NSString *searchQueryA;
}
#property (strong, nonatomic) NSString *searchQueryA;
ThirdViewController.h
#import "MasterViewController.h"
#import "AppDelegate.h"
#class MasterViewController;
#interface ThirdViewController : UIViewController {
code
}
#property (strong, retain) MasterViewController *masterViewController;
ThirdViewController.m
- (IBAction)showDetail:(id)sender {
AppDelegate *appDelegate = [[AppDelegate alloc] init];
appDelegate.searchQueryA = _searchField.text;
masterViewController = [[MasterViewController alloc] initWithNibName:#"MasterViewController" bundle:nil];
[self.navigationController pushViewController:masterViewController animated:YES];
}
MasterViewController.h
#import "AppDelegate.h"
#interface MasterViewController : UITableViewController
{
NSString *searchQueryM;
}
#property (nonatomic, strong) NSString *searchQueryM;
MasterViewController.m
AppDelegate *appDelegate = [[AppDelegate alloc] init];
searchQueryM = appDelegate.searchQueryA;
NSLog(#"%#", searchQueryM);
And in the log I can see that searchQueryM is (null). If I try to access the variable in AppDelegate from another class, that isn't involved with navigation controller, then it shows perfectly fine. What am I missing?
If you need to see more code I'd be happy to provide it.
EDIT:
For legibility I'll post code changes here:
I have the delegate in my AppDelegate.h
As Leonardo pointed out I only alloc'd and init'd my AppDelegate. I changed that snippet to this:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
searchQueryM = appDelegate.searchQueryA;
but still no go as searchQueryM still is (null).
This is what I do with searchQueryM
MasterViewController.h
#interface MasterViewController : UITableViewController
{
NSString *searchQueryM;
}
#property (nonatomic, strong) NSString *searchQueryM;
MasterViewController.m
#synthesize searchQueryM;
I'm fairly new to Objective-C (as well as OO-programming) and should probably read a book on it, but it seems to me like there isn't a lot more to it than that. Do correct me if I'm wrong.
EDIT 2
ThirdViewController.h
#interface ThirdViewController : UIViewController {
UITextField *_searchField;
}
#property (nonatomic, strong) IBOutlet UITextField *searchField;
ThirdViewController.m
#synthesize searchField = _searchField;
...
- (IBAction)showDetail:(id)sender {
_code_
NSLog(#"%#", searchField.text);
_code_
If i type in "asd" in the searchField textfield and output it with the log I get "asd".
}
Why are you alloc init your AppDelegate ?
The AppDelegate should be accessed with:
[[UIApplication sharedApplication] delegate]
We should see how you normally initialize searchQueryM, you are getting null, probably because the AppDelegate get only allocated and init, but the logic that initialize its properties never gets called.

Can't call controller method from delegate

I'm trying to do something like this: http://www.pushplay.net/2009/05/framework-for-having-multiple-views-in-an-iphone-app/
So far I've got this structure: appDelegate -> rootViewController -> welcomeViewController
I've a method (doSomething) in my delegate, which is called by an IBAction in welcomeViewController. It works, I can do an NSlog in doSomething and it shows the method is being called within the delegate.
The problem is when I run a command like [rootViewController loadNewView] in my doSomething method (in the delegate), it does nothing. It doesn't error, it just does nothing.
I've been reading and seen protocols and notifications are suggested, but I'd like to know why this method using the delegate doesn't work and if there is any way to fix it.
SurveyClientAppDelegate.h
#interface SurveyClientAppDelegate : NSObject <UIApplicationDelegate> {
UIWindow *window;
RootViewController *rootViewController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet RootViewController *rootViewController;
-(void)doSomething;
#end
SurveyClientAppDelegate.m
- (void)doSomething {
NSLog(#"Attempt: rootViewController loadLocationList");
[rootViewController loadLocationList];
}
RootViewController.h
#interface RootViewController : UIViewController {
WelcomeViewController *welcomeView;
}
#property (nonatomic, retain) WelcomeViewController *welcomeView;
#property (nonatomic, retain) SurveyListViewController *surveyList;
-(void)loadLocationList;
RootViewController.m
- (void)loadLocationList
{
NSLog(#"RootViewController: loadLocationList");
}
WelcomeViewController.h
#interface WelcomeViewController : UIViewController
-(IBAction)viewList:(id)sender;
-(void)loadLocationList;
WelcomeViewController.m
- (void)viewList:(id)sender
{
SurveyClientAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
[appDelegate doSomething];
}
Are you keeping a reference to rootViewContoller in your welcomeViewController? It's possible (and likely) that rootViewController will be released before you can call methods on it.
This is a good time to use delegates. You mention calling a method "in the delegate" but without seeing any of your code it's difficult to tell if you're using it correctly or not.

Xcode - warning problem

I have a navigation controller that utilizes an if statement to switch between the different views, and when i run it it comes up with a warning on the line:
ROSS_APP_7AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
warning: type 'id ' does not conform to the 'UITabBarControllerDelegate' protocol
I'd like some help on how to get rid of this warning.
Here is the whole if statement:
if(indexPath.row == 0)
{
MapDetailController *mapD = [[MapDetailController alloc] initWithNibName:#"MapDetailController" bundle:nil];
self.mapDetailController = mapD;
[mapD release];
mapDetailController.title = [NSString stringWithFormat:#"%#", [moreArray objectAtIndex:row]];
ROSS_APP_7AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
[delegate.moreNavController pushViewController:mapDetailController animated:YES];
}
Thanks
EDIT:
Here is what my AppDelegate looks like (response to answer #2)
#import <UIKit/UIKit.h>
#class MoreNavController;
#interface ROSS_APP_7AppDelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
IBOutlet UITabBarController *tabBarController;
IBOutlet MoreNavController *moreNavController;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (nonatomic, retain) IBOutlet MoreNavController *moreNavController;
#end
You probably forgot to have your app delegate conform to the UITabBarControllerDelegate protocol.
To implement it, your appDelegate header should look like this (the #interface declaration is the relevant line):
#import ...
#interface ROSS_APP_7AppDelegate : AppDelegate_Shared <UITabBarControllerDelegate>
{
....
}
#property(nonatomic, retain) .....
#end
You might be using AppDelegate_Shared / AppDelegate_iPhone / AppDelegate_iPad so bear in mind that the above example considers a shared app delegate
EDIT:
After seeing your comment,
Try replacing:
ROSS_APP_7AppDelegate *delegate = [[UIApplication sharedApplication] delegate];
With this:
ROSS_APP_7AppDelegate *delegate = (ROSS_APP_7AppDelegate*)[[UIApplication sharedApplication] delegate];
Does typecasting the return like this get rid of your warning?
Have you tried casting the delegate as in:
(id)[[UIApplication sharedApplication] delegate];
???

data between Views UIApplication

i want to share data between views...
i have the appdelegate of tabbar application:
myappdelegate.h
#import <UIKit/UIKit.h>
#interface myappdelegate : NSObject <UIApplicationDelegate, UITabBarControllerDelegate> {
UIWindow *window;
UITabBarController *tabBarController;
NSString *result;
}
#property (nonatomic, retain) IBOutlet UIWindow *window;
#property (nonatomic, retain) IBOutlet UITabBarController *tabBarController;
#property (copy , readwrite) NSString *result;
#end
if i want to call with this command, there is the hint: "may not respond"....
myappdelegate *dataCenter = [(myappdelegate *)[UIApplication sharedApplication] delegate]; <<may not respond
dataCenter.result = #"msg";
result_view *resultView = [[result_view alloc] initWithNibName:#"result_view" bundle:nil];
[self.navigationController pushViewController:resultView animated:YES];
[resultView release];
result_view.m
- (void)viewDidLoad
{
myappdelegate *dataCenter = (myappdelegate*)[[UIApplication sharedApplication]delegate];
[label setText:dataCenter.result];
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
}
the program crashes...
Your code is saying that the sharedApplication is of the class myappdelegate, which indeed does not respond to delegate. Do this:
(myappdelegate *)[[UIApplication sharedApplication] delegate];
to remove the warning.
Due to Objective-C's runtime messaging, your current (warning-generating) code won't crash the app. The crash lies somewhere else.
Your first line should be
myappdelegate *dataCenter = (myappdelegate *)[[UIApplication sharedApplication] delegate];
As for the second line, I can't tell what you expect to happen. You don't have a result_array property on your myappdelegate class, so of course you can't set that property.
If you were trying to set the result property, you should have written
dataCenter.result = #"msg";

Calling delegate method from popover class

I'm new to Objective C and I'm having trouble getting delegates to work in my code.
I have a class called cViewController and in this class has a UIWebView to fetch webpages and a button above it that calls a popover class called prodMenu. What I'm having trouble with is that the function to call webpages from the prodMenu class and display it on the parent UIWebView isn't working.
cViewController.h
#import <UIKit/UIKit.h>
#import "prodMenu.h"
#interface cViewController : UIViewController <prodMenuDelegate>{
UIPopoverController *cpopover;
IBOutlet UIWebView *webImageDisplay;
}
#property (nonatomic, retain) UIWebView *webImageDisplay;
#property (nonatomic, retain) UIPopoverController *cpopover;
- (IBAction)cPopoverTapped:(id)sender;
- (void) fetchWebsite:(NSString *)website; //This is the delegate method I'm trying to call in the popover class.
#end
cViewController.m
- (IBAction)cPopoverTapped:(id)sender {
prodMenu *tp = [[prodMenu alloc] init];
cpopover = [[UIPopoverController alloc] initWithContentViewController:tp];
[tp release];
CGRect rect = CGRectMake(40, 0, 50, 50);
cpopover.popoverContentSize = CGSizeMake(250, 225);
[cpopover presentPopoverFromRect:rect inView:self.view permittedArrowDirections:UIPopoverArrowDirectionUp animated:YES];
}
- (void)fetchWebsite:(NSString*)website{ //This function is called by prodMenu class
NSLog(#"address: %#", website);
NSString *urlAddress = website;
NSURL *url = [NSURL URLWithString:urlAddress];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[webImageDisplay loadRequest:requestObj];
[webImageDisplay release];
}
- (void)viewDidLoad {
[self fetchWebsite:#"http://www.yahoo.com"];
[super viewDidLoad];
}
prodMenu.h
#import <UIKit/UIKit.h>
#protocol prodMenuDelegate;
#interface prodMenu : UIViewController{
<prodMenuDelegate> delegate;
}
- (IBAction)radBtn:(id)sender; //This is the IBAction that calls the fetchWebsite function
#property (nonatomic, assign) id <prodMenuDelegate> delegate;
#end
#protocol prodMenuDelegate
- (void)fetchWebsite:(NSString *)website;
#end
prodMenu.m
#import "prodMenu.h"
#import "cViewController.h"
#implementation prodMenu
#synthesize delegate;
- (IBAction)radBtn:(id)sender{
[delegate fetchWebsite:#"http://www.google.com"]; //Here is the call to the method
}
Am I missing something here to call the delegate method? There aren't any errors or warnings. All I want to do is when the user presses a button on the popover view, the parent class underneath changes the webpage. Thanks in advance.
Just a quick idea. Have you tried declaring the delegate protocol like this
#protocol prodMenuDelegate <NSObject>
...
#end
? I often ran into troubles when omitting the < NSObject >. Also I think there is an 'id' missing in
#interface prodMenu : UIViewController{
<prodMenuDelegate> delegate;
}
Edit: Also, in the code you posted I do not see where you actually assign the prodMenu's delegate.