SwiftにはXMLParserと言う便利なパーサが用意されている。
これを使うとXMLをパースしてくれるので、RSSフィードをパースして簡単なニュースリーダー(iPhoneアプリ)が作れる。
試しにXcodeを使ってiPhoneアプリを開発しているのだが1つ困った問題が生じた。
日付のフォーマットが異なるのだ。
この問題を解決するためのコードを書いたのでご紹介したい。
[toc]RSSのバージョンによる違い
RSSの時間フォーマットが複数ある。
以下の記事はPHPの話だが、詳しく述べられている。
[RSS 2.0]のときは「pubDate」が。[RSS 1.0]のときは「dc:date」が使われています。
なぜ2つの形式があるのだろうか。
開発者としては1つに統一して欲しいと思うのだが、、、。
確かに複数のサイトのXMLファイルやRDFファイル(RSS用のファイル)を見てみるとサイトによって日付・時間の形式がバラバラである。
ニュース記事を取得するサイトが1つであれば、そのサイトのXMLを見てフォーマットを合わせれば良い。
しかし複数のサイトから記事を集める場合には、RSS2.0、RSS1.0両方に対応するのがベストだろう。
- RSS2.0の場合
pubDateの中に以下のフォーマットで格納されている。
Tue, 16 Aug 2016 15:27:33 +0000
- RSS1.0の場合
dc:dateの中に以下のフォーマットで格納されている。
2020-05-15T15:00:00+09:00
RSS2.0,1.0に対応したコード
RSS2.0、RSS1.0のフォーマットを読み取るために以下の関数を作成した。
var date: Date = Date() func convert_pubdate_date(currentString: String) { let dateFormatter = DateFormatter() dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale dateFormatter.dateFormat = "E, d MMM yyyy HH:mm:ss Z" if let date = dateFormatter.date(from: currentString) { self.date = date } } func convert_dcdate_date(currentString: String){ let dateFormatter = DateFormatter() dateFormatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ" if let date = dateFormatter.date(from: currentString){ self.date = date } }
パースしている中でそれぞれのタグが見つかったら作った関数を実行してあげれば良い。
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { switch elementName { case "pubDate": self.item?.convert_pubdate_date(currentString: currentstring) case "dc:date": self.item?.convert_dcdate_date(currentString: currentstring) default: break } }
RSSと言うのは面倒な仕様ですね。