iOS開発初心者がiOSアプリとWebでSocket連携してみる。Firebaseチュートリアル〜Objective-CのSwift書き換えまで。


超絶初心者ですがWebsocket使ってみたかったので色々サンプル動かしてみてたのですが、なかなか上手くいかず、
とりあえず入門としてFirebaseを使ってみたら上手くいったので記録しておきます。Objective-cでコード書いたあとにSwiftへ書き換えてます。

(※ ほぼほぼコピペプログラミングに近いので間違いなど指摘ありましたらコメントお願いします!!)


#環境
* Mac OS 10.9
* Xcode6.1
* iPhone 5s
* iOS 8.0

#Firebase

* バックエンドを提供してくれるBaaS的なサービス
* クライアント側に集中出来る
* iOSクライアント用のSDKもあるので今回はそれを活用

![](http://i.gyazo.com/1ea372f5daed0d085f152f043d8d4c26.png)

##firebaseのアカウントとアプリを作っておきます。

ダッシュボードでアプリを作れます。 https://www.firebase.com/account/#/

![](http://i.gyazo.com/7170725c857ee6565e0a0847a716235e.png)
nobiasukeappというアプリを作りました。

https://nobiasukeapp.firebaseIO.com がアプリのアドレスになります。

## https://アプリID.firebaseIO.com にアクセスします。

+を押してデータを追加します
![](http://i.gyazo.com/c33aaceb46dfafb6cfb24d40ebea594f.png)
iosというキーを作ってみました
![](http://i.gyazo.com/b106f1bda36c9fd59a52d8b2b22f96a9.png)
![](http://i.gyazo.com/4c26f9eff1f318aa9cc50c8473a86c42.png)

今回はこのiosキーを使います。 
https://nobisukeapp.firebaseio.com/ios を後ほど使います。

#とりあえずチュートリアル通りにObjective-Cで書いてみる



##①プロジェクト作成

[Single View Application] -> 言語はObjective-Cを選択
![](http://i.gyazo.com/a6b9b15f5fe450cd04f8bbda2778993d.png)

##②SDKなどの準備

### ・サイトからFirebaseSDKをダウンロード
現在の最新はv1.2.3 https://cdn.firebase.com/ObjC/Firebase.framework-1.2.3.zip

### ・SDKをプロジェクトに追加する
Copy items if neededのチェックを入れて追加します。
![](http://i.gyazo.com/8c45e2e012c2381d4279a91623d772ad.png)

![](http://i.gyazo.com/582fc663733db2badef64963a142205a.png)

### ・依存ライブラリを追加する
Build Phases -> Link Binary With Libraries -> +
![](http://i.gyazo.com/bbff74a4b89d66172db5ea98980cd686.png)

* libicucore.dylib
* libc++.dylib
* CFNetwork.framework
* Security.framework
* SystemConfiguration.framework

を追加します。

![](http://i.gyazo.com/cefee5f1183bba63e9c1780d5d5d8d68.png)

### ・クラス選択(?)
Objective-C使いますよ宣言的な感じかな(?)あまり分かってないです。

Build Settengs -> Linking -> Other Linker Flags に `-ObjC` と記述します。
![](http://i.gyazo.com/63dcb91fa56082a3564b7e851b5c51db.png)

##③ StoryBoardで部品を設置

ラベル１つ、ボタン二つを追加します。
![](http://i.gyazo.com/142b798410676658f4d8c212f946c142.png)

##④ コードを書きます。
viewController.hに部品を紐付けます。部品からcontrolキーを押しながらドラッグです。
SDK読み込みの`#import <Firebase/Firebase.h>`も記述しましょう。

```viewController.h
#import <UIKit/UIKit.h>
#import <Firebase/Firebase.h>

@interface ViewController : UIViewController
@property (weak, nonatomic) IBOutlet UILabel *mainlabel;
@property (weak, nonatomic) IBOutlet UIButton *leftBtn;
@property (weak, nonatomic) IBOutlet UIButton *rightBtn;

@end
```

![](http://i.gyazo.com/452eaa5299027367b776004ce8fcd691.png)


次に viewController.mにロジックを書きます。

initWithUrlに設定しているURLは↑で設定したURLです。

viewDidLoad内でobserveEventTypeを呼んでいますが、この関数が値の変更をチェックしてくれるみたいです。
Firebase側でiosの値が変わるたびに関数内の処理を実行してくれます。

buttonのクリックイベント(`(IBAction)right:(id)sender`と`(IBAction)left:(id)sender`)側ではクリックと連動させて押したタイミングで値が変わるようにしています。

```viewController.m
//
//  ViewController.m
//  firebasetest2
//
//  Created by nobisuke on 2014/10/25.
//  Copyright (c) 2014年 nobisuke. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    // Create a reference to a Firebase location
    Firebase *fb = [[Firebase alloc] initWithUrl:@"https://nobisukeapp.firebaseio.com/ios"];
    // Write data to Firebase
    [fb observeEventType:FEventTypeValue withBlock:^(FDataSnapshot *snapshot) {
        
        //self.mainlabel.text = snapshot.value;
        NSString *hogetext = @"";
        
        if([snapshot.value  isEqual: @"right"]){
            hogetext = @"右";
        }else if([snapshot.value  isEqual: @"left"]){
            hogetext = @"左";
        }else{
            hogetext = @"その他";
        }
        self.mainlabel.text = hogetext;
    }];
    
}


- (IBAction)right:(id)sender {
//    // Read data and react to changes
    Firebase *fb = [[Firebase alloc] initWithUrl:@"https://nobisukeapp.firebaseio.com/ios"];
    [fb setValue:@"right"];
}

- (IBAction)left:(id)sender {
    Firebase *fb = [[Firebase alloc] initWithUrl:@"https://nobisukeapp.firebaseio.com/ios"];
    [fb setValue:@"left"];
}


- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end


```

##⑤ 実行
シュミレータで実行して、ボタンを押した時に反応してFirebaseの管理画面側の値が変わるのが分かると思います。逆にFirebase側の値を変更したときにアプリ側の値も変更されています。
![](http://i.gyazo.com/d28df74710cae6544cf01cbe0fd75fcb.gif)


##参考URLなど
* 基本この動画の通りにやってます。 https://www.youtube.com/watch?v=umZLJThityQ
* Firebase iOS platform https://www.firebase.com/docs/ios/

#Swiftに書き換えてみる
やってみたかたったのでここからswiftにコードを書き換えてみました。

## ①Swiftプロジェクトを作る
最初の Single View Application -> 言語選択でSwift にするだけで、基本は上記と全く同じやり方です。
SDKやライブラリ読み込みなども行います。

## ②上記で作ったプロジェクトファイルを持ってくる

viewController.hとview.Controller.mをコピーして来ます。

```viewController.h
//
//  ViewController.h
//  firebasetest2
//
//  Created by nobisuke on 2014/10/25.
//  Copyright (c) 2014年 nobisuke. All rights reserved.
//

#import <UIKit/UIKit.h>
#import <Firebase/Firebase.h>

@interface ViewController : UIViewController

@end
```
こちらは部品の宣言は消しておきます。


## ③bridging-headerを作る
今回のようにswiftからObjective-Cで書かれたライブラリを参照する場合はbriging-headerという変換コネクタ的なファイルを作る必要があるみたいです。
`プロジェクト名-Bridging-Header.hを作成して、viewController.hをimportしましょう。

今回はfirebaseSwiftというプロジェクトにしています。

```firebaseSwift-Bridging-Header.h
#import "ViewController.h"
```

![](http://i.gyazo.com/b89c4c69810e78d857ba5f9d786ff561.png)

## ④swiftでViewControllerを記述
さっき読み込んだ ViewController.hと被るのでFbViewController.swfitに名前を変更します。

Firebase側でredに値を設定する(or 左を押す)と背景が赤く, blueだと青くするみたいな感じのものを作ってみました。

```FbViewController.swift
//
//  ViewController.swift
//  HelloRomo
//
//  Created by Hiromasa Nagamine on 10/22/14.
//  Copyright (c) 2014 my_name. All rights reserved.
//

import UIKit

class FbViewController: ViewController {
    
    @IBOutlet weak var mainlabel: UILabel!
    @IBOutlet weak var leftBtn: UIButton!
    @IBOutlet weak var rightBtn: UIButton!
    @IBOutlet weak var iro: UIView!
    
    var nobiFB = Firebase(url:"https://nobisukeapp.firebaseio.com/ios")
    
    override func viewDidLoad() {
        super.viewDidLoad()
        nobiFB.setValue("swift")
        // Read data and react to changes
        
        nobiFB.observeEventType(.Value, withBlock: {
            snapshot in
            
            println("\(snapshot.name) -> \(snapshot.value)")
            
            self.mainlabel.text = snapshot.value as String
            
            if(self.mainlabel.text == "red"){
                self.view.backgroundColor = UIColor.redColor()
            }else if(self.mainlabel.text == "blue"){
                self.view.backgroundColor = UIColor.blueColor()
            }else{
                self.view.backgroundColor = UIColor.whiteColor()
            }
        })
    }
    
    @IBAction func pushL(sender: AnyObject) {
        nobiFB.setValue("red")
    }
    
    @IBAction func pushR(sender: AnyObject) {
        nobiFB.setValue("blue")
    }
    
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    
}


```

ちなみにViewController.mは一見利用してないっぽいんですけど消してはだめみたいです。

## ⑤起動時のviewを変更する
名前を変更したらFbViewController.swiftを使いたいのでStoryBoardから CustomClass -> Classの項目でFbViewControllerを選択します。これで起動時にFbViewController.swiftが呼び出されます。

![](http://i.gyazo.com/09f9dfc0cdd5b3877fd0813aba64605b.png)


## ⑥実行
デモは省略します。
Firebase側の値を変更するとアプリ側に反映されます。

anyobject is not convertible to string

#まとめ
以上です、初心者すぎて色々と間違ってる部分もあると思うので指摘などしてくれると嬉しいです。
firebaseを使ったサンプルやチュートリアルが日本語のものが無かったので参考になれば幸いです。


今回のは[超・超・超初心者向けSwiftを始めてみよう勉強会](http://swiftstarter.connpass.com)で作ってみました。 興味ある方は次回以降のイベントに参加してみてはいかがでしょうか。