Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call static method provided by protocol in Swift

How to access to static protocol method within a instance

I have a list of Contact, the contact can be a FamilyContact that inherit from Contact and the GroupStatus protocol

I want to call the static method from GroupStatus but in vain...

Here is my code

protocol GroupStatus {
    static func isPrivate() -> Bool // static method that indicates the status
}

protocol IsBusy {
    func wizzIt()
}

class AdresseBook {

    private var contacts = [Contact]()

    func addOne(c: Contact) {
        contacts.append(c)
    }

    func listNonPrivated() -> [Contact]? {

        var nonPrivateContact = [Contact]()

        for contact in contacts {
            // here is I should call the static method provided by the protocol
            if self is GroupStatus {
                let isPrivate = contact.dynamicType.isPrivate()
                if !isPrivate {
                    nonPrivateContact.append(contact)
                }
            }
            nonPrivateContact.append(contact)
        }

        return nonPrivateContact
    }
}

class Contact : Printable {

    var name: String

    init(name: String) {
        self.name = name
    }

    func wizz() -> Bool {
        if let obj = self as? IsBusy {
            obj.wizzIt()
            return true
        }
        return false
    }

    var description: String {
        return self.name
    }
}

class FamilyContact: Contact, GroupStatus {

    static func isPrivate() -> Bool {
        return true
    }

}

I can't compile Contact.Type does not have a member named 'isPrivate'

How can I call it ? It works if I delete the static keyword, but I think is more logical to define it static.

If I replace

let isPrivate = contact.dynamicType.isPrivate()

by

let isPrivate = FamilyContact.isPrivate()

It works, but I can have more than 1 subclasses

If I remove the static keywork I can do it by this way :

if let c = contact as? GroupStatus {
    if !c.isPrivate() {
        nonPrivateContact.append(contact)
    }
}

But I want to keep the static keyword

like image 204
Kevin Machado Avatar asked May 04 '15 13:05

Kevin Machado


1 Answers

This looks like a bug or a non-supported feature. I would expect that the following works:

if let gsType = contact.dynamicType as? GroupStatus.Type {
    if gsType.isPrivate() {
        // ...
    }
}

However, it does not compile:

error: accessing members of protocol type value 'GroupStatus.Type' is unimplemented

It does compile with FamilyContact.Type instead of GroupStatus.Type. A similar problem is reported here:

  • Swift 1.1 and 1.2: accessing members of protocol type value XXX.Type' is unimplemented

Making isPrivate() an instance method instead of a class method is the only workaround that I currently can think of, maybe someone comes with a better solution ...

Update for Swift 2 / Xcode 7: As @Tankista noted below, this has been fixed. The above code compiles and works as expected in Xcode 7 beta 3.

like image 146
Martin R Avatar answered Sep 20 '22 00:09

Martin R