How to Access iOS Private APIs in Swift

How to access the method in the Private API framework and pass the value to it?

Class methods start with + and instance methods start with - in Objective-C.

// Following is an instance method because it starts with `-`
- (void)setCanEditRecipients:(bool)arg1;

Above method will NOT work with following code.

Class CKSMSComposeController = NSClassFromString(@"CKSMSComposeController");
SEL sel = NSSelectorFromString(@"setCanEditRecipients:");

// `CKSMSComposeController` is a class - NOT an instance
if ([CKSMSComposeController respondsToSelector:sel]) {
// will not enter if's body
}

On top of all this - you shouldn't create an instance of your own and do customizations on that. You should do the customizations on the instance that's presented by the system on screen.

Here's how you can try that -

- (void) showMessageComposeViewController {
if ([MFMessageComposeViewController canSendText]) {
MFMessageComposeViewController* messageController = [[MFMessageComposeViewController alloc] init];
messageController.recipients = @[@"555-555-5555"];
messageController.body = @"Example message";

[self presentViewController:messageController animated:YES completion:^{

// Allow enough time for the UI to be loaded fully
dispatch_after(1, dispatch_get_main_queue(), ^{
// Since `MFMessageComposeViewController` is a `UINavigationController`, we can access it's first view controller like this
UIViewController* targetVC = messageController.viewControllers.firstObject;

// Check if the instance is of correct class type
if ([targetVC isKindOfClass:NSClassFromString(@"CKSMSComposeController")]) {

SEL sel1 = NSSelectorFromString(@"setCanEditRecipients:");
if ([targetVC respondsToSelector:sel1]) {
// put breakpoint here to check whether this line is executed
[targetVC performSelector:sel1 withObject:@NO];
}

SEL sel2 = NSSelectorFromString(@"setTextEntryContentsVisible:");
if ([targetVC respondsToSelector:sel2]) {
// put breakpoint here to check whether this line is executed
[targetVC performSelector:sel2 withObject:@NO];
}
}
});
}];
}
}

Force iOS app to open in foreground using private APIs

Via Jailbreak you could look at something like AutoLaunch:

If you use a particular app that seems to crash here and there, then a new free jailbreak tweak called AutoLaunch could be your next best friend. It can automatically re-launch any app that crashes on your device so you don’t have to re-launch it yourself.

http://www.idownloadblog.com/2017/01/08/autolaunch/

Not sure how much control you'd have over wanting to launch regardless of whether it's crashed or not. You might be able to ask the author to provide the source-code or work with him to get your desired result.

UPDATE:

It's open source:

https://github.com/chenzhijie/autolaunch

Upon further inspection of the source it looks like it uses the following to launch the application after a crash:

int createSubProcessResult = fork();
if(createSubProcessResult == 0) {
execl("/usr/bin/open","open",[currentAppBundleId UTF8String],NULL);
}

I guess you could roll your own version of Autolaunch and have it wait/subscribe for a remove command that'll launch/switch different apps.

Apple and private APIs

A private API is an API that is not documented in the SDK. For instance, a framework class might declare a method that is not intended to be used by outside developers. The behavior of a private API is not guaranteed. You can't even be sure that the method will be there in the future updates of the platform. Its declaration is probably not available in publicly distributed SDK header files. If you stick to things publicly defined in the SDK documentation, you'll be OK.

How does Apple know you are using private API?

There are 3 ways I know. These are just some speculation, since I do not work in the Apple review team.

1. otool -L

This will list all libraries the app has linked to. Something clearly you should not use, like IOKit and WebKit can be detected by this.

2. nm -u

This will list all linked symbols. This can detect

  • Undocumented C functions such as _UIImageWithName;
  • Objective-C classes such as UIProgressHUD
  • Ivars such as UITouch._phase (which could be the cause of rejection of Three20-based apps last few months.)

3. Listing Objective-C selectors, or strings

Objective-C selectors are stored in a special region of the binary, and therefore Apple could extract the content from there, and check if you've used some undocumented Objective-C methods, such as -[UIDevice setOrientation:].

Since selectors are independent from the class you're messaging, even if your custom class defines -setOrientation: irrelevant to UIDevice, there will be a possibility of being rejected.


You could use Erica Sadun's APIKit to detect potential rejection due to (false alarms of) private APIs.


(If you really really really really want to workaround these checks, you could use runtime features such as

  • dlopen, dlsym
  • objc_getClass, sel_registerName, objc_msgSend
  • -valueForKey:; object_getInstanceVariable, object_getIvar, etc.

to get those private libraries, classes, methods and ivars. )

Will searching for a subview with a private API class name be rejected?

You could use visibleItemsInvalidationHandler to get contentOffset

layoutSection.visibleItemsInvalidationHandler = ({ (visibleItems, point, env) in
print(point)
})

How do I use this private API?

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.

iOS otool to detect private apis

Otool usage

Here is official documentation

Here is the question about otool usage:
how to use otool

Detect private api usage

How does Apple know you are using private API?

Detecting Private APIs

Here I have a question. Why do you want to detect private apis? Usually, this question happens when you plan to send your app to AppStore. If so, probably iphone-privateapi tag isn't good fit for the question. Since, this tag is more about how to use private api (and implication that the app won't be send to Appstore)

Documentation on private API

This one is tough. There is no good documentation. Information is scattered and becoming outdate as soon as new version of iOS are released.

Look at these questions to find some interesting links:

iOS Private API Documentation

How to use iPhone SDK Private APIs

https://stackoverflow.com/questions/12734960/some-structured-information-on-ios-internals



Related Topics



Leave a reply



Submit