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
Difference Between Sort and Sortinplace in Swift 2
Override UIgesturerecognizer Touchesbegan
Conversion Between Cgfloat and Nsnumber Without Unnecessary Promotion to Double
Bad_Access During Recursive Calls in Swift
How to Retrieve The Name of Participants in Msconversation
How to Cast from Cftyperef to Axuielement in Swift
Swift Protocol Extension Implementing Another Protocol with Shared Associated Type
Swift: Binary Operator '==' Cannot Be Applied to Operands of Type "Protocol"
Type 'Bundle' Has No Member "Module"
How to Create a Cocoapod with .Swift
How to Unwrap Optional<Optional<T>> in Swift 1.2
iOS 10 App Crashes When Accessing Camera
Using Index from Foreach in Other Array
How to Use Publishers.Combinelatest to Get 1 Publisher
How to Get Textfields from Static Cells in UItableviewcontroller? Swift