I am trying to make a simple Dependency Injection system for our app in swift, for 2 day now. I\'m flexible to whatever solution but I would like something so I can say \"gi
The comment given by nhgrif is the correct answer for Swift 2. You should use an optional binding:
if let aObjectWithAProtocol = aObject as? AProtocol {
// object conforms to protocol
someObject.someFunction(aObjectWithAProtocol)
} else {
// object does not conform to protocol
}
This if let something = obj as? type
statement is called optional binding and checks if the object can be type-casted to the given type/class/protocol/....
If so, you can use the optional (as?
) or force unwrap (as!
) the object.
This function will perfectly meet your requirement:
bool _swift_typeIsTargetType(id sourceType, id targetType)
It can check whether a swift type is the target type (is same type or subclass, or conforms to the target protocol), works like is
operator in swift. But it's for a type, not for an instance:
let sourceType: Any.Type = type(of: self)
let targetType: Any.Type = AnyProtocol.self
let result = _swift_typeIsTargetType(sourceType, targetType)
It uses private APIs in libswiftCore.dylib
, See swift source code Casting.cpp:
bool _conformsToProtocols(const OpaqueValue *value, const Metadata *type, const ExistentialTypeMetadata *existentialType, const WitnessTable **conformances)
Optional binding is not same. It can also check conformance, but you can't dynamically give the type to check:
let targetType: Any.Type = AnyProtocol.self
//error: use of undeclared type: 'targetType'
if let _ = aObject as? targetType {
// object conforms to protocol
} else {
// object does not conform to protocol
}
This function is used in ZIKRouter. It's a module router and also a Dependency Injection framework. It uses protocol to discover modules and inject dependencies. You can try it if you want to do something like 'finding a module conforming to some protocol'.
If you import obj-c then you can do something like you used to.
Otherwise, it's hard because protocols don't exist in the same way. Consider a registration based system for your factory. Each of your classes would register themselves by supplying a function or closure that can be called to return a new instance of that class, and the registration is against a string or some other type of identifier. This is where it would be good to have a protocol type, but in obj-c you were really doing the same thing with a string conversion. You could register against anything that is Equatable
to keep things very generic.