19
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

[iOS] RSS, XMLをパースしてモデルへ格納するライブラリを公開しました。(Swift, Xpath)

Posted at

XMLModelizer (Swift 3.0)

sample

URL

GitHub
CocoaPods

インストール

pod "XMLModelizer"

環境

  • iOS8.0以上

説明

SwiftでXMLをパースするライブラリはたくさんあったのですが、取得した値をモデルに格納するところまでカバーしているライブラリは探したところ見つけられなかったので、今回作成しました。

使用方法

以下のようなRSSから、title, link, content:media, category, pubDateの値をプロパティとして持ったモデルのインスタンスを要素分だけ取得したいとします。

<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:media="http://search.yahoo.com/mrss/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:nyt="http://www.nytimes.com/namespaces/rss/2.0" version="2.0">
    <channel>
        <item>
            <title>
                Xi Jinping May Delay Picking China’s Next Leader, Stoking Speculation
            </title>
            <link>
                http://www.nytimes.com/2016/10/05/world/asia/china-president-xi-jinping-successor.html?partner=rss&emc=rss
            </link>
            <guid isPermaLink="true">
                http://www.nytimes.com/2016/10/05/world/asia/china-president-xi-jinping-successor.html
            </guid>
            <atom:link rel="standout" href="http://www.nytimes.com/2016/10/05/world/asia/china-president-xi-jinping-successor.html?partner=rss&emc=rss"/>
            <media:content url="https://static01.nyt.com/images/2016/10/03/world/04CHINA-XI-web1/04CHINA-XI-web1-moth.jpg" medium="image" height="151" width="151"/>
            <media:description>
                President Xi Jinping of China during a ceremony observing Martyrs’ Day, a holiday that memorializes Chinese who died in battle against foreign powers, at Tiananmen Square in Beijing last week.
            </media:description>
            <media:credit>Mark Schiefelbein/Associated Press</media:credit>
            <description>
                The apparent plan by the Chinese president has unsettled the party elite and created uncertainty over whether Mr. Xi will try to stay in power beyond the usual two terms.
            </description>
            <dc:creator>CHRIS BUCKLEY</dc:creator>
            <pubDate>Tue, 04 Oct 2016 23:59:10 GMT</pubDate>
            <category domain="http://www.nytimes.com/namespaces/keywords/nyt_per">Xi Jinping</category>
            <category domain="http://www.nytimes.com/namespaces/keywords/nyt_org_all">Communist Party of China</category>
            <category domain="http://www.nytimes.com/namespaces/keywords/nyt_geo">China</category>
            <category domain="http://www.nytimes.com/namespaces/keywords/des">Appointments and Executive Changes</category>
            <category domain="http://www.nytimes.com/namespaces/keywords/nyt_per">Li Keqiang</category>
            <category domain="http://www.nytimes.com/namespaces/keywords/nyt_org_all">
                Politburo Standing Committee of the Communist Party of China
            </category>
        </item>
        <item>...

まず、下図のようにXMLの格納先のモデルを定義します。


import XMLModelizer

class NYTimesArticle: XMLModelizerModel {
    
    var title: [String]!
    var link: [String]!
    var media: [String]!
    var category: [String]!
    var pubDate: [String]!
    
    override class func xmlModelizerXpathKeyMap() -> [String:String] {
        return [
            "title":"//item/title",
            "link":"//item/link",
            "media":"//item/media:content/@url",
            "category":"//item/category",
            "pubDate":"//item/pubDate",
        ]
    }
}

XMLModelizerModel を継承した、格納先のモデルのクラス(今回はNYTimesArticleとします)を作成し、プロパティをArray<String>型で宣言します。配列で宣言しているのは上のcategoryのように複数要素がある場合があるからです。
次にxmlModelizerXpathKeyMapをオーバーライドして先ほど宣言したプロパティの値をkey、XML上のその要素を指すxpathをvalueとしたDectionaryを返すようにします。
ここでxpathを間違うとその要素の値がnilになってしまうのでご注意ください。

これだけで準備完了です!あとは以下のように、

import XMLModelizer
// open static func modelize(modelClass: XMLModelizerModel.Type, urlString: String) -> [AnyObject]
let nytimesArticles: Array<NYTimesArticle> = XMLModelizer.modelize(NYTimesArticle.self, "http://rss.nytimes.com/services/xml/rss/nyt/World.xml")

let article: NYTimesArticle = nytimesArticles.first
print(article.title.first) // "Xi Jinping May Delay Picking China’s Next Leader, Stoking Speculation"
print(article.category[1])// "Communist Party of China"

XMLModelizerのクラス関数 modelizeを使って第一引数に先ほど定義したNYTimesArticleのクラスを渡し、第二引数にXMLのURLを渡すだけで、NYTimesArticleのインスタンスが item分だけ作成され、格納されて返ってきます!

注意

もし Xcode8で
“Use Legacy Swift Language Version” (SWIFT_VERSION) is required to be configured correctly for targets which use Swift. Use the [Edit > Convert > To Current Swift Syntax…] menu to choose a Swift version or use the Build Settings editor to configure the build setting directly.
のようなエラーが返ってきたら、PodsプロジェクトのXMLModelizerのinfo.plist内の“Use Legacy Swift Language Version”をNoに設定してください。

終わりに

かなり簡単にRSSを扱うことができるようになっているので、オススメです!
コメント、PRお待ちしております!

19
17
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?