iOS How to Use Uiapplication Launchapplicationwithidentifier Which Is in Private APIs

iOS How can I use UIApplication launchApplicationWithIdentifier which is in private APIs?

REQUIREMENTS

  1. Jailbroken iDevice
  2. Valid certificates/keys in your keychain and its associated provisioning profile. (If you aren't enrolled in the apple developer program, use this workaround: self sign my code and test on iphone in xCode)

MY SOLUTION

1) Enable Entitlements in your XCode project.

To add Entitlements to your project, select your project in project navigator, then on active Target -> Summary -> Entitlements -> check Enable entitlements check box. New file with name "YourProject.entitlements" would appear in project navigator right after.

2) Add folowing property to Entitlements.

Add entitlement property: com.apple.springboard.launchapplications of type Boolean with value YES

3) Since launchApplicationWithIdentifier:suspended: is private API, you need to explicitly declare it in order to build your app. Just add folowing code in appropriate place(s):

// Simply make declaration  inside a Category.
#import "BlahBlah.h"
@interface UIApplication (Undocumented)
- (void) launchApplicationWithIdentifier: (NSString*)identifier suspended: (BOOL)suspended;
@end
....
@implementation BlahBlah
...

4) Build your project.

5) Copy YourProject.app into device's /Application folder (via SFTP, for example)

6) Respring or reboot iDevice.

7) ...

8) Profit!

SEE ALSO

Special API to launch an app from my application - another solution

What is the bundle identifier of apple's default applications in iOS?

iOS How to use private API?

Just specify the private methods in a category interface above the class implementation where you want to use it, like this:

@interface UIApplication (Private)

- (BOOL)launchApplicationWithIdentifier:(id)identifier suspended:(BOOL)suspended;

@end

Don't import the whole class-dump file and link with the original UIKit framework.

You must be very careful when using private API. These methods can change or be removed in future iOS versions!

Check if the method really exists with respondsToSelector: at runtime and be prepared for the case that it does not exist.

I used a secret MapKit feature in my own application and I knew that the private methods only exist in iOS 5. So my app still works in all iOS versions but this feature is only available in iOS 5 (Apple removed or changed it in iOS 6 beta 1).

Special API to launch an app from my application

Let me first say that this method is jailbreak only! It uses private API's that Apple can stop supporting at any time in a future version!

Let's get to it, this method uses the [UIApplication launchApplicationWithIdentifier:suspended:] private method:

[[UIApplication sharedApplication] launchApplicationWithIdentifier:@"com.apple.Preferences" suspended:NO];

From what I've tested calling this method from an application not running as root is useless, apparently SpringBoard (or LaunchServices) only allow root applications to launch other applications using this method.

So, first you need to jailbreak your iPhone, then you need to get your application running as root.

To get your app running as root you need to place it in /Applications/YourApp.app instead of the usual /User/Applications/UUID/YourApp.app.

You can install OpenSSH using Cydia and use SSH to access your phone's shell.

Then, after having your app in the right place you need to set permissions, for example:

Sample Image

I would use the same ones as Cydia:

chown -R root:wheel /Applications/YourApp.app

Next, a little trick. The binary will need the setuid bit:

chmod 4755 /Applications/YourApp.app/YourApp

And for the last step, SpringBoard doesn't open apps with the setuid bit, but it opens a script (which can open another app)! Just change the name of the binary to something like YourApp_:

mv /Applications/YourApp.app/YourApp /Applications/YourApp.app/YourApp_

And create a new file named YourApp in your app folder with the following script:

#!/bin/bash
CrrDir=$(dirname "$0")
exec "${CrrDir}"/YourApp_

Now, just respring (there's an app for that in Cydia) and you're ready to go.

Sorry if this seems hard, it isn't, I don't remember where I learned it, but it was a long time ago. This method works fine in all iOS versions and I've just tested it with iOS 5.1.

Again, YOUR APP WILL NOT BE APPROVED BY APPLE IF YOU DO THIS.

Test private APIs on iPhone

yes as long as your device is registered (on the provisioning page) and marked "use for development." you can test on your device without any kind of interference from apple.

Open Mobile Safari without using openURL:url

I solved this using the answers on this page ..

iOS How can I use UIApplication launchApplicationWithIdentifier which is in private APIs?

Though I didn't have to move my .app file in to /Applications

It was enough to add the entitlements, then simply call it using ...

[[UIApplication sharedApplication] launchApplicationWithIdentifier:@"com.apple.mobilesafari" suspended:NO];

Plasma

iOS How to use Entitlement.plist to specify property of my app

I see two problems/questions in your post:

1) you get the error

'Receiver type 'UIApplication' for instance message does not declare a
method with selector 'launchApplicationWithIdentifier:suspended:''

Is that a compiler error? It sounds like maybe it is. Here's the thing. There's plenty of objective-c classes in the set of Public Frameworks that still have some private methods in them. Thus, in the normal headers (.h files) for the public frameworks, those private methods won't be listed. But, they're there in the dynamic libraries. If you want to build an app that uses these, then one way to solve the problem is to find a copy of the full header.

For example, here's a copy of the full UIApplication.h header.

Then, you can copy the declaration of the private methods, and in your own code, declare them like so:

// Used to disable warning for non-public methods
@interface UIApplication (Extensions)
- (BOOL)launchApplicationWithIdentifier:(id)identifier suspended:(BOOL)suspended;
@end

That should stop the compiler from complaining that the private method doesn't exist.

For the future, you should read about class-dump, which is a tool that you can run on the public or private frameworks in the SDK, and reverse generate headers like the one above, yourself. They'll change with every release of the SDK, so it's good to be able to generate them yourself.

2) you ask about using entitlements without code signing.

First, read what Saurik originally wrote about it here. Yes, you do need to code sign the entitlements. But, no, it doesn't have to be with an Apple certificate on jailbroken phones. You can fake code sign, by downloading the ldid executable, and doing

cd MyAppName.app
ldid -Sentitlements.xml MyAppName

assuming your app is named MyAppName and you made the entitlements file entitlements.xml. I believe that this entitlements file would work for you, if you fake code-signed it with ldid:

<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.springboard.launchapplications</key>
<true/>
</dict>
</plist>

Be careful. I have found ldid on the internet in a couple places. I'm really not sure which one is the right one. I recall that once, I tried to do this, and the version of ldid I was using did not work for signing entitlements. I downloaded ldid from another source, and then it worked. So, beware.



Related Topics



Leave a reply



Submit