Override Objective-C class method with "new" prefix in Swift - ios

I have a problem with overriding class method from Objective-C in Swift. I can invoke it from Swift no problem but not override it.
Method signature:
+ (id<MyInterface>)newObjectWithId:(NSString *)objectId properties:(NSDictionary *)properties andClient:(Client *)client;
Class hierarchy:
NSObject <-- MyObject1 <-- MyObject2 <-- MySwiftClass
MyObject1 declares and implements aforementioned method and so does MyObject2. However trying to override it in Swift does not work. It is not visible in autocompletion and when I write it manually it says Method does not override any method from its superclass. Signature I wrote looks like this:
override class func newObjectWithId(objectId: String!, properties: NSDictionary!, andClient client: Client!) -> MyInterface
I did overriding for some other class methods in this class too and they work without a problem. I assume it's a problem with new prefix in this method. Has anyone encountered something like this and resolved it successfully?

Related

Use generic extended swift class in Objective-c

In my project i have many swift classes that extend generic classes. And Now i'm in a need to send data from objective-c class to these swift classes. Is there any possible way to do this ?
I have tried using #objc before class as shown below
but it didn't allow me to do this.
I followed this answer stack link. But i checked when i run my app with this code it dint create the variable in the Project-swift class as shown in below image
as the variable is not created here so it gives error while calling the variable in objective-c class.
Kindly help out with better solution.
I got my solution by creating another class which contain a protocol and i indirectly call the generic extended class.
class EntityDataTable :BaseData<EntitySw> {
}
this is the generic extended class
and the another class i made to indirectly access this class in objective-c is
#objc class EntityService : NSObject {
var entityProtocol:EntityDataProtocol?
override init() {
super.init()
entityProtocol = returnDataObject()
}
func returnDataObject() -> EntityDataTable {
return EntityDataTable()
}
}
#objc protocol EntityDataProtocol{
func addFromService(source: CWEntity)
func getAll() -> [EntitySw]
}
Then i imported the Project-swift.h file in objective c class and made the object of swift class

Use Realm subclass as custom function parameter

I am using Realm and it has function that take as an argument a class inheriting from Object (not NSObject), e.g.
realm.objects(Class)
I want to make a function that also takes Class as parameter.
I want make function that will take a class and forward it to Realm's function. I tried something like this, but it doesn't work:
func test(type: AnyClass) {
let realm = ..
realm.objects(type)
}
The Swift compiler reports an error saying that it cannot cast from AnyClass to Object.Type
I found a similar question here: Pass a Swift class as parameter, and then call a class method out of it
But maybe there is a simpler solution that doesn't require protocol implementation for every class? I want the function to make the decision of what to do by itself depending on what class it receives.
I want it to look like realm.objects(Class).
You can use the same signature: objects declaration looks like this:
func objects<T: Object>(type: T.Type) -> Results<T>
So you need a generic function constraining the type to subclasses of Realm.Object:
func test<T: Object>(type: T.Type) {
let realm = ...
realm.objects(type)
}
Then, assuming that your class (MyClass in this sample) inherits from Realm.Object, you can call it like this:
class MyClass: Object {}
test(MyClass)
If your method takes an object of that type, you can infer the type:
func test<T: Object>(element: T) {
let realm = ...
realm.objects(T.self)
}

Swift: Unable to override operationDidFinish from GroupOperation class

In a custom subclass of GroupOperation, I'm trying to override operationDidFinish(). When I attempt to implement the function in my subclass, I get this error message:
Method does not override any method from its superclass
If I remove the override keyword, I get
Method 'operationDidFinish(:withErrors:)' with Objective-C selector
'operationDidFinish:withErrors:' conflicts with method
'operationDidFinish(:withErrors:)' from superclass 'GroupOperation'
with the same Objective-C selector
Weirdness. I'm pretty sure my method signature is spot on, and I'm not trying to overload an obj-c method, so all should be well. What gives?
For reference, my class looks like this:
class ServerAuthenticationOperation: GroupOperation {
// properties... initializer stuff...
override func operationDidFinish(operation: NSOperation, withErrors errors: [NSError]) {
print("I finished!")
}
}
I assume you're using Swift 2.
Objective-C does not support method overloading, so you have to select a different name for your method. Or, you can try these options:
Rename the method using the #objc(newMethodName:)
Use #nonobjc
Edit:
It seems working for the repo you provided, you can check it here. https://www.dropbox.com/s/hb07u3hyjhjuews/OverrideTest.zip?dl=0

