Help us understand the problem. What is going on with this article?

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

More than 3 years have passed since last update.

まえがき的な(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のリポジトリ

yonell
片手でサクサク検索できるブラウザ『Smooz』をつくっています。
https://github.com/tatsuya-yokoyama
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした