What I did was, I tested two scenarios, one is to put the app back to the foreground by clicking on the icon, another by URL sys call, and compared all the variables inside UIApplication, and surprisingly I finally found what I was looking for in UIApplication.h:
struct {
unsigned int isActive:1;
unsigned int isSuspended:1;
unsigned int isSuspendedEventsOnly:1;
unsigned int isLaunchedSuspended:1;
unsigned int calledNonSuspendedLaunchDelegate:1;
unsigned int isHandlingURL:1;
unsigned int isHandlingRemoteNotification:1;
unsigned int isHandlingLocalNotification:1;
unsigned int statusBarShowsProgress:1;
unsigned int statusBarRequestedStyle:4;
unsigned int statusBarHidden:1;
unsigned int blockInteractionEvents:4;
unsigned int receivesMemoryWarnings:1;
unsigned int showingProgress:1;
unsigned int receivesPowerMessages:1;
unsigned int launchEventReceived:1;
unsigned int isAnimatingSuspensionOrResumption:1;
unsigned int isResuming:1;
unsigned int isSuspendedUnderLock:1;
unsigned int isRunningInTaskSwitcher:1;
unsigned int shouldExitAfterSendSuspend:1;
unsigned int shouldExitAfterTaskCompletion:1;
unsigned int terminating:1;
unsigned int isHandlingShortCutURL:1;
unsigned int idleTimerDisabled:1;
unsigned int deviceOrientation:3;
unsigned int delegateShouldBeReleasedUponSet:1;
unsigned int delegateHandleOpenURL:1;
unsigned int delegateOpenURL:1;
unsigned int delegateDidReceiveMemoryWarning:1;
unsigned int delegateWillTerminate:1;
unsigned int delegateSignificantTimeChange:1;
unsigned int delegateWillChangeInterfaceOrientation:1;
unsigned int delegateDidChangeInterfaceOrientation:1;
unsigned int delegateWillChangeStatusBarFrame:1;
unsigned int delegateDidChangeStatusBarFrame:1;
unsigned int delegateDeviceAccelerated:1;
unsigned int delegateDeviceChangedOrientation:1;
unsigned int delegateDidBecomeActive:1;
unsigned int delegateWillResignActive:1;
unsigned int delegateDidEnterBackground:1;
unsigned int delegateWillEnterForeground:1;
unsigned int delegateWillSuspend:1;
unsigned int delegateDidResume:1;
unsigned int userDefaultsSyncDisabled:1;
unsigned int headsetButtonClickCount:4;
unsigned int isHeadsetButtonDown:1;
unsigned int isFastForwardActive:1;
unsigned int isRewindActive:1;
unsigned int disableViewGroupOpacity:1;
unsigned int disableViewEdgeAntialiasing:1;
unsigned int shakeToEdit:1;
unsigned int isClassic:1;
unsigned int zoomInClassicMode:1;
unsigned int ignoreHeadsetClicks:1;
unsigned int touchRotationDisabled:1;
unsigned int taskSuspendingUnsupported:1;
unsigned int isUnitTests:1;
unsigned int requiresHighResolution:1;
unsigned int disableViewContentScaling:1;
unsigned int singleUseLaunchOrientation:3;
unsigned int defaultInterfaceOrientation:3;
} _applicationFlags;
This contains possibly all the information a programmer wish they have access to when the application returns to the foreground, to be in particular, I would like to access the flag "isHandlingURL" which says 1 if the app is put into foreground by a sys-call, 0 if the app is put into foreground by the user.
Next, I looked at the address of "application" and "_applicationFlags", noticed that they are offset by 0x3C, which is 60, so I decided to use address operations to get my needed bit:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
*/
id* app = [UIApplication sharedApplication];
app = app+15; //address increments by long words, don't know if it will be the same on device
NSLog(@"Test:%x",*app);
}
which prints out test:4a40012, or 0x04a40012 if I write in a complete long word format.
This gives me in binary 0000 0100 1010 0100 0000 0000 0001 0010.
Looking back into _applicationFlags, this will give us "isHandlingURL" on 6th bit from LSB, which is 0. Now if I try to put the app into background and bring it back with a URL sys call, I get a print out of 4a40032 which in binary is 0000 0100 1010 0100 0000 0000 0011 0010 and I have my isHandlingURL bit turned on! So all that there is left to do is to complete the statement by bit-shift operations, and the final code will look like:
- (void)applicationWillEnterForeground:(UIApplication *)application
{
/*
Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
*/
id* app = (id*)[UIApplication sharedApplication]+15;
BOOL isHandlingURL = ((Byte)*app>>5&0x1);
if (isHandlingURL) {
//do whatever I wanna do here
}
}
I can go on and write a complete function to parse out all the _applicationFlag, but then it is at this point uncertain if the address increment is fixed to be 15 on both the simulator and the target, my next goal will be to replace with magic number '15' by some macro defines or values from the system so I can be sure that it will always shift 0x3C as required, and I need to look into UIApplication header to make sure that the _applicationFlag will always shift by 0x3C.
That's all for now!