Dictionary of a Protocol Swift 4

Dictionary of a protocol Swift 4

This kind of mixing protocols with class inheritance is notoriously complicated. The answer to your specific issue is you can't directly, because if you make Playable conform to Hashable, you can't make an array of them.

The simplest solution is don't use a protocol here. Just make an abstract class. Swift isn't very good at abstract classes, but they will make most of these problems go away.

Given your specific case, I might also consider using an enum for Playable rather than a protocol. That would likely make things simpler.

From there, the solutions get a bit more complicated. For example, you could create a ClassDictionary along the lines of my ClassSet experiment. Or you can build a type-eraser. But it gets ugly.

You could also consider switching from a class to a struct, and getting rid of the Dictionary, and just using an Array. If the point of the Int is a count, then just have multiple copies of the struct. If the point of the Int is a parameter (like "how much damage"), then that should be inside the Damage struct, not in a dictionary.

(Unrelated note, your hash values are very strange. They'll work, but this isn't how hashes are meant to function.)

As an example of where I'm going with this, I'm seeing something like:

protocol Playable {
func play(game: Game) -> Player
}

struct Damage: Playable {
let amount: Int

func play(game: Game) -> Player {
// do stuff
return game.activePlayer
}
}

struct DrawACard: Playable {
func play(game: Game) -> Player {
// do stuff
return game.activePlayer
}
}

struct Card {
let id: Int
let name: String
let cost: Int
let description: String
let cardType: CardType
let target: Target
let abilities: [Playable]
}

// A card that inflicts one damage
let card = Card(id: 1,
name: "Strike",
cost: 1,
description: "Strike 'em",
cardType: CardType(),
target: Target(),
abilities: [Damage(amount: 1)])

This switched everything to immutable structs on purpose; I believe everything you're describing here are really value types.

Swift protocol to return a dictionary of selector

Well [String: Selector] is Dictionary<String, Selector> which is a struct and structs cannot be represented in Objective-C, so you would need an NSDictionary

@objc public protocol MazeProtocol: AnyObject {
@objc static func configurations() -> NSDictionary
}

Protocol Extension of Constrained Dictionary

Since Swift 4.2 you can do this with:

extension Dictionary : FirebaseValue where Key == String, Value == FirebaseValue {
}

Passing dictionary objects to Objective C protocol in Swift

Try implementing the method in your Swift class like this:

func handleNewMessageArrived(messageContent: [NSObject : AnyObject]!) {
// Handle the message
}

Adopt a protocol for Array and Dictionary

The reason for this error is the conflict between the dict type inferred by the compiler and the one you mentioned while conforming Array to your protocol.

When you write this line

let dict = [["key":"value"]]  

For compiler it will become as below where type is Array<Dictionary<String, String>>

let dict: Array<Dictionary<String, String>> = [["key":"value"]]

Now when you are doing dict.stringValue, compiler will first match the type of the calling object i.e dict with the type you defined during conformance of Array with MyProtocol

As the compiler inferred type i.e, Array<Dictionary<String, String>> is different than the type you mentioned in conformance i.e, Array<Dictionary<String, Any>> so compiler throws error.

But when you declare dict variable with explicit type i.e, Array<Dictionary<String, Any>> same as you defined in conformance of MyProtocol then compiler does not see any issue and your code works just fine.

While conforming Array/Dictionary to MyProtocol you can just ignore setting the Element type as below,

extension Array: MyProtocol {

var stringValue: String {

return "ArrayValue"
}
}

extension Dictionary: MyProtocol {

var stringValue: String {

return "DictionaryValue"
}
}


Related Topics



Leave a reply



Submit