Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
197 views
in Technique[技术] by (71.8m points)

ios - iPhone private API compiling

I'm searching through the whole internet since a few hours now, and I just can't find the informations I'm looking for. I would like to mess around with the private apis, see whats possible, etc., but I can't even compile something.

So I've got a few pretty basic questions:

  • Do I have to dump the headers? Because I downloaded a sample, where the API is loaded with
char *framework = "/System/Library/PrivateFrameworks/...";
dlopen(...);

I would like to use the objc-syntax (if possible) rather than using C (as mentioned above), if there are any opportunities.

  • How do I make Xcode compile, if I import the private APIs? Do I have to add other link flags? (because I read about two different opinions) I added a private framework and created a new Folder "Headers" and put all the headers files in there, so the framework shows up correctly in Xcode. Do I have to import the whole .framework, or only the headers from the framework I would like to use? After I imported the framework, I get 20+ errors, unknown type names, and many more.

And, finally, I've read about entitlements (which seem to be new in iOS 7). How do I use these entitlements and when do I use them?

Could someone please just type a few lines as an example?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Background

In order to use methods in any framework, you can choose to either reference those frameworks statically or dynamically. I haven't seen anything in your question that suggests you need to use dynamic linking, so I'm going to avoid that (it's slightly more complicated for a beginner). (‡)

To statically reference APIs in a framework, you would import the relevant headers, and then configure your Xcode project to link to the framework. These two steps only change slightly for Private APIs.

Private APIs usually don't provide you with the headers (*.h) that describe the APIs. I say "usually", because sometimes, an API that's private on iOS is actually public on Mac OS X, so to use it, you simply copy the OS X version of the header into your project.

Generating Headers

Probably more common, though, is that you have to generate the header yourself. If you know which header you need, often you can find it posted online under someone's github account. If not, you need a tool like class-dump, or class-dump-z. Run the class dump tool on the private framework, by finding it on your Mac:

cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/PrivateFrameworks/
class-dump -H -o ~/Headers/7.0/MusicLibrary/ MusicLibrary

Then, go into ~/Headers/7.0/MusicLibrary/ and find lots of dumped header files. Copy (only) the header(s) you need into your Xcode iOS project directory. Then, from inside Xcode, right click on a source folder in your Project Navigator view, select "Add files to <Project Name> ...". Pick the dumped header file you need to include in your project.

Linking

In order to successfully link against the API, you also need to add the framework to your Xcode Build Phases. From your project Target settings, select Build Phases then Link Binary with Libraries. You normally choose a public framework from the default list that the iOS SDK provides you. However, you can choose to browse your Mac for 3rd-party frameworks, or private frameworks, too. For private frameworks, you're just going to have to navigate to a folder location like this

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.0.sdk/System/Library/PrivateFrameworks/

and then pick the *.framework directory.

Then, simply use the APIs like you would use any public/private API. #import the header file, call the APIs, instantiate the classes, etc.

The use of this code:

char *framework = "/System/Library/PrivateFrameworks/...";
dlopen(...);

is an attempt to dynamically open a private framework. That's not necessary, if you know at compile time which framework you want to use, and have it present on your Mac to let Xcode link against.

Entitlements

Entitlements are not new to iOS 7. They have existed for quite some time, and are one technique iOS uses to prevent unauthorized usage of some private APIs. iOS will check to see if your app has been granted a particular entitlement (by name), and if it does not have that entitlement, calling the protected API will fail (usually silently, although sometimes you'll see a message in the Console log).

See here for an example of granting your (jailbreak) app an entitlement.


(&ddagger;) Update: iOS 9.3 has brought some changes with respect to Private APIs, and static vs dynamic linking. Please see this Stack Overflow question here for more.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...