まえがき的な(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でテーブル表示。
おまけに、テーブルをタップで詳細を表示もできるようにします。
完成すると、こんなかんじです。
作ってみる
1.プロジェクト作成
Single View Applicationで適当なプロジェクト名で作成。ここではweatherInfoとして作成。
2.UITableViewでテーブル作成して画面遷移
キャプチャのように、Object LibraryからTavble View Controllerを追加。
キャプチャ通りに操作。Action Segueはなんでも良いですがshowを選択。
Action Segueは画面遷移時にどのように画面を切り替えるかの設定。
ViewController.swiftを以下のように修正。
ただし、UILabelをViewController上ninfoLabelという名で設定しています。
設定の仕方がわからないでこれにチャレンジしてる人がいたら、ちょっと背伸びしすぎかもです。
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を以下を参考に修正。
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をリッチに
- とりあえず動く状態なのでコードは汚いです(^_^;)