2

I have found the class PSCellularDataSettingsDetail and its method +(void)setEnabled:(BOOL)enabled;, which I think will give me what I need, which is accessing the mobile data setting.

I found this method by opening up the compiled Preferences.framework using class-dump-z.

Now I found this answer and tried to access the class and method that way, but the class is private too. How can I open this class up to Xcode?

Community
  • 1
  • 1
vrwim
  • 13,020
  • 13
  • 63
  • 118
  • "the class is private" — do you mean that it's not exposed via the symbol table of the binary of Preferences.framework (i. e., `static`)? Because then there's not much you can do… – The Paramagnetic Croissant Apr 22 '15 at 20:16
  • @TheParamagneticCroissant when I tried using it in my Xcode project, it was not visible, so I guess the class definition is not in any of the frameworks that are imported in my project. How can I import this private framework in my project? Sorry, I'm new to this. – vrwim Apr 22 '15 at 20:22

2 Answers2

5

Have you tried calling performSelector? That is usually the trick to call private methods. Remember all that makes a method private in Objective-C is the fact that it is not advertised in the h file. But if you send a message to an object and the object can respond to that message it will, regardless of what's in the header file.

  • How can I get the class from the name to perform the selector on then? I'm sorry, I am new to this. – vrwim Apr 22 '15 at 20:29
  • @vrwim `NSClassFromString()`, `objc_getClass()`, etc… – The Paramagnetic Croissant Apr 22 '15 at 20:57
  • If it's a class method like +(void)setEnabled you would just call [MyClass performSelector(@selector(myMethod)] and if it is an instance method you would call it on a variable that is an instance of the class – Joseph Gagliardo Apr 22 '15 at 20:59
  • @TheParamagneticCroissant And if my class is not in any visible frameworks? What can I do then? – vrwim Apr 22 '15 at 21:17
  • @vrwim it's unclear what you mean by "visible framework". It seems as though you were confusing "visible" with "static"/"internal linkage" and "framework" with "header file". **You have already got the answer to your question about using private APIs that are available via external linkage but not exposed via a header file.** If you keep repeating your question verbatim, that's not going to help us guess what you are trying to do or what your problem is. Go search for the proper terminology and edit your question if you figured it out. Until then, we can't really help. – The Paramagnetic Croissant Apr 22 '15 at 21:31
  • 1
    @TheParamagneticCroissant I got the method definition from dumping headers with `class-dump-z`. Now I would like to use it, but I don't know how. I tried using `NSClassFromString` and `performSelector`, but that didn't do anything (literally). Then I wanted to see if there were any methods in this class, and I used [this method](http://stackoverflow.com/questions/330030/list-selectors-for-obj-c-object). That was empty. Is there a way to get to this method then or is it protected by iOS? – vrwim Apr 22 '15 at 21:49
  • @TheParamagneticCroissant Sorry for not knowing the right terminology, I'm still new to this. Could you maybe give me a few links/keywords I can go read up on this topic, so I know the terminology? – vrwim Apr 22 '15 at 21:52
  • There are lots of complexities involved. Without digging into the specific library you are trying to hack it's impossible to tell you what to do. Start simple. Build you own library and make a hidden method in there. Learn how to call it. Then try a simple well know private API call. Each of these steps will help you to understand what's going on. There could be all kinds of things, like retain/release issues with objects and so on. There is no easy answer to this. – Joseph Gagliardo Apr 23 '15 at 01:35
4

If it's a class method like +(void)setEnabled you would just call [MyClass performSelector(@selector(myMethod)] and if it is an instance method you would call it on a variable that is an instance of the class: MyClass *c = [[MyClass alloc] init];

[c performSelector: @selector(myMethod)]

It gets tricky when you need to pass parameters though like in this case, because the only way performSelector can pass parameters is if they are objects not primitives. You can also look into using objc_msgSend.

There is a ton of stuff online explaining how those two work. Either way it's messy to try to call private methods and is very risky.

  • And if my class is not in any visible frameworks? What can I do then? – vrwim Apr 22 '15 at 21:16
  • all that private means in Objective C is that the headers are not visible. Without the headers the programmer has no idea what is in the implementation unless they either know, they guess or they use a decompiler to figure out the hidden magic. How you find out what's inside the hidden parts is up to you. Once you know there is a method in there that you want to call, you can do it with performSelector or objc_msgSend. There's lots of stuff online about how to do that. – Joseph Gagliardo Apr 22 '15 at 21:22