How I manage to pass Apple iOS App review using method swizzling

As a developer I wanted to share the way I approach this to anyone who had come to anything similar, If you have experience with this or you are interested share it in the comments.

The app review process is a mandatory step for any app going to the App Store and it guarantees that developers make high quality apps, there are a bunch of definitions and guidelines for this process if you want to know more about them you can read it here:

I was finishing the development cycle of an iOS internet banking app, in this particular case the app required login credentials in the first screen. The Apple app review team specifies that if the app uses credentials they need a demo account so they can inspect all the app’s features. Since this is an app for a bank, they were very resilient on giving me any account because the app should be in production and they did not have any test account for that environment.

Many solutions were presented including some bizarre ones like switching APIs or databases just for the review process and then change them back.

Two weeks went by, I did not have the demo account yet and instead of falling to the Parkinson’s law of triviality, I decided to take part in the matter at hand and put some hardcoded data in the app to simulate all the methods that fetch information from the API.

So my first approach was to put an ugly if at the beginning of each method to see if Apple was logged in with the demo user, this was really ugly and I did not want to put this code inside of those functions, I did not even like the if statement there. Doing some googling prove really useful and I came up with something really interesting about iOS development that I did not know.

The method swizzling, the process of changing method’s implementations at runtime, I found an article in NSHipster to be really useful:

What I did was, that for every module in the app that communicates to the API, I created a new file as a category and in there I wrote the initialize method to do the swizzling of the methods I wanted:

+ (void)initialize {

if (!MACUSER) {
return;
}

Class class = [self class];

NSArray<NSString *> *originalSelectors = @[
@"doStuffOnSuccess:onFailure:",
@"doStuff1OnSuccess:onFailure:",
@"doStuff2OnSuccess:onFailure:",
@"doStuff3:onSuccess:onFailure:"
];

NSArray<NSString *> *swizzledSelectors = @[
@"appleReview_doStuffOnSuccess:onFailure:",
@"appleReview_doStuff1OnSuccess:onFailure:",
@"appleReview_doStuff2OnSuccess:onFailure:",
@"appleReview_doStuff3:onSuccess:onFailure:"
];

NSUInteger selectorsLength = originalSelectors.count;

for (int i = 0; i < selectorsLength; i++) {
    SEL originalSelector;
SEL swizzledSelector;
    originalSelector = NSSelectorFromString(originalSelectors[i]);
swizzledSelector = NSSelectorFromString(swizzledSelectors[i]);

Method originalMethod = class_getInstanceMethod(class, originalSelector);
Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector);

method_exchangeImplementations(originalMethod, swizzledMethod);
}
}

Here is also a gist of the code.


Finally I submitted my app and it got pass the app review process successfully.

Please feel free to leave a comment with your opinion about swizzling, its cons and pros. I also hope to help someone that were in the same struggle as I was.