// Paste this code into a Swift playground.
// @objc is required for this to work
// Try removing @objc and see what happens.
@objc protocol ServiceType {
func performService() -> String
}
class ServiceResolver {
private init() {}
private static var services = [String: Any]()
static func resolve<R>(proto: Protocol) -> R {
return services[NSStringFromProtocol(proto)]! as! R
}
static func register(proto: Protocol, instance: Any) {
// NSStringFromProtocol works ONLY with Objective-C protocols.
services[NSStringFromProtocol(proto)] = instance
}
}
// To conform to an @objc protocol,
// a class must descend from NSObject
class Service: NSObject, ServiceType {
func performService() -> String {
return "I'm doing it!"
}
}
// To conform to an @objc protocol,
// a class must descend from NSObject
class MockService: NSObject, ServiceType {
func performService() -> String {
return "I'm mocking you!"
}
}
// .self is required here due to a pecularity of Swift. If there's more than one parameter,
// you have to use .self
ServiceResolver.register(ServiceType.self, instance: MockService())
// We don't need .self here because there's only one parameter, though
// you can add it if you wish.
let service: ServiceType = ServiceResolver.resolve(ServiceType)
Comments