Swift - implementing NSXMLParserDelegate - swift

I'm trying to have a class of mine implement NSXmlProtocolDelegate but the compiler fails indicating that the class does not conform to NSObjectProtocol.
Is it required that all of the functions from NSObjectProtocol be implemented, or can that be avoided?
class GeoRssParser : NSXMLParserDelegate
{
func parserDidStartDocument(parser : NSXMLParser)
{
}
}
Not much to see at this point - I got this far before the compiler started failing.

Yes, at least anything that isn't tagged as #optional. The easiest way to achieve this would be to simply make your class a subclass of NSObject, which already conforms to the NSObjectProtocol, and implements all its methods.
class GeoRssParser: NSObject, NSXMLParserDelegate {
func parserDidStartDocument(parser : NSXMLParser) {
// stuff
}
}

Related

Two ways of implement Delegation in Swift, what is the difference?

Say for example you have a protocol in Swift:
protocol WeatherServiceDelegate: class {
func didCompleteRequest(result: String)
}
Two ways of implementing them:
Way 1: Via class inheritance
class ViewController: UIViewController, WeatherServiceDelegate {
....
}
Way 2: Via extension
However, Swift does provide a keyword extension which can be used to implement the protocol methods
extension ViewController: WeatherServiceDelegate{
func didCompleteRequest(result: String){
print(result)
}
}
Is there any difference on those two methods?
Per Apple's guide:
Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling).
So it appears in your case there is little difference except in how you want to arrange your code.
Well! There's no difference at runtime. But when adding protocol conformance to a model, prefer adding a separate extension for the protocol methods. This keeps the related methods grouped together with the protocol and can simplify instructions to add a protocol to a class with its associated methods.
Preferred:
class MyViewController: UIViewController {
// class stuff here
}
// MARK: - UITableViewDataSource
extension MyViewController: UITableViewDataSource {
// table view data source methods
}
// MARK: - UIScrollViewDelegate
extension MyViewController: UIScrollViewDelegate {
// scroll view delegate methods
}
Not Preferred:
class MyViewController:UIViewController,UITableViewDataSource,UIScrollViewDelegate {
// all methods
}

Can someone explain difference between class and NSObjectProtocol

Basically I want to know the difference between this
protocol ViewDelegate: class {
func someFunc()
}
and this
protocol ViewDelegate: NSObjectProtocol {
func someFunc()
}
Is there any difference ??
Only Object or Instance type can conform to both type of protocol, where Structure and Enum can't conform to both the type
But the major difference is:
If one declares a protocol like below means it is inheriting NSObjectProtocol
protocol ViewDelegate: NSObjectProtocol {
func someFunc()
}
if the conforming class is not a child class of NSObject then that class need to have the NSObjectProtocol methods implementation inside it. (Generally, NSObject does conform to NSObjectProtocol)
ex:
class Test1: NSObject, ViewDelegate {
func someFunc() {
}
//no need to have NSObjectProtocol methods here as Test1 is a child class of NSObject
}
class Test2: ViewDelegate {
func someFunc() {
}
//Have to implement NSObjectProtocol methods here
}
If one declare like below, it means only object type can conform to it by implementing its methods. nothing extra.
protocol ViewDelegate: class {
func someFunc()
}
when confirming with class it means we only making in object type. So we can declare it as weak or strong
But when confirming with NSObjectProtocol, we make it object type and also we can implement NSObjectProtocol method. which is already define in NSObjectProtocol delegate.
So its up to you which way you want confirm your delegate

Swift protocol nested in a class

