objective-c - 本地通知?

标签 objective-c ios cocoa-touch ipad

我的应用程序主要是一个真正没有连接到互联网的服务器的客户端。它连接到 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(只有 didFinishLaunchingWithOptionsapplicationDidEnterBackground)

- (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/

相关文章:

objective-c - iPad 应用程序 - CALayer 使其在旋转时非常滞后

ios - 为什么在UTC时区中比较两个NSDate总是失败?

ios - 用 SKShapeNode 画一条线

ios - 在半透明导航栏下查看?

iphone - 这个方法有什么问题吗?

iphone - 关于 plist 的快速问题

iphone - 应用程序未主动运行作业,怎么办?

ios - 通话未从我的 iOS 应用转到 Skype

ios - CoreData : warning: Unable to load class named 'WEEReadings' for entity 'Readings' . 找不到类,改用默认的 NSManagedObject

iphone - reloadData 没有被调用