Unable to access Swift 4 class from Objective-C: "Property not found on object of type"
Solution 1
The rules for exposing Swift code to Objective-C have changed in Swift 4. Try this instead:
@objc var foobar = true
As an optimization, @objc
inference have been reduced in Swift 4. For instance, a property within an NSObject
-derived class, such as your TestViewController
, will no longer infer @objc
by default (as it did in Swift 3).
Alternatively, you could also expose all members to Objective-C at once using @objcMembers
:
@objcMembers class TestViewController: UIViewController {
...
}
This new design is fully detailed in the corresponding Swift Evolution proposal.
Solution 2
Swift 3.2/4.0 / XCode 9.1
You you set swift3.2 in project settings ( //:configuration = Debug SWIFT_VERSION = 3.2 )
you can use your code,(using the correct import file in objc, see below). If You set project to swift 4.0 ( //:configuration = Debug SWIFT_VERSION = 4.0 )
You must prepend @objc for every property.
So:
Swift 3.2:
// MyClass.swift
@objc class MyClass: NSObject{
var s1: String?
@objc var s2 : String?
}
//
// ViewController.m
import "MixingObjCAndSwift-Swift.h"
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
MyClass * mc = [MyClass new];
NSString * s1 = mc.s1;
NSString * s2 = mc.s2;
}
works.
Swift 4.0:
// MyClass.swift
@objc class MyClass: NSObject{
var s1: String?
@objc var s2 : String?
}
.....
- (void)viewDidLoad {
[super viewDidLoad];
MyClass * mc = [MyClass new];
NSString * s1 = mc.s1;
NSString * s2 = mc.s2;
}
does NOT works: compiler fails:
/Users....ViewController.m:24:21: Property 's1' not found on object of type 'MyClass *'
as s1 is not prepended with @objc.
You must write:
@objc class MyClass: NSObject{
@objc var s1: String?
@objc var s2 : String?
}
(As a side-note: in C/C++/ObJC file, put always system/general *h files before your "local" class headers.)
Swift 4
just add @objcMembers before class @objcMembers class MyClassObject: NSObject { var s1: String! var s2: String!
} Swift evolutionenter link description here
Solution 3
As for Swift 5.1 I found that "@objc" is not enough, but also make it public "@objc public":
@objc public class SomeClass: NSObject {
@objc public let amount: NSNumber
...
Solution 4
- When you add a swift file in your Objective-C project, Xcode will prompt to add Objective-C bridging header file, so allow the header file to be created.
- In your Objective-C implementation file where you want to access the TestViewController property foobar. Use the following import syntax and replace the ProjectName with your project.
#import "ProjectName-Swift.h"
Objective-C implementation file:
#import "ViewController.h"
#import "ProjectName-Swift.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
TestViewController *testViewController = [[TestViewController alloc] init]; // success
BOOL prop = testViewController.foobar;
NSLog(@"Property: %d", prop);
}
@end
For more details go through the Apple Documents
Solution 5
Xcode 10.2 | Swift 4
Adding @objcMembers
before class solved my problem.
@objcMembers class MyClass:NSObject {
var s1: String!
var s2: NSMutableArray!
}
Doug Smith
I'm a web designer playing around with iOS from England
Updated on November 28, 2020Comments
-
Doug Smith over 3 years
Using the latest Xcode 9 beta, I'm seemingly completely unable to access properties on Swift classes. Even odder, I can access the class itself to instantiate it or whatever, but completely unable to access properties on it.
So if I have this Swift class:
import UIKit class TestViewController: UIViewController { var foobar = true }
And I try to do this:
TestViewController *testViewController = [[TestViewController alloc] init]; // success testViewController.foobar; // error
What exactly am I doing wrong? New project with Xcode 9.
-
shaqir saiyed about 6 yearsI am still facing issue to access Int & Bool properties from Swift to objective-C ... and getting this error : Property cannot be marked @objc because its type cannot be represented in Objective-C , Any suggetion ? .. I have used header "MyProject-Swift.h
-
shaqir saiyed about 6 yearsOnly String Properties are accessible
-
Scofield Tran about 6 yearsStupid upgrade. Now I have to add @objc pre-processor on every variable and method declaration if using it on Objective C class
-
Lehlohonolo_Isaac over 5 years@shaqirsaiyed I can access Booleans as well.
-
Nada Gamal over 5 yearsThank you very much, you save my day :)
-
Vijay Kumar Kanta over 5 yearsThe alternate didn't work for me. I had to prefix @objc to the class and all it's member fields
-
javi_swift almost 5 yearsVery interesting. I have it working with both versions.
-
Erik van der Neut over 4 yearsThank you SO MUCH! This has been driving me nuts all morning, but your post clarified several points and gave the solution in the form of @objcMembers that works perfectly in my case, which is a class with a variety of String, Int, Float and CLLocationDegrees properties.
-
Dan about 4 yearsIt doesn't work for me for String? property with explicit
set
andget
blocks. Anybody faced this as well? -
protspace about 4 years@Dan I believe optional is a Struct, this means that it can't be exposured to Obj-C runtime