当app从iBeacon区域唤醒时,将值保存到UserDefaults中

时间:2015-02-13 07:51:41

标签: ios objective-c cllocationmanager ibeacon

我尝试在用户进入和退出iBeacon区域时保存。我的应用程序正确地从后台唤醒,并调用委托方法(它显示LocalNotification)。在这个方法中,我也尝试将对象保存到UserDefaults

在前景中它完美无缺。但是当我的应用程序关闭(从任务管理器)并且用户进入或退出iBeacon区域时,LocalNotification将被发送(因此该方法被调用),但似乎没有任何内容保存到UserDefaults中。因为当应用程序再次打开时(由用户),我尝试从UserDefaults返回我在后台保存的内容。

这是我的代码:

// When user enters iBeacon Region
- (void)startTrip {
    // Check if a trip was already started
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *currentTrip = [userDefaults dictionaryForKey:kSTORECURRENTTRIP];

    if (currentTrip != nil) {
        // A trip is already running
        return;
    }
    NSLog(@"entered beacon");

    // Create new trip
    currentTrip = @{@"startDateTime": @([[NSDate date] timeIntervalSince1970])};

    // Store it into UserDefaults
    [userDefaults setObject:currentTrip forKey:kSTORECURRENTTRIP];
    [userDefaults synchronize];

    // Notification
    [Tools sendLocalNotificationWithMessage:[NSString stringWithFormat:@"Trip started at %@", [currentTrip valueForKey:@"startDateTime"]]];

}

// When user exits iBeacon Region
- (void)stopTrip {
    // Check if a trip was started
    NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *tmp = [userDefaults dictionaryForKey:kSTORECURRENTTRIP];

    if (tmp == nil) {
        // There is no current trip
        return;
    }

    NSLog(@"exited beacon");

    // Finish Trip (set values)
    NSMutableDictionary *currentTrip = [NSMutableDictionary dictionaryWithDictionary:tmp];
    [currentTrip setObject:@([[NSDate date] timeIntervalSince1970]) forKey:@"stopDateTime"];

    // Add Trip to array of Trips to save
    NSMutableArray *tripsToSave = [NSMutableArray arrayWithArray:[userDefaults arrayForKey:kTRIPSTOSAVE]];
    if (tripsToSave == nil) {
        tripsToSave = [NSMutableArray new];
    }
    [tripsToSave addObject:[NSDictionary dictionaryWithDictionary:currentTrip]];
    [userDefaults setObject:[NSArray arrayWithArray:tripsToSave] forKey:kTRIPSTOSAVE];

    // Reset stored current trip.
    [userDefaults removeObjectForKey:kSTORECURRENTTRIP];

    // Synchronize
    [userDefaults synchronize];

    // Notification
    [Tools sendLocalNotificationWithMessage:[NSString stringWithFormat:@"Trip finished at %@", [currentTrip valueForKey:@"stopDateTime"]]];
}

我的问题是:

  1. 当应用在后台时,我可以执行多长时间的代码?有没有更好的方法(如异步块?)

  2. 是否允许保存到UserDefaults并且是否可以取回保存到的值?

  3. UserDefaults在后​​台或前台模式下相同,不是吗?

  4. 编辑:新代码

2 个答案:

答案 0 :(得分:0)

回答您的具体问题:

  1. 在区域进入/退出事件后,您有10秒的时间在后台执行。
  2. 是的,您可以在此期间保存到UserDefaults。
  3. 背景没有区别。
  4. 我怀疑保存到UserDefaults的代码有问题。我不明白有什么不对。我会:

    1. 添加NSLog语句以确定执行哪些代码。将结果发布为您的问题的修改。
    2. 在手动触发的前景中测试相同的代码块(不是通过信标)并验证它是否有效。

答案 1 :(得分:0)

我担心这两行:

[Tools storeObjectIntoUserDefaults:tripsToSave withKey:kTRIPSTOSAVE];

// Reset stored current trip.
[Tools resetObjectIntoUserDefaultsWithKey:kSTORECURRENTTRIP];

你在评论中提到我在第一种方法中调用了synchronize。你绝对确定吗?因为如果不是这可能会导致您描述的症状。

第二行在代码片段中没有明显的用途,因为没有存储密钥的行。在您发布的代码之外似乎有很多事情发生,问题可能出在我们看不到的代码中。

我建议简化代码,以便存储逻辑(包括同步)发生在同一个地方。