RSSReader

<img width="200" alt="ezgif.com-video-to-gif" src="https://qiita-image-store.s3.amazonaws.com/0/302540/73551d78-6d50-c59f-38f1-f920d1763cc2.gif">!

URLの取得、XML解析への理解を深めるために作成。

#ソースコード
Cellをクリックするとyahooのページへ飛ぶ

```swift:ViewController.swift
import UIKit
//XMLファイルを呼び込み（XMLParserDelegate)
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, XMLParserDelegate {
    
    
    @IBOutlet weak var tableView: UITableView!
    
    //URLを取得するメソッド文（let feedurl = URL(string"RSS名"）
    let feedUrl = URL(string: "https://news.yahoo.co.jp/pickup/rss.xml")!
    //RSSのアイテムを格納するためにfeedItemクラスを作成
    //それを格納するための配列を作成。
    var feedItems = [FeedItem]()
    
    var currentElementName : String! // RSSパース中の現在の要素名
    
    let ITEM_ELEMENT_NAME = "item"
    let TITLE_ELEMENT_NAME = "title"
    let LINK_ELEMENT_NAME   = "link"
    
    
    //セルの行数　TableViewに表示するセルの数を返却します。UITableView に表示したいセルの数を教えるためのメソッド
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.feedItems.count
    }
    
    //セルのテキストを追加　各セルを生成して返却します。
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        //セルを作成します。            セルのスタイル。
        let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.subtitle, reuseIdentifier: "Cell")
        //セルのテキストを設定
        let feedItem = self.feedItems[indexPath.row]
        cell.textLabel?.text = feedItem.title
        return cell
        
    }
    
    //セルがタッチされた時の処理
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let feedItem = self.feedItems[indexPath.row]
        //アプリケーションの中から指定されたURLを Safari で開きたい場合があります。 Swift で Safari を開くには、以下のようにプログラムで実現できます。
        UIApplication.shared.open(URL(string: feedItem.url)!, options: [:], completionHandler: nil)
    }
    
    //XMLが解析中にアイテムが実行される際のメソッド
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        self.currentElementName = nil
        if elementName == ITEM_ELEMENT_NAME {
            self.feedItems.append(FeedItem())
        } else {
            currentElementName = elementName
        }
    }
    
    //タグ以外を読み込んだ時。開始タグと終了タグでくくられたデータがあったときに実行されるメソッド<title>tesut</title> testの部分がStrigに帰ってくること
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        //feedItemsの中に空っぽの入れ物が準備できている場合の処理
        if self.feedItems.count > 0 {
            //空っぽの入れ物のなかにそれぞれの要素の文字列を入れる{
            let lastItem = self.feedItems[self.feedItems.count - 1]
            switch self.currentElementName {
            case TITLE_ELEMENT_NAME:
                //name要素を入れる
                //一番最初に取ってくるものについてはこの書き方（もしname要素内にすでに値があったら追記する）
                let tmpString = lastItem.title
                lastItem.title = (tmpString != nil) ? tmpString! + string : string
            case LINK_ELEMENT_NAME:
                //url要素を入れる
                lastItem.url = string
            default: break
            }
        }
    }
    
    // 解析中に要素の終了タグがあったときに実行されるメソッド
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        self.currentElementName = nil
    }
    
    
    // XML解析終了時に実行されるメソッド。通信が終わってデータが正常に取得できたらテーブルをリロードして表示する
    func parserDidEndDocument(_ parser: XMLParser) {
        self.tableView.reloadData()
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //ネット上のXMLを取得しXMLParaseに読み込む
        let parser: XMLParser! = XMLParser(contentsOf: feedUrl)
        //XMLをデリゲートを自分自身に指定している
        parser.delegate = self
        parser.parse()
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

class FeedItem {
    var title: String!
    var url: String!
}

```
#URL取得
URLを取得するメソッド文（let feedurl = URL(string"RSS名"）