我的应用程序主要是一个真正没有连接到互联网的服务器的客户端。它连接到 Polycom 编解码器并管理 2 个端点之间的视频通话。所以我的应用程序可以发送结束通话、提高音量等命令... 但是我的问题是这样的。当来电发生并且应用程序不在前台时,我需要某种通知。 由于服务器无法访问互联网,因此 APNS/推送通知对我不起作用。我研究过做类似 this 的事情.这似乎让我的客户端保持运行但是我无法发出警报,因为我的应用程序在后台。
所以除了如何解决我的问题的基础知识之外,我的问题是:
我可以使用链接中列出的技术将我的应用程序带到前台吗(做一些我在下面做的事情)。我可以从日志中看到这段代码使我的代码保持运行。我知道我的 while 循环不正确,最后我需要 KVO,但不管怎样都不应该影响答案。 (我不明白的一件事是,这让我的整个应用程序都在运行,而不仅仅是我在 bcClient 中拥有的类?)
- (void)applicationDidEnterBackground:(UIApplication *)application
{
[bcClient connect];
bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
// Start the long-running task and return immediately.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while(1) {
sleep(3);
NSLog(@"held join %d",bcClient.heldjoin);
if (bcClient.heldjoin == 602 || bcClient.heldjoin == 604 || bcClient.heldjoin == 513) {
NSLog(@"incoming call");
}
}
});
}
如果我不能将我的应用程序带到前台,那么是否可以在本地推送通知(不需要 APNS 服务器)?
我觉得这一切都不可能,但我想我会问。
最佳答案
这是我的答案。这使我的客户端应用程序在后台运行,并在有来电时显示通知。
AppDelegate.h
@interface CameleonAppDelegate : NSObject <UIApplicationDelegate> {
CrestronClient *cClient;
CrestronControllerValues *CCV;
RootViewController *rootViewController;
CrestronValues *crestronValues;
UIBackgroundTaskIdentifier bgTask;
dispatch_block_t expirationHandler;
UIApplication* app;
BOOL showedCall;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel;
@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator;
- (void)saveContext;
- (NSURL *)applicationDocumentsDirectory;
-(void)save;
-(void)load;
- (void)backgroundHandler;
@end
AppDelegate.m(只有 didFinishLaunchingWithOptions
和 applicationDidEnterBackground
)
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
app = [UIApplication sharedApplication];
expirationHandler = ^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
bgTask = [app beginBackgroundTaskWithExpirationHandler:expirationHandler];
};
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSArray *keys = [NSArray arrayWithObjects:@"IPaddress", @"PortNumber",@"IPID", nil];
NSArray *objs = [NSArray arrayWithObjects:@"10.8.40.64", @"41794",@"3", nil];
//10.8.30.143 10.8.40.64
NSDictionary *dict = [NSDictionary dictionaryWithObjects:objs forKeys:keys];
[defaults registerDefaults:dict];
CCV = [CrestronControllerValues sharedManager];
[CCV setIpAddress:[defaults stringForKey:@"IPaddress"]];
[CCV setPortNumber:[defaults stringForKey:@"PortNumber"]];
[CCV setIPID:[defaults stringForKey:@"IPID"]];
cClient = [CrestronClient sharedManager];
rootViewController = [[RootViewController alloc]initWithNibName:@"RootViewController" bundle:nil];
self.window.rootViewController = rootViewController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
showedCall = FALSE;
BOOL backgroundAccepted = [[UIApplication sharedApplication] setKeepAliveTimeout:600 handler:^{ [self backgroundHandler]; }];
if (backgroundAccepted)
{
NSLog(@"VOIP backgrounding accepted");
}
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
sleep(4);
//NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
if ([rootViewController isIncomingCall] && showedCall != TRUE) {
UILocalNotification *localNotif = [[UILocalNotification alloc] init];
if (localNotif) {
localNotif.alertBody = [NSString stringWithFormat:@"Incoming Call."];
localNotif.alertAction = NSLocalizedString(@"Accept Call", nil);
localNotif.soundName = @"alarmsound.caf";
localNotif.applicationIconBadgeNumber = 1;
[application presentLocalNotificationNow:localNotif];
[localNotif release];
}
showedCall = TRUE;
}
}
});
}
- (void)backgroundHandler {
NSLog(@"### -->VOIP backgrounding callback");
bgTask = [app beginBackgroundTaskWithExpirationHandler:^{
[app endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
while (1) {
NSLog(@"BGTime left: %f", [UIApplication sharedApplication].backgroundTimeRemaining);
[rootViewController isIncomingCall];
sleep(1);
}
});
}
关于objective-c - 本地通知?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8234279/