Parse saveEventually сохраняет пустой объект

Когда я пытаюсь сохранить PFObject без сетевого подключения, он успешно сохраняется локально, всякий раз, когда я снова запускаю приложение с сетевым подключением, кажется, что объект будет сохранен на сервере, но все параметры пусты.

Я делаю следующую процедуру: сначала я создаю PFObject с разными значениями и вызываю saveEventually. Во время этих шагов у меня нет подключения к интернету (режим полета включен), поэтому он не может быть сохранен на сервер и был сохранен локально.

PFObject *contact = [PFObject objectWithClassName:@"Contact"];
[contact setObject:[PFUser currentUser] forKey:kRelatedToUserKey];
[contact setObject:self.firstname forKey:kFirstnameKey];
[contact setObject:self.lastname forKey:kLastnameKey];

[contact saveEventually];

Теперь я закрываю приложение и запускаю его снова, я так загружаю свои контакты. Я возвращаю правильный объект со всеми правильными значениями имени, фамилии и т. д.

PFQuery *postQuery = [PFQuery queryWithClassName:@"Contact"];
[postQuery whereKey:@"related_to_user" equalTo:[PFUser currentUser]];
[postQuery fromLocalDatastore];
[postQuery findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
    if (!error) {
        // here I get back the correct object from local storage, with all values
    }
}];

Теперь, когда я выключаю режим полета, он пытается сохранить объект на сервере, но все, что я вижу в бэкэнде, это objectId без каких-либо значений.

введите здесь описание изображения

В то время как локально сохраненный объект имеет все правильные значения.


person gpichler    schedule 15.01.2015    source источник
comment
Вы не установили никаких параметров или значений для PFObject. Вы просто указываете, куда он идет, а затем закрепляете его. Добавьте значения или ключи   -  person soulshined    schedule 16.01.2015
comment
@soulshined спасибо за подсказку, я попытался сократить свой ответ и сделал ошибку при копировании.   -  person gpichler    schedule 16.01.2015


Ответы (4)


Так что именно вы пытаетесь сделать? Вот как это звучит:

Ваш запрос класса «Контакт», и как только вы запрашиваете его и находите объект по его идентификатору (объект, с которым вы ничего не делаете [PFObject *contact]), вы создаете PFObject для совершенно другого класса ?? Вы можете обойти все это, если просто хотите опубликовать PFObject, но, может быть, вы пропустили другой код, который не имел отношения к вопросу? Но ладно. Чтобы ответить на ваш вопрос, saveEventually работает рука об руку с локальным хранилищем данных, поэтому у вас не должно быть никаких проблем, как вы можете видеть, он вызывается, но ваши значения не сохраняются, как objectID. Идентификатор объекта создается автономно, поэтому он сохраняется и ничего больше. Я буквально пытался воспроизвести вашу ошибку всеми возможными способами, но не могу, это ваши значения, они возвращают ноль. Я даже использовал макросы (похоже, именно так вы настраиваете свои клавиши), эмулировал режим полета и т. Д. Чтобы проверить, запросите закрепленный объект и посмотрите, что он возвращает. Кроме того, лучше всего, когда вы выполняете обратный вызов, попытаться включить оператор if или случай переключения, который явно определяет его соответственно для лучшей практики:

{
    if (succeeded) {
         debt.parseID = newDebt.objectId;
    }];
}];

Кроме того, будьте осторожны при размещении важных задач в блоке успеха, потому что важным элементом saveEventually является то, что если он не завершится до закрытия приложения и если объект все еще находится в памяти, он попытается снова, но если объект больше не находится в памяти, он попытается снова при следующем выполнении, но БЕЗ блока успеха.

Устраните неполадки со значениями свойств (self.contact | self.amount | self.incomingDebt), как вы их определяете


Мы прошли долгий путь от исходного сообщения, поэтому, пытаясь вернуть его, настоящей и единственной проблемой здесь является saveEventually.

Сохраняет этот объект на сервере в неустановленное время в будущем, даже если Parse в данный момент недоступен.

Основная цель saveEventually :

Используйте это, когда у вас может не быть надежного сетевого подключения и не нужно знать, когда сохранение завершится

Если ожидается отправка более 10 МБ данных, последующие вызовы приведут к тому, что старые сохранения будут автоматически удалены до тех пор, пока соединение не будет восстановлено и объекты в очереди не будут сохранены.

Вы не можете контролировать, когда это вызывается. Кроме того, при сохранении данные в конечном итоге кэшируются на локальном диске до тех пор, пока они не будут успешно загружены, поэтому закрепление одного и того же объекта является излишним. Сохранение в конечном итоге, если вы думаете об этом, является собственным локальным хранилищем данных, оно хранит их на локальном диске до тех пор, пока не будет доступен Интернет (локальное хранилище данных).

У вас есть два способа обойти это. Локальное хранилище данных — это функция, похожая на основные данные, позволяющая пользователям отказаться от NSFRC с помощью простого однострочного кода pin/pinInBackground:. Вы можете просто закрепить объекты и, когда вы узнаете, что есть интернет, снова открепить и сохранить их в своем бэкэнде. В качестве альтернативы вы можете сделать это по-другому, немедленно вызвать доступность, а если нет Интернета, pin: объект, иначе saveInBackground: сначала. Или просто воспользуйтесь их политикой кэширования.


ССЫЛКИ :

person soulshined    schedule 16.01.2015
comment
большое спасибо за ваш ответ, я очень ценю вашу помощь. У меня было время, чтобы обновить весь свой ответ, и, надеюсь, теперь он немного понятнее. У меня все еще та же проблема. - person gpichler; 19.01.2015
comment
@user1463853 user1463853 у вас есть опечатка в вашем недавно исправленном вопросе или это возможная зацепка? [новый контакт сохранить в конечном итоге]; не ссылается на созданный вами PFObject с именем *contact not *newContact. Вместо этого выполните: `[свяжитесь с saveEventually]; - person soulshined; 23.01.2015
comment
это была опечатка в моем вопросе, я использую правильную ссылку в своем коде. (исправлено в вопросе) - person gpichler; 23.01.2015
comment
@ user1463853, не могли бы вы показать все, что связано с настройкой объекта, пожалуйста. Как вы устанавливаете self.firstname и self.lastname и, пожалуйста, покажите, как вы устанавливаете kFirstnameKey kRelatedToUserKeyetc. - person soulshined; 25.01.2015
comment
Я не уверен, что это проблема, потому что, если я использую приложение в онлайн-режиме, все значения прекрасно сохраняются в бэкэнде. Это также не работает, если я устанавливаю жестко заданную строку вместо ссылки на эти свойства. - person gpichler; 25.01.2015
comment
@user1463853 user1463853 Я обновил свой ответ - вам действительно следует рассмотреть «гарантированный» метод (т. Е. saveInBackground, save:), если это важная информация, или, как уже упоминалось, сначала проверьте доступность, а затем действуйте соответственно. - person soulshined; 26.01.2015
comment
если saveEventually установлен на объект и до того, как он получит возможность перейти на сервер синтаксического анализа, как вы можете его удалить? Открепление, похоже, не работает. - person DogCoffee; 06.04.2015

Это была ошибка в SDK (1.6.2).

Представлено здесь: https://developers.facebook.com/bugs/1554492594835537/

person Franck    schedule 05.02.2015

У меня была похожая проблема, я действительно обнаружил, что удаление или отсутствие вызова [Parse enableLocalDatastore]; приводит к тому, что saveEventually работает так, как ожидалось (с использованием Parse 1.6.2). Я предполагал, что для этого потребуется [Parse enableLocalDatastore];.

person Workshed    schedule 04.02.2015
comment
То же самое. SaveEventually() не работает, если мы используем хранилище данных. У тебя есть решение? - person VipulKumar; 27.08.2015

Эта ошибка исправлена ​​в Parse версии 1.6.3!

person gpichler    schedule 02.03.2015