12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SwiftでAPIを叩いてQiita記事をTableViewに表示しよう!

12
Last updated at Posted at 2019-10-21

この記事について

 この記事は、Swiftを勉強していて「アプリの幅を広げたい!」「APIとか叩いて多くの情報を扱いたい!」という人に向けての記事です。 

もくじ

  1. やること
  2. 完成予想図
  3. ViewController -API叩いて情報取得-
  4. ViewController -tableViewに表示-
  5. おわりに

1. やること

 APIを利用するときは、 AlamofireやSwiftyJSONなどのライブラリを用いたり、Codableを使用することが多いですが、今回はAPIを叩いてJson型の情報を取得後Jsonをパースして表示するところまでやります。
 
 取得する情報としては、僕がSwiftを勉強するときにお世話になったまっすーさんのQiita記事のタイトルにします。

2. 完成予想図

スクリーンショット 2019-10-21 15.18.26.png

3. ViewController -API叩いて情報取得-

 APIを叩いて情報を取得し、それをパースしてタイトルだけ抜き出し配列に保存することを、getQiitaTitle() としました。

ViewController
func getQiitaTitle() {
        
        
        // (A) リクエストURL指定
        let url: URL = URL(string: "https://qiita.com/api/v2/items?page=1&query=user%3Amasuhara")!
        
        // (B) URLSessionを用いてリクエスト
        let task: URLSessionTask = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
            
            do {
                // (C) JSONに変換するためのメソッド
                let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]
                // (D) Any型の配列に変換したものを、[String: Any]の辞書型にダウンキャスト
                let articles = json.map { (article) -> [String: Any] in
                    return article as! [String: Any]
                }
                
                // (E) 記事の総数をcountと定義する
                let count = articles.count
                
                // (F) for文で各記事のtitleを抜き出し、titleArray配列に追加
                for i in 0...count-1 {
                    let title = articles[i]["title"] as! String
                    self.titleArray.append(title)
                }
                
                // (G) TableView更新
                DispatchQueue.main.sync {
                    self.tableView.reloadData()
                }
                
            }
            catch {
                print(error)
            }
        })
       
        task.resume()
        
    }

一つずつ見てきます。

(A)  

ViewController
        // (A) リクエストURL指定
        let url: URL = URL(string: "https://qiita.com/api/v2/items?page=1&query=user%3Amasuhara")!

 まず、QiitaAPIのドキュメントを参考にして、取得したいデータをURLで指定します。URL指定する際、いくつかの文字はエンコードする必要がありますので、この記事を読んでみてください!

(B)

ViewController
        // (B) URLSessionを用いてリクエスト
        let task: URLSessionTask = URLSession.shared.dataTask(with: url, completionHandler: {data, response, error in
            
            do {
            
          
            }
            catch {
                print(error)
            }
        })

 URLで指定したデータをリクエストします。HTTPからはじまるURLや、HTTPSからはじまるURLを、ブラウザ上で叩いて呼び出すことを「リクエスト」、リクエストを受けたサーバがそれをもとに返すデータのことを「レスポンス」といいます。do-catch文を用いて分岐させています。

(C)

ViewController
 // (C) JSONに変換するためのメソッド
    let json = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.allowFragments) as! [Any]

 レスポンスをJsonに変換するためのメソッドを実行したあと、パースしてAny型の配列にダウンキャストします。

(D)

ViewCotroller
 // (D) Any型の配列に変換したものを、[String: Any]の辞書型にダウンキャスト
    let articles = json.map { (article) -> [String: Any] in
       return article as! [String: Any]
    }

 Any型にしたものを、[String:Any]の辞書型配列にして、KeyとValueが対応するようにします。これをすることによって、得たいデータ(今回であればtitle)を、Keyを指定することによって得ることができます。

(E)

ViewController
  // (E) 記事の総数をcountと定義する
    let count = articles.count

 各記事のタイトルを、for文を用いて取得したいので、前記事の総数をcountと定義します。

(F)

ViewController
// (F) for文で各記事のtitleを抜き出し、titleArray配列に追加
  for i in 0...count-1 {
     let title = articles[i]["title"] as! String
     self.titleArray.append(title)
   }

 For文を用いて、各記事の”title"キーを指定してタイトルの情報を取得し、これはAny型なのでString型にダウンキャストします。それを、事前に定義したString型の空配列titleArrayに追加していきます。

(G) 

ViewController
   // (G) TableView更新
  DispatchQueue.main.sync {
      self.tableView.reloadData()
  }

 ここまでで完了かと思いきや、それだけだとtableViewに何も表示されません。これは同期処理や非同期処理などの扱いになり、やや難なのでここでは省きます。ここでは、この記事を参考にしてtableViewの更新を行いました。

4. ViewController -tableViewに表示-

 tableViewのDataSourceメソッドは以下の通りです。

ViewCotroller
  func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        //cellの数
        return titleArray.count
        
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
        //titleArayはAny型の配列なのでString型にダウンキャストする
        cell.textLabel?.text = (titleArray[indexPath.row] )
       
        return cell
    }

4. おわりに

 WebAPIを使えば、アプリの幅が圧倒的に広がります。(WetherAPIを用いて天気情報を取得したり、じゃらんAPIを使えば宿泊情報をアプリに組み込めたり......。)
実際使用するときは、Codableやライブラリを使ったほうが、扱いやすいと思われます。

以下の記事はQiitaの記事をCodableを使用してTableViewに表示する方法です。

また、作成したQiitaAPIのサンプルプロジェクトは以下のGithubページからクローンできます。

12
16
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
12
16

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?