CLBeacons处于app暂停状态

时间:2014-07-28 12:35:23

标签: ios objective-c ios7 cllocationmanager ibeacon

我想要实现的目标在以下步骤中进行了描述

1.User打开应用程序,导航等等等等等等  2.用户按下主页按钮,应用程序自行关闭  3.用于检测CLbeacons的后台任务开始。在每次检测时,立即触发A UILocalNotification,以使用户意识到已发现信标。

现在我发生了什么

  1. 我打开应用程序,导航然后按主页按钮关闭应用程序
  2. 手机慢慢变暗,即滑动到解锁状态。这里没有通知被解雇;地狱,CLLocationManger's方法-(void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region根本没有被调用。
  3. 手机进入睡眠状态。我滑开手机唤醒它;立即多个`UIlocalNotifications进入。
  4. 任何人都可以向我解释为什么会发生这种情况?

    //
    //  AppDelegate.m
    //  Beacon Proximity
    //
    //  Created by Debanjan Chakraborty on 7/15/14.
    //  Copyright (c) 2014 Debanjan Chakraborty. All rights reserved.
    //
    
    #import "AppDelegate.h"
    #import "CustomerRegViewController.h"
    #import "IntialViewController.h"
    #import "BeaconProduct.h"
    #import "DBManager.h"
    #import "APLDefaults.h"
    #import "ScanViewController.h"
    
    
    typedef NS_ENUM(NSUInteger, BeaconType)
    {
        Check,
        Bundle
    };
    
    @interface AppDelegate ()<CLLocationManagerDelegate>
    
    @property CLLocationManager *locationAppManager;
    @property (nonatomic) NSInteger localNotificationCount;
    //@property (nonatomic,strong) UILocalNotification *localNotification;
    //@property (nonatomic) NSTimer *timerForNotifier;
    
    
    @end
    
    @implementation AppDelegate
    
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
        {
            // app already launched
        }
        else
        {
            [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"HasLaunchedOnce"];
            [[NSUserDefaults standardUserDefaults] synchronize];
    
    
            [self entryDatabase];
    
        }
    
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
        [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
         (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)];
    
    
        UILocalNotification *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey];
    
        if (notification)
        {
            NSLog(@" aache ?");
    //        self.localNotificationCount = 0;
            UIAlertView *aw = [[UIAlertView alloc] initWithTitle:@"Case 1" message: notification.alertBody delegate:self cancelButtonTitle:@"Ok" otherButtonTitles:nil];
            [aw show];
        }
        application.applicationIconBadgeNumber = 0;
    
        return YES;
    }
    - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    
        NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet: [NSCharacterSet characterSetWithCharactersInString:@"<>"]];
        token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];
        NSLog(@"content---%@", token);
    
    }
    
    - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err {
    
        NSLog(@"Error %@",err.localizedDescription);
    
    }
    - (void)applicationWillResignActive:(UIApplication *)application
    {
        if(![[NSUserDefaults standardUserDefaults] boolForKey:@"HasLaunchedOnce"])
        {
             NSLog(@" Will REsign and initialise");
    
        }
        else
        {
          NSLog(@" Will REsign?");
        }
    }
    -(void)applicationWillTerminate:(UIApplication *)application
    {
        NSLog(@" terminated");
    }
    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
    
        [self initialise];
    
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        application.applicationIconBadgeNumber=0;
    
    
            for (NSUUID *uuid in [APLDefaults sharedDefaults].supportedProximityUUIDs)
            {
                CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:[uuid UUIDString]];
                [self.locationAppManager stopMonitoringForRegion:region];
            }
        self.locationAppManager = nil;
    
    }
    -(void)insert:(NSDate *)fire WithBeaconType:(BeaconType )beaconType ForBeacon:(CLBeacon *)beacon
    {
    
        self.localNotificationCount++;
    
                UILocalNotification *localNotification = [UILocalNotification new];
    
                localNotification.soundName = UILocalNotificationDefaultSoundName;
    
                localNotification.applicationIconBadgeNumber =self.localNotificationCount;
    
                localNotification.fireDate = [NSDate date];
    
                localNotification.alertAction = @"Show me";
    
                if(beaconType == Check)
                {
                    localNotification.alertBody = [NSString stringWithFormat:@"Check out new offers"];
    
                    localNotification.alertAction = NSLocalizedString(@"Read Offer", nil);
    
                }
                else
                {
                    localNotification.alertBody = [NSString stringWithFormat:@"You've reached offers. Grab them before they expire soon"];
    
                    localNotification.alertAction = NSLocalizedString(@"Grab Offer", nil);
                }
    
    
    
             [[UIApplication sharedApplication] scheduleLocalNotification:localNotification];
    
             NSLog(@" should Notify minor is %d and major is %d",[beacon.minor integerValue],[beacon.major integerValue]);
    
             [[DBManager getSharedInstance] updateNotifiedTimeForBeacon:beacon];
    
    }
    
    - (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification
    {
    
    }
    
    
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        [[UIApplication sharedApplication] setApplicationIconBadgeNumber:0];
        self.localNotificationCount = 0;
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
    }
    
    -(UIViewController *)omegaScreen
    {
        UIStoryboard *strybrd = [UIStoryboard storyboardWithName:@"Storyboard" bundle:nil];
        NSString *viewId=[[NSUserDefaults standardUserDefaults]objectForKey:@"custId"]?@"initial":@"custReg";
        UIViewController *controller=[strybrd instantiateViewControllerWithIdentifier:viewId];
    
        if([[NSUserDefaults standardUserDefaults] objectForKey:@"custId"])
            [self initialise];
    
        return [viewId isEqualToString:@"initial"]?(IntialViewController *)controller:(CustomerRegViewController *)controller;
    }
    
    
    
    -(void)initialise
    {
        self.locationAppManager = [[CLLocationManager alloc] init];
        self.locationAppManager.delegate = self;
    
    
        for (NSUUID *uuid in [APLDefaults sharedDefaults].supportedProximityUUIDs)
        {
            NSLog(@" uuid is %@",uuid.UUIDString);
            CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:[uuid UUIDString]];
            region.notifyEntryStateOnDisplay=YES;
           [self.locationAppManager startMonitoringForRegion:region];
        }
    
        self.localNotificationCount = -1;
    }
    - (void) locationManager:(CLLocationManager *)manager didStartMonitoringForRegion:(CLRegion *)region
    {
        NSLog(@" it did");
        if([region isKindOfClass:[CLBeaconRegion class]])
        {
            [self.locationAppManager requestStateForRegion:(CLBeaconRegion*)region];
        }
    
    }
    -(void)locationManager:(CLLocationManager *)manager didDetermineState:(CLRegionState)state forRegion:(CLRegion *)region
    {
        if (state == CLRegionStateInside)
        {
            //Start Ranging
            [manager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
        }
    }
    - (void)locationManager:(CLLocationManager*)manager didEnterRegion:(CLRegion *)region
    {
    
        if ([region isKindOfClass:[CLBeaconRegion class]])
        {
          [self.locationAppManager startRangingBeaconsInRegion:(CLBeaconRegion*)region];
        }
    }
    - (void)locationManager:(CLLocationManager *)manager didRangeBeacons:(NSArray *)beacons inRegion:(CLBeaconRegion *)region
    {
    
    //    if([self runningInBackground])
    //    {
    //        NSLog(@" didRangeBeacons in App Delegate");
    
            for (CLBeacon *beacon in beacons)
            {
                if([[DBManager getSharedInstance]shouldNotifyFor:beacon])
                {
                    BeaconType type;
                    if([beacon.major integerValue]==0)
                    {
                        type = Check;
                    }
                    else
                    {
                        type = Bundle;
                    }
                    [self insert:[NSDate date]WithBeaconType:type ForBeacon:beacon];
                }
            }
    //    }
    }
    -(BOOL) runningInBackground
    {
        UIApplicationState state = [UIApplication sharedApplication].applicationState;
        BOOL result = (state == UIApplicationStateBackground);
        return result;
    }
    -(void)resetStatus
    {
        NSLog(@" timer has been fired");
    }
    
    -(void)entryDatabase
    {
    
            NSMutableArray *localArray = [NSMutableArray new];
            BeaconProduct *bP1 = [[BeaconProduct alloc] initWithProductSku:@"1" andId:@"1" andbTitle:@"BeaconAdTitle1" andDescription:@"Description1" andCurrency:@"Rupees" andSmallImage:@"Shampoo" andLargeImage:@"Shampoo" andPrice:[NSNumber numberWithInteger:700]];
            BeaconProduct *bP2 = [[BeaconProduct alloc] initWithProductSku:@"2" andId:@"1" andbTitle:@"BeaconAdTitle2" andDescription:@"Description2" andCurrency:@"Rupees" andSmallImage:@"conditionerFree" andLargeImage:@"conditionerFree" andPrice:[NSNumber numberWithInteger:200]];
            BeaconProduct *bP3 = [[BeaconProduct alloc] initWithProductSku:@"3" andId:@"2" andbTitle:@"BeaconAdTitle3" andDescription:@"Description3" andCurrency:@"Rupees" andSmallImage:@"soap" andLargeImage:@"soap" andPrice:[NSNumber numberWithFloat:20.50]];
            BeaconProduct *bP4 = [[BeaconProduct alloc] initWithProductSku:@"4" andId:@"3" andbTitle:@"BeaconAdTitle4" andDescription:@"Description4" andCurrency:@"Rupees" andSmallImage:@"shirt" andLargeImage:@"shirt" andPrice:[NSNumber numberWithFloat:250]];
    
            [localArray addObject:bP1];
            [localArray addObject:bP2];
            [localArray addObject:bP3];
            [localArray addObject:bP4];
    
            [[DBManager getSharedInstance] insertBeaconProduct:localArray];
    
    
    }
    
    @end
    

1 个答案:

答案 0 :(得分:1)

您应该发布您的代码,以便我们明确地解释这一点,但听起来您在设置区域时只需region.notifyEntryStateOnDisplay = YES;。当您设置了该选项后,每次点亮显示屏时,您都会从CLLocationManager获得额外的回调。[/ p>

编辑:看到代码后,我还注意到应用程序开始监控它何时到达后台,然后在它返回前台时停止它。我怀疑这可能会使问题复杂化,并给你额外的回调,导致额外的通知。看起来没有任何理由继续停止并重新启动监控。我建议您在应用程序启动时简单地设置对您的信标区域的监控,并让监控继续进行。这与设置region.notifyEntryStateOnDisplay = NO相结合可以防止多次通知。

第二次编辑关于第(2)项,你应该明白你在背景中通常不能范围。一旦你的应用程序离开前台,你只能回调didRangeBeacons: inRegion:大约五秒钟,此时这样的回调会停止,直到应用程序再次被唤醒。唤醒它的一种方法是使用监控API从进入/离开信标区域转换。但是,您应该了解在后台,这些过渡并不总是瞬间完成,最多可能需要15分钟。 See here for details.