Delegate won't work - objective-c

I have a simple delegate test, but for some reason it doesn't get called.
I want to call -(void)test from AppDelegate class via delegate.
/// AppDelegate.h
#import <Cocoa/Cocoa.h>
#protocol AppDelegateDelegate
#required
-(void)test;
#end
#interface AppDelegate : NSObject <NSApplicationDelegate> {
id<AppDelegateDelegate> _delegate;
}
#property(nonatomic, retain) id<AppDelegateDelegate> delegate;
#end
/// AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize delegate = _delegate;
-(void)awakeFromNib {
[_delegate test];
}
#end
/// test.h
#import <Foundation/Foundation.h>
#import "AppDelegate.h"
#interface test : NSObject <AppDelegateDelegate>
-(void)test;
#end
/// test.m
#import "test.h"
#implementation test
-(void)test {
//this should be called from AppDelegate
NSLog(#"delegate test");
}
#end

You are calling the delegate test method as soon as the AppDelegate class is loaded and no other class has had a chance to set themselves as the delegate. You need to call the delegate method after another class has had a chance to set itself as the delegate.
Also your delegate property should be defined as:
#property (assign) IBOutlet id <AppDelegateDelegate> delegate;

Related

add property to NSApplication/NSResponder causes error on macOS app

I am trying to migrate one iOS app to macOS, the code below work!
AppDelegate.h
#import <UIKit/UIKit.h>
#interface AppDelegate : UIResponder <UIApplicationDelegate>{
}
#property (nonatomic, assign) NSInteger myProperty;
#end
RootController.h
#import <UIKit/UIKit.h>
#interface RootController : UIViewController{}
#property (strong,nonatomic) AppDelegate *appDelegate;
#end
RootController.m
appDelegate =(AppDelegate *)[[UIApplication sharedApplication] delegate];
appDelegate.myProperty=5;
so I set the similar code on macOS app
AppDelegate.h
#import <AppKit/AppKit.h>
#import <CoreData/CoreData.h>
#import <Cocoa/Cocoa.h>
#interface AppDelegate :NSResponder <NSApplicationDelegate>{
}
#property (nonatomic, assign) NSInteger myProperty;
#end
AppDelegate.m
#import "AppDelegate.h"
#implementation AppDelegate
#synthesize myProperty;
#end
AppController.h
#import "AppDelegate.h"
#interface AppController : NSWindowController <>{
}
#property (strong,nonatomic) AppDelegate *appDelegate;
#end
AppController.m
//..
appDelegate =(AppDelegate *)[[NSApplication sharedApplication] delegate];
appDelegate.myProperty=5;//
cause error
[AppController setMyProperty:]: unrecognized selector sent to instance 0x7f8992b4a280
your comment welcome

"missing setter or instance variable" log message occurs initializing NSWindowController with Objective-C in Xcode:

Here is an abstract I took from an app that already works in which a parent window and sheet are processed. The abstract here compiles, launches, and displays the parent window without having received the message I sent to its text field. The run produces 'missing setter or instance variable' log messages for the text field, the button, and the window itself. For some reason I have not gotten the parent window to be properly initialized, and I suspect I will have the same problem with the sheet window but I can't get past this problem to debug the rest of the app.
I believe I have omitted something fundamental in the process of connecting the window to its File's Owner, even though when looking at the connections inspector for the .xib it shows the custom class to be the ParentClass and the various connections are made. I can find no instructions in Apple's labyrinthine documentation nor here in StackOverflow to guide me through the connection process that would allow me to discover the part(s) I'm missing.
Anything you can offer will be gratefully studied.
ParentDelegate.h
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#class ParentClass;
#interface ParentDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow * window;
#property (weak, nonatomic) ParentClass * parentController;
#end
ParentDelegate.m
#import "ParentDelegate.h"
#implementation ParentDelegate
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification { }
- (void)applicationDidBecomeActive:(NSNotification *)aNotification { }
- (void)applicationDidResignActive:(NSNotification *)aNotification { }
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication *)theApplication
{ return YES; }
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication *)sender
{ return NSTerminateNow; }
#end
ParentClass.h
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#interface ParentClass : NSWindowController {
}
#property (assign) IBOutlet NSWindow * window;
#property IBOutlet NSTextField * messageTextField;
#property IBOutlet NSButton * proceedButton;
#property (strong) NSMutableString * parentPropInfo;
- (IBAction) awakeFromNib;
- (IBAction) doProceed:(id)sender;
#end
ParentClass.m
#import "ParentClass.h"
#import "ParentDelegate.h"
#import "SheetClass.h"
#implementation ParentClass
ParentDelegate * parentDelegate;
SheetClass * sheetController;
- (IBAction)awakeFromNib {
parentDelegate = [NSApplication sharedApplication].delegate;
parentDelegate.parentController = self;
sheetController = [[SheetClass alloc] initWithWindowNibName: #"SheetClass"];
_messageTextField.stringValue = #"Click Proceed button";
}
- (IBAction)doProceed:(id)sender {
_parentPropInfo = #"Hello!".mutableCopy;
[NSApp runModalForWindow:sheetController.window];
// Sheet active now until it issues endModal, then:
_messageTextField.stringValue = sheetController.sheetPropInfo;
[NSApp endSheet: sheetController.window];
[sheetController.window orderOut:self];
}
#end
SheetClass.h
#import <Foundation/Foundation.h>
#import <Cocoa/Cocoa.h>
#interface SheetClass : NSWindowController {
}
#property (assign) IBOutlet NSWindow * window;
#property (weak) IBOutlet NSTextField * propTextField;
#property (weak) IBOutlet NSButton * returnButton;
#property (strong) NSMutableString * sheetPropInfo;
- (IBAction)awakeFromNib;
- (IBAction)doReturn:(id)sender;
#end
SheetClass.m
#import "SheetClass.h"
#import "ParentClass.h"
#implementation SheetClass
ParentClass * parent;
- (IBAction)awakeFromNib {
parent.window = self.window.sheetParent;
_propTextField.stringValue = parent.parentPropInfo;
}
- (IBAction)doReturn:(id)sender {
_sheetPropInfo = #"Done!".mutableCopy;
[NSApp stopModal];
}
#end
Ultimately I would like to use this mini-app as a starting template for several other apps.

