[英]Show an alert when iOS app is in the background
当我的iOS应用程序在后台 (并且正在使用位置) 时,我想显示一个警报视图 。
例如,即使在以下情况下, 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.