こんにちは!クラウドナインアップスのショウです。
前回に引き続き、アプリ完成までの一部始終を解説していきたいと思います。
”「ファイナンス・経済ニュース」 アプリができるまで #1”では TableView について書きました。二回目となる今回は、RSSなどのXMLを読み込む(パースする)方法を解説していきたいと思います。
あと、リフレッシュコントロール(refreshControl)というメールやツイッターなどにある、下にスワイプすると更新される機能も付けたいと思います。
アプリ作成
手順② XMLParse
Xcodeでは[Event-driven API]という方法でXMLParseしています。
XMLの要素の読み込み毎に、以下のデリゲードメソッドが呼び出されます。
これらメソッドを用いて、XMLの中身を読み込んで行きます。
・parser:didStartElement:namespaceURI:qualifiedName:attributes:
エレメントの読み込み開始時のイベント
・parser:foundCharacters:
エレメントに挟まれた文字列要素を読み込んだ際のイベント
・parser:didEndElement:namespaceURI:qualifiedName:
エレメントの読み込み終了時のイベント
ViewController.h
前回(#1)、ViewController.hの@interfaceの末尾に
UITableViewDelegate,UITableViewDataSourceを書きました。
ここのうしろにNSXMLParserDelegateを追加で書きます。これを書かないとXMLParserは使えません。
また、XMLParserを使うための道具(nowTagStr,txtBuffer,urlTagStr)と
リフレッシュコントロール(_refreshControl)と
XMLParseで読み込んだニュースの情報を入れておくための文字列(titleString,urlString,dateString)
を追加で入れます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
@interface ViewController : UIViewController <UITableViewDelegate,UITableViewDataSource,NSXMLParserDelegate> { NSString *nowTagStr;//解析中タグ NSString *txtBuffer;//テキストバッファ NSString *urlTagStr;//URLタグ UIRefreshControl *_refreshControl;//リフレッシュコントロール } @property NSString *titleString;//ニュースタイトルの文字列 @property NSString *urlString;//ニュースURLの文字列 @property NSString *dateString;//日付の文字列 @end |
ViewController.m
viewDidLoadにリフレッシュコントロールと
起動したらまず最初にstartReloadメソッドの所へ飛ぶことを設定します。
startReloadメソッドの中にXMLParserのデータ(URL)を用意し、インスタンスを生成します。
さらにリフレッシュした時に呼び出されるrefreshメソッドを加えます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
- (void)viewDidLoad { [super viewDidLoad]; //起動したら最初にstartReloadの所へ飛ぶ [self startReload]; //リフレッシュ設定 _refreshControl = [[UIRefreshControl alloc] init]; [_refreshControl addTarget:self action:@selector(refresh) forControlEvents:UIControlEventValueChanged];//詳細はrefreshで設定 [self.tableView1 addSubview:_refreshControl]; } #pragma mark - リフレッシュコントロール -(void)startReload { //URLを指定してXMLパーサーを作る // 一旦配列の中を削除する if (self.newsArr) { [self.newsArr removeAllObjects]; } //フラグを設定して一つ目の情報を無視 titleIgnoreFlag = YES; urlIgnoreFlag = YES; dateIgnoreFlag = YES; NSURL *myURL = [NSURL URLWithString:@"http://newsbiz.yahoo.co.jp/industry/fince.rss"]; NSXMLParser *myParser = [[NSXMLParser alloc] initWithContentsOfURL:myURL]; myParser.delegate = self; //解析を開始 [myParser parse]; } -(void)refresh { NSLog(@"refresh!"); [self startReload]; } |
XMLを読み込む (XMLPaeser)
NSXMLParserはXMLデータを読み込む際に、下記のメソッドを呼び出します。
・解析開始時(parserDidStartDocument:メソッド)
・開始タグを読み込んだ時(parser didStartElement:メソッド)
・閉じタグを読み込んだ時(parser didEndElement:メソッド)
・タグ以外のテキストを読み込んだ時(parser foundCharacters:メソッド)
・解析終了時(parserDidEndDocument:メソッド)
また、NSDictionaryという辞書を作成し、読み込んだデータのタイトル・URL・日付を
それぞれ文字列に入れて辞書に格納します。その時、文字列にはforKeyという鍵を付けます。
その辞書をnewsArrという配列に格納することでセルに表示することができます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
#pragma mark XMLパーサー //XMLパース開始時のメソッド -(void)parserDidStartDocument:(NSXMLParser *)parser { //"nowTagStr"を初期化 nowTagStr = @""; } //開始タグを読み込んだ時のメソッド -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"title"]) { nowTagStr = elementName; //解析タグをelementNameに設定 txtBuffer = @""; //テキストバッファの初期化 } else if ([elementName isEqualToString:@"link"]) { nowTagStr = elementName; txtBuffer = @""; } else if ([elementName isEqualToString:@"pubDate"]) { nowTagStr = elementName; txtBuffer = @""; } } //タグ以外のテキストを読み込んだ時のメソッド -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { if ([nowTagStr isEqualToString:@"title"]) { txtBuffer = string; } else if ([nowTagStr isEqualToString:@"link"]) { txtBuffer = string; } else if ([nowTagStr isEqualToString:@"pubDate"]) { txtBuffer = string; } } //閉じタグを読み込んだ時のメソッド -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:@"title"]){ if (!titleIgnoreFlag){ //もし"titleIgnoreFlag"がNOなら //"txtBuffer"のデータを"titleString"に追加 self.titleString = txtBuffer; } titleIgnoreFlag = NO; } else if ([elementName isEqualToString:@"link"]) { if (!urlIgnoreFlag){ // urlを代入 self.urlString = txtBuffer; } urlIgnoreFlag = NO; } else if ([elementName isEqualToString:@"pubDate"]) { // 日付をちゃんと表示できるように変更する。 if (!dateIgnoreFlag) { NSDateFormatter *inputDF = [[NSDateFormatter alloc] init]; // 1."inputDF"の作成(中継役) [inputDF setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss Z"]; // 2.フォーマットの設定("txtBuffer"の表示形式と同じ) [inputDF setLocale:[[NSLocale alloc]initWithLocaleIdentifier:@"ENGLISH"]]; // 3.ロケール(地域指定)の設定(英語) NSDate *inputDate = [inputDF dateFromString:txtBuffer]; // 4."txtBuffer"を"inputDF"を介して"inputDate"に変更(文字列->日付型) [inputDF setDateFormat:@"yyyy/MM/dd/ HH:mm"]; // 5.日付を yyyy/MM/dd hh:mm:ss形式に変更 NSString *dString = [inputDF stringFromDate:inputDate]; // 6."inputDate"を"inputDF"を介して"dString"に格納(日付型->文字列) self.dateString = dString; //7."dString"を"dateString"に代入 //辞書を作成し、タイトル・URL・日付を格納 NSMutableDictionary *dic = [NSMutableDictionary dictionary]; [dic setObject:self.titleString forKey:@"title"]; [dic setObject:self.urlString forKey:@"url"]; [dic setObject:self.dateString forKey:@"date"]; [self.newsArr addObject:dic]; } dateIgnoreFlag= NO; } } //XMLパース終了時のメソッド -(void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"self.newsArr %@",self.newsArr); [self.tableView1 reloadData]; [_refreshControl endRefreshing]; } |
ビルド(実行)
ここまで出来たら一回ビルド(実行)してみましょう。
こんな感じになりました。
ニュースを表示しているセルを下にスワイプするとニュースを更新することができます。
第2回まとめ
今回はここまでです。
これでRSSなどのXMLの読み込み、refreshControlができるようになりました。
このとおりやってもうまくいかない方は、アプリ開発スクール「クラウドナインアップス」へお気軽にご相談ください。
このとおりやってもうまくいかない方は、アプリ開発スクール「クラウドナインアップス」へお気軽にご相談ください。
次回はWebViewとGitHubについて説明します。お楽しみに!
〜#3へ続く〜
コメントをどうぞ