Call Function When WebView Changes

So, I've been looking at the documentation and Googling, but I can't figure out how to call a method when my WebView (OSX, not iOS), changes... All the examples seem to be for iOS. My code looks like this:
SNAFAppDelegate.h
#import <Cocoa/Cocoa.h>
#import <WebKit/WebKit.h>
#interface SNAFAppDelegate : NSObject <NSApplicationDelegate>
#property (assign) IBOutlet NSWindow *window;
#property (assign) IBOutlet WebView *browser;
- (IBAction)forwards:(id)sender;
#end
SNAFAppDelegate.m
#import "SNAFAppDelegate.h"
#implementation SNAFAppDelegate
#synthesize window = _window;
#synthesize browser = _b;
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[[_b mainFrame] loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:#"https://google.com"]]];
}
#end
SNAFBrowser.h
#import <Cocoa/Cocoa.h>
#import <WebKit/WebView.h>
#import <WebKit/WebFrame.h>
#import <WebKit/WebEditingDelegate.h>
#import <WebKit/WebKit.h>
#interface SNAFBrowser : WebView
#property (assign) IBOutlet WebView *browser;
#end
SNAFBrowser.m
#import "SNAFBrowser.h"
#implementation SNAFBrowser
#synthesize browser = _b;
- (void)webViewDidChange:(NSNotification *)notification
{
NSLog(#"Hello World");
}
#end
Then, in my MainMenu.xib file, I linked the Outlet "browser" from the AppDelegate to the WebView and set the WebView's custom class to SNAFBrowser.
Essentially, I just want to know when the webview loads another page.
I'm probably doing something ridiculously stupid, so any help is appreciated.
Implement the WebFrameLoadDelegate protocol, and see which methods are suitable to implement, for example webView:didFinishLoadForFrame:.
Example:
#interface SNAFBrowser : WebView <WebFrameLoadDelegate>
...
#end
#implementation SNAFBrowser
- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
NSLog(#"Something got loaded!");
}
...
#end

Delegates issues

I can't get why I can't set delegate. I'm using UINavigationController to switch between two views. Here is my code
SecondViewProtocol.h
#import <Foundation/Foundation.h>
#protocol SecondViewProtocol <NSObject>
#required
-(void)textFieldDidChange:(NSString *)data;
#end
SecondView.h
#import <UIKit/UIKit.h>
#import "SecondViewProtocol.h"
#interface SecondView : UIViewController
#property (nonatomic, retain) id<SecondViewProtocol>delegate;
#end
SecondView.m
#synthesize delegate = _delegate;
.......
-(IBAction)textFieldReturn:(id)sender
{
[[self delegate] textFieldDidChange:[self.textField text]];
}
.......
I have imported SecondViewProtocol.h in FirstView.h
FirstView.m
....
SecondView *secondView = [[SecondView alloc]init];
secondView.delegate = self;
....
Here I get Assigning to id from incompatible type FirtView.
What is wrong here ?
First of all, delegate property should be declared as assign, not retain. You should never retain delegates.
Second, FirstView should conform to SecondViewProtocol like the following.
#interface FirstView: UIViewController <SecondViewProtocol>

Method in objective-c never called

I've got this class.
.h:
#import
#class GLEngine;
#interface opengl_engineAppDelegate : NSObject {
// Pointer to engine
GLEngine * myGLEngine;
UIWindow * window;
}
#property (nonatomic, retain) IBOutlet GLEngine * myGLEngine;
#property (nonatomic, retain) IBOutlet UIWindow * window;
#end
Here is .m:
#import "opengl_engineAppDelegate.h"
#import "GLEngine.h"
#implementation opengl_engineAppDelegate
#synthesize window;
#synthesize myGLEngine;
// Creating Application
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[myGLEngine activateEngine];
return YES;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[myGLEngine activateEngine];
}
// Destroying Application
- (void)dealloc {
[window release];
[myGLEngine release];
[super dealloc];
}
#end
And GLEngine looks like:
#import
#import
#import
#import
#import
#import
#interface GLEngine : UIView {
}
- (void)activateEngine;
#end
Why activateEngine never calls?
It looks like you are never allocing myGLEngine or setting it to anything. You should set a breakpoint at the activateEngine call and check that myGLEngine is actually the object you think it is.