I want to show an alert view when my iOS app is in the background (and it\'s using location).
For example, the Uber Partner (Driver) app
After some static analysis of the binary, it became clear that they are not using PKPushRegistry (VOIP), undocumented NSNotificationCenter calls or SBAlertItem.
Took a little while to find it, but they are actually using CFUserNotification for the alerts. The class is documented for Mac, but private for iOS.
I found the usage by doing this:
nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification
The output is:
_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey
If I grep for PKPushRegistry or for SBAlertItem, both return no results.
Can use the class by importing this file to your project.
UPDATE
I have 'working' code, however it immediately calls the callback function (responseFlags set to kCFUserNotificationCancelResponse) without showing the alert..
I am using the same keys and calls as the Uber app (compare code below to list above), so there must be something extra. Will keep looking.
#import "CFUserNotification.h"
@interface AppDelegate ()
@property (nonatomic) CFRunLoopSourceRef runLoopSource;
@property (nonatomic) CFUserNotificationRef notification;
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
SInt32 error;
NSDictionary *keys = @{(__bridge NSString*)kCFUserNotificationAlertHeaderKey: @"Hello",
(__bridge NSString*)kCFUserNotificationAlertMessageKey: @"World",
(__bridge NSString*)kCFUserNotificationAlertTopMostKey: @YES,
(__bridge NSString*)kCFUserNotificationDefaultButtonTitleKey: @"asdf",
(__bridge NSString*)kCFUserNotificationAlternateButtonTitleKey: @"asdf",
};
self.notification = CFUserNotificationCreate(NULL, 10, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)keys);
self.runLoopSource = CFUserNotificationCreateRunLoopSource(NULL, self.notification, NotificationCallback, 0);
CFRunLoopAddSource(CFRunLoopGetMain(), self.runLoopSource, kCFRunLoopCommonModes);
return YES;
}
void NotificationCallback(CFUserNotificationRef userNotification, CFOptionFlags responseFlags) {
NSLog(@"got response: %lu", responseFlags);
}