search
LoginSignup
268

More than 5 years have passed since last update.

posted at

updated at

[Swift]APIで取得したJSONをswiftyJSONでパースして、天気情報をUITableViewで表示。お天気アプリを作ってみる。

まえがき的な(2015年の年始あたりに書いた記事です)

Swiftの勉強がてら、色々調べながら簡単なアプリを作ってみました。
どうせなら作るだけじゃなくて、これから同じようなことする人の役に立つような記事にしようと思って書いてみました。
Swiftでごくごく簡単なアプリを作ったことある人向けを想定していて、ざっくり説明になっています。
不明点あった場合、コメントいただけれは補足追加します(^O^)

swift2対応しました(2015年12月5日)

swift2向けに更新したのと、当時のスキルでは仕方なかった微妙な実装方法も改修しています。
Xcodeは7.1でiOS9.1向けに作ってます。あと、pullして更新する項目を削除しちゃいました。

swift3対応

@shinsakujazzbass sanに、swift3対応してくださった記事を投稿していただきました。ご参照ください。
http://qiita.com/shinsakujazzbass/items/b71ad65571a05645a44c#_reference-64f1b5cd9fa96a495b8a

何を作るんだっけ

OpenWeatherMap APIを叩いて取得したJSONを、swiftyJSONを使ってパースして、UITableViewでテーブル表示。
おまけに、テーブルをタップで詳細を表示もできるようにします。
完成すると、こんなかんじです。

8.png

作ってみる

1.プロジェクト作成

Single View Applicationで適当なプロジェクト名で作成。ここではweatherInfoとして作成。

2.UITableViewでテーブル作成して画面遷移

キャプチャのように、Object LibraryからTavble View Controllerを追加。

image

キャプチャ通りに操作。Action Segueはなんでも良いですがshowを選択。
Action Segueは画面遷移時にどのように画面を切り替えるかの設定。
image

キャプチャ通りに操作(が続いてすみませんw)
image

キャプチャ通りに操作
image

ViewController.swiftを以下のように修正。
ただし、UILabelをViewController上ninfoLabelという名で設定しています。
設定の仕方がわからないでこれにチャレンジしてる人がいたら、ちょっと背伸びしすぎかもです。

ViewController.swift
import UIKit
class ViewController: UIViewController {

    var info: String?
    @IBOutlet weak var infoLabel: UILabel!
    override func viewDidLoad() {
        super.viewDidLoad()
        self.infoLabel?.text = self.info
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

その後、先ほど作成したTableViewController.swiftを以下を参考に修正。

TableViewController.swift
import UIKit

class TableViewController: UITableViewController {

    // APIのURLを定義
    // APPID=XXXは先程取得したAPI KEYを各自設定してください
    var urlString = "http://api.openweathermap.org/data/2.5/forecast?units=metric&q=Tokyo&APPID={各自設定}"
    var cellItems = NSMutableArray()
    let cellNum = 10
    var selectedInfo : String?

    override func viewDidLoad() {
        super.viewDidLoad()
        makeTableData()
    }

    // セクション数を設定
    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }
    // 1セクションあたりの行数を設定
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.cellNum
    }

    // コメントアウトされてるのをはずす & cellにテスト表示をつっこむ
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
        if self.cellItems.count > 0 {
            cell.textLabel?.text = self.cellItems[indexPath.row] as? String
        }
        return cell
    }
    // 継承時は書かれていない。メソッドを追加。
    // テーブルのcellを選択した時に呼ばれる関数。
    // その中で先ほど作成したsegueを呼び出して画面遷移させる

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)
        self.selectedInfo = self.cellItems[indexPath.row] as! String
        performSegueWithIdentifier("toDetail", sender: nil)
    }
    // segueで遷移するときに、行われる前処理
    // 今選択されたcellの情報を遷移先の画面に渡す
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if (segue.identifier == "toDetail") {
            let viewController : ViewController = segue.destinationViewController as! ViewController
            viewController.info = self.selectedInfo
        }
    }
    // APIをたたいて、配列に保存する
    // 非同期でAPIを叩いている
    func makeTableData() {
        let url = NSURL(string: self.urlString)!
        let task = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {data, response, error in
            // リソースの取得が終わると、ここに書いた処理が実行される
            let json = JSON(data: data!)
            // 各セルに情報を突っ込む
            for var i = 0; i < self.cellNum; i++ {
                let dt_txt = json["list"][i]["dt_txt"]
                let weatherMain = json["list"][i]["weather"][0]["main"]
                let weatherDescription = json["list"][i]["weather"][0]["description"]
                let info = "\(dt_txt), \(weatherMain), \(weatherDescription)"
                print(info)
                self.cellItems[i] = info
            }
            self.tableView.reloadData()
        })
        task.resume()
    }
}

これで一応完成したかと!!

githubに上がってます

cloneしたい場合は↓からどぞ。
githubのリポジトリ

参考にしたサイト

[2015/1/7(水)追記]改修版を作りました

少し改修したものを作成しました。
ただしswift2に対応してないです(´;ω;`)(2015/12/6追記)

改修点

  • ViewControllerをスリム化
  • UIをリッチに
  • とりあえず動く状態なのでコードは汚いです(^_^;)

キャプチャ

version3.png

またまたgithubにあげてあります

githubのリポジトリ

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
What you can do with signing up
268