在iOS应用程序处于后台时显示提醒
我想显示一个警报视图,当我的iOS应用程序在后台 (和它使用的位置)。
例如,即使在以下情况下, Uber合作伙伴(驱动程序)应用程序也会显示警报并播放声音:
- 我已closures通知!
- 我的iPhone处于静音模式!
我知道本地通知方式,如果用户closures/更改设置中的通知不起作用。 我正在寻找不同的东西。
为达到上述状态而采取的行动:
- Uber合作伙伴应用程序上线(你是司机!)
- 在设置中禁用应用的通知
- 将应用程序移到后台并等待乘车请求
- 经过一段时间后,一个驾驶请求popup警报视图,并在后台播放声音
当然,即使用户在“设置”中禁用“通知”,使用didReceiveRemoteNotification: fetchCompletionHandler:
API也可以通过应用程序轻敲静音远程通知。 但是,警报是如何popup的,这正是我想要find的。
我会想象Uber有一些特殊的权限或使用一些私人的API,使他们能够实现这种行为,而不使用本地通知。 虽然我不知道Uber是如何在他们的合作伙伴应用程序中实现这一点的,但是我可以稍微谈一谈在主屏幕上警报是如何工作的。
SpringBoard是pipe理SpringBoard应用程序(SpringBoard.app)的单例类,它是iPhone的应用程序启动器。 SpringBoard不使用标准的UIAlertView
/ UIAlertController
类,因为它们不参与SpringBoard范围的警报系统。 iOS 5引入了SBAlertItem
,用于在SpringBoard上显示UIAlertViews(电池通知警报,Sim Unlock Alert等)。 苹果公司使用SBAlertItem
为他们的locking和主屏幕警报,我会工作的假设,Uber使用SBAlertItem
这个答案。
SBAlertItem
有一个受保护的ivar UIAlertView *_alertSheet
。 假设这是一个普通的UIAlertView
,你应该可以改变这个警报的属性来适应你的需要。 我还会通读saurik的Cydia Substrate项目,特别是MobileSafety.mm来查看一些用例。 我还发现了noweibogoodsleep ,它提供了一个在SpringBoard上使用SBAlertItem
的例子。
我还发现了SBUserNotificationAlert
, SBUserNotificationAlert
一个子类。 这似乎有更多的方法来促进警报定制,可能比标准的SBAlertItem
更适合您的需要。
我意识到挂钩到私有API可能不是你在问这个问题时所期望的。 由于我不知道Uber是如何工作的,我只能从运行时和越狱设备的个人经验中得到答案。
经过二进制的一些静态分析,很明显他们没有使用PKPushRegistry(VOIP),未logging的NSNotificationCenter调用或SBAlertItem。
花了一些时间来find它,但他们实际上使用CFUserNotification警报。 这个类是为Maclogging的,但对于iOS来说是私有的。
我发现这样做的用法:
nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification
输出是:
_CFUserNotificationCancel _CFUserNotificationCreate _CFUserNotificationCreateRunLoopSource _kCFUserNotificationAlertHeaderKey _kCFUserNotificationAlertMessageKey _kCFUserNotificationAlertTopMostKey _kCFUserNotificationAlternateButtonTitleKey _kCFUserNotificationDefaultButtonTitleKey _kCFUserNotificationSoundURLKey
如果我grep的PKPushRegistry或SBAlertItem,都不返回结果。
可以通过将该文件导入到项目中来使用该类。
UPDATE
我有'工作'的代码,但是它立即调用callback函数(responseFlags设置为kCFUserNotificationCancelResponse ),而不显示警报。
我使用与Uber应用程序相同的键和调用(比较下面的代码以上列出),所以必须有额外的东西。 将继续寻找。
#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); }
你的问题错过了关于“Uber合作伙伴”应用程序的最重要的部分,将使事情变得更清晰。 “Uber合作伙伴”应用程序是一个企业应用程序,不限于Appstore指南。
它没有得到像其他答案build议的任何特殊的权限。
不pipeSound \ Notification设置如何,使用SBAlertItem
显示警报视图是可能的,但是如果您的最终目标是将其设置到appstore,不幸的是,您的应用程序将因使用私有API而被拒绝。