Unable to access protocol methods via delegate - objective-c

While accessing protocol methods via delegate I'm getting following error:
"No known instance method for selector 'lostConnection'"
Swift Protocol:
#objc protocol GameDelegate {
func lostConnection()
}
Objective C game file
//game.h
#protocol GameDelegate;
#interface SSStreamManager : NSObject
#property (assign) id<GameDelegate> delegate
#end
Getting error while calling protocol methods
[self.delegate lostConnection]; // No known instance method for selector 'lostConnection'

You haven't shown any real code, but here's an example that will get you started. These are the three files in an iOS app project:
ViewController.swift
import UIKit
#objc protocol GameDelegate {
func lostConnection()
}
class ViewController: UIViewController {
}
Thing.h
#import <Foundation/Foundation.h>
#protocol GameDelegate;
#interface Thing : NSObject
#property (assign) id<GameDelegate> delegate;
#end
Thing.m
#import "Thing.h"
#import "MyApp-Swift.h"
#implementation Thing
- (void) test {
[self.delegate lostConnection];
}
#end
That compiles. You should be able to follow this model in your own code.

Related

Objective C forward declared protocol methods types are not available on Swift

I have the following Objective C class header :
#protocol CustomKeyboard;
#class CustomKeyboardView;
#protocol CustomKeyboardViewProtocol <NSObject>
- (void)customKeyboardView:(UIView<CustomKeyboard> *)customKeyboard numberPress:(UIButton *)sender;
#end
#protocol CustomKeyboard <NSObject>
#required
-(id)initWithDelegate:(id<CustomKeyboardViewProtocol>)delegate;
-(void)reload;
#property (nonatomic, weak) UITextField * textField;
#property (nonatomic, weak) id<CustomKeyboardViewProtocol> delegate;
#end
#interface CustomKeyboardView : UIView <CustomKeyboard>
{
IBOutlet UIView *keyboardView;
}
- (void)hide;
- (void)show;
#end
And this class in Swift is trying to adopt the protocol but I am getting an error about the types in the methods and autocomplete is gone:
extension MyViewController: CustomKeyboardViewProtocol {
func customKeyboardView(_ customKeyboard: UIView!, numberPress sender: UIButton!) {
}
}
The error says:
Candidate has non-matching type '(UIView!, UIButton!) -> ()'
Any clues if the error is because circular dependency in the protocols or is it about the types? I just updated to Xcode 9 and Swift 4, and updated to recommended settings, it used to work just fine.

Use delegate in objective c class to call swift method

I have two files
Question.m
Question.h
These two are written by Objective-C
MainView.swift
This is written by Swift
Question Class has the delegate
#interface Question : NSObject{
id delegate;// put MainViewController here
- (void)trythisfunction{
[delegate test] // compiler doesn't find this method.
}
}
and I make class instance and put MainViewController as delegate of Question in MainViewController.swift
class MainViewController: UIViewController {
override func viewDidLoad(){
q = Question()
q.delegate = self // put self in delegate
}
func test(){
NSLog("test is OK")
}
}
However Compiler found error [delegate test]
Question.m:169:19: No known instance method for selector 'test:'
How can I solve this??
You need to make few changes.
Below class declaration doesn't compile because you can't declare variables inside interface.
#interface Question : NSObject{
id delegate;
- (void)trythisfunction {
[delegate test]
}
}
I have fixed above and the class now looks like this,
# Question.h file
#import <Foundation/Foundation.h>
#interface Question : NSObject
#property (nonatomic, strong) id delegate;
#end
Below is the implementation of the class
# Question.m file
#import "Question.h"
#implementation Question
#synthesize delegate;
- (void)trythisfunction{
[delegate test];
}
#end
As we are integrating this swift and so we will need a Bridging Header whose content look like.
#import "Test.h"
Finally in your swift class now you can import this class
import UIKit
class MainViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let q = Test()
q.delegate = self
}
func test(){
NSLog("test is OK")
}
}
And above code works like a charm.

Can i use two delegates: delegateA in classB, delegateB in classA?

