LoginSignup
0
1

More than 1 year has passed since last update.

SwiftでNews APIを使ってみた

Last updated at Posted at 2021-09-01

はじめに

SwiftでNews APIを使ってニュースアプリを作ってみたいと思います。
初心者にもわかりやすく、AutoLayoutの設定、デザインパターン、コードの可読性もしっかり守っているので、APIの入門記事としてはぴったりかなと。
では始めていきます。ぜひ最後までご覧ください。

UIの設計

このように配置していきます。

スクリーンショット 2021-09-01 20.39.33.png
NewsListTableViewControllerからDetailViewControllerまでのsegueのidentifierに"toWeb"とつけてください。

ArticleTableViewCellを作り、IBOutlet接続します。

ArticleTableViewCell.swift
import Foundation
import UIKit

class ArticleTableViewCell: UITableViewCell {

    @IBOutlet weak var titleLabel: UILabel!
    @IBOutlet weak var descriptionLabel: UILabel!
    @IBOutlet weak var urlImageView: UIImageView!

}

全体設計

UIができた後に、今回のアプリの設計を行なっていく。
スクリーンショット 2021-09-01 20.57.52.png

スクリーンショット 2021-09-01 20.56.00.png

APIの取得

まず、APIの取得からやっていきたいと思います。
NewsAPIを使います。
操作は以下。

スクリーンショット 2021-09-01 21.00.05.png

ログインをする、またアカウントがない場合は新規アカウント登録を行う。
それができたら、ここでAPIKeyを取得する。

スクリーンショット 2021-09-01 21.00.58.png

そしてこのようにAPIを叩くと、JSONデータを変換してくれます。

スクリーンショット 2021-09-01 21.05.36.png
これらのデータをうまく使い今回はアプリを作成していきます。

Webservice

今回のAPIにおいてのロジックを管理するWebserviceを書いていきます。

Webservice.swift
import Foundation

class Webservice {

    func getArticles(with urlString:String,completion:@escaping ([Article]?) -> ()){
        if let url = URL(string: urlString) {

            let session = URLSession(configuration: .default)

            let task = session.dataTask(with: url) { data, response, error in
                if error != nil {
                    print(error!)

                    completion(nil)
                }

                if let safeData = data {
                    // print(response)
                    let decoder = JSONDecoder()
                    do {
                        let decodedData = try decoder.decode(ArticleList.self, from: safeData)

                        completion(decodedData.articles)
                        //プリントをしながら中身を確認する
                        //print(decodedData.articles[0].description)

                    } catch  {
                        print(String(describing: error))

                    }
                }
            }

            task.resume()
        }
    }
}


Article

レスポンスしたデータをデコードするためのArticleを作成していきます。

Article.swift
import Foundation

struct ArticleList: Codable {
    let articles: [Article]
}

struct Article: Codable{
    let title:String
    let description:String
    let urlToImage:String
    let url:String
}

NewsListTableViewController

最後に取得したデータをViewに反映させる、またUITableViewの操作のためにViewControllerを作っていきます。
その前に画像のキャッシュのために便利なSDWebImageというライブラリを使いたいと思います。
SDWebImageの詳しい説明、導入の仕方などはこれらの記事を見るとわかると思います。

NewsListTableViewController
import Foundation
import UIKit
import SDWebImage

class NewsListTableViewViewController: UITableViewController{

    fileprivate var articles: [Article] = []

    var urlArticle = ""

    override func viewDidLoad() {
        super.viewDidLoad()

        setup()
    }

    private func setup(){

        //ここにAPIKeyを挿入する
        let urlString =  "https://newsapi.org/v2/top-headlines?country=us&apiKey=[APIKey]"

        Webservice().getArticles(with: urlString,completion: { (articles) in
            guard let data = articles else{
                return
            }
            self.articles = data

            print(articles![0].title)
            print(articles![0].description)
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        })

    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        guard let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as? ArticleTableViewCell else {
            fatalError("ArticleTableViewCell not found")
        }
         cell.titleLabel.text = articles[indexPath.row].title
         cell.descriptionLabel.text = articles[indexPath.row].description

        cell.urlImageView.sd_setImage(with: URL(string: articles[indexPath.row].urlToImage), completed: nil)

        return cell
    }


    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return articles.count 
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.urlArticle = articles[indexPath.row].url

        self.performSegue(withIdentifier: "toWeb", sender: nil)

    }
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "toWeb" {
            let detailVC = segue.destination as! DetailViewController
            detailVC.urlString = self.urlArticle
        }
    }
}


そして最後はクリックした記事を閲覧させるためにWKWebViewを使っていきたいと思います。

DetailViewController
import UIKit
import WebKit

class DetailViewController: UIViewController , WKUIDelegate{

    var webView: WKWebView!

    var urlString = ""

    override func loadView() {
        let webConfiguration = WKWebViewConfiguration()
        webView = WKWebView(frame: .zero, configuration: webConfiguration)
        webView.uiDelegate = self
        view = webView
    }
    override func viewDidLoad() {
        super.viewDidLoad()

        let myURL = URL(string:urlString)
        let myRequest = URLRequest(url: myURL!)
        webView.load(myRequest)
    }
}

WKWebViewの処理はWKWebViewのドキュメントを確認しながら学んでください。

完成形はこちらを参照してください。
指摘点がありましたら、コメントでもよろしくお願いします。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1