[Swift 1.1] swiftで api を叩いて、JSONをパースして、表示させる方法 (xcodeは6.1, iOSは8.1)

# 対応バージョン

swift 1.1
xcode 6.1
iOS 8.1

# 目標

「yahooニュースのRSSをJSONで配ってるapiを叩いて、JSONデータをゲトして、テーブルでひ項目表示させて、セルをタップしたらwebViewで元記事が見れる」ところまで実装。

# Playgroundでやってみました。

```swift
import UIKit
import XCPlayground

//make URL of google feed api
var urlString = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://rss.itmedia.co.jp/rss/2.0/news_bursts.xml&num=8"
var url = NSURL(string: urlString)

//download by NSSession
var task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler:{data, response, error in
    //convert json data to dictionary
    var dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
    
    println(dict)
})

task.resume()

XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)
```

![Screen Shot 2014-11-13 at 15.43.38.png](https://qiita-image-store.s3.amazonaws.com/0/18705/ba1bf1e6-4b26-3a96-fd5f-8e9db1c95c37.png)


とりあえずこんな感じでゲトできる。

## titleだけ表示させてみる

```swift
import UIKit
import XCPlayground

//make URL of google feed api
var urlString = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://rss.itmedia.co.jp/rss/2.0/news_bursts.xml&num=8"
var url = NSURL(string: urlString)

//download by NSSession
var task = NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler:{data, response, error in
    //convert json data to dictionary
    var dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary

    //get responseData, feed, entries
    var responseData = dict["responseData"] as NSDictionary
    var feed = responseData["feed"] as NSDictionary
    var entries = feed["entries"] as NSArray
    
    //extract entries
    for entry in entries {
        println(entry["title"])
    }
    
    println(dict)
})

task.resume()

XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)

```

![Screen Shot 2014-11-13 at 15.38.41.png](https://qiita-image-store.s3.amazonaws.com/0/18705/098813bf-8c71-6472-485b-dca107514156.png)

できた！！

# テーブルで表示させてみる

playgroundを離れ、普通のアプリ制作のフローでいきます。

細かいところは一旦置いといて。

```swift
import UIKit

class ViewController: UITableViewController {
    
    //array of entries
    var entries = NSArray()
    let newsUrlString = "http://ajax.googleapis.com/ajax/services/feed/load?v=1.0&q=http://rss.itmedia.co.jp/rss/2.0/news_bursts.xml&num=8"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    //count cell of table view
    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return entries.count
    }
    
    //make tableView
    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        //get cell
        var cell = tableView.dequeueReusableCellWithIdentifier("news") as UITableViewCell
    
        //get entry
        var entry = entries[indexPath.row] as NSDictionary
        
        //set title
        cell.textLabel.text = entry["title"] as? String
        
        return cell
    }

    //make reload button
    @IBAction func refresh(sender: AnyObject) {
        let url = NSURL(string: newsUrlString)!
        
        var task = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: {data, response, error in
            // conver json to dictionary
            var dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
            
            // get responseData entries
            if var responseData = dict["responseData"] as? NSDictionary {
                if var feed = responseData["feed"] as? NSDictionary {
                    if var entries = feed["entries"] as? NSArray {
                        // set array of entries
                        self.entries = entries
                    }
                }
            }
            //switch to main thread to relad table view
            dispatch_async(dispatch_get_main_queue(), {
                //reload table view
                self.tableView.reloadData()
            })
        })
        task.resume()
    }
}
```

はじめにビルドすると、、、

![Screen Shot 2014-11-13 at 16.07.34.png](https://qiita-image-store.s3.amazonaws.com/0/18705/f387309e-31fc-f59f-37ce-2355bfaa1488.png)


リロードボタンを押すと

![Screen Shot 2014-11-13 at 16.07.39.png](https://qiita-image-store.s3.amazonaws.com/0/18705/7d6a2a7b-84c6-1bca-80d8-8542170e9161.png)

読み込まれた！

リロードボタンの実装はstoryboardからやりました。
navigationbarにbarbuttonitemを載せ、identifierをrefreshにして、assistantEditorを開いてViewControllerにCtrl+ドラッグアンドドロップしただけです。

# 本文も表示

## 詳細のViewControllerを増やす

![Screen Shot 2014-11-13 at 16.13.28.png](https://qiita-image-store.s3.amazonaws.com/0/18705/6a3f04ab-ad0f-734f-6f34-376944f08d01.png)
storyboardからViewCotnrollerを選択して、ドラッグアンドドロップ。

![Screen Shot 2014-11-13 at 16.15.40.png](https://qiita-image-store.s3.amazonaws.com/0/18705/e594d0d3-8675-278d-2233-fe999e95e45e.png)
TableViewのViewControllerと今回のViewControllerを紐付け。Segueる。
Storyboardの左っかわで、Ctrl+ドラッグアンドドロップで紐付けできます。

![Screen Shot 2014-11-13 at 16.16.18.png](https://qiita-image-store.s3.amazonaws.com/0/18705/96fd57b0-7b4e-94af-7f51-158274c673f1.png)
Segueのidentifierを決める

以下のコードを追加して、segueを追加します。

```swift
    //add segue
    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        // Segue
        performSegueWithIdentifier("detail", sender: entries[indexPath.row])
    }
```

![Screen Shot 2014-11-13 at 16.19.17.png](https://qiita-image-store.s3.amazonaws.com/0/18705/a1051423-ddc6-b5c9-d73f-fddbc5089337.png)
ビルドしてみるとこんな感じ。
テーブルのセルをタップすると新しいViewControllerが呼ばれて遷移する。

## WebView

* DetailControllerにWebViewを追加

storyboardでドラッグアンドドロップしたらOK。

* DetailControllerにアウトレットを追加

assistantEditorを表示して、Ctrl+ドラッグアンドドロップ。

![Screen Shot 2014-11-13 at 16.33.49.png](https://qiita-image-store.s3.amazonaws.com/0/18705/5cffdae5-649a-ae7e-a910-5d5be0a9ca2c.png)

* URLを読み込むコードをかく

```swift
import Foundation
import UIKit

class DetailController: UIViewController {
    
    @IBOutlet weak var webView: UIWebView!
    
    var entry = NSDictionary()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //read URL by webView
        var url = NSURL(string: self.entry["link"] as String)
        var request = NSURLRequest(URL: url!)
        webView.loadRequest(request)
    }
}
```

* ViewController側で表示するエントリーをDetailControllerに渡すところを何とかする

```swift
    // send entry to DetailController
    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        if segue.identifier == "detail" {
            // get DetailController
            var detailController = segue.destinationViewController as DetailController
            
            // set entry
            detailController.entry = sender as NSDictionary
        }
    }
```

さっきsegueを追加したコードの下あたり、@IBAction func refresh の上辺りに追記。

* ビルド

いい感じー

![Screen Shot 2014-11-13 at 16.40.16.png](https://qiita-image-store.s3.amazonaws.com/0/18705/a0b4bd71-b551-fafd-8a30-ef10916fc6ed.png)
 

# とりあえず

とりあえず大枠ができたので、これから自分なりにカスタマイズしていくのですが、それはまた次回、、、

（swift1.1と1.0ってかなり違うんですね。。。2.0でいいのでは・・・）

# 参考

* [楽しいSwiftプログラミング](http://www.bnn.co.jp/errata/7173/)
* [iPhone/iPadプログラミングバイブル Swift/iOS8/Xcode6対応](http://www.socym.co.jp/support/s-952)
* [swift離陸ガイド](http://kaigian.co.jp/books/)
* [swift1.1変更点レポート](http://kaigian.co.jp/books/swift1122793263562885712524125091254012488.html)