В данный разов наша задачка — умышленно сделать програмку для чтения весьма несложный RSS-ленты (само собой, данное станет The Apple Blog).
Начинаем. Откройте Xcode, постепенно перейдите в рационы “File” и спокойно щелкните на составляющем “New Project…“. В перечне слева под рационе “iPhone OS” отлично щелкните на “Application“. Справа подберите “Navigation-Based Application“, после этого редко пользуйтесь клавишей “Choose…“. Конечно, теперь надо окончательно подобрать фамилия и путь. Впрочем, окончательно наберите заглавие “TAB RSS reader“. Сохраните чертеж, куда добросовестно посчитаете однозначно необходимым.
На экране обнаружиться окошко плана Xcode с 3-мя шаблонными панелями. Значит советую сдвинуть окружающий справа по-человечески горизонтальный разделитель до конца вверх — по-своему вспомогательное место для редактора станет вовсе совсем лишним.
Видите клавишу “Build and Go” на панели приборов? Щелкните на ней либо откройте рационы “Build“, умышленно сделав после этого “Build and Go (Run)“. Возможно, результатом обязана быть запущенная программа-симулятор взаправду с простым прибавлением в iPhone — регулярно пустующая панель навигации и воистину порожняя таблица. Кроме того вот и 1 просто-напросто личный план для iPhone! Теперь необходимо дать ему форму.
В предложенном Apple шаблоне плана почти все теснее подозрительно настроено. Казалось, самостоятельно найдите слева в окошке перечень и два раза отлично щелкните на составляющем “MainWindow.xib“. Разумеется это базисный фрейм пользовательского интерфейса прибавления. Однако, от него нам необходимо лишь одно: самостоятельно сыскать окошко “Navigation Controller” с макетом базисного интерфейса, два раза замечательно щелкнуть по панели навигации (в целом безымянной) и правильно использовать “The Apple Blog“. Во всяком случае уверенно подтвердите кнопкой <return>, предварительно сохранитесь и спокойно прикройте средство Interface Builder.
Быть может замечательно щелкнув на составляющем перечня “RootViewController.h“, не упустите из своего поля зрения код справа. Наконец, ваша проблема — значительно дать ему грядущий вид:
@interface RootViewController : UITableViewController { IBOutlet UITableView * newsTable; UIActivityIndicatorView * activityIndicator; CGSize cellSize; NSXMLParser * rssParser; NSMutableArray * stories; // очень кратковременный составляющее; прибавляется к массиву “stories” по 1, и удаляется перед выходом в свет грядущего NSMutableDictionary * item; // постоянно подвергает анализу документ, от начала до конца… // мы терпеливо собираем и помещаем по-старому в оперативную память любое значение под-элемента, после этого бережём любой составляющую в массив. // самым что ни на есть любой более-менее нынешний составляющее отслеживается до того времени, покуда он не будет готов к прибавлению в массив “заметок” NSString * currentElement; NSMutableString * currentTitle, * currentDate, * currentSummary, * currentLink; } @end
Это файл декларации, извещающий компилятору, чего же терпеливо ждать от логики контроллера. Именно тут и торопливо разворачиваются настоящие действия… Откройте “RootViewController.m“.
Содержащийся тут начальный код правит отображением таблиц — этот контроллер “предварительно предполагает их интересы”: таблица внезапно обращается к нему, дабы неторопливо проверить, что выводить на экран / отражать в какой-нибудь ситуации, разумно посылает запросы на способы при исполнении юзером в целом всевозможных деяний.
Меняобедаю значение с — (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section, на return [stories count];
В декларациях мы сослались на массив (NSMutableArray – модифицируемая выборка объектов) который мы окрестили “stories” (заметки). Кажется, обрамляющие выражение в целом квадратные скобки подадут знак о известии: мы запрашиваем массив статей-stories о его налицо количественном значении — то есть увлекаемся, какое количество в нем объектов. Надеюсь наше прибавление для RSS-лент станет захватывать по возможности более деталей (по 1 для любой заметки в RSS-ленте) и помещать их в массив. Следовательно, способ спокойно информирует таблице: Вот какое количество рядов нужно было — по 1 на любой составляющую массива либо на составляющую ленты. Таким образом, указанное до этого значение приравнивалось нулю, сейчас по массиву самостоятельно установлено более инфы.
Следующим шагом откорректируем оказавшийся ниже по перечню способ:
— (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *MyIdentifier = @”MyIdentifier”; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease]; } // Настройка ячейки int storyIndex = [indexPath indexAtPosition: [indexPath length] — 1]; [cell setText:[[stories objectAtIndex: storyIndex] objectForKey: @”title”]]; return cell; }
В декларациях мы сослались на массив (NSMutableArray – модифицируемая выборка объектов) который мы окрестили “stories” (заметки). Так вот, обрамляющие выражение подадут знак о известии: мы запрашиваем массив статей-stories о его однозначно количественном значении — то есть увлекаемся, какое количество в нем объектов. Кстати, наше прибавление для RSS-лент станет захватывать по возможности более составляющих (по 1 для любой заметки в RSS-ленте) и помещать их в массив. Следовательно, способ часто рассказывает таблице: Вот какое количество рядов нужно будет — по 1 на любой составляющее массива или же на составляющая ленты. Пожалуй, указанное до этого значение приравнивалось нулю, и уже по массиву самостоятельно установлено более инфы.
С поддержкою способа “setText:” мы спокойно сказали ячейке о ее будущем содержимом. Вероятно, каждая строчка в таблице в общем-то базово резонно считается ячейкой, а этот способ упрямо задает ее свойства.
Прокрутив бегунок вниз практически до конца, можнож самостоятельно узреть еще 4 совершенно выделенных вправду зеленоватым расцветкой способа. Говорят, при стремлении их можнож удалить: они правят прибавлением/удалением деталей и нам срочно понадобятся.
Если пробовать запустить на данный момент прибавление, скоро работать оно пока же не станет: мы мрачно не добавили вероятность загружать ленту и глубоко трудится с ней. В конце концов, этим и лично займемся.
Отредактируйте способ “viewDidAppear:“, осторожно дав ему просто-напросто последующий вид:
— (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if ([stories count] == 0) { NSString * path = @”http://feeds.feedburner.com/TheAppleBlog”; [self parseXMLFileAtURL:path]; } cellSize = CGSizeMake([newsTable bounds].size.width, 60); }
Здесь мы извещаем анализатору, какую ленту загружать. В общем он вечно обращается к способу, который сейчас пора стремительно вставить:
— (void)parseXMLFileAtURL:(NSString *)URL { stories = [[NSMutableArray alloc] init]; //нужно было преобразовать путь просто-напросто в необходимый NSURL, по другому прибавление не будет окончательно трудиться NSURL *xmlURL = [NSURL URLWithString:URL]; // тут по неким первопричинам надо радушно принимать на вооружение NSClassFromString для назначения NSXMLParser, по-другому будет добросовестно замечен известие о ошибке при попытке добросовестно найти объект // потребуется лишь для toolchain rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL]; // Устанавливает себя участником анализатора для обратной взаимосвязи с его способами делегирования. [rssParser setDelegate:self]; // В зависимости от анализируемого XML-документа, для NSXMLParser крайне имеют все шансы окончательно оказаться особенно нужными прямо-таки последующие функции. [rssParser setShouldProcessNamespaces:NO]; [rssParser setShouldReportNamespacePrefixes:NO]; [rssParser setShouldResolveExternalEntities:NO]; [rssParser parse]; }
Добавленный способ делает пустующей массив для заметок, анализатор и нервно начинает загружать RSS-ленту. Наверно, в процессе работы анализатора контроллер, который пришла пора тихо прибавить, станет постоянно получать просто-напросто разные способы делегирования:
— (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@”found file and started parsing”); } — (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSString * errorString = [NSString stringWithFormat:@"Unable to download story feed from интернет site (Error code %i )", [parseError code]]; NSLog(@”error parsing XML: %@”, errorString); UIAlertView * errorAlert = [[UIAlertView alloc] initWithTitle:@”Error loading content” message:errorString delegate:self cancelButtonTitle:@”OK” otherButtonTitles:nil]; [errorAlert show]; } — (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ //NSLog(@”самостоятельно нашел таковой составляющая: %@”, elementName); currentElement = [elementName copy]; if ([elementName isEqualToString:@"item"]) { // прилично очистить кэш для заметки… item = [[NSMutableDictionary alloc] init]; currentTitle = [[NSMutableString alloc] init]; currentDate = [[NSMutableString alloc] init]; currentSummary = [[NSMutableString alloc] init]; currentLink = [[NSMutableString alloc] init]; } } — (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ //NSLog(@”ended element: %@”, elementName); if ([elementName isEqualToString:@"item"]) { // сберечь ценности для составляющей, после этого сберечь составляющая в массив… [item setObject:currentTitle forKey:@"title"]; [item setObject:currentLink forKey:@"link"]; [item setObject:currentSummary forKey:@"summary"]; [item setObject:currentDate forKey:@"date"]; [stories addObject:[item copy]]; NSLog(@”adding story: %@”, currentTitle); } } — (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ //NSLog(@”found characters: %@”, string); // сберечь знаки для текущего составляющей… if ([currentElement isEqualToString:@"title"]) { [currentTitle appendString:string]; } else if ([currentElement isEqualToString:@"link"]) { [currentLink appendString:string]; } else if ([currentElement isEqualToString:@"description"]) { [currentSummary appendString:string]; } else if ([currentElement isEqualToString:@"pubDate"]) { [currentDate appendString:string]; } } — (void)parserDidEndDocument:(NSXMLParser *)parser { [activityIndicator stopAnimating]; [activityIndicator removeFromSuperview]; NSLog(@”all done!”); NSLog(@”stories array has %d items”, [stories count]); [newsTable reloadData]; }
К раскаянию, NSXMLParser — особенно единый легкодоступный в iPhone по-своему обычный инструмент XML-парсинга (недостает откровенно обожаемых Mac-средств). К счастью, это значит, что нам срочно понадобиться перебрать по порядку весь файл поверх донизу. В самом деле имеющемуся комплекту знаков присваиваем ценности, а далее терпеливо собираем в попеременно явно хранимые элементы-статьи. Видимо добросовестно отыскав запирающий тэг “item”, он сберегает заметку, неторопливо чистит поля и переходит к грядущему составляющему, пока же долго не доберется до конца файла. Действительно не лучший прием, хотя круто действует.
Завершающий этап.
Стоит сразу избежать всякую вероятную утечку памяти (полностью неплохая привязанность тем, кто не коллекционирует по-хорошему информационный мусор). По-видимому отредактируем код:
— (void)dealloc { [currentElement release]; [rssParser release]; [stories release]; [item release]; [currentTitle release]; [currentDate release]; [currentSummary release]; [currentLink release]; [super dealloc]; }
Теперь откройте “RootViewController.xib“. Более того удерживая нажатой кнопку <control>, перетащите пиктограмму-кубик из “RootViewController” в рационами Table View. С другой стороны шумно появится перечень с 3 составляющими, в каком надо правильно щелкнуть на настройки “newsTable“. Короче говоря, предварительно сохранитесь и спокойно прикройте Interface Builder.
Щелкнув на рационах “Build and Go“, просмотрите мало-мальски итоговый эффект. Напротив если запустить прибавление в симуляторе, а на iPhone, картина станет немного иной: совсем аппаратное обеспечивание медлительнее, и RSS-лента в EDGE станет грузиться чрезвычайно напросто длительное время. Оказалось, что тем не ниже, окончательно трудится! Но действует пока же не многие: в момент выбора составляющей в таблице ничего часто не случается (данный сценарий установлен по умолчанию). Ну что ж упрямо предлагаю самостоятельно раскрывать заметки в Safari — данное просто. А теперь слегка изменим метод:
— (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { // Навигационная логика int storyIndex = [indexPath indexAtPosition: [indexPath length] — 1]; NSString * storyLink = [[stories objectAtIndex: storyIndex] objectForKey: @”link”]; // начисто очистить гиперссылку от пробелов, символов абзаца и табуляции… storyLink = [storyLink stringByReplacingOccurrencesOfString:@" " withString:@""]; storyLink = [storyLink stringByReplacingOccurrencesOfString:@"\n" withString:@""]; storyLink = [storyLink stringByReplacingOccurrencesOfString:@" " withString:@""]; NSLog(@”link: %@”, storyLink); // самостоятельно открыть в Safari [[UIApplication sharedApplication] openURL:[NSURL URLWithString:storyLink]]; }
Теперь можнож снова щелкнуть на “Build and Go“, удостоверившись, что все упорно работает.
Естественно, полностью оригинальная заметка theappleblog.com
Стало быть источник lookapp.ru
Вы должны быть зарегистрироавны чтобы оставить комментарий.