I have an (OS X) Objective-C framework to which I want to add some Swift extensions and I'm using Xcode 7ß6 to work with this. There is class in the framework (let's call it "Sample") implemented in the files "Sample.h" and "Sample.m" .. "Sample.h" contains:
#import <Foundation/Foundation.h>
@interface Sample : NSObject
@property int x;
@end
.. and "Sample.m" contains:
#import "Sample.h"
@implementation Sample
- (instancetype) init {
if ((self = [super init]) == nil) return nil;
self.x = 99;
return self;
}
@end
I have added "Sample.swift" to the framework containing:
import Foundation
extension Sample {
func PrettyPrint () {
print("\(x)")
}
}
This is clearly a trivial version of what I want to do in a larger context, here I want to use the Swift file to extend "Sample" by adding a "PrettyPrint" function.
.. the framework builds without error, but the framework function "PrettyPrint" is not visible to a calling app. App code calling into the framework like:
import Foundation
import TestKit
let sample = Sample()
sample.PrettyPrint()
fails on "sample.PrettyPrint()" with: Value of type 'Sample' has no member 'PrettyPrint'
Why does this fail? and Can it be made to work?
Extra info: If I remove the file "Sample.swift" from the framework and place it the app which is calling into the framework, the "Sample" class is successfully extended and "sample.PrettyPrint()" works as expected (printing "99").
You can write a Swift extension and use it in Objective-C code.
To access and use swift classes or libraries in objective-c files start with an objective-c project that already contains some files. Add a new Swift file to the project. In the menu select File>New>File… then select Swift File, instead of Cocoa Touch Class. Name the file and hit create.
The methods declared by a class extension are implemented in the implementation block for the original class, so you can't, for example, declare a class extension on a framework class, such as a Cocoa or Cocoa Touch class like NSString. Extensions are actually categories without the category name.
Have you tried making the extension and function public?
public extension Sample {
public func PrettyPrint () {
print("\(x)")
}
}
In a similar case, Tie's answer really helped me but it didn't work for me, I had to add @objc for the method:
public extension SearchBarWidget {
@objc public func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
self.endEditing(true)
}
}
The SearchBarWidget class was @objc public
signatured.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With