Redundant conformance of "HomeTabBarViewController" to protocol 'UITabBarControllerDelegate' iOS [duplicate] - ios

I updated my project to Swift 2, and received a bunch of redundant conformance of XXX to protocol YYY. This happens especially often (or always) when a class conforms to CustomStringConvertible. Also some place with Equatable.
class GraphFeatureNumbersetRange: GraphFeature, CustomStringConvertible { // <--- get the error here
...
}
I suspect that I don't need to explicitly conform to a protocol when I implement var description: String { get }, or whatever methods the protocol requires. Should I just follow fixit instructions and remove all these? Does Swift now automatically infer the conformance if a class implements all the protocol's methods?

You'll get that error message in Xcode 7 (Swift 2) if a subclass declares conformance
to a protocol which is already inherited from a superclass. Example:
class MyClass : CustomStringConvertible {
var description: String { return "MyClass" }
}
class Subclass : MyClass, CustomStringConvertible {
override var description: String { return "Subclass" }
}
The error log shows:
main.swift:10:27: error: redundant conformance of 'Subclass' to protocol 'CustomStringConvertible'
class Subclass : MyClass, CustomStringConvertible {
^
main.swift:10:7: note: 'Subclass' inherits conformance to protocol 'CustomStringConvertible' from superclass here
class Subclass : MyClass, CustomStringConvertible {
^
Removing the protocol conformance from the subclass declaration
solves the problem:
class Subclass : MyClass {
override var description: String { return "Subclass" }
}
But the superclass must declare the conformance explicitly, it is
not automatically inferred from the existence of the description
property.

For googlers, I also got this error when including SwiftyJson in my Tests target and adding a swift test class, as it caused SwiftyJson to be compiled in again, and it declares NSNumber as Comparable. The solution was to only include it in the app target.

The point is that your GraphFeatureNumbersetRange is NSObject's subclass.
Which in its turn already conforms to CustomStringConvertible! That's it! Just delete this redundant protocol. Now you're declaring it twice! :-)

Related

Swift NSKeyedArchiver: Do custom members of an NSCoding-conformant class need to conform to NSCoding as well?

Say I have this Swift class:
class Foo: NSObject, NSCoding
{
var stringMember: String
var intMember: Int
var customObjectMember: CustomObject
//conforms with encode and required init...
}
I know that "Foo" has to conform to NSCoding so I can archive it. Does the member "customObject" also have to conform to NSCoding/NSObject or can it be a regular Swift class?
The answer is "yes". Custom object members must also conform to NSCoding.

Swift cast object to type and protocol at the same time

How can I cast a given object to a type and a protocol in order to call some methods that are defined as an extension
For Example:
extension Identifiable where Self: NSManagedObject, Self: JsonParseDescriptor {
func someMethod() { }
}
Now I have an object that I retrieved from Core data and I would like to cast it to the above protocols in order to call someMethod on it. I could cast to the protocols using protocol<Identifiable, JsonParseDescriptor> , but how can I include the NSManagedObejct type in it also?
Thanks
As of Swift 4, it is now possible to make mentioned cast directly without tricky workarounds. The task is accomplished similarly as we do protocol composition:
var myVar = otherVar as! (Type & Protocol)
No more need for extensions and bridge protocols.
What you're looking for it called a concrete same-type requirement. Unfortunately, it's not yet possible in Swift.
See ticket SR-1009 and SR-1447 for details. You should also checkout this answer.
In the mean-while, you can extend NSManagedObject with a dummy protocol with the methods you need:
protocol _NSManagedObject {
//the methods you want
}
extension NSManagedObject: _NSManagedObject {}
extension Identifiable where Self: _NSManagedObject, Self: JsonParseDescriptor {
func someMethod() { }
}

How can I create a Set of delegate protocol items in Swift?

Let's assume I have five UIView objects which all conform to a particular protocol. I have an object which should maintain a list of these objects, and message them all when necessary.
protocol MyProtocol: AnyObject {
func doSomething()
}
The problem is, when I go to add these UIViews to a Set variable, the compiler produces an error because MyProtocol does not conform to Hashable. I can understand the reasoning for this, can anyone think of good ways to overcome this? In the meantime I considered using NSHashTable instead, but you lose the nice enumeration features of Sets.
Updating answer to post some sample code (this is still not working)
protocol MyProtocol: class, AnyObject {
func doSomething()
}
class MyClass {
var observers: Set<MyProtocol> = Set<MyProtocol>()
}
As you are defining protocol for class so you need to write 'class' keyword before inheriting any other protocol:
protocol MyProtocol: AnyObject, Hashable{
func doSomething()
}
class MyClass<T: MyProtocol> {
var observers: Set<T> = Set<T>()
}
Change your protocol to this and it will work fine.
You can refer Apple Documentation for further details.

Swift Declare Class Func in Protocol

I had following confusion. As far as I know the main difference between static and class keywords when declaring method is that the second one could be overridden in subclasses.
The problem
However when I declare a protocol in Swift 1.2 like this:
protocol MyProtocol
{
class func dummyClassMethod()
}
compiler gives an error:
Class methods are only allowed within classes; use 'static' to declare
a static method
The error is pretty descriptive as obviously MyProtocol is not a class, however I want to make a class func part of the protocol.
What I've tried
I've found that if I declare interface in protocol as static, compiler is happy and I could use this static method in all classes that adopt this protocol:
protocol MyProtocol
{
static func dummyClassMethod()
}
The question
So my question basically is is this right? This declaration states that my class method cannot be overridden in children, however in my implementation I could write and use the following:
class ClassA: MyProtocol
{
class func dummyClassMethod() {
}
}
class ClassB: ClassA
{
override class func dummyClassMethod() {
}
}
and now my dummyClassMethod is not static anymore...
Compiler is Ok and everything works - but why?
Is it specific to the fact that interface itself is static, however
it's implementation is not?
Is there a better alternative for class func in protocols?
Objective-C solution
In ObjC this is pretty easy and compile & run flawlessly:
#protocol MyProtocol
+(void)dummyClassMethod;
#end
You can review Apple's Documentation (subsection Method Requirements).
There says:
As with type property requirements, you always prefix type method requirements with the static keyword when they are defined in a protocol. This is true even though type method requirements are prefixed with the class or static keyword when implemented by a class
In practice, You can do it as follow:
First, declare your protocol:
protocol SomeProtocol {
static func someMethod()
}
Then, in your class you've 2 options:
First:
class SomeClass : SomeProtocol {
class func someMethod()
}
Second:
class SomeClass : SomeProtocol {
static func someMethod()
}
I hope, this may clarify your doubt..
https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Protocols.html
A protocol defines a blueprint of methods, properties, and other
requirements that suit a particular task or piece of functionality.
The protocol doesn’t actually provide an implementation for any of
these requirements—it only describes what an implementation will look
like. The protocol can then be adopted by a class, structure, or
enumeration to provide an actual implementation of those requirements.
After this protocol definition it becomes reasonable that
As with type property requirements, you always prefix type method
requirements with the static keyword when they are defined in a
protocol. This is true even though type method requirements are
prefixed with the class or static keyword when implemented by a class...
To make protocol method static and final implement that method with static keyword
class ClassA: MyProtocol{
static func dummyClassMethod() {
}
}
and now you cant override dummyClassMethod function anymore. If you want to prevent overriding only you must declare protocol method as final. About class functions, they were not fully supported in Swift 1.0 and now in Swift 1.2 I think that they are moving towards static functions

How to define an array of objects conforming to a protocol?

Given:
protocol MyProtocol {
typealias T
var abc: T { get }
}
And a class that implements MyProtocol:
class XYZ: MyProtocol {
typealias T = SomeObject
var abc: T { /* Implementation */ }
}
How can I define an array of objects conforming to MyProtocol?
var list = [MyProtocol]()
Gives (together with a ton of SourceKit crashes) the following error:
Protocol 'MyProtocol' can only be used as a generic constraint because it has Self or associated type requirements
Even though the typealias is in fact defined in MyProtocol.
Is there a way to have a list of object conforming to a protocol AND having a generic constraint?
The problem is about using the generics counterpart for protocols, type aliases.
It sounds weird, but if you define a type alias, you cannot use the protocol as a type, which means you cannot declare a variable of that protocol type, a function parameter, etc. And you cannot use it as the generic object of an array.
As the error say, the only usage you can make of it is as a generic constraint (like in class Test<T:ProtocolWithAlias>).
To prove that, just remove the typealias from your protocol (note, this is just to prove, it's not a solution):
protocol MyProtocol {
var abc: Int { get }
}
and modify the rest of your sample code accordingly:
class XYZ: MyProtocol {
var abc: Int { return 32 }
}
var list = [MyProtocol]()
You'll notice that it works.
You are probably more interested in how to solve this problem. I can't think of any elegant solution, just the following 2:
remove the typealias from the protocol and replace T with AnyObject (ugly solution!!)
turn the protocol into a class (but that's not a solution that works in all cases)
but as you may argue, I don't like any of them. The only suggestion I can provide is to rethink of your design and figure out if you can use a different way (i.e. not using typealiased protocol) to achieve the same result.

Resources