I'm trying to extend an Objective-C class in Swift and make it conform to the Equatable
protocol. This requires to access some private members of the extended class, which the compiler doesn't let me do. What is the correct way to do it without making the private members public?
My Swift code:
import Foundation
extension ShortDate : Equatable { }
public func == (lhs: ShortDate, rhs: ShortDate) -> Bool {
if (lhs.components.year == rhs.components.year)
&& (lhs.components.month == rhs.components.month)
&& (lhs.components.day == rhs.components.day) {
return true;
}
return false;
}
Objective-C:
@interface ShortDate : NSObject<NSCopying, NSCoding> {
NSDate *inner;
NSDateComponents *components; // The date split into components.
}
...
@end
The error I'm getting:
ShortDate.swift:26:9: 'ShortDate' does not have a member named 'components'
I came across this question while trying to find a way to access a private variable of a class from one of the SDKs we use. Since we don't have or control the source code we can't change the variables to properties. I did find that the following solution works for this case:
extension ObjcClass {
func getPrivateVariable() -> String? {
return value(forKey: "privateVariable") as? String
}
open override func value(forUndefinedKey key: String) -> Any? {
if key == "privateVariable" {
return nil
}
return super.value(forUndefinedKey: key)
}
}
Overriding value(forUndefinedKey:)
is optional. value(forKey:)
will crash if the private variable doesn't exist on the class unless you override value(forUndefinedKey:)
and provide a default value.
I believe that there is no way to access Objective-C instance variables from Swift. Only Objective-C properties get mapped to Swift properties.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With