I'm trying to get access to MKMapSnapshotter's private instance variables _lodpiSnapshotCreator and _hidpiSnapshotCreator in Swift on macOS.
Thanks to class-dump, I know they're there (see here):
@interface MKMapSnapshotter : NSObject
{
[...]
VKMapSnapshotCreator *_lodpiSnapshotCreator;
VKMapSnapshotCreator *_hidpiSnapshotCreator;
}
but no matter what I do, I can't get ahold of them.
This is how I checked whether I could access them or not:
let snapshotter = MKMapSnapshotter(options: snapshotOptions)
let varNames = ["_lodpiSnapshotCreator", "_hidpiSnapshotCreator"]
for varName in varNames {
if let testIVar = class_getInstanceVariable(MKMapSnapshotter.self, varName) {
if let test = object_getIvar(snapshotter, testIVar) as? VKMapSnapshotCreator {
print(test)
} else {
print("Got ivar, but \(varName) is still nil (getInstanceVariable)")
}
} else {
print("\(varName) is nil (getInstanceVariable)")
}
}
Curiously, class_getInstanceVariable doesn't return nil, but object_getIvar does.
Got ivar, but _lodpiSnapshotCreator is still nil (getInstanceVariable)
Got ivar, but _hidpiSnapshotCreator is still nil (getInstanceVariable)
I'm at my wit's end here. All I can find via Google is people recommending the use of class_getInstanceVariable (which I already use) and key-value-coding (which doesn't work at all).
This must have been done before. Can anyone help me out?
Edit: So far, I have tried this:
@interface MKMapSnapshotter() {
@public VKMapSnapshotCreator *_lodpiSnapshotCreator;
@public VKMapSnapshotCreator *_hidpiSnapshotCreator;
}
@end
That compiles successfully, but when trying to use it, Swift keeps insisting that the members _lodpiSnapshotCreator and _hidpiSnapshotCreator don't exist.
Since we don't have or control the source code we can't change the variables to properties. Just tried this works for your case:
extension MKMapSnapshotter {
func getPrivateVariable() -> String? {
return value(forKey: "_lodpiSnapshotCreator") as? String
}
open override func value(forUndefinedKey key: String) -> Any? {
if key == "_lodpiSnapshotCreator" {
return nil
}
return super.value(forUndefinedKey: key)
}
}
You can find more about this here.
If this does not work then I believe that there is no way to access Objective-C instance variables from Swift. Only Objective-C properties get mapped to Swift properties.
Hope this helps!!
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