Рекомендации по проектированию / внедрению синтаксического анализа XML с несколькими подключениями / каналами / представлениями - PullRequest
7 голосов
/ 27 октября 2011

Я начал свой первый iOS-проект и хотел посоветовать, как структурировать приложение.Приложение извлекает фид XML, анализирует его и отображает список, представляющий элементы в фиде XML.При нажатии на элемент в списке приложение извлекает новый XML-канал, используя один из атрибутов из ранее извлеченного XML-канала.Это происходит, когда несколько слоев pull, parse, display и user selection делают одно и то же снова.Теперь большая часть структуры элементов XML выглядит примерно так:

(Это простые примеры, просто чтобы продемонстрировать, что происходит)

возвращает (Показать информацию в новом представлении):

<items>
    <item id="123" name="item 1" />
    <item id="124" name="item 2" />
    <item id="125" name="item 3" />
</itmes>

возвращает:

<itemDescription>
    <description itemId="123" name="desc 1" description="blah 1" />
</itemDescription>

Хотел бы узнать:

  • Должен ли я иметь класс / объект соединения или новое соединение в каждом представлении?
  • Должен ли я иметькласс / объект синтаксического анализатора или анализировать фид XML в каждом представлении?
  • Я также хочу сохранить некоторые возвращаемые данные, поэтому мне не нужно повторно вызывать фид XML, если пользователь переходит обратно ксписок основных элементов, но мне нужно будет каждый раз анализировать XML-канал itemsDescription.

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

Ответы [ 2 ]

4 голосов
/ 04 ноября 2011

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

Базовая структура (без автономного режима):

Пример приложения SeismicXML демонстрирует, какиспользовать NSXMLParser для анализа данных XML.Когда вы запускаете приложение, оно загружает и анализирует RSS-канал из Геологической службы США (USGS), который предоставляет данные о недавних землетрясениях по всему миру.Он отображает местоположение, дату и величину каждого землетрясения, а также цветную графику, которая указывает на серьезность землетрясения.Синтаксический анализ XML выполняется в фоновом потоке с использованием NSOperation и обновляет представление таблицы землетрясений пакетами проанализированных объектов.

Расширенная структура (в автономном режиме):

Демонстрирует использование Core Data в многопоточной среде в соответствии с первым рекомендуемым шаблоном, упомянутым в Руководстве по программированию Core Data.

На основе примера SeismicXML он загружает и анализирует RSS-канал изГеологическая служба США (USGS), которая предоставляет данные о недавних землетрясениях по всему миру.Отличительной чертой этого образца является то, что он постоянно хранит землетрясения с использованием базовых данных.Каждый раз, когда вы запускаете приложение, оно загружает новые данные о землетрясениях, анализирует их в NSOperation, который проверяет дубликаты и сохраняет вновь обнаруженные землетрясения как управляемые объекты.

Для новичков в Core Data может быть полезно сравнитьОбразец SeismicXML с этим образцом и обратите внимание на необходимые ингредиенты для введения основных данных в ваше приложение.

Что касается ответа cwieland, я бы не стал использовать ASIHTTPRequest, поскольку устарел , так что если вы хотитеследуя его подходу, я рекомендую вам использовать AFNetworking , где вы можете легко и быстро обрабатывать XML-запрос:

NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"http://api.flickr.com/services/rest/?method=flickr.groups.browse&api_key=b6300e17ad3c506e706cb0072175d047&cat_id=34427469792%40N01&format=rest"]];
AFXMLRequestOperation *operation = [AFXMLRequestOperation XMLParserRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, NSXMLParser *XMLParser) {
  XMLParser.delegate = self;
  [XMLParser parse];
} failure:nil];

NSOperationQueue *queue = [[[NSOperationQueue alloc] init] autorelease];
[queue addOperation:operation];
2 голосов
/ 01 ноября 2011

Вот как я бы это реализовал. Я бы использовал ASIHTTPRequest для всех элементов подключения и не беспокоился об этой части. Он может очень легко обрабатывать все ваши загрузки данных асинхронно с помощью простых методов делегирования.

Я хотел бы иметь класс анализатора, который принимает URL-адрес, загружает его асинхронно, а затем анализирует возвращаемые данные. Затем он вернет массив проанализированных потомков с помощью метода делегата в табличное представление, которое отобразит потомков в данных XML.

Я бы создал подкласс UITableViewController, который будет обрабатывать любой тип URL / данных, в этом случае вам нужно будет написать только один класс табличного представления и не беспокоиться о том, как пользователь перемещается. Это сделает так, что вам нужно будет написать только один класс, и он будет обрабатывать любое количество разверток или комбинаций. Эта реализация сильно зависит от того, насколько сложны отдельные уровни XML-данных. Если они существенно отличаются, было бы более разумно иметь более чистый код в табличном представлении и не проверять if's тип данных при создании ячейки.

Использование приложения в стиле навигации избавило бы от необходимости повторного анализа данных каждый раз, когда представление загружается, когда вы выводите представления из стека. В любое время, хотя это будет повторный анализ, но простой кэш массива urls-> может решить эту проблему, если это необходимо / желательно. Это потребует перезагрузки данных каждый раз при запуске приложения. Конечно, если вы получили предупреждение о глубине памяти на 3 уровня, это потребует повторного анализа или восстановления кэша на вашем пути к резервному копированию.

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

Лично я бы использовал NSXMLParser, поскольку это то, с чем я знаком. Возможно, вы захотите поместить элементы в оболочку класса, и в этом случае вам просто нужно будет проверить, какой тип элемента у вас есть на didStartElement и установить enum для включения при создании. это довольно легко с nsxmlparser. Я не использовал никакого другого парсера для сравнения, но обнаружил, что отладка NSXMLParser была достаточно простой, а кодирование было простым, поэтому его было легко установить и запустить. Вот отличный сайт по всем различным xml-парсерам:

http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

Итак, в заключение я хотел бы иметь подкласс NSObject, который принимает URL-адрес, загружает его через ASIHTTPRequest, анализирует его. Подкласс UITableviewController, который на касании ячейки выделяет тот же класс контроллера представления с новым URL-адресом и помещает его в стек навигации. Представление будет отображать экран загрузки, пока не будет возвращен массив, а затем просто перезагрузить данные. Надеюсь, это был бы СУХОЙ ПОЦЕЛУЙ.

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

<items>
    <stuff></stuff>
    ....
    <stuff></stuff>
</items>
EOF

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...