How to call a ViewController.m method from the AppDelegate.m - objective-c

In my ViewController.m I have my void "Save Data":
#import "ViewController.h"
#interface ViewController ()
#end
#implementation ViewController
#synthesize myDatePicker, myTextField;
-(void)saveData
{
NSArray *value = [[NSArray alloc] initWithObjects:[myTextField text],[myDatePicker date], nil];
[value writeToFile:[self getFilePath] atomically:YES];
}
And I want to use my void "Save Data" in my AppDelegate.m :
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[self.ViewController saveData];
}
But Xcode doesn't recognize the "ViewController" neither "saveData".
I don't know if I have to #import something in my AppDelegate, please help.

How you access your viewcontroller from the app delegate will depend on how many viewcontrollers you have / where it is in your current navigation hierarchy, etc etc. You could add a property for it, or perhaps it will be your app delegate's rootViewController.
However, you'd probably be better off listening out for a notification in your viewcontroller when the app enters the background. This means that the logic you need can be entirely self contained within your viewcontroller, and your app delegate doesn't need to know anything about it.
In your viewcontroller's initialization method, you can register to receive notifications:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationDidEnterBackground:)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
Then, implement the method:
- (void)applicationDidEnterBackground:(NSNotification *)notification
{
[self saveData];
}
And make sure you also remove yourself as an observer in your viewcontroller's dealloc method:
-(void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidEnterBackgroundNotification object:nil];
}

In your "appDelegate.m" implementation file at the top do this import ->
#import "ViewController.h"
This will make the custom class ViewController visible to the appDelegate.
In order to be able to call the -(void)saveData method from another class (in our case the other class is the AppDelegate class), this method needs to be declared in the public interface. That means ->
#import "ViewController.h"
#interface ViewController ()
-(void)saveData;
#end

Related

how to call a method from one controller to another controller in Objective-C

