iOS应用在后台时显示提醒

时间:2016-04-16 21:09:03

标签: ios uialertcontroller springboard

我希望在我的iOS应用在后台时显示提醒视图(并且它正在使用位置)。

例如, Uber合作伙伴(驱动程序)应用会显示提醒并即使在以下情况下播放声音:

  • 我已关闭通知!
  • 我的iPhone处于静音模式!

我知道本地通知方法,如果用户关闭/更改“设置”中的“通知”,则无法使用。我正在寻找不同的东西。

enter image description here
为达到上述状态而采取的行动:

  • 在Uber Partner App上线(你是司机!)
  • 在设置
  • 中禁用应用的通知
  • 将应用移至后台并等待乘车请求
  • 一段时间后,一个乘车请求会弹出一个警报视图,一个声音在后台播放

当然,即使用户在“设置”中停用了通知,应用也可以使用didReceiveRemoteNotification: fetchCompletionHandler: API轻触无声远程通知。但是,警报是如何弹出的,这就是我想要找到的。

3 个答案:

答案 0 :(得分:10)

我认为Uber有一些特殊权限或使用一些私有API,允许他们在不使用本地通知的情况下实现此行为。虽然我不知道优步如何在他们的合作伙伴应用程序中实现这一点,但我可以谈谈警报如何在主屏幕上工作。

SpringBoard是管理SpringBoard应用程序(SpringBoard.app)的单例类,它是iPhone的应用程序启动器。 SpringBoard不使用标准UIAlertView / UIAlertController类,因为它们不参与SpringBoard范围的警报系统。 iOS 5引入了SBAlertItem,用于在SpringBoard上显示UIAlertViews(电池通知警报,模拟解锁警报等)。 Apple使用SBAlertItem进行锁定和主屏幕警报,我将假设Uber正在使用SBAlertItem来获得此答案。

SBAlertItem有受保护的ivar UIAlertView *_alertSheet。假设这是一个正常的UIAlertView,您应该能够更改此警报的属性以满足您的需求。我还会阅读saurik的Cydia Substrate项目,特别是MobileSafety.mm来查看一些用例。我还发现noweibogoodsleep提供了在SpringBoard上使用SBAlertItem的示例。

我还找到了SBUserNotificationAlertSBAlertItem的子类。这似乎有更多方法可以促进警报自定义,可以比标准SBAlertItem更好地满足您的需求。

我意识到挂钩私有API可能不是你在问这个问题时所期望的。由于我不知道优步如何运作,我只能根据我使用运行时和越狱设备的个人经验提供答案。

答案 1 :(得分:7)

在对二进制文件进行一些静态分析之后,很明显他们没有使用PKPushRegistry(VOIP),未记录的NSNotificationCenter调用或SBAlertItem。

花了一会儿找到它,但他们实际上正在使用CFUserNotification进行警报。对于Mac,该类为documented,但对于iOS则为私有。

我通过这样做找到了用法:

nm -u ~/Downloads/Payload/UberDriver.app/UberDriver | grep CFUserNotification

输出结果为:

_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey

如果我grep for PKPushRegistry或SBAlertItem,两者都不会返回任何结果。

可以通过将this file导入项目来使用该类。

<强>更新

我有'工作'代码,但它立即调用回调函数(responseFlags设置为kCFUserNotificationCancelResponse)而不显示警告..

我使用相同的键和调用作为优步应用程序(比较下面的代码列出上面的代码),所以必须有额外的东西。会继续寻找。

#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);
}

答案 2 :(得分:4)

您的问题错过了关于&#34;优步合作伙伴的最重要部分&#34;应用程序,将使事情更清晰。 &#34; Uber合作伙伴&#34; app是 Enterprise 应用,不限于Appstore指南。

它没有得到任何其他答案建议的特殊权限。

无论Sound \ Notification设置如何,都可以使用SBAlertItem显示警报视图,但如果您的最终目标是将其发送到appstore,那么您的应用将因使用私有API而被拒绝。