@tiger_13

Как лучше обновлять контент в приложении?

Пишу программу, бд реализована с помощью Realm. Когда приложение открывается впервые (бд пустая), то я обычным if closure проверяю, нужно ли грузить данные с сервера.

if objects.count == 0 {
// загружаем данные через Alamofire request, парсим и сохраняем их в Realm
}


Суть вопроса:
Данные на сервере обновляются хаотично (примерно раз в месяц), как реализовать обновление этих данных (скачивание данных с сервера)?

Лично у меня присутствует три идеи:

1) каждый раз в viewDidLoad() я делаю запрос на сервер, есть ли какие-то обновления, если да, то делаю уже запрос на данные, и парсю + сохраняю их

Минусы: как по мне, то такой подход увеличивает нагрузку на сервер + жрет оперативку девайса, что не гуд.

2) использовать BGTask/BGAppRefreshTask, BGProcessingTaskRequest - IOS 13 (еще полностью не прокурил его) / application(_:performFetchWithCompletionHandler:) - IOS 7 - IOS 12.

3) отправлять remote notification при обновлении бд на сервере:
https://developer.apple.com/documentation/usernoti...

Минусы:
- нашел статейку, где говорится, что если юзер убьет приложение, то handler вообще не сработает.
- непонятка с DeviceToken и Authorization.

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

P.S. пока писал, пришел четвертый вариант - через UserDefaults, записывать туда Date, и если прошло больше 24 часа, то спрашивать у сервера, есть ли обновления (ну и соответственно писать Date, и так по кругу)
  • Вопрос задан
  • 254 просмотра
Решения вопроса 1
doublench21
@doublench21 Куратор тега Swift
Дисклеймер: Не изобретайте велосипед!


У меня глаза на лоб лезут от подобных вопросов.

Ну есть у Вас данные, которые на момент запуска приложения должны быть строго актуальными, ТО это самые обычные запросы на сервер. Ровно так же как и в любом другом приложении. Заходишь в приложение, приложение отправляет запрос на сервер, а сервер отдаёт. Вы парсите, после отображаете информацию. НЕТ абсолютно никакой разницы изменилось там что-то или нет. Вы ведь просто запрашиваете JSON.

Я ещё могу понять, если вы передаёте некий файл размеров в 10GB и который не хочется качать снова, если он не изменился. Тут я могу понять ваши опасения. Ну даже в таком случае, такие вопросы решаются на сервере путём нужных заголовков. Один из них E-TAG. Всё уже давно за вас придумали.

Возвращаясь к вопросу автора. Если всё о чем мы говорим - это лишь JSON составленный из БД, то не мучайте сами знаете что. Просто сделайте запрос и всё. Не важно изменились ли там данные или нет. Обо всём остальном позаботится кэш, как на клиенте(URLSession), так и на сервере.

---------------------------------------------------------------------------------------------------

Когда делать запросы на сервер?

Ну смотря где эти данные отображаются.
  • данные относятся глобально ко всему приложения и могут использоваться в любом контроллере, тогда:
    func application(
            _ application: UIApplication,
            willFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? = nil
        ) -> Bool {
            // ...
            return true
        }

    или
    func application(
            _ application: UIApplication,
            didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
        ) -> Bool {
           // ...
            return true
        }

    или как инициализация св-ва вообще в AppDelegate

  • если данные нужны лишь для конкретного контроллера, то как уже написали выше:
    override func viewDidLoad()  {
        super.viewDidLoad()
       // ...
     }

Ответ написан
Пригласить эксперта
Ответы на вопрос 1
ivanvorobei
@ivanvorobei
iOS разработчик, канал https://t.me/sparrowcode
Не понятно какую проблему вы пытаетесь решить.
  1. Нагрузка на сервер - вряд-ли статическим JSON вы хоть как то упретесь в половину мощности даже самой дешевой виртуалки на DO.
  2. Оперативка девайса - жрется от http запроса? Один контейнер реалма сожрет больше, а запрос по БД улетит в 100 порядков выше с их lazy запросами.
  3. performFetchWithCompletionHandler не для вашей задачи.

Чтобы сформулировать проблему, нужно определить:
  • Насколько в актуальном состоянии должна быть информация (минута / месяц)
  • Насколько оперативно она должна доставляться (перед запуском, в основном потоке после запуска, в фоне после запуска, когда угодно),
  • На какие расходы вы готовы пойти (готов купить каплю на DO за 5$)

Обновлю ответ после вашего комментария.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы