以前の、Swiftで作成したRSSリーダーの記事が好評でしたがSwiftのバージョンもあがって古くなったので作り直しました。
RSSリーダーはTableViewを使いますし、データの通信もあるので、サンプルとしては手頃です。
今回はシンプルにYahoo!トピックスの見出しのみを表示して、内容はSafariに飛ばして表示するようにしています。
ストーリーボード
まずはXcodeを立ちあげて、Single View Applicationから作成します。
言語はもちろんSwiftです。
Main.storyboardのViewの上にTableViewを配置します。
TableViewを右クリックしてdataSourceとdelegateをViewControllerにつなげておきます。
また ViewController.swift に Outlet で紐付けます。
class ViewController: UIViewController { @IBOutlet weak var tableView: UITableView!
ViewController.swiftの実装
ViewControllerにはUITableViewDelegate、UITableViewDataSourceに加えてXMLParserDelegateプロトコルも適合します。XMLParserはSwift標準ライブラリのXMLパーサーです。
class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, XMLParserDelegate {
RSSのURLを指定します。今回はソースに直書きです。
let feedUrl = URL(string: "https://news.yahoo.co.jp/pickup/rss.xml")!
RSSのitemを格納するためにFeedItemクラスを用意します。
またそれらを配列に保持しておきます。
var feedItems = [FeedItem]()
class FeedItem { var title: String! var url: String! }
あとは表示用のUITableViewDelegateプロトコルとRSSパース用のXMLParserDelegateプロトコロのメソッドを適切に実装していくだけです。
絶対に挫折しないiPhoneアプリ開発「超」入門 増補第6版【Swift 4 & iOS 11】完全対応 (Informatics&IDEA)
- 作者: 高橋京介
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2017/11/22
- メディア: 単行本
- この商品を含むブログを見る
ソースコード
import UIKit class ViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, XMLParserDelegate { @IBOutlet weak var tableView: UITableView! let feedUrl = URL(string: "https://news.yahoo.co.jp/pickup/rss.xml")! var feedItems = [FeedItem]() var currentElementName : String! // RSSパース中の現在の要素名 let ITEM_ELEMENT_NAME = "item" let TITLE_ELEMENT_NAME = "title" let LINK_ELEMENT_NAME = "link" 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] UIApplication.shared.open(URL(string: feedItem.url)!, options: [:], completionHandler: nil) } 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 } } func parser(_ parser: XMLParser, foundCharacters string: String) { if self.feedItems.count > 0 { let lastItem = self.feedItems[self.feedItems.count - 1] switch self.currentElementName { case TITLE_ELEMENT_NAME: let tmpString = lastItem.title lastItem.title = (tmpString != nil) ? tmpString! + string : string case LINK_ELEMENT_NAME: lastItem.url = string default: break } } } func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) { self.currentElementName = nil } func parserDidEndDocument(_ parser: XMLParser) { self.tableView.reloadData() } override func viewDidLoad() { super.viewDidLoad() let parser: XMLParser! = XMLParser(contentsOf: feedUrl) 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! }