Swift class in Objective-C project (Compiler error)

I created an Swift class in my Objective-C project. There are no problems with the generated bridging interfaces between objective-c and swift.
In my objective-c project, I have an class named Task, its Task.h looks like following:
#interface Task: NSObject
…
- (id) initWithHomeworks:(NSDictionary *)homeworks
#end
The Task.m looks like this:
#implementation Task
- (id) initWithHomeworks:(NSDictionary *)settings {
self = [super init];
//Do something with self...
...
return self
}
My swift code inherits the above class:
import Foundation
class SubTask : Task {
//Compiler Error 1
func initWithHomeworks(homeworks: Dictionary<String, String>) -> AnyObject{
//Compiler Error 2
return super.initWithSettings(settings)
}
}
I get two compiler errors in the place commented above. The error messages are below:
Compiler Error 1:
Method ‘initWithHomeworks’ with Objective-C selector ‘initWithHomeworks:’ conflicts with initializer ‘init(homework:)’ from superclass ‘Task’ with the same Objective-C selector
(I haven't declared any method init(homework:))
Compiler Error 2:
‘Task’ does not have a member named ‘initWithHomeworks’
Why I get these two errors in my Swift class? How to fix them?
The fundamental reason for that you are seeing is that Swift converts Objective-C methods names intelligently. From the docs:
To instantiate an Objective-C class in Swift, you call one of its
initializers with Swift syntax. When Objective-C init methods come
over to Swift, they take on native Swift initializer syntax. The
“init” prefix gets sliced off and becomes a keyword to indicate that
the method is an initializer. For init methods that begin with
“initWith,” the “With” also gets sliced off. The first letter of the
selector piece that had “init” or “initWith” split off from it becomes
lowercase, and that selector piece is treated as the name of the first
argument. The rest of the selector pieces also correspond to argument
names. Each selector piece goes inside the parentheses and is required
at the call site.
In your case the Objective-C initWithHomeworks:(NSDictionary *)homeworks method is converted to Swift as init(homeworks: [NSObject : AnyObject]!). You can override it as follows:
Given an Objective-C header:
#interface Task : NSObject
- (id)initWithHomeworks:(NSDictionary *)homeworks;
#end
Swift subclass:
class SubTask : Task {
override init!(homeworks: [NSObject : AnyObject]!) {
super.init(homeworks: homeworks)
}
}
This answer was completed using Swift 1.2 in Xcode 6.4
Update based on comments
You have defined your SubTask's initialiser as a regular function:
func initWithHomeworks(homeworks: Dictionary<String, String>) -> AnyObject{
return super.initWithSettings(settings)
}
This is incorrect for the following reasons:-
func is not allowed on init methods
init methods shouldn't declare a return type, remove -> AnyObject
init methods don't return anything, remove the return keyword from the super.init...
Swift initialisers do not return a value however you can still assign the result to a variable:
Swift:
var mySubTask = SubTask(homeworks: someDictionary)
Objective-C:
SubTask *mySubTask = [[SubTask alloc] initWithHomeworks:someDictionary];
If you want to override init method,you should write it like this
class SubTask:Task{
override init!(homeworks: [NSObject : AnyObject]!) {
super.init(homeworks: homeworks)
}
}

Override Objective-C class method in Swift

I'm trying to use JSONModel in a Swift project.
I would like to override the method keyMapper from JSONModel but I don't find how to override an Objective-C class method in the model class.
The signature of the method is:
+(JSONKeyMapper*)keyMapper;
How can I do that?
You do it just like you override an instance method, except with the class keyword:
override class func keyMapper() -> JSONKeyMapper! {
//code here
}

Resources