Reputation: 33
I'm writing some Swift classes that build upon functionality in our objective-c app. I have a objective-c class with a delegate that conforms to a protocol. I'm trying to call a method on that delegate from inside of a Swift class I'm simplified it down to this.
FredTestProtocol.h:
@protocol FredTestProtocol
- (void) dumbMethod;
@end
FredTestClass.h:
#import <Foundation/Foundation.h>
#import "FredTestProtocol.h"
@interface FredTestClass : NSObject <FredTestProtocol>
@property (nonatomic, weak) NSObject <FredTestProtocol> *delegate;
@end
FredTestClass.m:
#import "FredTestClass.h"
@implementation FredTestClass
- (void) dumbMethod
{
NSLog(@"Boy, this is a dumb method");
}
@end
FredSwiftClass.swift
import Foundation
class FredSwiftClass {
func test()
{
let ocObject = FredTestClass()
ocObject.delegate.dumbMethod() // Error occurs here.
}
}
The indicated line produces the error "'NSObject' does not have a method named 'dumbMethod'" I've tried a lot of ways to eliminate the error, to no avail. I'm sure I'm missing something really fundamental. Can someone tell me how I should go about calling the delegate method from Swift?
Upvotes: 3
Views: 4226
Reputation: 33
Pretty sure I've got it.
func test()
{
let ocObject = FredTestClass()
if let myDelegate = ocObject.delegate as? FredTestProtocol
{
myDelegate.dumbMethod()
}
}
Upvotes: 0
Reputation: 114826
When Swift examines the property delegate
it simply sees that is is an NSObject
and the fact that you have noted that it implements a protocol is ignored. I can't find any specific documentation as to why this is the case.
You can address this in a couple of ways.
First, you can redefine your delegate
property to use class anonymity, then Swift will just see it as some object that implements the protocol -
FredTestClass.h
#import <Foundation/Foundation.h>
#import "FredTestProtocol.h"
@interface FredTestClass : NSObject <FredTestProtocol>
@property id<FredTestProtocol> delegate;
@end
Then your Swift code will compile as written.
or you can leave your delegate definition as is and tell Swift that you want to access the delegate as an instance of an object that implements the protocol via downcast -
FredTestSwift.swift
import Foundation
class FredSwiftClass {
func test()
{
let ocObject = FredTestClass()
let theDelegate=ocObject.delegate as! FredTestProtocol
theDelegate.dumbMethod()
}
}
Upvotes: 2