在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的例子。

我还发现了SBUserNotificationAlertSBUserNotificationAlert一个子类。 这似乎有更多的方法来促进警报定制,可能比标准的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而被拒绝。