xml(rss)の取得を行い、パースする。
(タイトルが長いので本文にまたがって書きました。)
colormakerのバージョン2を申請しており、その間、次のアプリケーションの構成を練っています。
次は、いよいよ、ネットワーク通信を使ったアプリケーションを作りたいなと思っています。
ネットワーク通信だと、なんだか抽象的ですが、ようは、httpプロトコルのgetメソッドを使ってxml(rss)を取得するということです。
まずは、ポイントを書いてからプログラムをのせたいと思います。
最初のポイントですが、xml(rss)を取得する際、iPhoneのUIつまり、画面(スクリーン)を固めずに取得したいと思います。
これはいまはやりの、ajaxです。
(ajaxのjはjavascriptだが、これは作者がわかりやすいようにつけた名前であり、概念としては、UIをブロックせずに、httpプロトコル通信を行うことであります。)
また、取得するにあたって、
1:http通信を行い、xml(rss)のダウンロードを行う
2:ダウンロードしたxmlを解析し、表示を行う
の2点が重要なポイントとなってきます。
以上をふまえて、実装してみたのですが、ちょっと長いです。
(ご勘弁ください。。。)
プロジェクトの名前は、「Test」です。
/* TestAppDelegate.h */ #import "TestViewController.h" @interface TestAppDelegate : NSObject <UIApplicationDelegate> { UIWindow *window; TestViewController *testviewcontroller; NSURLConnection *RssConnection; NSMutableData *RssData; BOOL appendflg; } @property (nonatomic, retain) IBOutlet UIWindow *window; - (void)parseRSS:(NSData *)data; @end /* TestAppDelegate.m */ - (void)applicationDidFinishLaunching:(UIApplication *)application { testviewcontroller = [[TestViewController alloc] initWithStyle:UITableViewStylePlain]; NSString *feedURLString = @"http://dailynews.yahoo.co.jp/fc/rss.xml"; NSURLRequest *httpRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:feedURLString] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0 ]; RssConnection = [[NSURLConnection alloc] initWithRequest:httpRequest delegate:self]; /* 接続がうまくいかなかった場合 */ if(RssConnection == nil){ UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"エラー" message:@"接続に失敗しました。" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil ]; [alertView show]; [alertView release]; return; } [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; [window addSubview:[testviewcontroller view]]; [window makeKeyAndVisible]; } /* ヘッダー返ってきたとき */ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{ /* データの大きさを0で初期化 */ RssData = [[NSMutableData alloc] initWithData:0]; } /* コンテンツのダウンロードしたとき(完了ではない。連続的にコールされる) */ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{ /* データを追加する */ [RssData appendData:data]; } /* コンテンツのダウンロードエラー */ - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [RssConnection release]; [RssData release]; UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"エラー" message:@"接続に失敗しました。" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil ]; [alertView show]; [alertView release]; } /* コンテンツのダウンロードが完了した時 */ - (void)connectionDidFinishLoading:(NSURLConnection *)connection { [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; [self parseRSS:RssData]; [RssConnection release]; [RssData release]; } - (void)parseRSS:(NSData *)data { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; testviewcontroller.parsedData = [NSMutableArray array]; [parser setDelegate:self]; [parser parse]; [pool release]; [testviewcontroller.tableView reloadData]; } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{ if([elementName isEqualToString:@"title"]){ appendflg = YES; return; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if(appendflg == YES){ [testviewcontroller.parsedData addObject:[string stringByReplacingOccurrencesOfString:@"\n" withString:@" "]]; return; } } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { appendflg = NO; return; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { } - (void)dealloc { [RssConnection release]; [RssData release]; [window release]; [super dealloc]; } /* TestViewController.h */ #import <UIKit/UIKit.h> @interface TestViewController : UITableViewController { NSMutableArray *parsedData; } @property (nonatomic, retain) NSMutableArray *parsedData; @end /* TestViewController.m */ ・・・省略・・・ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { return [[[NSNumber alloc] initWithUnsignedInteger:[parsedData count]] integerValue]; } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } // Set up the cell... cell.textLabel.text = [parsedData objectAtIndex:indexPath.row]; return cell; } ・・・省略・・・ |
Event-Driven XML Programming Guide for Cocoa
URL Loading System
及び、サンプルコードのSeismicXMLを参考にしながら作ってみました。
SeismicXMLは、マルチスレッドを使って実装されていたのですが、シングルスレッドの方が好きなので、ならべくマルチスレッドを使わずに、実装した結果、上のようになりました。
取得先となったのは、Yahoo.co.jpで公開されているYahoo!ニュース・トピックス - トップなのですが、いざ、実行してみた結果、このような感じになりました。
今回は、時間の都合上、タイトルだけ表示するプログラムなのですが、「Yahoo!ニュース・トピックス - トップ」が、「!」を境に改行を起こしてしまっています。
xmlでは表示されない改行があるのかなーっと思い、配列に追加する時に、置換をかけているのですが、それでも解消されません。
なぜなんだろうなー?
0 コメント:
コメントを投稿