Reputation: 1177
I am currently testing private frameworks for IOS and currently I'm trying to figure out how to check if Night Shift is enabled. For reference, the header file I am working with is located here.
And here is the code I am using below:
if (!(NSClassFromString(@"CCUINightShiftSectionController"))) {
dlopen("System/Library/PrivateFrameworks/ControlCenterUI.framework/ControlCenterUI", RTLD_LOCAL);
}
NSObject *manager = [NSClassFromString(@"CCUINightShiftSectionController") performSelector:NSSelectorFromString(@"_defaultFontTight")];
NSLog(@" ok= %@", manager);
}
From that file, I got the data for _defaultFontTight
to print in the NSLog just fine, but what I'm struggling with is how do I get the instance functions? More specifically, everything below that start with a -
symbol. I can only get info from a +
symbol.
If I were to switch out _defaultFontTight
with enabled
then I get the following:
2017-07-02 18:09:35.382109-0400 Testing[809:96270] +[CCUINightShiftSectionController enabled]: unrecognized selector sent to class 0x1b7d5e420
Any help would be greatly appreciated!
EDIT:
I tried this code below:
id myInstance =[NSClassFromString(@"CCUINightShiftSectionController") new];
[myInstance performSelector:NSSelectorFromString(@"enabled")];
For some frameworks, it gets the instance variable values sucessfully, while for most it just returns null
or errors such as [core] "Error returned from daemon: Error Domain=com.apple.accounts Code=9 "(null)""
Upvotes: 2
Views: 435
Reputation: 124
You can do it in this way. Declare protocol with methods that you want to use.
@protocol TestPrivateMethods <NSObject>
- (BOOL)enabled;
@end
Then do it in this way :
id myInstance = [NSClassFromString(@"CCUINNightShiftSectionController") new];
NSLog(@"enabled %d", [(id<TestPrivateMethods>)myInstance enabled]);
Upvotes: 1
Reputation: 9570
NSClassFromString
will return nil
. They're various ways you can do that but for now dlopen("/System/Library/PrivateFrameworks/ControlCenterUI.framework/ControlCenterUI", RTLD_LAZY)
would be the simplest.With that out of the way you will be able to call anything you want from private frameworks. But it doesn't mean it will actually work. Most private APIs are protected by entitlements and wouldn't work without jailbreak. And there's always a problem with figuring how to actually use them. You can't just call a random method and expect it to work. You might need to do some initialization. The only way to figure that out is to disassemble the methods and applications that call these methods.
Upvotes: 1
Reputation: 531
Please note that you are using private frameworks (not documented), and the header file that you are referencing to it, is corresponding to iOS 10.2, so make sure to make your tests on a real iPhone running the same iOS version.
For your calls, try to make them like this:
id myInstance = [NSClassFromString(@"CCUINightShiftSectionController") new];
if ([myInstance respondsToSelector:@selector(someInstanceMethod)]) {
[myInstance performSelector:@selector(someInstanceMethod)];
}
Also i note that "CCUINightShiftSectionController" is looking to be a "UIViewController" subclass, and it will not be well initialized using the "new" initializer, so you may have null or wrong results.
Good luck to make it working.
Upvotes: 1
Reputation: 53000
Try create an instance of your class first if you wish to call instance methods. E.g. something like:
id myInstance = [NSClassFromString(@"CCUINNightShiftSectionController") new];
... [myInstance someInstanceMethod] ...
HTH
Upvotes: 1