RSS Readerを作成中です。そのための第一歩として、Swift版RSS Parserを作成しました。
実行環境は、MacOSX El Capitan、Xcode 7.1.1です。
概要
NSXMLParserを使ってRSS Feed(XML)をパースします。RSS Feedのitem要素をDictionaryに変換して配列に格納しています。
使い方
playgroundファイルを、GitHubから取得してXcode7でオープンください。
Consoleに以下の内容が出力されます。
http://weather.livedoor.com/forecast/rss/area/330010.xml
count: 7
13
title ---> [ 28日(土)の天気 ] 岡山 - 晴時々曇 - 最高気温13℃ - 11月28日(土)
category ---> 天気予報
...
RSSフィードを変更する場合には、108行目を修正します。
let URL = NSURL(string: "http://weather.livedoor.com/forecast/rss/area/330010.xml")
出力を変更する場合には122行のコードを修正します。
print("count: \(parser.items.count)")
for item in parser.items {
print(item.count)
for (key, value) in item {
print("\(key) ---> \(value)")
}
}
取得しているRSSフィードの内容を知りたい場合には、117行目のコメントアウトを外します。
// print(NSString(data: data!, encoding: NSUTF8StringEncoding))
実装
RSSフィード
今回処理対象にしている天気予報のRSSフィードです。
<rss version=\"2.0\" xmlns:ldWeather=\"http://weather.livedoor.com/ns/rss/2.0\">
<channel>
...
<item>
<title>[ 28日(土)の天気 ] 岡山 - 晴時々曇 - 最高気温13℃ - 11月28日(土)</title>
<link>http://weather.livedoor.com/area/forecast/330010?r=rss20151128</link>
<category>天気予報</category>
<day>Saturday</day>
<image>
<title>晴時々曇</title>
<link>http://weather.livedoor.com/area/forecast/330010?r=rss20151128</link>
<url>http://weather.livedoor.com/img/icon/2.gif</url>
<width>50</width>
<height>31</height>
</image>
<description>28日(土)の天気は晴時々曇、最高気温は13℃ 最低気温は3℃でしょう。</description>
<pubDate>Wed, 25 Nov 2015 17:00:00 +0900</pubDate>
</item>
...
</channel>
これを、辞書の配列データに変換します。item以下を辞書に変換し配列に格納します。
var items = Array<Dictionary<String, String>>()
辞書のデータイメージです。image要素の子要素は、キーにimage_というprefixを付け、辞書に追加しています。
{
"title":"[ 28日(土)の天気 ] 岡山 - 晴時々曇 - 最高気温13℃ - 11月28日(土)",
...,
"image_title":"晴時々曇",
"image_link":"http://weather.livedoor.com/area/forecast/330010?r=rss20151128",
...
}
RSSフィード取得
NSURLSession.dataTaskWithRequestを使っています。
使い方は、iOS - NSURLSession経由でHTTP requestを投げるサンプルコード Swift版 - Qiitaを参考にしました。また、XCode7での変更点について、Swift2.0 - Xcode 7.1で気がついたPlaygroundの変更点 - Qiitaを参考にしました。
let URL = NSURL(string: "http://weather.livedoor.com/forecast/rss/area/330010.xml")
let config = NSURLSessionConfiguration.defaultSessionConfiguration()
let session = NSURLSession(configuration: config)
let request = NSURLRequest(URL: URL!)
let task = session.dataTaskWithRequest(request, completionHandler: {
(data, resp, err) in
// 取得したデータの処理を記述する
})
task.resume()
XMLパース
NSXMLParserを使っています。NSXMLParserはSAXベースのXML Parserです。NSXMLParserDelegateのメソッドをオーバーライドして必要なデータを処理します。
今回は、Element開始/終了とテキストを処理しました。
オーバーライドしたメソッドです。
処理 | 関数 |
---|---|
Element開始 | parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) |
Element終了 | parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) |
Text | parser(parser: NSXMLParser, foundCharacters string: String) |
処理内容です。
処理 | 処理内容 |
---|---|
Element開始 | 辞書を作成します。 |
Element終了 | 辞書のキー(要素名)にテキストを追加します。item要素の場合には、現在処理中の辞書を配列に追加します。 |
Text | テキストを結合します。テキスト要素は、複数回呼ばれるので文字列結合する必要があります。 |
image要素は、要素名(image_)をキーに追加しています。この処理をするためにimage要素処理中フラグ(processingImage)を使っています。