Reputation: 3927
UPDATE START It was because this array was coming from Objective-C and there were some screw-ups happening in the whole process. Needed some fixes, but all the answers below are correct. UPDATE END
I've a protocol as below
protocol SomeProtocol
{
func someFunctionProtocol
}
There is a struct that implements this protocol as
struct SomeStruct: SomeProtocol
{
....
}
Now, at runtime, I get an argument arg: Any
that I know for sure will implement SomeProtocol
How should I call this protocol method on arg
. I have tried
let ob = arg as! HanselProviderProtocol
, however this gives me runtime error Could not cast value of type '_SwiftValue' (0x111952720) to 'SomeProtocol' (0x111957158)
The images below show that it is not working
Upvotes: 2
Views: 248
Reputation: 6151
Type cast the Any
type to the struct
type, not the protocol
.
guard let ob = arg as? SomeStruct else {
print("invalid type")
return
}
ob.someFunctionProtocol()
EDIT
Or just check with the is
keyword.
let foo: Any = SomeStruct()
if foo is SomeProtocol {
// you can safely use force unwrapping here, because the condition above returned true
(foo as! SomeProtocol).someFunctionProtocol()
}
If you would be using SwiftLint, you can disable the force cast warning or error with the following command:
// swiftlint:disable:this force_cast
Upvotes: 1
Reputation: 19602
In Swift3, you can cast the argument of type Any
to a protocol:
protocol SomeProtocol {
func someFunctionProtocol()
}
struct SomeStruct: SomeProtocol {
func someFunctionProtocol() {
print("Yep")
}
}
func test(arg: Any) {
if let castee = arg as? SomeProtocol {
castee.someFunctionProtocol()
}
}
test(arg: SomeStruct())
Prints:
Yep
Upvotes: 2
Reputation: 119242
If you have a value of Any
type, you can test for conformance and execute like so:
(arg as? SomeProtocol)?.someFunction()
Or, if you want it to have wider scope:
guard let conformer = arg as? SomeProtocol else { return }
conformer.someFunction()
Upvotes: 1
Reputation: 916
If there could be more different structs implementing the protocol, use:
protocol SomeProtocol {
func a()
}
struct SomeStruct: SomeProtocol {
func a() {
print("a called from SomeStruct")
}
}
let x = SomeStruct() as Any // Just as an example
if let x = x as? SomeProtocol {
x.a()
}
Upvotes: 1