I would like to nest a protocol in my class to implement the delegate pattern like so :
class MyViewController : UIViewController {
protocol Delegate {
func eventHappened()
}
var delegate:MyViewController.Delegate?
private func myFunc() {
delegate?.eventHappened()
}
}
But the compiler will not allow it :
Protocol 'Delegate' cannot be nested inside another declaration
I can easily make it work by declaring MyViewControllerDelegate outside of the class scope.
My question is why such a limitation ?
according to the swift documenation
Swift enables you to define nested types, whereby you nest supporting enumerations, classes, and structures within the definition of the type they support.
Given protocols are not on that list, it doesn't appear that it's currently supported.
It's possible they will add the feature at some point, (Swift was announced less than 2 years go after all). Any idea on why they won't or haven't would be speculation on my part.
this is my work around:
protocol MyViewControllerDelegate : class {
func eventHappened()
}
class MyViewController : UIViewController {
typealias Delegate = MyViewControllerDelegate
weak var delegate: Delegate?
private func myFunc() {
delegate?.eventHappened()
}
}
A separate problem with your class is that delegate does not have a concrete type. You can get away with declaring it a MyViewController.Delegate? because it is an optional type and can be .None. But that just makes your private myFunc dead code. Only enumerations, classes, and structures can conform to a protocol. Which of those three types is delegate?
That said, this is not the cause of your problem. When I make a real type for delegate and make it conform to the Delegate protocol, I still get the same error.
class MyViewController: UIViewController {
protocol Delegate {
func eventHappened()
}
class Classy: Delegate {
func eventHappened() {
print("eventHappened")
}
}
var delegate: Classy? = Classy()
func myFunc() {
delegate?.eventHappened()
}
}
As an esoteric exercise this might be interesting in pushing the bounds of what a class might do but no one should every try to declare a protocol inside of a class. Protocols are all about type composition and collections. There is no code reuse scenario when you are limited to being in the same outer class.

Swift 2, protocol extensions & respondsToSelector

I am not sure, it looks to me that it is some kind of bug or bad implementation with protocol extensions in Swift 2.0.
I have protocolA, protocolB extending protocolA and implementing methods in protocolB extension.
I have conformed an class instance to conform to protocolB, however when inspected by respondsToSelector for protocolA/B methods the results is false.
import Cocoa
import XCPlayground
protocol ProtocolA : NSObjectProtocol {
func functionA()
}
protocol ProtocolB : ProtocolA {
func functionB()
}
extension ProtocolB {
func functionA() {
print("Passed functionA")
}
func functionB() {
print("Passed functionB")
}
}
class TestClass : NSObject, ProtocolB {
override init () {
}
}
var instance:TestClass = TestClass()
instance.functionA() // Calls code OK..
if instance.respondsToSelector("functionA") {
print("Responds to functionA") // **False, never passing here**
}
if instance.respondsToSelector("functionB") {
print("Responds to functionB") // **False, never passing here**
}
Should be reported as a bug?
Interesting. Looks like a bug to me. It does recognize functions on a class, but not on extension. No matter what type Instance has. Moreover without an extension code would not be compilable, since protocol methods are non optional. So really looks like a bug/feature? in responds to selector implementation.

swift error multiple inheritance from classes NSObject and NSCoder

I have a class called Diary which implements NScoder and has a member which is an array of another class called DiaryEntry
Here is my Diary class
import Foundation
class Diary: NSObject,NSCoder
{
var dia=[DiaryEntry]()
override init()
{
super.init()
}
func setDiary(ent:DiaryEntry)
{
if(dia.count==0)
{
self.dia.append(ent)
}
else {
for entrie in dia
{
if(entrie==ent)
{
entrie.text+="\n"
entrie.text+=ent.text
break
}
else {
self.dia.append(ent)
}
}
}
}
required init(coder decoder: NSCoder) {
self.dia = decoder.decodeObjectForKey("dia") as [DiaryEntry]
super.init()
}
func encodeWithCoder(encoder: NSCoder) {
encoder.encodeObject(dia, forKey: "dia")
}
}
Swift does not support multiple inheritance. NSCoder already inherits NSObject so there is no reason for your diary class to try and inherit both (which, again, is not possible).
This is an easy mistake to make; you accidentally used NSCoder instead of NSCoding. -er vs -ing
For an explanation;
NSCoder is a class, while NSCoding is a protocol. Placing another class after NSObject makes the compiler think you're asking for multiple class inheritance. Swift doesn't currently (as of 5.x) support multiple inheritance.
In Swift, you 'conform' to protocols, therefore bypassing the multiple v-table issue (and all the complexity and problems it causes) by basically merging (gross simplification) the protocol with the conforming class. You can therefore conform to as many protocols as you like (within compiler imposed limitations of course).
Long story short, you want your class to inherit from NSObject and conform to NSCoding, which is a protocol, and not inherit from both NSObject and NSCoder (which is what you were accidentally telling the compiler to do).
the protocol's name is: NSCoding no NSCoder