当用户进入和退出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"]]];
}
我的问题是:
当应用程序处于后台时,我可以执行代码多长时间?有没有更好的方法(比如异步块?)
是否允许保存到
UserDefaults
,是否可以取回保存到的值?UserDefaults
在背景或前景模式下是相同的,不是吗?
编辑:新代码
要回答您的具体问题:
- 区域进入/退出事件后,您有10秒的时间在后台执行
- 是的,在此期间您可以保存为UserDefaults
- 背景没有区别
我怀疑保存到UserDefaults的代码有问题。我不清楚出了什么问题。我会:
- 添加NSLog语句以确定执行了哪些代码。将结果作为编辑发布到您的问题中
- 在前台手动触发(不是由信标触发)测试相同的代码块,并验证它是否工作
我担心这两行:
[Tools storeObjectIntoUserDefaults:tripsToSave withKey:kTRIPSTOSAVE];
// Reset stored current trip.
[Tools resetObjectIntoUserDefaultsWithKey:kSTORECURRENTTRIP];
您在对我的另一个回答的评论中提到,synchronize
是在第一个方法内部调用的。你绝对确定吗?因为如果没有,这可能会导致你描述的症状。
第二行在代码片段中没有明显的用途,因为没有存储密钥的行。在你发布的代码之外似乎有很多事情在发生,问题可能出在我们看不到的代码中。
我建议简化代码,使存储逻辑(包括同步)发生在同一个位置。