Twitter APIを使ってツイートの投稿とプロフィールの更新をしてみよう

##ツイートを投稿してみよう

###投稿フォームの作成
前回までは、Twitterでフォローしている友達のツイートを見るためにタイムラインを実装しました。ですが、自分でツイートができなければ友達とコミュニケーションをとることができませんよね。せっかくツイートがみれるのに友達とコミュニケーションが取れないのはつまらないですよね。

なので、今回は友達とコミュニケーションが取れるようにツイートする機能を作っていきます。今回も前回利用したフレームワークを利用していきます。

###ファイルの作成とストーリーボードへの追加

まず、ツイート投稿をするために投稿画面を作っていきます。投稿画面用のViewControllerが必要なのでTweetPostViewController.swiftファイルを新規に追加します。

![Screen Shot 2015-08-30 at 2.24.37 PM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/281a6bb4-571d-10d7-a38a-ec96465142ee.png)

新規作成するファイルのテンプレート"Cocoa Touch Class"を選択します。

![Screen Shot 2015-08-30 at 2.26.08 PM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/d4e84ed8-1fdd-3c89-0a0e-2d0c013d2ddd.png)

Class:TweetPostViewController, Subclass:UIViewController, Language:Swiftにします。xibは使わないので、チェックボックスはオフにします。

![Screen Shot 2015-08-30 at 2.26.25 PM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/b7f422b6-3829-666b-64aa-db4bbef8167c.png)

作成するとナビゲーションエリアにTweetPostViewController.swiftが追加されます。

![Screen Shot 2015-08-31 at 12.31.41 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/79830e25-8e35-e1ab-0772-d08b7939c24a.png)


次は、Storybaord上にViewControllerを追加しましょう。
Main.storyboardを選択してstoryboard上にViewControllerを追加します。
次に、インスペクタエリアから追加したViweControllerのクラスをTweetPostViewControllerにします。

![Screen Shot 2015-08-31 at 12.36.52 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/f60baac2-0bf9-ca7c-7b0d-9bf3b657e171.png)

###投稿フォームへの画面遷移

次は、追加したタイムラインから投稿フォームに遷移する処理を追加します。
遷移するためのボタンをタイムラインのナビゲーションバーの左側に追加したいと思います。ナビゲーションバーにボタンを追加するには、まず、ナビゲーションバーの上に"Navigation Item"というUIを追加します。

![Screen Shot 2015-08-31 at 1.01.17 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/3ad956ea-5b66-4bd4-eade-1261e658a24a.png)

設置したNavigation Item上の右側に"Bar Button Item"を持っていきます。するとボタンが追加できるようになっています。

![Screen Shot 2015-08-31 at 1.02.34 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/7e1bec26-8091-fe8f-4ea0-dc7e136d5812.png)

ここからは、今まで何どもやっている"Triggered Segues"を使った画面遷移で投稿フォームへ遷移する処理を追加します。先ほど追加したボタンを選択した状態で、インスペクタエリアの一番右のタブを選択してTriggered Seguesの"action"の右側の◯からStoryboard上のTweetPostViewControllerへドラッグして接続します。ポップアップが出現するので今回は"show detail"を選択します。

![Screen Shot 2015-08-31 at 1.11.04 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/ca81d204-bbb8-fd35-3ef1-d2703e1cbe58.png)

すると、ボタンをタップした時にこの接続を参照して投稿フォームがモーダルで表示されるようになっています。

接続したら、シミュレーターを起動してボタンを押した時に遷移するか確かめてみましょう。

###投稿フォームのレイアウト

ここからは、ボタンやラベルを使って投稿フォームを作っていきます。
設置したTweetPostViewController以下のようにLabel, TextView, Buttonを２つ設置してみましょう。各パーツのラベルも変更しましょう。

![Screen Shot 2015-08-31 at 12.53.46 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/2633bedf-7743-9a7d-2425-12b3408d2b85.png)

AutoLayoutを各パーツに設定して、自動的にサイズ調整をできるようにしましょう。

* Label: Top, Left
* TextView: Top, Left, Right
* Send/Cancel: Top, Left

シミュレーターで起動して、向きを変えてもレイアウトされるか確認しましょう。

![Screen Shot 2015-08-31 at 10.35.34 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/498032ef-c326-e99f-baa5-69aa3a48d1dc.png)


