当应用程序从iBeacon区域唤醒时,将值保存到UserDefaults中



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

在前景中,它工作得很好。但是,当我的应用程序关闭(从任务管理器),用户进入或退出iBeacon Region时,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在背景或前景模式下是相同的,不是吗?

编辑:新代码

要回答您的具体问题:

  1. 区域进入/退出事件后,您有10秒的时间在后台执行
  2. 是的,在此期间您可以保存为UserDefaults
  3. 背景没有区别

我怀疑保存到UserDefaults的代码有问题。我不清楚出了什么问题。我会:

  1. 添加NSLog语句以确定执行了哪些代码。将结果作为编辑发布到您的问题中
  2. 在前台手动触发(不是由信标触发)测试相同的代码块,并验证它是否工作

我担心这两行:

[Tools storeObjectIntoUserDefaults:tripsToSave withKey:kTRIPSTOSAVE];
// Reset stored current trip.
[Tools resetObjectIntoUserDefaultsWithKey:kSTORECURRENTTRIP];

您在对我的另一个回答的评论中提到,synchronize是在第一个方法内部调用的。你绝对确定吗?因为如果没有,这可能会导致你描述的症状。

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

我建议简化代码,使存储逻辑(包括同步)发生在同一个位置。

最新更新