Swift初心者がシンプルなRSSリーダーを作る。

プログラミングの基礎はVisualBasic6.0で学び、perlも少々いじってましたが、今回Swiftを使えるようになりたいと思い、本を購入して勉強しました。
流石にたった2日でマスターは出来ませんでしたが、SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応は、良い教本ですね。

そこで、Swift勉強の為に本に載っていたサンプルのコードも使いつつシンプルなRSSををリーダーを作ってみました。

目 次

  1. 参考とした記事と本
  2. 機能はシンプルで2点のみ
  3. 開発環境
  4. ソースコードDownload
  5. 全体ソース
  6. コードの追加及び修正箇所
  7. 今後、追加予定の機能

1. 参考とした記事と本

2. 機能はシンプルで2点のみ

  • RSSを取得して「タイトル」「日付」の2つをListに表示する。
  • 記事をタッチして該当のニュースをSafariViewで表示する

完成イメージ

記事一覧スクリーンショット
サファリビュースクリーンショット

   

3. 開発環境

  • iMac(Late2012)
  • macOS Catalina(10.15.7)
  • Xcode 12.4
  • Swift 5.3.2
  • 使用外部ライブラリ なし

4. ソースコードDownload

Download

5. 全体ソース

はじめに全体ソースをお見せしますが、元となるコードは、【SwiftUI】外部サイトからデータを取得する|カピ通信のコードを使用してます。

//
//  ContentView.swift
//  Simple RSS Reader
//
//  Created by Assy on 2021/09/05.
//

import SwiftUI

//RSS情報をまとめる構造体
struct Response: Codable {
    let items: [Result]
}
//記事詳細
struct Result: Codable {
    let title: String
    let link: URL
    let guid: String
    let pubDate: String
}


struct ContentView: View {
    
    //空のJSON配列を生成
    @State private var results = [Result]()
    
    //SafariViewの表示有無を管理する変数
    @State var showSafari = false
    
    var body: some View {
        NavigationView {
            List(results, id: \.guid) { item in
                
                Button(action: {
                    //SafariViewを表示する
                    showSafari.toggle()
                }) {
                    VStack(alignment: .leading) {
                        Text(item.title )      //記事タイトル
                            .font(.headline)
                        Text(item.pubDate)      //記事の日付
                    }
                }
                .sheet(isPresented: self.$showSafari, content: {
                    //記事リンクをSafariViewで表示する
                    SafariView(url: item.link)
                    //画面下部をいっぱいになるようにセーフエリア外までいっぱいになるように指定
                        .edgesIgnoringSafeArea(.bottom)
                })
            }.navigationTitle("Simple RSS Reader")
        }.onAppear(perform: loadData)           //RSSデータ読み込み処理
        
    }
    
    //RSSデータ読み込み処理
    func loadData() {
        
        //取得したいRSSを指定
        let rss_url = "https://news.yahoo.co.jp/rss/categories/it.xml"
        //指定したRSSをJSONに変換するAPIと連結して取得する
        let url: URL =  URL(string:"https://api.rss2json.com/v1/api.json?rss_url=\(rss_url)")!
        let task: URLSessionTask = URLSession.shared.dataTask(with: url, completionHandler: {(data, response, error) in
            
            //データ取得チェック
            if let data = data {
                //JSON→Responseオブジェクト変換
                let decoder = JSONDecoder()
                guard let decodedResponse = try? decoder.decode(Response.self, from: data) else {
                    return
                }
                //RSS情報をUIに適用
                DispatchQueue.main.async {
                    results = decodedResponse.items
                }
            } else {
                //データが取得できなかった場合の処理
                print("Fetch failed: \(error?.localizedDescription ?? "Unknown error")")
            }
        })
        task.resume()
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

SafariViewの部分のコードは教本(SwiftUI対応 たった2日でマスターできるiPhoneアプリ開発集中講座 Xcode 12/iOS 14対応)のコードをそのまま使用しました。

//
//  SafariView.swift
//  Simple RSS Reader
//
//  Created by Assy on 2021/09/05.
//

import SwiftUI
import SafariServices

//SFSafariViewConrollerを起動する構造体
struct SafariView: UIViewControllerRepresentable {
    
    //表示するウェブサイトのURLを受ける変数
    var url: URL
    
    //表示するViewを生成するときに実行
    func makeUIViewController(context: Context) -> SFSafariViewController {
        
        //Safariを起動
        return SFSafariViewController(url: url)
    }
    
    //Viewが更新されたときに実行
    func updateUIViewController(_ uiViewController: SFSafariViewController, context: Context) {
        //処理なし
    }
    
}

6. コードの追加及び修正箇所

元となるコードに追加したり修正した箇所は下記の通りですが、きちんと取得出来るまでに相当に時間が掛かってしまいました。
JsonDecoderまでは良かったんだけど、その後のCodable構造体に読み込む時にエラーが出ていて表示出来なかったのが一番難しかった所でしょうか。
まあ、JSONの構造からモデルを作成する箇所が間違っていたのですがね。

  1. 使用しているのはYahoo!ニュースのRSSです。(https://news.yahoo.co.jp/rss/categories/it.xml)
  2. RSS(XML)をJSONに変換するAPIを通してJSONを取得するコードを追加
  3. 取得したJSONに基づいてCodableを修正
  4. JsonDecoderでCodable構造体に読み込み取得した記事をListに表示
  5. 表示した項目一つ一つをButton化して記事をタップしたらSafariViewを開くようにコードを追加

7. 今後、追加予定の機能

勉強も兼ねて、このコードを発展させて、もう少し使えるようにしてみたいので今後追加予定の機能です。
機能追加したら、新しく記事を書きたいと思います。

  1. 下に引っ張って更新
  2. 下スクロールすると過去の記事が表示されるようにする
  3. サムネイル画像を取得し表示する
  4. タブメニューで記事の種類を選択できるようにする
XPS Previous post 0x800f0954エラーでXPSビューワーがインストール出来ない時の対処方法
Next post ソースコードをシンタックスハイライトするWordPressプラグイン Highlighting Code Block

コメントを残す