......或者以其他方式发布通知?
可以的。您可以使用后台(启动)守护程序触发通知(不一定是UILocalNotification
)。当通知向用户显示警报时,您的守护程序可以决定打开常规的UI应用程序(或不打开)。
建立一个启动守护程序。
这是我找到的最好的教程。启动守护程序在手机启动时启动,并作为非图形化后台进程运行。 从那里,您可以安排检查更新。 (我有一个名为HelloDaemon
的类,它在run:
方法中完成所有工作):
int main(int argc, char *argv[]) {
@autoreleasepool {
HelloDaemon* daemon = [[HelloDaemon alloc] init];
NSTimer* timer = [[NSTimer alloc] initWithFireDate: [NSDate date]
interval: 1.0
target: daemon
selector: @selector(run:)
userInfo: nil
repeats: NO];
NSRunLoop* runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer: timer forMode: NSDefaultRunLoopMode];
[runLoop run];
}
return 0;
}
守护进程可以正常使用 NSTimer
,因此在需要时(在 run:
中)可以安排另一个计时器来检查要下载的更新。
从守护进程通知用户
如果守护进程决定应该通知用户,则可以:
1) 打开完整的 UI 应用程序。
#include <dlfcn.h>
#define SBSERVPATH "/System/Library/PrivateFrameworks/SpringBoardServices.framework/SpringBoardServices"
-(void) openApp {
void* sbServices = dlopen(SBSERVPATH, RTLD_LAZY);
int (*SBSLaunchApplicationWithIdentifier)(CFStringRef identifier, Boolean suspended) = dlsym(sbServices, "SBSLaunchApplicationWithIdentifier");
int result = SBSLaunchApplicationWithIdentifier(CFSTR("com.mycompany.AppName"), false);
dlclose(sbServices);
}
这段代码需要 com.apple.springboard.launchapplications
权限才能使你的守护程序顺利使用。 请参考这里添加权限。 你需要为你的守护程序可执行文件准备一个 entitlements.xml 文件,像这样:
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.springboard.launchapplications</key>
<true/>
</dict>
</plist>
2) 从您的守护程序中显示一个简单的警告窗口,通知用户事件并提示他们打开UI应用程序。
#include "CFUserNotification.h"
-(void) showAlert {
NSMutableDictionary* dict = [NSMutableDictionary dictionary];
[dict setObject: @"Alert!" forKey: (__bridge NSString*)kCFUserNotificationAlertHeaderKey];
[dict setObject: @"Updates Ready!" forKey: (__bridge NSString*)kCFUserNotificationAlertMessageKey];
[dict setObject: @"View" forKey:(__bridge NSString*)kCFUserNotificationDefaultButtonTitleKey];
[dict setObject: @"Cancel" forKey:(__bridge NSString*)kCFUserNotificationAlternateButtonTitleKey];
SInt32 error = 0;
CFUserNotificationRef alert =
CFUserNotificationCreate(NULL, 0, kCFUserNotificationPlainAlertLevel, &error, (__bridge CFDictionaryRef)dict);
CFOptionFlags response;
if((error) || (CFUserNotificationReceiveResponse(alert, 10, &response))) {
NSLog(@"alert error or no user response after 10 seconds");
} else if((response & 0x3) == kCFUserNotificationAlternateResponse) {
NSLog(@"cancel");
} else if((response & 0x3) == kCFUserNotificationDefaultResponse) {
NSLog(@"view");
[self openApp];
}
CFRelease(alert);
}
要使用我上面展示的代码,你需要一个CFUserNotification.h
头文件。你可以通过谷歌搜索或在这里找到。这个旧的维基文档也展示了如何在iOS应用中使用CFUserNotification
的一些有用信息。
KennyTM之前链接到的答案也展示了如何使你的弹出提示即使设备被锁定也能显示。