「SwiftUI」でニュースを表示して見た!

Swift
この記事は約8分で読めます。

みなさんこんにちは!

イザナギです!

現在に至っても、コロナが世界中で流行っていますね。

なんと!日本でも、27日時点では感染者数が1387人となっており(出典:厚生労働省)感染者が増え続けているそうです。

何かしら重要なことがなければ、まだ外出しない方が良さそうです。

みなさん気をつけてくださいね。

さて、話題も変わりまして今回は久しぶりの「Swift UI」に関する話題です!

だいぶ前ですが、Swift UIを使っていたときのエラーについての記事について書いていました。

それからしばらくSwift UIは使っていなかったのですが、

しばらく経って「やっぱ気になる!」と思ったので、また使って見ました!

SwiftUIについて

おさらいですが、SwiftUIとはより少ないコードでデザインを構築できるツールです。

Xcode - SwiftUI - Apple Developer
SwiftUIでは、Swiftを利用してすべてのAppleプラットフォーム向けのユーザーインターフェイスを、革新的かつ極めてシンプルに構築することができます。

前のUIkitに比べて、比較的コードが少なく書くことができます!

利用するもの

今回利用するものは以下の通りです。

  • SwiftUI
  • NewsAPI
  • iPad(シュミュレーター)

NewsAPIについては前回も記事で紹介しましたね!

実装!

では、早速実装して見ましょう!

データの受け取りに「Codable」を利用する

「Codable」とは、簡単にいうとAPIなどで受け取ったデータ(JSONデータ)をSwiftで使いやすくするために、「データ型」に変換するプロトコルです。

簡単にいうと、Swiftで使いやすくするものですね!

例えば、NewsAPIで以下のようなデータを取ったとします。

{
  "status": "ok",
  "totalResults": 3456,
  -"articles": [
    -{
    -"source": {
      "id": null,
      "name": "Cointelegraph.com"
    },
    "author": "Cointelegraph By Marie Huillet",
    "title": "Roger Ver Apparently Unconcerned About Coronavirus",
    "description": "Roger Ver, the prominent Bitcoin Cash advocate and former CEO of Bitcoin.com,     appears to think that the world’s reaction to the COVID-19 pandemic is disproportionate",
    "url": "https://cointelegraph.com/news/roger-ver-apparently-unconcerned-about-coronavirus",
    ...
},
...
}

一例として、これを構造体で表すと以下の通りになります。

struct NewsSource: Codable {
    let status: String!
    let totalResults: Int!
    var articles: [Article]
}
struct Article: Codable{
    var id: Int?
    var author: String!
    var title: String!
    var description: String!
    var publishedAt: String!
   ・・・
}

今回は、必要なもののみ取り出しています。

このように、まずJSONの階層ごとにデータ型を決めていきます。

今回のように、必要なデータのみを書いていても大丈夫なので、

必要ないデータはCodableに入れないようにしましょう!

APIからデータを取得し、格納させる

そして、先ほど作ったCodableのなかにデータを格納していきます。

//APIを叩いてデータを取得し、構造体に格納
class GetNewsEventFetcher: ObservableObject {
  @Published var articles: [Article] = []
  let url: URL = URL(string:"ここにAPIキーを含んだURLを挿入")!
  URLSession.shared.dataTask(with: url) { data, response, error in
     guard let data = data else { return }
     let decoder: JSONDecoder = JSONDecoder()
     do {
          var searchedResult = try decoder.decode(NewsSource.self, from: data)
          DispatchQueue.main.async {
//           データを格納
             self.articles = searchedResult.articles
             print(self.articles)
          }
      } catch {
//            何かしらのエラー処理を書く          
      }
  }.resume()
}

クラスに「ObservableObject」をつけることで、変数などのプロパティの情報を管理できるようになります!

これがとても便利で!

非同期通信で、データが取得(プロパティが更新)されると通知してくれるものです。

「ObservableObject」をつけずに、SwiftUIのViewで、普通に値を取り出そうとするとエラーになると思います。

そして、自動通知させる変数の宣言の前に「@Published」をつけると、

値が変更された時に、通知されるようになります。

Viewの実装

ここで、SwiftUIによるView画面を実装していきます。

今回はあまりデザインを気にせずに、ただ表示だけを行っています。

struct ContentView: View {
//
    @ObservedObject var store = GetNewsEventFetcher()
    var body: some View{
//      リスト表示(idはdescription(記事の内容)を使用)
        List(self.store.articles, id: \.description){ res in
            VStack(alignment: .leading){
//              記事の表示
                Text(res.author)
                Text(res.title)
                Text(res.description)
                Text(res.publishedAt)
            }
//          余白を開ける
            .padding()
        }
    }
}

「@ObservedObject var store = GetNewsEventFetcher()」の部分が、通知を受け取っています。

@ObservedObject」をつけないと、通知を受け取れませんのでご注意を!

詰まったところ

SwiftUIの「List」で値を表示する時に、「id」を指定していなかったので、表示されるものが一種類だけになった。

よく、NewsAPIのJSON値を見てみるとidがないではないか!

でも「List」を使って表示するときは、ユニークなidが必要になるらしい。

なので、今回は記事の内容はかぶらないと思い「description」を採用させてもらいました。

まあ、IDをつけた方がいいとは思うのだけれど、今回は表示だけなので実装はしていないです。

完成!

完成するとこのようになると思います。

これは、キーワードを「気仙沼」にしたときのものです。

ちゃんと表示できてますね!

あとは、デザインのみ!

まとめ

今回はSwiftUIでニュースを表示させて見ました。

初めは、Codableを理解するのにちょっと苦しみました。

でも、慣れればなんとかなるもんですね!www

まだ理解できてない部分もあるので、これからも学習に励んでいきたいと思います!

それでは、今回はここで筆を置かせていただきます!

最後まで記事をご覧頂きありがとうございました!

コメント

タイトルとURLをコピーしました