i've got my code in HelloWorldLayer, i'm using a delegate to change the score number in ScoreLayer, and i would like to send a message back from ScoreLayer to HelloWorldLayer, in order to change the ui with a new image.
Is it ok to create a delegate in each class (one delegate of HelloW... in ScoreLayer, and one delegate of ScoreLayer in HelloW...) ? Something like that :
hellolayer.delegate = scoreLayer;
scoreLayer.powerUpDelegate = hellolayer;
?
#class MyClass does not work : the protocols are not being recognized.
"#import "..." : one of the protocol is not recognized, but i guess there will be a problem, as classA will import classB, which will import classA again etc.
How should i do? Here's some of the code :
//in HelloWorldLayer.h :
#import "ScoreLayer.h"
#protocol PowerUpDelegate
-(void)scalePowerUp;
#end
// HelloWorldLayer
#interface HelloWorldLayer : CCLayer <PowerUpDelegate>
{ … }
#property (nonatomic,retain) id <ScoreDelegate> delegate;
//in ScoreLayer.h :
//#class HelloWorldLayer; -->does not recognize the protocol
#import "HelloWorldLayer.h"
#protocol ScoreDelegate
//...
#end
#interface ScoreLayer : CCLayer <ScoreDelegate>{
//...
}
#property (nonatomic,retain) id <PowerUpDelegate> powerUpDelegate;//-->cannot find protocol definition...
Thanks
I recommend using a third class which implements both protocols and use that class to handle the delegate methods.
Yes; you can pre-declare the protocols like you pre-declare classes, so put this at the top of your ScoreLayer class:
#protocol PowerUpDelegate;

Objective-C calling a delegate method from a class where the delegate method resides within another class

If I have a delegate which resides within its own header file myDelegate.h. Then I have a class (ClassOne) that implements the delegate protocol (therefore implementing the delegate function(s)). Then I create another class (ClassTwo) that has a instance variable of myDelegate. Can I then use this variable to call the function that resides in ClassOne?
Here is the code:
//myDelegate.h
#protocol myDelegate <NSObject>
- (BOOL)myFunction:(NSString*)sString;
#end
//ClassOne.h
#interface ClassOne : NSObject <myDelegate> {
}
- (BOOL)myFunction:(NSString*)sString;
#end
//ClassOne.m
#import "ClassOne.h"
#implementation ClassOne
- (BOOL)myFunction:(NSString*)sString
{
//do stuff
}
#end
//ClassTwo.h
#import "myDelegate.h"
#interface ClassTwo : NSObject {
id<myDelegate> del;
}
#property (nonatomic, retain) id<myDelegate> del;
#end
//ClassTwo.m
#import "ClassTwo.h"
#implementation ClassTwo
- (void)aFunction:(NSString*)string
{
[del myFunction:string];
}
#end
Yes, that is exactly right.
Except myDelegate should be MyDelegate. It's not a syntax error and will execute perfectly, but standard objective-c conventions say that you should never define a delegate with a lowercase first character.

Cannot use respondsToSelector using ARC on Mac

When I call respondsToSelector in an ARC environment, I get the following error message Automatic Reference Counting Issue No known instance method for selector respondsToSelector:
This is the header
#import <AppKit/AppKit.h>
#class MTScrollView;
#protocol MTScrollViewDelegate
-(void)scrollViewDidScroll:(MTScrollView *)scrollView;
#end
#interface MTScrollView : NSScrollView
{
}
#property(nonatomic, weak) id<MTScrollViewDelegate>delegate;
#end
This is the implementation file
#import "MTScrollView.h"
#implementation MTScrollView
#synthesize delegate;
- (void)reflectScrolledClipView:(NSClipView *)aClipView
{
[super reflectScrolledClipView:aClipView];
if([delegate respondsToSelector:#selector(scrollViewDidScroll:)])
{
[delegate scrollViewDidScroll:self];
}
}
#end
Any suggestions on why I am getting this error?
Make the protocol conform to NSObject
#protocol MTScrollViewDelegate <NSObject>
Otherwise the compiler doesn't think that the object will respond to NSObject messages like respondsToSelector, and will generate a warning. It will succeed at runtime without issues either way.
For Swift this becomes:
#objc protocol MTScrollViewDelegate: NSObjectProtocol
The NSObject protocol groups methods that are fundamental to all Objective-C objects.
For more information on what NSObjectProtocol is: https://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/index.html