###投稿ロジック

次は、投稿フォームからツイートするための処理をプログラムで書いていきます。
まず初めに、Storyboard上に設置したボタンとテキストビューをプログラムと接続しましょう。

TweetPostViewControllerを選択した状態で"Show the assistant editor"ボタン、もしくは"option"を押しながらstoryboardを選択してアシスタントエディターを表示します。

![Screen Shot 2015-08-31 at 10.45.10 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/ec670dee-3486-ead7-b788-49f1febb2580.png)

"Control"ボタンを押しながらパーツを選択し、プログラムの上にドラッグするとプログラムにパーツを追加して接続することができます。

![Screen Shot 2015-08-31 at 10.47.35 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/4ef34a00-fbe8-e7f4-d5b8-07cf596c6a35.png)

これで、プログラム内でも各パーツを扱えるようになります。次は、各ボタンにアクションを追加していきましょう。

![connect_action_2.png](https://qiita-image-store.s3.amazonaws.com/0/35442/6b8f82a3-fe77-aadf-67fe-9c5dc3e2a70d.png)


まずは、Cancelボタンにアクションをつけていきます。

```swift
class TweetPostViewController: UIViewController {
    /* 省略 */
    @IBAction func tappedCancelButton(sender: AnyObject) {
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}
```

シミュレーターを実行してみましょう。
次は、Sendボタンにアクションを追加していきます。

```swift
class TweetPostViewController: UIViewController {
    /* 省略 */
    @IBAction func tappedSendButton(sender: AnyObject) {
        let URL = NSURL(string: "https://api.twitter.com/1.1/statuses/update.json")
    
        if count(postField.text) <= 0 {
            var alert = UIAlertController(title: "Error", message: "Please input text", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:nil))
            self.presentViewController(alert, animated: true, completion:nil)
            
            return
        }
        
        var params = ["status": postField.text]
        
        // リクエストを生成
        let request = SLRequest(forServiceType: SLServiceTypeTwitter,
            requestMethod: .POST,
            URL: URL,
            parameters: params)
        
        // 取得したアカウントをセット
        request.account = twAccount
        
        // APIコールを実行
        request.performRequestWithHandler { (responseData, urlResponse, error) -> Void in
            
            if error != nil {
                println("error is \(error)")
            }
            else {
                // 結果の表示
                let result = NSJSONSerialization.JSONObjectWithData(responseData, options: .AllowFragments, error: nil) as! NSDictionary
                println("result is \(result)")
            }
        }
        
        self.dismissViewControllerAnimated(true, completion: nil)
    }
}
```

シミュレーターを実行してみましょう。投稿フォームからテキストビューに入力してSendボタンを押して送信してみましょう。

~~友達のつぶやきをRetweet, Favoriteしてみよう~~

##プロフィールを更新してみよう

Menuボタンをタイムラインのナビゲーションバーの左側に追加しましょう。

![addMenuToNavi_crop.png](https://qiita-image-store.s3.amazonaws.com/0/35442/3452f7e3-db61-4139-7276-3f03af7b2ade.png)

Menuボタンにアクションを追加しましょう。

![tappedMenuButton_crop.png](https://qiita-image-store.s3.amazonaws.com/0/35442/733cf3b0-4133-f753-c60c-bc6f8c0b273a.png)

```swift
class TimelineViewController: UITableViewController, UITableViewDelegate, UITableViewDataSource {
    @IBAction func tappedMenuButton(sender: AnyObject) {
        var alertController = UIAlertController(title: "Menu", message: nil, preferredStyle: .ActionSheet)
        

        alertController.addAction(UIAlertAction(title: "Edit Profile", style: .Default, handler: {
            (action) -> Void in
            
        }))
        alertController.addAction(UIAlertAction(title: "Logout", style: .Default, handler: {
            (action) -> Void in
            self.navigationController?.popViewControllerAnimated(true)
        }))

        
        let CanceledAction = UIAlertAction(title: "Cancel", style: .Cancel, handler: nil)
        alertController.addAction(CanceledAction)
        
        self.presentViewController(alertController, animated: true, completion: nil)
    }
}
```

シミュレーターで実行してみましょう！プロフィールに遷移することができます。

###UIとクラスの作成

StoryboardでUIを作ってみましょう。

![Screen Shot 2015-09-01 at 2.53.49 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/d52b57f7-76f7-b3fe-cb2e-f4655a86d26b.png)

###AutoLayoutを設定しましょう

![Screen Shot 2015-09-01 at 3.19.00 AM.png](https://qiita-image-store.s3.amazonaws.com/0/35442/f3ab7254-4979-ce96-eeb4-f073cc34033e.png)


###プロフィールを更新するロジック

ProfileEditViewControllerに次の表示ロジックを追加していきます。

```swift
    @IBOutlet var userIcon: UIImageView!
    @IBOutlet var userNameLabel: UILabel!
    @IBOutlet var twitterIdLabel: UILabel!
    @IBOutlet var profileMessageView: UITextView!
    @IBOutlet var sendButton: UIButton!
    
    var twAccount = ACAccount()
    
    override func viewDidLoad() {
        super.viewDidLoad()
    
        
        UIApplication.sharedApplication().networkActivityIndicatorVisible = true
        
        let URL = NSURL(string: "https://api.twitter.com/1.1/users/lookup.json?screen_name="+twAccount.username)
        
        let request = SLRequest(forServiceType: SLServiceTypeTwitter,
            requestMethod: .GET,
            URL: URL,
            parameters: nil)
        
        request.account = twAccount
        
        request.performRequestWithHandler { (data, response, error:NSError?) -> Void in
            UIApplication.sharedApplication().networkActivityIndicatorVisible = false
            
            if error != nil {
                println("Fetching Error: \(error)")
                return;
            }
            
            var tweetResponse: AnyObject? =  NSJSONSerialization.JSONObjectWithData(data, options: .AllowFragments, error: nil)
            
            if let tweetDict = tweetResponse as? Dictionary<String, AnyObject>{
                if let errors = tweetDict["errors"] as? Array<Dictionary<String,AnyObject>>{
                    var alert = UIAlertController(title: "Error", message: errors[0]["message"] as? String, preferredStyle: UIAlertControllerStyle.Alert)
                    alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:nil))
                    self.presentViewController(alert, animated: true, completion:nil)
                }
                
                return
            }
            
            var results = tweetResponse as! Array<Dictionary<String, AnyObject>>
            var myStatus = results[0]
            
            var userName = myStatus["name"] as? String
            var profileMessage = myStatus["description"]as? String
            var twitterID = "@"+self.twAccount.username
            var imageURL = NSURL(string: myStatus["profile_image_url"] as! String)
            var image = UIImage(data: NSData(contentsOfURL: imageURL!)!)
            
            dispatch_async(dispatch_get_main_queue(), {
                self.userNameLabel.text = userName
                self.profileMessageView.text = profileMessage
                self.twitterIdLabel.text = twitterID
                self.userIcon.image = image
            })
        }
    }
```

シミュレーターを再起動して、表示してみましょう。プロフィールを表示することができます。次に、更新処理を追加していきます。

```swift
@IBAction func tappedSendButton(sender: AnyObject) {
        
        let URL = NSURL(string: "https://api.twitter.com/1.1/account/update_profile.json")
        
        if count(profileMessageView.text) <= 0 {
            var alert = UIAlertController(title: "Error", message: "Please input text", preferredStyle: UIAlertControllerStyle.Alert)
            alert.addAction(UIAlertAction(title: "OK", style: .Default, handler:nil))
            self.presentViewController(alert, animated: true, completion:nil)
            
            return
        }
        
        var params = ["description": profileMessageView.text]
        
        // リクエストを生成
        let request = SLRequest(forServiceType: SLServiceTypeTwitter,
            requestMethod: .POST,
            URL: URL,
            parameters: params)
        
        // 取得したアカウントをセット
        request.account = twAccount
        
        // APIコールを実行
        request.performRequestWithHandler { (responseData, urlResponse, error) -> Void in
            
            if error != nil {
                println("error is \(error)")
            }
            else {
                // 結果の表示
                let result = NSJSONSerialization.JSONObjectWithData(responseData, options: .AllowFragments, error: nil) as! NSDictionary
                println("result is \(result)")
            }
        }
        self.navigationController?.popViewControllerAnimated(true)
    }
```

##まとめ

* Frameworkを使ってツイートを取得したように、ツイートを投稿することもできる
* ツイートやプロフィールの投稿にはテキストビューを使おう
* ログアウト時はpopViewControllerを使おう