Чтение онлайн

на главную

Жанры

iOS. Приемы программирования

Нахавандипур Вандад

Шрифт:

Обсуждение

Многие приложения, ежедневно поступающие на рынок App Store, обладают возможностями соединения с теми или иными серверами. Некоторые выбирают с сервера данные для обновления, другие отсылают информацию на сервер и т. д. В течение долгого времени в iOS существовал лишь один способ обновлять контент в фоновом режиме. Требовалось «занять» у iOS некоторое количество времени (об этом мы говорили в разделе 14.2), и приложение могло потратить это время на завершение своей работы в фоновом режиме. Но такой способ работы является активным. Существует и пассивный способ решения аналогичных задач, когда приложение просто «сидит», а iOS сама выделяет приложению некоторое время на обработку данных в фоновом режиме. Итак, вам требуется просто подключить к приложению такую

возможность и приказать системе iOS разбудить ваше приложение в относительно спокойный момент, когда будет удобно обработать данные в фоновом режиме. Обычно при этом происходит фоновое обновление информации.

Например, вам может потребоваться загрузить новый контент. Предположим, у нас есть приложение для работы с Twitter. Открывая это приложение, пользователь в первую очередь хочет просмотреть новые твиты. До недавнего времени это можно было реализовать лишь одним способом: открыть приложение, а потом потратить некоторое время на обновление списка твитов. Но теперь система iOS может активизировать твиттерное приложение в фоновом режиме и приказать ему обновить ленту сообщений. Таким образом, когда пользователь откроет это приложение, твиты на экране уже будут обновлены.

Чтобы задействовать в приложении возможность фонового обновления, нужно перейти на вкладку Capabilities (Возможности) в настройках вашего проекта, а в области Background Modes (Фоновые режимы) установить флажок Background fetch (Фоновое обновление) (рис. 14.1).

Рис. 14.1. Активизация фонового обновления в приложении

Приложение может использовать фоновые обновления двумя способами. Во-первых, пока приложение работает в фоновом режиме, iOS будит его и приказывает ему получить определенный контент для обновления. Во-вторых, ваше приложение может быть еще не запущено и iOS будит его (опять же в фоновом режиме) и приказывает найти контент для последующего обновления. Но как iOS узнает, какое приложение следует разбудить, а какие должны оставаться неактивизированными? В этом системе должен помочь программист.

Для этого нужно вызвать метод экземпляра setMinimumBackgroundFetchInterval:, относящийся к классу UIApplication. В качестве параметра этому методу передаются временной интервал и частота, с которой iOS должна будить ваше приложение в фоновом режиме и приказывать ему получать новые данные для обновления. По умолчанию это свойство имеет значение UIApplicationBackgroundFetchIntervalNever. При таком значении iOS вообще не активизирует ваше приложение в фоновом режиме. Но значение этого свойства можно установить вручную, сообщив количество секунд, образующих интервал, либо просто передать значение UIApplicationBackgroundFetchIntervalMinimum, при котором iOS будет «прилагать минимальные усилия» — будить ваше приложение, но делать это очень редко.

— (BOOL) application:(UIApplication *)application

didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

[application setMinimumBackgroundFetchInterval:

UIApplicationBackgroundFetchIntervalMinimum];

return YES;

}

Сделав это, реализуйте метод экземпляра application: performFetchWithCompletionHandler, относящийся к делегату вашего приложения. Параметр performFetchWithCompletionHandler: этого метода дает нам блоковый объект, который нужно будет вызвать, как только приложение закончит обновлять данные. Вообще этот метод вызывается в делегате приложения, когда iOS приказывает приложению получить в фоновом режиме новый контент для обновления. Поэтому вам придется отреагировать на это и вызвать обработчик завершения, как только все будет готово. Блоковый объект, который вам потребуется вызвать, будет принимать значение типа UIBackgroundFetchResult:

typedef NS_ENUM(NSUInteger, UIBackgroundFetchResult) {

UIBackgroundFetchResultNewData,

UIBackgroundFetchResultNoData,

UIBackgroundFetchResultFailed

} NS_ENUM_AVAILABLE_IOS(7_0);

Итак,

если iOS приказывает вашему приложению обновить контент новыми данными, вы пытаетесь получить эти данные, но их в наличии не оказывается, то вам придется вызвать обработчик завершения и передать ему значение UIBackgroundFetchResultNoData. Так вы сообщите iOS, что для обновления информации вашего приложения не нашлось новых данных, и система сможет откорректировать свой алгоритм планирования и механизмы искусственного интеллекта. В результате система станет вызывать приложение не столь часто. iOS действительно очень толково справляется с такими задачами. Допустим, вы приказываете iOS вызвать приложение в фоновом режиме, чтобы оно могло получить новый контент. Но сервер не дает приложению каких-либо обновлений, и в течение целой недели приложение активизируется на пользовательском устройстве в фоновом режиме, но так и не может получить новых данных и неизменно передает блоку завершения вышеупомянутого метода значение UIBackgroundFetchResultNoData. В таком случае совершенно очевидно, что iOS стоит будить это приложение не так часто. Так можно будет более экономно расходовать вычислительную мощность и, соответственно, заряд батареи.

В этом разделе мы собираемся написать простое приложение, которое будет получать с сервера новости. Чтобы не перегружать этот пример слишком сложным серверным кодом, мы просто сымитируем серверные вызовы. Сначала создадим класс NewsItem, который имеет в качестве свойств дату и текст:

#import <Foundation/Foundation.h>

@interface NewsItem: NSObject

@property (nonatomic, strong) NSDate *date;

@property (nonatomic, copy) NSString *text;

@end

У этого класса не будет никакой реализации, поэтому всю информацию он будет нести только в свойствах. Возвращаемся к делегату нашего приложения и определяем изменяемый массив новостей. Таким образом мы сможем закрепить этот массив в контроллере табличного вида и отобразить новостные элементы:

#import <UIKit/UIKit.h>

@interface AppDelegate: UIResponder <UIApplicationDelegate>

@property (nonatomic, strong) UIWindow *window;

@property (nonatomic, strong) NSMutableArray *allNewsItems;

@end

Теперь выполним отложенное выделение массива. Это означает, что массив не будет выделяться и инициализироваться до тех пор, пока приложение прямо к нему не обратится. Так экономится память. Как только массив будет выделен, мы добавим к нему один новый элемент:

#import «AppDelegate.h»

#import «NewsItem.h»

@implementation AppDelegate

— (NSMutableArray *) allNewsItems{

if (_allNewsItems == nil){

_allNewsItems = [[NSMutableArray alloc] init];

/* Заранее записываем в массив один элемент */

NewsItem *item = [[NewsItem alloc] init];

item.date = [NSDate date];

item.text = [NSString stringWithFormat:@"News text 1"];

Поделиться:
Популярные книги

Генерал Империи

Ланцов Михаил Алексеевич
4. Безумный Макс
Фантастика:
альтернативная история
5.62
рейтинг книги
Генерал Империи

Отмороженный 9.0

Гарцевич Евгений Александрович
9. Отмороженный
Фантастика:
боевая фантастика
рпг
5.00
рейтинг книги
Отмороженный 9.0

Под знаменем пророчества

Зыков Виталий Валерьевич
3. Дорога домой
Фантастика:
фэнтези
боевая фантастика
9.51
рейтинг книги
Под знаменем пророчества

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Дядя самых честных правил 8

Горбов Александр Михайлович
8. Дядя самых честных правил
Фантастика:
попаданцы
альтернативная история
аниме
5.00
рейтинг книги
Дядя самых честных правил 8

Para bellum

Ланцов Михаил Алексеевич
4. Фрунзе
Фантастика:
попаданцы
альтернативная история
6.60
рейтинг книги
Para bellum

Идеальный мир для Лекаря 5

Сапфир Олег
5. Лекарь
Фантастика:
фэнтези
юмористическая фантастика
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 5

Покоритель Звездных врат

Карелин Сергей Витальевич
1. Повелитель звездных врат
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Покоритель Звездных врат

Отборная бабушка

Мягкова Нинель
Фантастика:
фэнтези
юмористическая фантастика
7.74
рейтинг книги
Отборная бабушка

Жестокая свадьба

Тоцка Тала
Любовные романы:
современные любовные романы
4.87
рейтинг книги
Жестокая свадьба

Смертник из рода Валевских. Книга 1

Маханенко Василий Михайлович
1. Смертник из рода Валевских
Фантастика:
фэнтези
рпг
аниме
5.40
рейтинг книги
Смертник из рода Валевских. Книга 1

Сердце Дракона. Том 11

Клеванский Кирилл Сергеевич
11. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.50
рейтинг книги
Сердце Дракона. Том 11

Тройняшки не по плану. Идеальный генофонд

Лесневская Вероника
Роковые подмены
Любовные романы:
современные любовные романы
6.80
рейтинг книги
Тройняшки не по плану. Идеальный генофонд

Возвращение Низвергнутого

Михайлов Дем Алексеевич
5. Изгой
Фантастика:
фэнтези
9.40
рейтинг книги
Возвращение Низвергнутого