我希望在我的iOS应用在后台时显示提醒视图(并且它正在使用位置)。
例如, Uber合作伙伴(驱动程序)应用会显示提醒并即使在以下情况下播放声音:
我知道本地通知方法,如果用户关闭/更改“设置”中的“通知”,则无法使用。我正在寻找不同的东西。
当然,即使用户在“设置”中停用了通知,应用也可以使用didReceiveRemoteNotification: fetchCompletionHandler:
API轻触无声远程通知。但是,警报是如何弹出的,这就是我想要找到的。
答案 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
的示例。
我还找到了SBUserNotificationAlert
,SBAlertItem
的子类。这似乎有更多方法可以促进警报自定义,可以比标准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而被拒绝。