SwiftでXMLParseをしてアプリを作ろう

# 初めに
今回作るアプリは[名言API](https://meigen.doodlenote.net/)を使って、XML解析をし、ランダムに名言をラベル上に表示するという簡素なアプリです。
XML解析は、JSON解析と比べ少し難しいところがあるので、XML解析の入門としてはぴったりかなと思います。
完成形はこんな感じです。

![スクリーンショット 2021-09-02 16.19.47.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/9dbcc466-7c98-f71a-0e73-3a0d35b0ee99.png)

では、始めていきます。

## UIの設計
![スクリーンショット 2021-09-02 16.20.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/e2ba900d-e466-893d-a3fe-782c869b3688.png)

ViewControllerを作り、@IBOutlet接続していきます。

```swift:ViewController.swift
import UIKit

class ViewController: UIViewController{
    
    @IBOutlet weak var meigenLabel: UILabel!
}
```

## APIの取得
APIの取得をしていきたいと思います。
[名言API](https://meigen.doodlenote.net/)を使います。

そしてこのようにAPIを叩くと、XMLDataデータを返してくれます。
![スクリーンショット 2021-09-02 16.27.08.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/2090a40d-b3a2-dd88-3f2f-cc23dfeefa87.png)

そしてXcodeの設定としてhttp通信を許可するために、
Info.plistでこのような設定を行っていきます。
![スクリーンショット 2021-09-02 16.28.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/325764/1f778ce8-f8f5-548d-1b22-52ff7088088c.png)

## ViewController
いよいよXML解析を行っていきます。

```swift:ViewController.swift
import UIKit

class FeedItem {
    var meigen = ""
    var auther = ""
}

class ViewController: UIViewController{
    
    @IBOutlet weak var meigenLabel: UILabel!
    
    var parser = XMLParser()
    var feedItem = [FeedItem]()
    
    //nilを許容するから
    var currentElementName:String!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
    
        getXMLData()
 
        parser.delegate = self
        parser.parse()
    }
    
    func getXMLData(){
        //XML解析を行う
        let urlString = "http://meigen.doodlenote.net/api?c=1"
        
        if let url = URL(string: urlString){
            parser = XMLParser(contentsOf: url)!
        }
    }
}

extension ViewController:XMLParserDelegate{
    //デバックをしながら、処理の順番を調べると良い
    //要素解析の開始
    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        currentElementName = nil
        //①elementName = response
        if elementName == "data" {
            
            self.feedItem.append(FeedItem())
        }else{
            currentElementName = elementName
        }
    }
    
    //要素内の値の取得
    func parser(_ parser: XMLParser, foundCharacters string: String) {
        
        if self.feedItem.count > 0 {
            //meigenとautherを処理していく
            let lastItem = self.feedItem[self.feedItem.count - 1]
            
            switch self.currentElementName {
            case "meigen":
                //キー値が入る
                lastItem.meigen = string
            case "auther":
                lastItem.auther = string
                
                meigenLabel.text = lastItem.meigen + "\n" + lastItem.auther
            default:
                //②data
                break
            }          
        }
    }
    
    //要素の終了時
    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        currentElementName = nil
    }
}
```

# 終わりに
これでデータを解析することが出来ました。
コード内でデバックをしながら、どのような順番で解析が行われているのかを調べるとより理解が深まるかと思います。

完成形は[こちら](https://github.com/matushinn/DiagnosticMaker)にも載せています。
指摘がありましたら、コメントよろしくお願いします。