Swift Protocol to Require Properties as Protocol

what is the meaning when a property's type is a protocol in swift?

Property1 is anything that conforms to protocol A. So this could either be another class, a struct, etc. Say you have a protocol Vegetable and a class named Market. You'll want to sell multiple types of Vegetable, however, you want to make sure that the vegetables are for sale. You can do this with protocols.

protocol Vegetable {
var isForSale: Bool { get }
}

// Now let's create some vegetables
class Carrot: Vegetable {
let isForSale = true
}

class Spinach: Vegetable {
let isForSale = false
}

// This is our market.
class Market {
let vegetables: [Vegetable] = [Carrot(), Spinach()]

// Now we can check if the vegetables are for sale, because we know for sure that they conform to Vegetable so must implement this variable.
var forSale: [Vegetable] = {
vegetables.filter { $0.isForSale } // This will return [Spinach()]
}
}

Swift protocol property of type Set Self

The way to put constraints in protocols is similar to how you specify protocol conformance (they're the same thing after all)

protocol Groupable: Hashable
{
var parent: Self? { get }
var children: Set<Self> { get }
}

swift protocol conformance when same property name is optional

There is no elegant solution to your problem other than renaming the conflicting property on the conforming type.

Swift doesn't allow 2 properties of the same name to exist on a type even if their types are different. On the other hand, Int? and Int are completely different types, so you cannot have trackNumber: Int fulfil the protocol requirement of trackNumber: Int?.

The only solution (other than changing the type in either the protocol or the struct) is to rename the non-Optional property in SpotifyTrack and make an optional computed property of the same name returning the non-optional one.

protocol Track {
var trackNumber: Int? { get }
}
struct SpotifyTrack {
private let _trackNumber: Int
}
extension SpotifyTrack: Track {
var trackNumber: Int? { _trackNumber }
}

How to make a swift class conform to a protocol that requires a protocol-conform type for one of its properties?

You can do this with associated types.

Declare an associated type in ProtocolA:

protocol ProtocolA {
associatedtype BType: ProtocolB
var b: BType? { get } // Note the change in the type of b
}

This is saying that b is an optional of some type that conforms to ProtocolB. What type exactly? That depends on the conformers of ProtocolA.

In A's extension, you specify what BType is:

extension A: ProtocolA {
typealias BType = B
}

And you're done!

As a result of this, you won't be able to use ProtocolA as the type of a variable:

var protocolA: ProtocolA? // error

Because you don't know what b's type is.

Swift protocol default values are not changable


var type1: AssetViewAttribures = Crypto(name: "name", logo: URL(string: "https://pixabay.com/de/illustrations/online-maus-web-internet-weltweit-523234/")!, symbol: "symbol", avgPrice: "123", precision: 2)

type1.avgPrice

This would call the getter declared in the protocol extension, which just returns "". This is because Crypto.avgPrice has no relation to the avgPrice declared in the protocol extension. You can't "override" a member in an extension, because extensions are dispatched statically. The compiler sees that test is of type AssetViewAttributes, finds the default getter you have declared in the extension, and that's what it will call.

To fix this, you need to add avgPrice as a requirement of the protocol:

protocol AssetViewAttributes {
...
var avgPrice: String { get }
}

This causes Swift to find avgPrice declared in the protocol, and dispatches it dynamically. If the implementing class happens to implement avgPrice, that implementation will be called. If not, then the default implementation is called.



Related Topics



Leave a reply



Submit