Tech Sketch Bucket of Technical Chips by TIS Inc.

PaaS と iOS で Socket.IO (iOS側 ~ CocoaPods利用)

Pocket

PaaS( eXcale や Heroku )上の Node.js とiOS間で Socket.IO を用いたリアルタイムな双方向通信をする方法について、 前回 はリアルタイム通信の概念とサーバ側実装について解説しました。今回は Objective-C用のライブラリ管理システム CocoaPods を利用して、iOSからSocket.IO通信する方法を解説します。


CocoaPodsとは

CocoaPods は、Objective-C用のライブラリ管理システムです。Rubyでの Bundler やNode.jsでの npm に相当します。
iOSやMacOS向けにObjective-Cでプログラムを開発する場合、これまでは依存するライブラリをgithubなどからダウンロードし、ソースコードやリソースファイルをXcodeプロジェクトへ一つ一つ追加する必要がありました。しかしこれはかなり煩雑な作業です。
特にiOSの場合、iOSのバージョンやXcodeのバージョンによってコードの書き方がかなり異なります。シンタックスシュガーの違い程度ならまだマシですが、ARCコードとnonARCコードを混ぜると、そのままではビルドさえ通りません。

CocoaPodsの利点

そこでCocoaPodsが登場します。npmでのpackage.jsonに相当する "podfile" に依存ライブラリを定義すれば、コマンド一発で依存ライブラリがダウンロードされ、プロジェクトに導入され、メインとなるコードから参照・利用できるようになります。なんとスバラシイ!
CocoaPodsが利用できるのであれば、利用すべきでしょう。

CocoaPodsの弱点

このように便利なCocoaPodsなのですが、残念ながらBundlerやnpmほどには利用されていません。その理由はズバリ、CocoaPodsから利用できるライブラリの少なさでしょう。BundlerではRubyGemsが公開している5万余りのgemが利用できますし、npmでも2万余りのライブラリが公開されています。一方でCocoaPodsは、2013/02時点で 1000余りのライブラリ しか公開されていないのです。。。
皆さんも今後Objective-Cのライブラリを作った場合CocoaPodsで公開するようにしましょうね!

CocoaPodsの準備

ということで、さっそくCocoaPodsを利用できる環境を準備します。と言っても、gemでインストールするだけです。以前はMacRubyでなければなりませんでしたが、現時点のバージョンでは通常のcRubyで動作します。今回は下記バージョンで検証しました。

OS Mac OS X Lion v10.7.4
Xcode 4.5.2
cRuby 1.9.3p385 (2013-02-06 revision 39114) [x86_64-darwin11.4.2]
gem 1.8.25
cocoapods 0.16.2

cocoapodsのインストールと設定

gemでインストール後、"pod setup"するだけです。

もし以下のエラーが表示された場合、pod setupより先に "Xcode Command Line Tools" をインストールする必要があります。

Xcodeを起動した後Preference>Downloadsからインストールしてください。

xcode_commandlinetools.png

SocketIO-Client (iOS)の実装

CocoaPodsも準備できましたので、SocketIO-Client (iOS)を実装します。

Objective-C用のSocket.IOライブラリは複数公開されており、 Socket.IOの公式サイト では pkyeck/socket.IO-objc が紹介されています。ただこのpkyeckのsocket.IOライブラリはCocoaPodsと相性が悪いようで、コマンド一発インストールとはいかないようです。
そこで"Cocoapods-friendly"と自ら主張している AZSocketIO を利用することにします。

Xcodeプロジェクトの作成

通常どおりにXcodeで新規プロジェクトを作成し、一旦終了します。ただし後でpodfileの設定に利用しますので、Deployment TargetとなるiOSのバージョンは意識しておいてください。

podfileの作成

上で生成したXcodeプロジェクトの"プロジェクトファイル(XXX.xcodeproj)と同じディレクトリ"に、下記podfileを作成します。

このpodfileでは、ターゲットとなるプラットフォームを、iOS5.0と定義しています。Xcodeで指定されているDeployment Targetバージョンと一致させてください。
またAZSocketIOはバージョンを "~>0.0.4"と指定しているため、0.0.4~0.0.9の中から最新バージョンが選択されます。

依存ライブラリのダウンロードと依存関係の解決

ターミナルから"pod install"を実行すれば、podfileに指定した依存ライブラリ(=Pod)がダウンロードされます。
各Podには"podspec"という定義ファイルがあり、そこにはソースコードのリポジトリURLや依存する他のPod、前提とするOSバージョンやframework、ARCの利用有無などが記載されています。CocoaPodsはこれらの情報を元に、以下のような作業を行います。

  1. Xcodeワークスペースを作成し、当初のプロジェクトをワークスペースに追加
  2. "プロジェクトファイル(XXX.xcodeproj)と同じディレクトリ"に、podfileで指定したPod、及びそれらが依存するPodを収めるプロジェクト(=Podsプロジェクト)を作成し、ワークスペースに追加
    1. Podsプロジェクトでは、podspecに従ってビルド設定が施され、各Podは一つのスタティックライブラリ(libPods.a)へビルドされる
  3. 当初のプロジェクトの設定変更
    1. Podsプロジェクトに含まれる各Podのヘッダファイルをヘッダサーチパスへ追加、libPods.aのリンク設定、libPods.aも同時にビルドされるようにビルドターゲットとビルドフェーズの変更など

以降は、生成されたXcodeワークスペースで開発を続けることになります。

socketio-client_01.png

Xcodeでワークスペースを開くと、以下のような状態になっているはずです。

socketio-client_02.png

UIの構築

今回はStoryBoardを用いて、以下のようなシンプルなUIを定義しました。このViewを"ViewController"クラスへとバインドしておきます。

socketio-client_03.png

ロジックの記述

では、Socket.IOでリアルタイム双方向通信するロジックを記述します。なお、この記事のソースコードでは、エラー処理などを省略しています。完全なソースコードは ココ を参照してください

ViewController.m

CocoaPodsによって依存関係が設定されているため、特に何もしなくてもAZSocketIOクラスを利用することができます。便利ですねっ!

Commons.hとCommons.m

Objective-Cで定数を定義する方法には複数の流儀がありますが、今回はconstな文字列をexternしたヘッダファイルをincludeする方法を取ってます。

前回 ご紹介したサーバ側のcommons.jsとは以下の点が異なります。注意してください。

  1. HOST名に"http://"は不要
  2. commons.jsで指定したPORTは「PaaS内部で使用するPORT(8080など)」だったが、Objective-Cで指定しているのは「PaaS外部からみたPORT(80)」

SocketIO-Client (iOS)の動作確認

Xcodeワークスペース上で「Run」すれば、特に何も設定しなくても依存するPodsがビルドされてリンクされ、 SocketIO-Client (iOS)が起動します。実際にメッセージを送受信してみたところ、きちんとSocket.IOで双方向通信できているようです。

socketio-client_04.png

最後に

前回 、今回と2回に渡って、PaaS上のNode.jsとiOSでSocket.IOによるリアルタイム双方向通信をする方法を解説し、関連してCocoaPodsの紹介も行いました。
スマートデバイスのネイティブパワーとSocket.IOを組み合わせれば、強力なリアルタイムアプリケーションを構築できるようになるでしょう。皆さんも活用してください。

エンジニア採用中!私たちと一緒に働いてみませんか?