繁体   English   中英

在iOS应用程序处于后台时显示警报

[英]Show an alert when iOS app is in the background

当我的iOS应用程序在后台 (并且正在使用位置) 时,我显示一个警报视图

例如,即使在以下情况下, Uber合作伙伴(驾驶员)应用程序也会显示警报并播放声音:

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

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

在此处输入图片说明
为达到上述状态而执行的操作:

  • 在Uber合作伙伴应用程序上在线(您是驱动程序!)
  • 在设置中禁用该应用的通知
  • 将应用程序移至后台并等待乘车请求
  • 一段时间后,会以“警报”视图的形式弹出一个“乘车请求”,并在后台播放声音

当然,即使用户在“设置”中禁用了“通知”,应用也可以使用didReceiveRemoteNotification: fetchCompletionHandler: API来获取无提示的远程通知。 但是,如何弹出警报,这就是我试图找出的。

我可以想象,Uber具有某些特殊权限或使用了一些私有API,这些特权使他们无需使用本地通知即可实现此行为。 虽然我不知道Uber如何在其合作伙伴应用程序中实现此功能,但我可以谈谈警报在主屏幕上的工作方式。

SpringBoard是用于管理SpringBoard应用程序(SpringBoard.app)(用于iPhone的应用程序启动器)的单例类。 SpringBoard不使用标准的UIAlertView / UIAlertController类,因为它们不参与整个SpringBoard警报系统。 iOS 5引入了SBAlertItem ,用于在SpringBoard上显示UIAlertViews(电池通知警报,Sim Unlock警报等)。 苹果将SBAlertItem用于锁定和主屏幕警报,我将假设Uber对此答案使用SBAlertItem

SBAlertItem具有受保护的ivar UIAlertView *_alertSheet 假设它充当普通的UIAlertView ,您应该能够更改此警报上的属性以适合您的需求。 我也将通过Saurik公司的苹果蠹基板项目中读取,具体MobileSafety.mm看到一些用例。 我还发现了noweibogoodsleep ,它提供了在SpringBoard上使用SBAlertItem的示例。

我还找到了SBUserNotificationAlert ,它是SBAlertItem的子类。 与标准SBAlertItem相比,这似乎有更多的方法可以促进警报自定义,这些方法可能更适合您的需求。

我意识到,挂接到私有API可能不是您在问这个问题时所期望的。 由于我不知道Uber的工作原理,因此我只能根据我在运行时和越狱设备方面的经验提供答案。

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

花了一点时间找到它,但是他们实际上正在使用CFUserNotification来发出警报。 该类文件的Mac,但私人的iOS。

我这样做是找到了用法:

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

输出为:

_CFUserNotificationCancel
_CFUserNotificationCreate
_CFUserNotificationCreateRunLoopSource
_kCFUserNotificationAlertHeaderKey
_kCFUserNotificationAlertMessageKey
_kCFUserNotificationAlertTopMostKey
_kCFUserNotificationAlternateButtonTitleKey
_kCFUserNotificationDefaultButtonTitleKey
_kCFUserNotificationSoundURLKey

如果我为PKPushRegistry或SBAlertItem使用grep,则两者均不返回结果。

可以通过将该文件导入到项目中来使用该类。

更新

我有“工作中”的代码,但是它立即调用回调函数(将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指南。

它没有像建议的其他答案一样获得任何特殊权限。

无论Sound \\ Notification设置如何,都可以使用SBAlertItem显示警报视图,但是不幸的是,如果您的最终目标是进入应用商店,则您的应用将因为使用私有API而被拒绝。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM