Set a generic class as a delegate in swift - swift

I have a class XMLUtil, that wraps some xml parsing functionality. The class has one generic parameter T. The class also acts as the NSXMLParserDelegate to the NSXMLParser delegator.
class XMLUtil<T>: NSObject, NSXMLParserDelegate{
...
...
init(){
parser = NSXMLParser(data: NSData)
parser.delegate = self
parser.parse()
}
...
...
//delegate method implementations
}
The problem:
When my XMLUtil class is a generic class, the delegate methods never get called. They do however, when I implement the XMLUtil class without generic parameters
These two questions seem to be of similar nature
Swift Generic class as delegate
NSURLConnection Delegate Methods Not Called In Generic Class
Is there anything in the documentations that would explain this behavior? Is this intended or is it a bug?

When my XMLUtil class is a generic class
But Objective-C knows nothing of generic classes. So there is no way to show your XMLUtil class to Objective-C. Thus, it cannot serve as NSXMLParser's delegate; NSXMLParser is an Objective-C class and cannot see your XMLUtil class if it is generic.
One easy way to see this is to try to mark your XMLUtil class as #objc. You will fail; the compiler will stop you. There is no way to show this class to Objective-C.

Related

Swift Complex type in parameter

In order to be a bit more clear I am looking for a solution for the user to pass a class with a specific subclass and protocol, i.e. a class that inherits a viewController and delegate protocol. I know its possible to create a protocol list but cannot find a solution that works correctly. Currently I use a initializer and use the viewcontroller as a parameter and check for delegate inside the function but I would rather if I can have these types in the parameter instead.
EDIT:
Looking to do something similar to this
Protocol prot:Delegate{}
class cla:ViewController{}
class impl{
init(mainUI: cla, prot){
do things
}
}
That way back in the main view controller I can do something like this
class viewController: cla, prot{
var view:impl
override func loadView() {
//Attach to Screen
view = impl(mainUI: self);
}
}
Their is a bit more happening but that's the only part thats really relevant. Currently I use a initializer to just fail if the class doesn't inherit the correct protocols
You could create a dummy type that represents your requirements. A typealias doesn't work in this case, but this might:
class DummyClass: MyViewController, MyDelegateProtocol {}
func needsRequiredClass(input: DummyClass) {...}
With MyViewController and MyDelegateProtocol being the superclass and delegate you mentioned. The DummyClass would have an empty implementation.
Then, make your specific classes sub classes of DummyClass:
class TestClass: DummyClass {...}
And you can pass in that new class:
let test = TestClass()
self.needsRequiredClass(test)
You're asking the wrong question. In other words trying to shoe-horn in a serious design mistake.
A view should not know that its delegate is a UIViewController or a subclass.
A delegate should be any class that obeys (adopts) a specific delegate protocol.
A view should only delegate specific responsibilities. Each of those responsibilities must be described by a protocol method or property.
If you explain what your issue is in more detail (why you think you need direct access to the entire definition of a UIViewController within a UIView), we can help you avoid this mistake.

Superclass vs Protocol in Swift?

I've never worked with objective C but have a fair bit of experience with C++.
What exactly is the difference between a superclass and a protocol in objective C? I read that a protocol is essentially a pure virtual class, but is that it? Is a protocol simply a specific type of superclass?
A protocol is a contract a class is going to conform to. When a class conforms to a protocol it tells the compiler that it will implement all the methods and all the properties declared in the protocol.
In Objective-C the class additionally needs a superclass. In a lot of cases this is NSObject. The superclass implements already a lot of methods (like isEqual:). A protocol never implements any methods or defines any property.
A protocol tells which properties/operations a class must implement. A superclass implements them and you can add your own stuff on top.
A protocol defines a set of method definitions that a class or struct must implement, very much like a Java interface.
A superclass is the class from which a given class inherits its method definitions, the implementation for those methods, and the instance and class properties.

is NSObject an abstract class? [duplicate]

Which class is Abstract class in Objective-C, I have read some doc where NSObject is Abstract class, but we can create instance of NSObject, then how it is follow the abstract class rule.
NSObject *obj = [[NSObject alloc] init];
NSLog(#"description = %#",[obj description]);
NSLog(#"class name = %#",[obj class]);
Please advice.
And also I heard another one Abstract Class in Objective-C, what is the name of the class?
Objective-C has no compile time restraint against instantiating abstract classes. See Creating an abstract class in Objective-C
In Objective-C there is no language level concept of an abstract class. You have to read the documentation for a class to find out if it should be treated as an abstract class. There are a few such classes in Cocoa, e.g. NSObject, NSProxy and NSOperation. It's more common for behaviour to be defined in protocols rather than in abstract classes.
The Cocoa framework contains to root classes (i.e. class which do not have superclasses). NSObject is one root class and NSProxy is the other. NSProxy does not implement an init method which means an exception is raised when you attempt to create an instance.

Calling protocol methods on super

Can I call a protocol method from a child on its super class, even though the super class supports the protocol privately?
Let's say I have a Class A which privately conforms to UIGestureRecognizerDelegate protocol. Class B inherits from Class A but when I tried to call [super gestureRecognizerShouldBegin:gestureRecognizer]; I get an error.
Any idea?
The UIScrollViewDelegate doesn't declare a method named gestureRecognizerShouldBegin:gestureRecognizer:.
But generally speaking, yes, its possible to call methods declared in protocols that the super class implements, but keep in mind that methods marked with #optional in the protocol aren't guaranteed to be implemented (you can check this via the respondsToSelector: method)

Why does adding a Swift protocol in some situations not require all the normally required methods?

For example, these are valid and will compile without (all) protocol stubs
public class ViewController: UIViewController, SFSpeechRecognizerDelegate {
}
class BLEController: CBCentralManager, CBCentralManagerDelegate {
func centralManagerDidUpdateState(_ central: CBCentralManager) {
}
}
Edit: Solved! Creating a class without inheriting from UIViewController or CBCentralManager still does comply with the delegate protocols, but it does not comply with NSObjectProtocol. It just seems to be that I'm attempting to use the frameworks in an unintended way.
Why does my code compile without fulfilling all the protocol requirements?
What you are seeing here are optional protocol requirements. They are here because Swift code needs to interact with Objective-C, and Objective-C has them.
All methods except centralManagerDidUpdateState declared in CBCentralManagerDelegate are optional, from here:
The only required method is centralManagerDidUpdateState(_:); the central manager calls this when its state updates, thereby indicating the availability of the central manager.
And SFSpeechRecognizerDelegate, only contains one optional method, from here:
Use this protocol's optional method to track those changes and provide an appropriate response.
why does the code not compile if you remove the superclasses then?
This is because both of those protocols in your question also inherit from NSObjectProtocol, so they actually also have the additional requirements of NSObjectProtocol. UIViewController and CBCentralManager both inherits from NSObject, so they satisfy the NSObjectProtocol requirements, but your Swift class without a superclass doesn't.
Protocols with optional requirements don't have to inherit from NSObjectProtocol though. It's just that most of them are that way in the framework. You can for example do:
#objc protocol Foo {
#objc optional func foo()
}
class FooClass : Foo {
// compiles fine!
}
It compiles without needing the protocol stubs because all the requirement is optional. Check within the declaration of SFSpeechRecognizerDelegate it has only one requirement for a method called availabilityDidChange and you can see that it's optional from the keyword given at the beginning of the function.
In the second case, the class you have created doesn't inherit from NSObject but the first one does because it's a sub-class of UIViewController which in-turn is a sub-class of NSObject.