Hello everyone, I am a beginner in Mac OS Developer. I have a problem when calling a method in a controller named Controller1.
Here is my code for Controller1:
Controller1.h
#import <Cocoa/Cocoa.h>
#interface Controller1 : NSViewController
- (void)LoadViewActiveCall;
#end
Controller1.m
#import "Controller1.h"
#implementation Controller1
- (void)showCallViewController:(NSViewController*)target_viewcontroller2{
NSLog(#"Run method showCallViewController");
NSLog(#"Parameter targe view controller 2 : %#",target_viewcontroller2);
if(current_controller2!=nil){
[current_controller2.view removeFromSuperview];
[current_controller2 removeFromParentViewController];
}
[self addChildViewController:target_viewcontroller2];
target_viewcontroller2.view.frame=container_Call.frame;
[container_Call addSubview:target_viewcontroller2.view];
current_controller2=target_viewcontroller2;
}
- (void)LoadViewActiveCall {
[self showCallViewController:vCall];
NSLog(#"keluar active call berhasil");
}
#end
I want call LoadViewActiveCall method on button IBAction of Controller2
Controller2.h
#import <Cocoa/Cocoa.h>
#import "Controller1.h"
#interface Controller2 : NSViewController
- (IBAction)audioCall:(id)sender;
#end
Controller2.m
#import "Controller1.h"
#import "Controller2.h"
#implementation Controller2
- (IBAction)audioCall:(id)sender {
Controller1 *co1 = [[Controller1 alloc] init];
[co1 LoadViewActiveCall];
}
#end
My problem is when I press audioCall button, but LoadViewActiveCall method is not being called.
I am sorry for my bad english
The way you are calling a function from another view controller is correct only.
Please check whether you have connected the button action correctly to the function
- (IBAction)audioCall:(id)sender
pleas echeck it and reply. It is perfectly working for singleview application for ios using UIViewcontroller
Add NSNotificationCenter to call a method.
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(audioCall:) name:#"notificationName" object:nil];
-(void) audioCall:(NSNotification*)notification
{
}
post the notification from the second view controller as below.
[[NSNotificationCenter defaultCenter] postNotificationName:#"notificationName" object:obj];
Initialize the SecondViewController in your FirstViewController.
let vc = self.storyboard?.instantiateViewController(withIdentifier:
"SecondViewController") as! SecondViewController
add the method you want to call in SecondViewController header file (SecondViewController.h)
#interface SecondViewController : NSViewController
- (void) LoadViewActiveCall;
Then call from FirstViewController
let vc = self.storyboard?.instantiateViewController(withIdentifier: "SecondViewController") as! SecondViewController
[vc LoadViewActiveCall];

Add notification observer to custom class

I am new to Objective-C and I’m having trouble adding a notification observer. I have a class CoreDataStack that’s a subclass of NSObject. I am trying to add notification observers for iCloud sync but I keep getting compiler errors. Code sense is not picking up on NSNotificationCenter. As far as I know there isn’t anything extra I need to import. I must be missing something really obvious.
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(persistentStoreCoordinatorStoresDidChange:)
name:NSPersistentStoreCoordinatorStoresDidChangeNotification
object:self.persistentStoreCoordinator];
- (void)persistentStoreCoordinatorStoresDidChange:(NSNotification*)notification {
NSLog(#"persistentStoreDidImportUbiquitousContentChanges");
}
Here are the errors it's giving me:
Missing '[' at start of message send expression
Use of undeclared identifier 'self'
Expected identifier or '('
Your string [[NSNotificationCenter defaultCenter] addObserver... is written correctly but you have to put it inside some method, not to the top level as it is now.
For example this method can be put inside your AppDelegate:
#import <CoreData/CoreData.h>
#interface AppDelegate ()
#property (nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
...
#end
#implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Initialize self.persistentStoreCoordinator somehow....
// ...
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(persistentStoreCoordinatorStoresDidChange:)
name:NSPersistentStoreCoordinatorStoresDidChangeNotification
object:self.persistentStoreCoordinator];
return YES;
}
- (void)persistentStoreCoordinatorStoresDidChange:(NSNotification*)notification {
NSLog(#"persistentStoreDidImportUbiquitousContentChanges");
}
Of course any other class will also work, just make that string [[NSNotificationCenter defaultCenter] addObserver... to be a part of some executable method.

NSApplicationDelegate application:openFile. Never reaches to openFile: function

I want to open a file dropping it on the app icon.
When I do it my app is opened so the file extension is well defined and related to my app.
But the application:openFile: function never is called. so I can't open the file dropped in my app.
I traced openFile: but never goes.
All the answers that I found are just to add in the delegate the openFile: and that's all but not in my case.
Any help will be very appreciate it. Thanks a lot in advance.
This is my environment.
The plist has got the extension of files to be opened. My app is opened when I drop the files.
I initialize my delegate at the beggining of the app,
mydelegate = [[MyController alloc] init];
And in the delegate,
in the include,
#interface MyController : NSObject <NSApplicationDelegate> {
#private
NSWindow *window;
}
#property (assign) IBOutlet NSWindow *window;
-(id) init;
-(BOOL) application: (NSApplication*)sharedApplication openFile:(NSString*) fileName;
#end
And in the .m file,
#implementation MyController
#synthesize window;
- (id)init{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(applicationWillFinishLaunching:)
name:NSApplicationWillFinishLaunchingNotification object:nil];
}
return self;
}
- (void) applicationWillFinishLaunching:(NSNotification *)aNotification{
NSLog(#"applicationWillFinishLaunching");
}
-(BOOL) application: (NSApplication*)sharedApplication openFile:(NSString*) fileName {
NSLog(#"openFile=%#", fileName);
return YES;
}
#end
At least in the code provided above, you are not explicitly setting the app's delegate to be an instance of MyController. Are you setting the delegate anywhere?
Immediately following [[MyController alloc] init], try this:
[[NSApplication sharedApplication] setDelegate: mydelegate];
Without making this connection, the app won't know who is supposed to handle delegate responsibilities.
OR
The most common way to handle drag and drop onto the dock icon is to simply implement:
-(BOOL)application:(NSApplication *)sender openFile:(NSString *)path
as part of the AppDelegate class that is auto-generated for you by Xcode when you start a project.
If you have an AppleEvent event handler listening to for 'odoc' Open Document apple events:
NSAppleEventManager.shared().setEventHandler(self,
andSelector: #selector(handle(event:replyEvent:)),
forEventClass: AEEventClass(kCoreEventClass),
andEventID: AEEventID(kAEOpenDocuments))
Then the handler will intercept the calls and the normal App Delegate methods will not be called.

Delegate - How to Use?

I think I understand the logic behind a delegate. I got more the problem to use it. How many steps are involved? Do I have to use existing delegates? Or can I use my one ones?
In my example I got the AppDelegate that created many views (Objects / View Controllers) of the same type. Each view should somehow call a method on the AppDelegate to close itself. This would happen when a button within the view is touched. The method call would include the reference of the view (self).
So far I know from other languages responders, event listeners and so on. They are so simple to use.
Can anybody help me. I just found massive examples with a lot of code in the web. It can't be that hard to just call a parent in Objective C.
I think you should use for this the NSNotificationCenter
in you AppDelegate.m
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
...
...
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(buttonPushed:) name:#"ButtonPushedNotification" object:nil];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
...
...
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
this is the selector it will be called when the notification happens (we are still in the AppDelegate.m)
- (void)buttonPushed:(NSNotification *)notification {
NSLog(#"the button pushed...");
}
and in the ViewController.m when the button pushed (inside the method), you should post a notification like this:
{
...
[[NSNotificationCenter defaultCenter] postNotificationName:#"ButtonPushedNotification" object:nil];
...
}
You can create your own:
In MyView1.h:
#class MyView1;
#protocol MyView1Delegate <NSObject>
- (void)closeMyView1:(MyView1 *)myView1;
#end
#interface MyView1 : NSObject
{
id<MyView1Delegate> _delegate;
}
#property (assign, nonatomic, readwrite) id<MyView1Delegate> delegate;
...
#end
In MyView1.m:
#interface MyView1
#synthesize delegate = _delegate;
...
// The method that tells the delegate to close me
- (void)closeMe
{
....
if ([_delegate respondsToSelector:#selector(closeMyView1:)])
{
[_delegate closeMyView1:self];
}
}
#end
In AppDelegate.h:
#import "MyView1.h"
#interface AppDelegate <MyView1Delegate>
{
MyView1 *_myView1;
}
...
#end
In AppDelegate.m:
- (void)someCreateViewMethod
{
_myView1 = [[MyView1 alloc] initWithFrame:NSMakeRect(0, 0, 100, 200)];
[_myView1 setDelegate:self];
...
}
An easy way to get what you want is to just start with one view. Then, have each other view be presented modally. When the button in the view is pressed do
[self dismissModalViewControllerAnimated:YES];
And here's something I made a while ago when I was starting iPhone development that might help you with delegates
Delegates
//In parent .m file:
//assign the delegate
- (void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if([segue.identifier isEqualToString:#"segueName"])
{
childController *foo = segue.destinationViewController;
foo.delegate = self;
}
}
//implement protocol method(s):
- (void) methodName:(dataType*) dataName
{
//An example of what you could do if your data was an NSDate
buttonLabel.titleLabel.text = [[date description] substringToIndex:10];
}
//In parent .h file:
//import child header
#import "ChildName.h"
//indicate conformity with protocol
#interface ParentName : UIViewController <ChildNameDelegate>
//In child .h file
//declare protocol
#protocol ChildNameDelegate
- (void) methodName:(dataType*) dataName;
#end
//declare delegate
#property (unsafe_unretained, nonatomic) id<ChildNameDelegate> delegate;
//In child .m file
//synthesize delegate
#synthesize delegate;
//use method
- (IBAction)actionName:(id)sender
{
[delegate methodName:assignedData];
}

Calling selectors from multiple file

In AppDelegate.m, I've defined
#import "AppDelegate.h"
#import "allerta.h"
#implementation AppDelegate
#synthesize window = _window;
-(void)awakeFromNib {
// Add an observer that will respond to loginComplete
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(alerticonstatus:)
name:#"alert" object:nil];
// Post a notification to loginComplete
[[NSNotificationCenter defaultCenter] postNotificationName:#"alert" object:nil];
}
#end
I want to call alerticonstatus from allerta.h:
#import <Foundation/Foundation.h>
#interface allerta : NSObject{
}
-(void)alerticonstatus:(NSNotification *)note;
#end
allerta.m:
#import "allerta.h"
#implementation allerta
-(void)alerticonstatus:(NSNotification *)note {
NSLog(#"called alerticonstatus");
}
#end
Can I import a function whit #selector from another file like allerta.h?
Now I have SIGABRT error.
Can you help me? Thanks.
Change you method for this, it work:
#import "AppDelegate.h"
#import "allerta.h"
#implementation AppDelegate
#synthesize window = _window;
-(void)awakeFromNib {
allerta *_allerta = [allerta alloc]; //allocation memory
// Add an observer that will respond to loginComplete
[[NSNotificationCenter defaultCenter] addObserver:_allerta //here you called self, but you need to call your class allerta
selector:#selector(alerticonstatus:)
name:#"alert" object:nil];
[_allerta release]; //kill _allerta class if you don't need more
// Post a notification to loginComplete
[[NSNotificationCenter defaultCenter] postNotificationName:#"alert" object:nil];
}
#end
When you create class files, set firs letter big, like as "Allerta".
I think your problem is that you declare AppDelegate as receiver of alerticonstatus message when AppDelegate doesn't have this method declared. You are doing this in this line:
[[NSNotificationCenter defaultCenter] addObserver:self
selector:#selector(alerticonstatus:)
name:#"alert" object:nil];
Your solution would be to change observer from self which in this case is AppDelegate to some allerta object. Just alloc-init some allerta object and add it as observer.