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

# XMLModelizer (Swift 3.0)

![sample](https://github.com/aoifukuoka/XMLModelizer/raw/master/sample.gif)

## URL
[GitHub](https://github.com/aoifukuoka/XMLModelizer)
[CocoaPods](http://cocoapods.org/pods/XMLModelizer)

## インストール

```
pod "XMLModelizer"
```

## 環境
* iOS8.0以上

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

## 使用方法



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

```xml
<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の格納先のモデルを定義します。

```Swift

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になってしまうのでご注意ください。


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

```Swift
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お待ちしております！