2015-02-13 3 views
0

Я пытаюсь сохранить, когда пользователь входит и выходит из iBeacon Region. Мое приложение правильно проснулось от фона и вызывается метод делегата (он показывает LocalNotification). В этом методе я также пытаюсь сохранить объект в UserDefaults.Сохранение значения в UserDefaults при пробуждении приложения из области iBeacon

На переднем плане он отлично работает. Но когда мое приложение отключено (из диспетчера задач), и пользователь входит или выходит из 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 такое же в фоновом режиме или переднем плане, нет?

EDIT: новый код

+0

Каковы реализации методов удобства по умолчанию? –

+0

К сожалению, у меня сейчас нет моего компьютера. Но я думаю, что это то, как я получаю и сохраняю свой массив. Я пытаюсь использовать другой способ и даю обратную связь. – Jonathan

+0

Я отредактировал свой первый вопрос и добавил весь код, когда пользователь входит и выходит из iBeacon Region. Я многое изменил, чтобы получить и сохранить значение. Я не сохраняю объект Trip, но NSDictionary. К сожалению, он все еще не работает ... – Jonathan

ответ

0

Чтобы ответить на конкретные вопросы:

  1. У вас есть 10 секунд времени для выполнения в фоновом режиме после события входа области/выхода.
  2. Да, вы можете сохранить его в UserDefaults за это время.
  3. В фоновом режиме нет разницы.

Я подозреваю, что что-то не так с кодом, который сохраняется в UserDefaults. Для меня не очевидно, что не так. Я бы:

  1. Добавить NSLog заявления, чтобы выяснить, какой код будет выполнен. Опубликуйте результаты этого в качестве редактирования вашего вопроса.
  2. Проверьте этот же блок кода на переднем плане, который запускается вручную (а не маяком) и проверяет, работает ли он.
+0

Да, он работает на переднем плане, мой объект «Поездка» сохраняется в «UserDefaults», и я могу его вернуть. В фоновом режиме сложнее проверить его, но LocalNotification отправляется и отображается на экране iPhone, поэтому код выполняется. Я согласен с тобой, что-то не так с моим кодом ... Но это сложно проверить, потому что это только в фоновом режиме. – Jonathan

+0

Я добавил несколько журналов. Я могу подтвердить, currentTrip не nil и array tripToSave содержит один объект. StoreObjectIntoUserDefaults - это вызов, и внутри есть синхронизация. И он работает на переднем плане. Когда я хочу получить массив, хранящийся с помощью его ключа, я получаю нулевой объект. – Jonathan

0

Я беспокоюсь об этих двух линиях:

[Tools storeObjectIntoUserDefaults:tripsToSave withKey:kTRIPSTOSAVE]; 

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

Вы упомянули в комментарии к моему другому ответу, который synchronize называются внутри первого метода. Вы абсолютно уверены? Потому что, если нет, это может вызвать симптомы, которые вы описываете.

Вторая строка не имеет очевидной цели в фрагменте кода, так как нет строки, в которой хранится ключ. Похоже, что вне кода, который вы опубликовали, многое происходит, и проблема может быть в коде, который мы не видим.

Я предлагаю упростить код, поэтому логика хранения (включая синхронизацию) происходит в одном и том же месте.

+0

Я думаю, что ты прав. Я исследую, и я думаю, что это то, как я храню и получаю свой массив, который вызывает проблемы. Мой объект поездки - это нормально, и это делается с помощью этих двух методов. Но это не так, как с массивом. Я попробую следующим образом: http://stackoverflow.com/a/9212596, но теперь у меня нет моего компьютера. Но это не объясняет, почему он работает на переднем плане ... Я дам вам обратную связь как можно скорее. – Jonathan

+0

Вызов синхронизации не требуется в любом из этих сценариев. –

+0

Я изменил свой код для хранения другим способом (посмотрите на мой отредактированный вопрос). Но все равно не работает. Поэтому мне удалось сохранить tripSoSave массив в файл. Но журналы показывают мне, что при выполнении этого кода: NSArray * arrayToFile = [NSArray arrayWithArray: tripToSave]; [arrayToFile writeToFile: путь атомарно: ДА]; ответ НЕТ ... Опять же, на переднем плане он возвращает ДА, и все работает. – Jonathan