Using Private API in App Store Applications

    I think that most iOS developers in one way or another were faced with the fact that, according to Apple's rules, it was not possible to make any functions. This is often due to the fact that certain methods fall into the private section. If you try to publish the application using them, it will be rejected (paragraph 2.5 of the Apple Review Guidelines).



    Under the cut, I will tell you how to partially remove this restriction.


    It will not be possible to hide major violations of the rules in this way, because from the functionality of your application it will be clear that it uses something forbidden (transferring files via bluetooth, for example), but this method is suitable for any changes to the standard UI and something similar perfect.

    So, suppose we want to change the color of UISwitch, but on iOS 4 (tintColor appeared in iOS 5). This can be done using the following code:

    [testSwitch setAlternateColors:true];
    

    It seems that everything is simple, but this method is not in the UISwitch documentation, and therefore it cannot be used. You can hide this using the capabilities of Objective-C Runtime.

    So, hereinafter a small step-by-step instruction:
    1. We collect NSString in pieces so that code analyzers do not notice its name in its entirety:
      NSString *nameOfMethod = @””;
      for (NSString *s in [NSArray arrayWithObjects:@"set",@"Alt",@"ernate",@"Colors:",nil])
      nameOfMethod = [nameOfMethod stringByAppendingString:s];
      const char *nameOfMethodUTF8 = [nameOfMethod UTF8String];
      

    2. We iterate over the UISwitch methods until we find the desired one:
          SEL methodSel = nil;
          Method *methods = class_copyMethodList([UISwitch class], &count);
          i = 0;
          while(i < count)   {
              SEL s = method_getName(methods[i]);
              if (0 == strcmp(sel_getName(s), methodNameUTF8String))  {
                  methodSel = s;
                  i = count;
              }
          }
      

    3. We call the function for the corresponding object (testSwitch):
      if (methodSel != nil) {
              IMP m_imp = method_getImplementation(methodsList[i]);
              m_imp(theSwitch, methodSel, YES);
      }
      free(methods);
      


    Voila, we circumvented this limitation, but please consider why Apple blocked it before using this method.

    PS: To check the application for using private api, you can use the App Scanner application

    Also popular now: