2013-11-25 3 views
0

Myapp использует удаленный API для обновления своих данных, и он должен работать в автономном режиме, поэтому все данные должны быть загружены перед отображением основного раздела приложения.Должны ли мои объекты модели отвечать за загрузку собственных ресурсов?

API возвращает одну большую структуру JSON, представляющую содержимое приложения. JSON преобразуется во многие словари и массивы, затем моделируются экземпляры классов и подкрепляются этими словарями и массивами.

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

Кроме того, что было бы хорошим подходом к этому? Например, как узнать, когда все объекты модели завершили загрузку своих ресурсов?

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

+1

это зависит от многих факторов. общий ответ невозможен. Вы хотите/нужно предварительно кэшировать, или это невозможно? Насколько велико каждый образ? у вас есть другие одновременные и, возможно, более важные запросы одновременно? ... – vikingosegundo

+1

Не сказать, что это не по теме, но это своего рода [«доска» - в отличие от «клавиатуры»] (http://meta.stackexchange.com/questions/82988/) - вопрос, который может быть более подходящим для [Programmers.SE]. Просто вариант на будущее. –

+2

Нет. Объекты модели (которые на самом деле называются [объектами домена] (http://c2.com/cgi/wiki?DomainObject) не должны нести ответственность за хранение самих себя. Это нарушит [SRP] (http: // ru. wikipedia.org/wiki/Single_responsibility_principle) –

ответ

2

Ответ зависит от бизнес-требований вашего приложения.

  1. Часто один будет загружать данные в формате JSON фронта, но отложить загрузку изображений, не скачивая их, пока не требуется пользовательский интерфейс (шаблон, известный как «отложенная загрузка»). Одним из особенно элегантных способов обработки является использование категории UIImageView, которая выполняет асинхронное извлечение изображений точно в срок (SDWebImage - довольно хорошая реализация, если вы используете AFNetworking, у нее тоже есть). Для обоих из них, вы бы просто сделать что-то вроде:

    [self.imageView setImageWithURL:url]; 
    

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

  2. Иногда, однако, вы действительно хотите получить все впереди (например, вы загружаете контент для журнала, который вы хотите сделать доступным для чтения в автономном режиме).

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

Хотя этот последний образец может показаться привлекательным на первый взгляд, он имеет множество недостатков. Если, например, пользователь подключен к сотовому соединению, вы можете потратить много трафика на загрузку изображений, которые пользователь может не понадобиться немедленно, потребляя план данных пользователя и аккумулятор в процессе. Таким образом, вы можете захотеть сделать это, только если (а) вам действительно нужно все для использования в автономном режиме; и (б) у вас все в порядке с ресурсом (план данных и потребление батареи).

+1

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

+0

@DarrenFindlay: можете ли вы упаковать сервер изображений в один архив? – vikingosegundo

+1

@DarrenFindlay Я лично используйте механизм загрузки на основе NSOperation (либо сверните свой собственный ([например, это] (https://github.com/robertmryan/download-operation)), либо, лучше, используйте [AFNetworking] (https: // github. ком/AFNetworking/AFNetworki ng)), а затем создайте окончательное «завершение операции», которое имеет зависимости для всех отдельных загрузок, и когда загрузка будет завершена, ваше «завершение операции» сработает. – Rob

1

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

Ваш менеджер загрузок создаст цикл AFHTTPClient, создав массив из AFImageRequestOperation s, по одному на каждую модель (или по одной на загрузку, если есть несколько изображений на модель). Передайте свой массив операций enqueueBatchOfHTTPRequestOperations: progressBlock: completionBlock: на ваш HTTP-клиент. Ваш блок завершения будет вызываться, когда все операции загрузки будут завершены.

Этот процесс загрузки должен запускаться после того, как у вас есть все ваши модели от JSON, чтобы убедиться, что у вас есть все данные, необходимые для получения всех ваших активов.

EDIT: Допустимо отметить, что если вы поддерживаете только iOS 7, то AFHTTPSessionManager AFNetworking будет более уместным. Предложения, которые я предоставил, будут работать на iOS 7 и поддерживаются также на iOS 6.

+0

Обратите внимание, что вы имеете в виду AFNetworking 1.0, а не более недавнее AFNetworking 2.0 – vikingosegundo

+0

@vikingosegundo благодарим вас за указание на это. Я все еще поддерживаю iOS 6 с моим кодом, поэтому я не смог перейти на 2.0 –

+1

, вы можете использовать AFN2.0 с iOS 6, а не диспетчер сеансов. – vikingosegundo

Смежные вопросы