This is the first Swift-related tip I am writing! Starting with this issue, I'll be covering both Swift and Objective C.
When you use Objective C code from Swift, you might notice an error like:
manager() is unavailable: use object construction SomeManager()
This happens if you have a class like this:
@interface SomeManager : NSObject
+ (instancetype)manager;
@end
+manager
is likely meant to return a singleton and you were trying to call the equivalent of Objective C:
SomeManager* m = [SomeManager manager];
with:
var m = SomeManager.manager()
which triggers the error message. Using this as suggested by the error message will probably run, but it is wrong since it just creates an object by calling init():
var m = SomeManager()
This happens because of an interoperability feature of Swift for initialization which does some method name parsing based around naming conventions. Basically given an Objective C class like:
@interface SomeManager : NSObject
- (instancetype)initWithName:(NSString*)name;
- (instancetype)initWithName:(NSString*)name height:(int)aNumber;
@end
you can do the following in Objective C:
SomeManager* m1 = [[SomeManager alloc] initWithName:@"some name"];
SomeManager* m2 = [[SomeManager alloc] initWithName:@"another name" height:123];
Swift interoperability will let you do:
var m1 = SomeManager(name: "some name")
var m2 = SomeManager(name: "some name", height: 123)
You can see this with UIView
's -initWithFrame:
method.
In addition, Swift interoperability for initializers work for factory methods too, so given this Objective C class:
@interface SomeManager : NSObject
+ (instancetype)managerWithName:(NSString*)name;
+ (instancetype)managerWithName:(NSString*)name height:(int)aNumber;
@end
you can do the following in Objective C:
SomeManager* m1 = [SomeManager managerWithName:@"some name"];
SomeManager* m2 = [SomeManager managerWithName:@"another name" height:123];
Swift interoperability will let you do the following too:
var m1 = SomeManager(name: "some name")
var m2 = SomeManager(name: "some name", height: 123)
Unfortunately, if you have a class method that accepts no arguments like the +manager
class method we talked about at the start of this tip, it can't be called directly from Swift. You'll need to create an Objective C class extension with a class method that wraps around it, that doesn't adhere to the naming convention. e.g.
@interface SomeManager (SwiftInterop)
+ (instancetype)singleton; //or some appropriate name
@end
@implementation SomeManager(SwiftInterop)
+ (instancetype)singleton {
return [self manager];
}
@end
then you can call +singleton
from Swift instead.
Your feedback is valuable: Do you want more nuggets like this? Yes or No
.
.