AlmofireとSwiftyJSONで天気アプリ

(記録用)

環境

  • Xcode8.2.1
  • Swift3.0.2

天気API

つくる

1.プロジェクト作成
Single View Applicationで適当なプロジェクトを作る。 一回、閉じる

2.CarthageでAlmofireとSwiftyJSON入れる
Carthageのインストール
CartFileにAlamofireとSwiftyJSONを追加

github "Alamofire/Alamofire"
github "SwiftyJSON/SwiftyJSON"

追加したらcarthage update --platform iOS --no-use-binariesをする
(--no-use-binariesをしないとSwiftyJSONがエラーでうごいてくれない)
ここで2〜3分待つので気長に待つ
終わったら、プロジェクトを開く

3.ライブラリを追加
プロジェクトファイル(左バーの上の青いやつ)のgeneralタブにある「Linked Frameworks and Library」の+ボタンを押す
Frameworksの選択画面が出ますが、出てるのは無視で、「Add Other...」を押す
Carthage/Build/iOSの中にあるAlamofire.framewarkSwiftyJSON.frameworkを選択する

追加できたら、Build Phasesタブで左上の+ボタンの「New Run Script Phase」をして、リストの下に「Run Script」ができるので
Shell

/usr/local/bin/carthage copy-frameworks

input Filesの+ボタン

$(SRCROOT)/Carthage/Build/iOS/Alamofire.framework
$(SRCROOT)/Carthage/Build/iOS/SwiftyJSON.framework

これでプロジェクトにライブラリを追加できる

4.実装
今回は、Viewの名前をWeatherViewControllerとします。(以後、ViewComtrollerと言う)
最初からあるViewController.swiftを消して、WeatherTableViewController.swiftを作成します。

  1. ViewControllerのStoryboard
    StoryboardのTable View Controllerを選択して、Custom ClassをWeatherViewControllerにします。
    EditorタブよりEmbed InからNavigation Controllerを選択します。
    (Navigator ControllerをIs Initial View Controllerにしときましょう)

  2. ViewControllerのコード(土台作成)

import UIKit

class WeatherViewController: UITableViewController {

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

ここに、AlamofireとSwiftyJSONをインポート

import UIKit
import Alamofire
import SwiftyJSON
  1. ViewControllerのコード(Alamofire編)
    次は、AlamofireでAPIを取得します。 取得する処理はgetWeatherメソッドで定義していきます。
func getWeather() {

}

openWeatherMapへリクエストを飛ばします。

func getweather() {
       //        APPID={取得したやつ}
    Alamofire.request("http://api.openweathermap.org/data/2.5/forecast?q=Machida&mode=json&APPID=")
}

標準でURLのみのときはGETになっています。

func getWeather() {
       //        APPID={取得したやつ}
    Alamofire.request("http://api.openweathermap.org/data/2.5/forecast?q=Tokyo&mode=json&APPID=").responseJSON { response in
            switch response.result {
            case .success(let value):
                // ここに書いていく
            case .failure(let error):
                print(error)
            }
        }

}

(↑一応、エラーも見たいのでSuccessかFailtureの書いてます。) ここまで書いたら、上のviewDidLoadgetweatherメソッドを書いときます。

override func viewDidLoad() {
        super.viewDidLoad()

        getWeather()
    }
  1. ViewControllerのコード(SwiftyJSON編)
    上で取得したJSONをSwiftyJSONを使って変換してデータにします。
    特に考えもしないforで回しました。
func getWeather() {
       //        APPID={取得したやつ}
    Alamofire.request("http://api.openweathermap.org/data/2.5/forecast?q=Tokyo&mode=json&APPID=").responseJSON { response in
            switch response.result {
            case .success(let value):
                let json = JSON(value)
                for i in 0 ..< self.cellNum {
                    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()

            case .failure(let error):
                print(error)
            }
        }
}

JSONから日付時間と天気と天気詳細をだしたました。 cellNumとcellItemはviewDidLoad()の前に書きました。

var cellItems = NSMutableArray()
let cellNum = 40
  1. ViewControllerのコード(TableView編)
    あとは、テーブルビューで表示できるようにするだけなのでぱっぱと終わらせました。
override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.cellNum
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath)
        if self.cellItems.count > 0 {
            cell.textLabel?.text = self.cellItems[indexPath.row] as? String
        }
        return cell
    }

StoryboardのTableViewのCellにはIdentifierでcellとしています。

5.Httpを使えるようにする
たぶん、このまま動かすとエラーでnullと出ると思うので、ここでHttpを許可します。
info.plistで一番上のInformation Property List の+ボタンを押すとリストが出てくるので、そこで「App Transport Security Settings」を打つかコピペしてもらうとそこにもう一つ+ボタンがでるので同じように「Allow Arbitrary Loads」して出てくるもののValueをNO→YESに替えるとHttpが使えるようになります。

完成

これでできました。 記録なので、ちょっとしたらQiitaとかにも同じのを出すと思います。(こっちは下書き的な感じだったので)