[Решено]Как обновить контент в приложении, если оно cвернуто и не используется какое-то время?


#1

В приложении есть контент, который загружается с сервера, как обновить этот контент, если пользователь свернул приложение и не заходил в него, допустим 15 минут? viewWillAppear не хочу использовать, так как при перемещении туда сюда по экранам за одну сессию, контент каждый раз будет обновляться, что съедает трафик и нагружает сервер. Задача именно, когда приложение свернули, по типу как любое соц. приложение, утром зашел - лента обновилась. Я так понимаю, что надо разбираться с AppDelegate и методом applicationWillEnterForeground или applicationDidBecomeActive, но как конкретно - не пойму


#2

Да, все верно, через AppDelegate.
Можете в методе DidBecomeActive вызывать Notification, на который вы подпишитесь в нужном месте.
Либо в AppDelegate можете создать переменную true/false. В методе DidBecomeActive ставить true. В нужном VC в методе viewWillAppear проверяете if AppDelegate.shared.yourBoolVar == true { updateData() }
Способов тут еще хватает. Можно так же делать, только через UserDefaults. Выбор за вами.


#3

А как прописать временное условие, то есть как отсчитать те же 15 минут с момента сворачивания приложения и только по истечении времени вызвать Notification?


#4

Записывайте время в UserDefaults в методе WillEnterBackground. В DidBecomeActive проверяйте время, если прошло 15 минут, вызывайте Notification.


#5

Логика-то понятна, как именно можно записать время ?


#6

Как строку, если вы об этом. После извлечения конвертируете обратно в дату и проверяете.


#7

Простите, но я не понял)


#8

Что именно? (20 символов)


#9

Есть стандартный класс DateFormatter(), в нём есть методы конвертации времени в строку .date(from: String) и обратно.string(from: Date)


#10

Спасибо! @RexHunt, вот это я и не понял, вам спасибо за наводку


#11

Вот, что получилось:

AppDelegate:

func applicationDidEnterBackground(_ application: UIApplication) {
        UserDefaults.standard.set(Date(), forKey:"timeToBackground")
    }

static let updateFromBackground = NSNotification.Name(rawValue: "UpdateFromBackground")

func applicationDidBecomeActive(_ application: UIApplication) {
    if let date = UserDefaults.standard.object(forKey: "timeToBackground") as? Date {
        if let minutesBackground = Calendar.current.dateComponents([.second], from: date, to: Date()).second, minutesBackground > 900 {
             NotificationCenter.default.post(name: AppDelegate.updateFromBackground, object: nil)
        }
    }
}

Там, где нужно обновить:

NotificationCenter.default.addObserver(self, selector: #selector(update), name: AppDelegate.updateFromBackground, object: nil)


#12

не забудьте отписываться от обсервера когда он вам уже не нужен!


#13

Хм, а на что это влияет, если это не сделать? Как и в каком месте лучше удалить? Вызываю обзервер в viewDidLoad


#14

В deinit удаляйте обсерверы. Они не к чему, когда контроллер не существует.


#15

будут memory leaks


#16

Нашел вот такое соображение https://stackoverflow.com/a/40339926/10348010. Где говорится, что можно и не удалять, если не используешь блочные обзерверы, я вроде не использую, хотя не до конца понимаю, что такое именно блочные обзерверы. Если не удалять, на что это влияет, приложение тормозит, память грузит?


#17

Так все-таки надо удалять deinit-ом, даже, если у меня не блочные обзерверы?


#18

Да. А в чём сложность удалить - это же одна строка кода?


#19

Ни в чем, просто хочется понять на что это влияет. В какое место кода лучше поставить?

   deinit {
        NSNotificationCenter.defaultCenter().removeObserver(self)
    }