【Swift】Twitter APIを使って画像を探す

# 概要

「Advent Calendar 2015」ということでエンジニアの心の支えになるようなアプリを実装しようと思いまして...


以下のようなサンタコスアプリを作ります。

ちょっとぼかしておきます。あかちゃんかわいいですね。





##仕様

1. Fabricというサービスを用いて『Twitterでログイン』をします。
2. TwitterKitというフレームワークを用いて検索APIを叩きます。
3. 取得した画像をCollectionViewに画像を配置します。

# 実装手順

では黙々と作っていきましょう。

## Fabricを導入する

[Fabric](https://fabric.io/)コチラからユーザ登録しましょう。

Macアプリが存在するのでダウンロードします。

ダウンロードできるとこんな感じになります。

![スクリーンショット 2015-12-02 23.11.36.png](https://qiita-image-store.s3.amazonaws.com/0/48036/1cdcffba-9003-b351-91f3-86aa1a852c22.png "スクリーンショット 2015-12-02 23.11.36.png")

## Xcode新規プロジェクトを作成する

いつものように作りましょう。プロジェクト名は「SantaGirls」としました。

## XcodeプロジェクトにFabricを導入する

素晴らしい記事がありますのでコチラをご参考いただければと思います。
[[iOS]FabricでTwitterクライアントを作った](http://qiita.com/mokumoku/items/bf0460f420acac3c04fc)


## 事前準備をする

AppDelegate.swiftファイルを以下のように編集します。

```AppDelegate.swift
import UIKit
import Fabric  //追記
import TwitterKit //追記

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        Fabric.with([Twitter.self]) //追記
        
        return true
    }
```


## Twitterログインを実装する

ログインボタンを配置したいViewControllerにて以下のコードを追記します。

```
let loginButton = TWTRLogInButton(logInCompletion: {
    session, error in
    if session != nil {
        print(session!.userName)
    } else {
        print(error!.localizedDescription)
    }
})
loginButton.center = self.view.center
self.view.addSubview(loginButton)
```

## おまちかね


```
func getSantaGirls() {
    let url = "https://api.twitter.com/1.1/search/tweets.json"
    let params = [
        "q": "#サンタコス -割 -Set -メイド風 -アクセント -点セット -お買い得 -#子供 -#マンチカン -#サンタ衣装 -#コスチューム -#sugar filter:images exclude:retweets ",
        "lang": "ja",
        "count": "100",
    ]
    let request = Twitter.sharedInstance().APIClient.URLRequestWithMethod("GET", URL: url, parameters: params, error: nil)
        Twitter.sharedInstance().APIClient.sendTwitterRequest(request, completion: {
            response, data, err in
            if err == nil {
                let json = JSON(data: data!)
                for tweet in json["statuses"].array! {
                    if let imageURL = tweet["entities"]["media"][0]["media_url"].string {
                        self.images.append(imageURL)
                        self.collectionView.reloadData()
                    }
                }
            } else {
                print(err)
            }
        })
}
```

ここはこの記事のメインなので細かく見ていきましょう。

### 検索APIの基本となるURL

```
let url = "https://api.twitter.com/1.1/search/tweets.json"
```

このURLにパラメータとしてオプションを付け加えることで柔軟な検索をすることができます。

### 画像をゲッツするためのパラメータ

```
let params = [
     "q": "#サンタコス -割 -Set -メイド風 -アクセント -点セット -お買い得 -#子供 -#マンチカン -#サンタ衣装 -#コスチューム -#sugar filter:images exclude:retweets ",
     "lang": "ja",
     "count": "100",
]
```

さらに細かく見てみます。

``"q"``というキーで指定している文字列はどのような条件で検索をするか指定します。ここに一番力を注いでいます。サンタコスを効率よく探すための神オプションです。

<br>

``#サンタコス``: #を付けるとハッシュタグ検索をすることができます。つまりこの時点では「#サンタコス」で投稿されたツイートが取得されます。これだけでいけると思っていましたが、案外広告が多いんですねえ

<br>

``-◯◯``: ``-割``や``-メイド風``とすることで指定したワードが含まれるツイートを除く事ができるんです...!
これを駆使して出来る限り広告を除きます。

<br>

``filter:images``: これは画像付きツイートのみを取得するためのオプションです。

<br>

``exclude:retweets``: リツイートは省く！これがとっても便利でした。
取得するツイートはリツイートも含まれてしまうので、同じ画像が何件も取得してしまってつまらないアプリになってしまっていましたが、このオプションのおかげでハッピーになれました。

<br>

``"count": "100"`` :　お察しの通り取得するツイートの数です。

### なんやかんやでツイート情報を取得する

ツイート情報はJSONというフォーマットで取得します。おなじみSwiftyJSONを使用しました。

```
let json = JSON(data: data!)
for tweet in json["statuses"].array! {
    if let imageURL = tweet["entities"]["media"][0]["media_url"].string {
        self.images.append(imageURL)
        self.collectionView.reloadData()
    }
}
```

なんやかんやで画像のURLを取得します。

```
let imageURL = tweet["entities"]["media"][0]["media_url"].string
```

このURLを用意しておいたimagesプロパティにぽこぽこ入れていきます。
そのタイミングでCollectionViewをリロード。

## 取得したURLをUIImageに変換

```
let url = NSURL(string:imageStr)
let req = NSURLRequest(URL:url!)
//非同期で変換
NSURLConnection.sendAsynchronousRequest(req, queue:NSOperationQueue.mainQueue()){(res, data, err) in
	let image = UIImage(data:data!)
　　imageView.image = self.cropThumbnailImage(image!, w: 100, h: 100)
}
```

これをCollectionViewDataSouceが提供するcollectionView:cellForItemAtIndexPathメソッド内に記述すると良い感じになります。


cropThumbnailImageメソッドは画像サイズを変更してます。この操作が無いとアプリがカクついてしまうんです。
以下の記事を参考にします。

[[Swift] 画像のサムネイル生成（縮小＆切り抜き）](http://qiita.com/taku/items/fb44d0bf10509d977bc0)

***

なんやかんやで完成しました。