I'm trying to call a method that's inside someClass from the AppDelegate class.
I usually create an instance and then using that instance, call the method. Like so:
FFAppDelegate *delegate = (FFAppDelegate *) [[UIApplication sharedApplication] delegate];
[delegate someMethod];
I use that ^^ quite a bit in my code and it works perfectly. What I want to do, is switch it around. Instead of calling a method INSIDE the AppDelegate, I want to call a method inside another class FROM the AppDelegate.
SomeClass *test = (SomeClass *) [[UIApplication sharedApplication] delegate];
[test someMethod];
In this case, I keep getting "Terminating app due to uncaught exception 'NSInvalidArgumentException'" error due to "unrecognized selector sent to instance".
Any light shed on the matter would be greatly appreciated! :)
[[UIApplication sharedApplication] delegate]; return your AppDelegate class , not SomeClass
you can use like this :
FFAppDelegate *delegate = (FFAppDelegate *) [[UIApplication sharedApplication] delegate];
[delegate someMethodForSomeClass];
And then in your AppDelegate code someMethodForSomeClass like this :
- (void)someMethodForSomeClass
{
SomeClass *someClass = _yourSomeClass;
[someClass someMethod];
}
Instantiate an instance of the class that you want to send the request from and make the method public (in the .h file). Then import that class into the app delegate and call it.
Like so...
YourClass * yourClassInstance = [[YourClass alloc] init];
[yourClassInstance someMethod];
in YourClass.h below the #interface you would declare the method like so
-(void)someMethod;
So anyone could access it.
For Example if you want to Create AlertView only Once and Use it in any UiViewController
So, you can make Method For UIAlertView and Call the Method When you Want
1)In your appDelegate.h file
#property (nonatomic, strong) UIAlertView *activeAlertView;
2) In your AppDelegate.m File
-(void)openAlert
{
NSString *strMsgPurchase = #"Write your message";
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Buy" message:strMsgPurchase delegate:self cancelButtonTitle:#"Cancel" otherButtonTitles:#"Buy",#"Restore", nil];
[alert setTag:100];
[alert show];
self.activeAlertView = alert;
}
3) To Call the Method in which uiview you want
[((AppDelegate *)[[UIApplication sharedApplication] delegate])openAlert];
Note: Define -(void)openAlert Method in Appdelegate.h file
Related
I like to show the latest Push Notification in a label in my main StoryBoard I use this code to display the alert message in my AppDelegate.m:
-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
NSDictionary *test =(NSDictionary *)[userInfo objectForKey:#"aps"];
NSString *alertString =(NSString *) [test objectForKey:#"alert"];
NSLog(#"String recieved: %#",alertString);
UIApplicationState state = [[UIApplication sharedApplication] applicationState];
if (state == UIApplicationStateActive) {
UIAlertView *alertmessage=[[UIAlertView alloc]initWithTitle:#"Geier"
message:alertString delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertmessage show];
AudioServicesPlaySystemSound(1002);
}
}
i tried this in my ViewController.m file latestpush.text = #"%#",alertString; but it doesn't work.
Can someone help me?
Thanks:)
You need to make the text available to the view controller.
You could do this by sending a custom NSNotification with the alert message, from inside application:didReceiveRemoteNotification:
[[NSNotificationCenter defaultCenter]
postNotificationName:#"PushAlertNotification"
object:self
userInfo:#{#"alertString":alertString}];
In your view controller's viewDidLoad method, register as an observer:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(updateStoryboard:)
name:#"PushAlertNotification"
object:nil];
and create the updateStoryboard: method in the view controller:
- (void) updateStoryboard:(NSNotification *) notification {
self.latestpush.text = notification.userInfo[#"alertString"];
}
An alternative solution is to create a property in your AppDelegate that takes in the ViewController as an observer.
AppDelegate.h (change ViewController to the actual type of your VC).
#property (nonatomic, weak) ViewController *observer;
Inside the ViewController create a method that accepts the NSString and have that method update your Storyboard.
ViewController.m
-(void)updateStoryboard(NSString *alertString) {
self.latestpush.text = alertString;
}
Also, in your ViewContoller's viewDidLoad method, register yourself with the appDelegate:
- (void)viewDidLoad {
[super viewDidLoad];
AppDelegate *delegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
delegate.observer = self;
}
Call updateStoryboard inside your application:didReceiveRemoteNotification: method:
[self.observer updateStoryboard:alertString];
I have been trying for days to get this code to work, but I have no idea what I am doing wrong. Everytime the app wakes up from sleep, or the user closes the app and opens it again (without closing the app from multitasking), I want a label value to change.
In my applicationDidBecomeActive, I am running a counter, which I want to display on whatever viewcontroller is open at that moment.
Code:
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel];
}
In my viewcontroller W1G1, I have the following code:
Code:
- (void) setlabel {
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
I have imported W1G1 in my appdelegate, but the code does not run :( Please help!
Thanks
In the AppDelegate.m file, where you have
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel];
}
the variable counter being incremented is confined to the AppDelegate. In other words, your view controller doesn't know that it has been incremented.
I would suggest that you use NSUserDefaults to store the value of counter so that you can easily pass it between these view controllers. Either that, or you could allow for an input into the method setLabel, e.g.
- (void) setlabel:(int)counter {
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
and then in the AppDelegate you'll want to do:
- (void)applicationDidBecomeActive:(UIApplication *)application {
counter = counter + 1;
W1G1 *view1 = [[[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil] retain];
[view1 setlabel:counter]; // <-- now you're using counter
[self.window addSubview:view1];
}
1) When you say 'the code does not run' do you mean that? That is, if you put NSLogs in applicationDidBecomeActive: and in setLabel does it show the code is run?
2) I would suspect the code is running. But your code won't "show the counter on whatever view controller is open at that moment". Your code creates a new view (view1), but that view won't be displayed. It is not added as a subview to anything. Your code will also leak. You create a W1G1 object, but it is never released and you throw away any reference you have to it.
To achieve what you want, you could add a subview to the application's window. Depending how your app delegate is set up, something like the following should do the trick:
counter++;
W1G1 *viewController1 = [[W1G1 alloc] initWithNibName:#"W1G1" bundle:nil];
[viewController1 setlabel: counter];
[[self window] addSubview: [viewController1 view]]
// you'll want to save a reference to the viewController somehow so you can release it at a later date
Then in W1G1
- (void) setlabel: (int) counter;
{
NSString *string = [NSString stringWithFormat:#"%d", counter];
vocabword.text = string;
}
There are, of course, lots of other approaches you could take towards this problem. And you'll need some strategy for removing the W1G1 view that you are adding at some stage, otherwise you'll just get more and more views added.
Update: You ask (in comments) how to keep track of your viewController throughout lifetime of the app... One approach is to keep track of it in your appDelegate. In the header have something like:
#class W1G1;
#interface MyAppDelegate : : NSObject <UIApplicationDelegate>
{
// other decelerations
int counter;
W1G1 * _myW1G1
}
#property (nonatomic, retain) W1G1* theW1G1
In the .m file include
#synthesize theW1G1 = _myW1G1;
Probably in application:didFinishLaunchingWithOptions: create the viewController, set the property to refer to it, and add its view to the view hierarchy.
W1G1* theViewController = [[W1G! alloc] initWithNibName: #"W1G1" bundle: nil];
[[self window] addSubview: [theViewController view]];
[self setTheW1G1: theViewController];
[theViewController release];
Then when you want to access the viewController again from with the app delegate use [self theW1G1], e.g.
[[self W1G1] setlabel: counter];
Hi there I currently I have a warning on a line of code where I am trying to push a new view onto the screen.
Outline // my NSObject receives a code=1 from my server I have set up. Everything works fine the code comes through which then initializes an AlertView where I have set up an if statement to catch the button click of my AlertView message. When that button is pressed my application falls over.
I have declared my ViewController of the view I am trying to push in its header file and there are no errors just the warning when compiled.
this is my NSObject I have made
/////.h
#import <Foundation/Foundation.h>
#interface alerts : NSObject {
}
- (void)pleaseRegisterDevice;
#end
/////.m
#import "alerts.h"
#import "instaCode1_3AppDelegate.h"
#import "RegisterDeviceViewController.h"
#implementation alerts
//use this alert when phone falls out of sync
- (void)pleaseRegisterDevice {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Please Register Device"
message:#"click OK to register"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert autorelease];
[alert show];
}
//Catch pleaseRegisterDevice method
- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex {
NSString *buttonTitle=[alertView buttonTitleAtIndex:buttonIndex];
if ([buttonTitle isEqualToString:#"OK"]) {
NSLog(#"msg from alertView method");
//open new wndow
RegisterDeviceViewController *regViewController = [[RegisterDeviceViewController alloc] init];
//Push it onto the top pf the navigation controller's stack
**[[self navigationController] pushViewController:regViewController animated:YES];**
}
else {
NSLog(#"was not able to push view");
}
}
- (void)dealloc {
[super dealloc];
}
#end
I have bolded the line of code where I get the warning 'alerts' may not respond to -navigationController
any help would be greatly appreciated.
I dont think an NSObject subclass has a UINavigationController...
You need to get a pointer to your app delegate's navigation controller like so
MyAppDelegate *appDelegate = (MyAppDelegate *)[[UIApplication sharedApplication] delegate];
[appDelegate.navigationController pushViewController:regViewController animated:YES];
navigationController is a property defined on a UIViewController. A NSObject does not have this method.
You don't have any instance member or method called navigationController, hence the warning.
I am trying to make an app that contains a class that is created in the app delegate.
I initialize it with:
Mobile *tmp = [[Mobile alloc] init];
mobile = tmp;
[tmp release];
and then I try to use it in other classes in my app with this:
projectAppDelegate *delegate = (projectAppDelegate *)[[UIApplication sharedApplication] delegate];
mobile = delegate.mobile;
but when I do something like:
[mobile enter:x :y];
it crashes...
Is there something I did wrong, or is there any solution for making a class that all the other classes in the app can use?
Thank you.
If you want to use instances of your object you have to store them as properties of app delegate.
//appdelegate.h
//
//...
//
#interface AppDelegate : NSObject <UIApplicationDelegate> {
Mobile *tmp;
}
//...
//appdelegate.m
//
//...
//
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
mobile = [[Mobile alloc]init];
}
//...
- (void)dealloc {
[mobile release];
[super dealloc];
//...
}
Than you have to get a pointer to your application delegate shared instance and call your mobile property.
//... Somewhere
AppDelegate* ref = (AppDelegate*) [[UIApplication sharedApplication] delegate];
NSLog(#"%#", [ref mobile]);
//...
In your first code snippet you are effectively creating and immediately destroying the object. If the object is supposed to persist after that method is done executing you should just use
mobile = [[Mobile alloc] init];
I'm currently using a UIAlertView at startup in my app with the UIAlertViewDelegate. It all works fine. The only problem is, I get the warning "type 'id ' does not conform to the 'UIAlertViewDelegate' protocol" every time I reference the App Delegate, giving me about 32 warnings.
Can anyone shed some light on why I'm getting this warning and how I can satisfy it?
Thanks in advance!
I assuming your app delegate is your alert view delegate?
If so, you need to tell the compiler that in the declaration of the app delegate. Like so:
#interface SomeAppDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate> {
}
// ... rest of interface
#end
And then you also need to implement the required methods.
EDIT: Thinking about it further, I think probably you're missing a cast when you reference the app delegate. So you have something like this:
MyAppDelegate* appDelegate = [[UIApplication sharedApplication] delegate];
// what you want is:
MyAppDelegate* appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
It might not exist on the main thread, try
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"My Title"
message:#"My message"
delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView performSelectorOnMainThread:#selector(show) withObject:nil waitUntilDone:NO];