I'm doing this for testing purposes. It helps with dependency injection.
I have an Objective-C library that I've imported into my Swift 3 project. One of the classes in the Objective-C library is defined this way:
@interface Auth : NSObject
@property (strong, readwrite) NSString *clientId;
@property (strong, readwrite) NSArray *scopes;
@end
In my Swift project, I want to define a protocol. The protocol should define 4 methods: 2 setters and 2 getters.
I want the protocol to be defined in a way so that I can reopen the Auth class in Swift with an extension and declare that Auth conforms to my protocol without putting anything in the body of the extension because the Objective-C class already conforms.
Here's my protocol:
protocol AuthProtocol {
var clientID: String! { get set }
}
Here's the extension:
extension Auth: AuthProtocol {}
This works fine. Now I can treat Auth objects as AuthProtocols and have access to setting and getting their clientID property.
The problem arises when I try to make the protocol define the setter and getter for the scopes array. I believe NSArray
is Array<AnyObject>
in Swift. Here's what I tried:
protocol AuthProtocol {
var clientID: String! { get set }
var scopes: Array<AnyObject> { get set }
}
Now the line which reopens Auth
for extension complains that
Type
Auth
does not conform to protocolAuthProtocol
Xcode suggests a solution when I click on the error, which adds this code to the body of the exention:
extension Auth: AuthProtocol {
internal var scopes: Array<AnyObject> {
get {
<#code#>
}
set {
<#code#>
}
}
}
This code now has an error on the internal
line:
scopes
used within its own type
How do I define AuthProtocol
with a getter and setter for the scopes
array so that this line:
extension Auth: AuthProtocol {}
Doesn't complain?
All this indicates to me that the problem has to do with the NSArray
type.
you can use Xcode to show you exactly what the protocol should be by using the "Generated Interface" command:
this jumps you to the generated code:
open class Auth : NSObject {
open var clientId: String!
open var scopes: [Any]!
}
transform this generated class definition into the correct protocol definition:
protocol AuthProtocol {
var clientId: String! { get set }
var scopes: [Any]! { get set }
}
// doesn't complain anymore
extension Auth: AuthProtocol {}