【问题标题】:Save value into UserDefaults when app awake from iBeacon region当应用从 iBeacon 区域唤醒时,将值保存到 UserDefaults
【发布时间】:2015-02-13 07:51:40
【问题描述】:

当用户进入和退出 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在后台或前台模式下是一样的,不是吗?

编辑:新代码

【问题讨论】:

  • 你的默认便利方法的实现是什么?
  • 很遗憾我现在没有电脑。但我认为这就是我获取和存储数组的方式。我尝试使用另一种方式并在这里提供反馈。
  • 我已经编辑了我的第一个问题,并在用户进入和退出 iBeacon 区域时添加了所有代码。关于获取和存储价值,我已经改变了很多。我不保存 Trip 对象,而是保存 NSDictionary。不幸的是它仍然不起作用......

标签: ios objective-c cllocationmanager ibeacon


【解决方案1】:

回答您的具体问题:

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

我怀疑保存到 UserDefaults 的代码有问题。对我来说,出了什么问题并不明显。我会:

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

【讨论】:

  • 是的,它在前台工作,我的“Trip”对象被保存到UserDefaults,我可以取回它。在后台测试它更加困难,但是 LocalNotification 被发送并显示在 iPhone 屏幕上,因此代码被执行。我同意你的观点,我的代码应该有问题......但很难测试,因为它只是在后台。
  • 我添加了一些日志。我可以确认, currentTrip 不是 nil 并且数组 tripsToSave 包含一个对象。 storeObjectIntoUserDefaults 被调用,里面有一个同步。它在前台工作。当我想使用它的键存储数组时,我得到一个 nil 对象。
【解决方案2】:

我担心这两行:

[Tools storeObjectIntoUserDefaults:tripsToSave withKey:kTRIPSTOSAVE];

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

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

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

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

【讨论】:

  • 我认为你是对的。我进行了调查,我认为这是我存储和获取数组的方式导致了问题。我的 Trip 对象没问题,它是由这两种方法制成的。但这与数组的处理方式不同。我会尝试这种方式:stackoverflow.com/a/9212596 但我现在没有电脑。但它没有解释为什么它在前台工作......我会尽快给你一个反馈。
  • 在这些情况下都不需要调用同步。
  • 我已经修改了我的代码以另一种方式存储(查看我编辑的问题)。但还是不行。所以我设法将 tripsToSave 数组保存到一个文件中。但是日志告诉我,当执行此代码时: NSArray *arrayToFile = [NSArray arrayWithArray:tripsToSave]; [arrayToFile writeToFile:path atomically:YES];响应是 NO ... 同样,在前台它可以正常工作,返回 YES 并且一切正常。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-16
  • 2022-01-17
  • 1970-01-01
  • 2021-11-14
  • 1970-01-01
  • 1970-01-01
  • 2021-01-11
相关资源
最近更新 更多