socket.ioで投稿した内容がリアルタイムに表示される簡単なサンプルを作ってみました。
サーバーサイドは node.jsです。
ローカルの適当な場所に作業用のフォルダを作成します。
$ mkdir socket-saver && cd socket-server/
socket.ioを追加します。
$ npm install socket.io
server.jsというファイルを作りサーバーの実装を記述します。
var http = require("http");
var server = http.createServer(function(req,res) {
res.write("Hello World!!");
res.end();
});
var io = require('socket.io')(server);
var postArray = [];
// クライアント接続時
io.on('connection', function(socket) {
console.log("client connected!!")
// クライアント切断時
socket.on('disconnect', function() {
console.log("client disconnected!!")
});
// クライアント投稿時
socket.on("post", function(obj){
postArray.push(obj);
// クライアントに最新のデータを送る
io.emit("addedPost", JSON.stringify(postArray));
});
});
server.listen(8080);
“post”という名前で投稿内容を取得し”addedPost”でクライアントに最新のデータを送っています。
サーバーの実装はこれで終わりです。
プロジェクトを作成しswift用のsocket.ioのライブラリーをcocoapodsで追加します。
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'Socket.IO-Client-Swift', '~> 4.1.2' # Or latest version
これで$pod install とするとsocket.ioがインストールされます。
画面のレイアウトです。
投稿ボタン、テキストフィールド2つ、投稿された内容が表示されるテーブルビューを配置します。
socket.ioの実装です。
socket = SocketIOClient(socketURL: SocketURL, options: nil)
// 接続時
socket.on("connect") { data in
print("socket connected!!")
}
// 切断時
socket.on("disconnect") { data in
print("socket disconnected!!")
}
// 投稿された時
socket.on("addedPost") { (data, emitter) in
if let message = data as? [String] {
// 最新のデータを取得
print(message[0])
let jsonData: NSData = message[0].dataUsingEncoding(NSUTF8StringEncoding)!
var err:NSError?
do {
self.postArray = try NSJSONSerialization.JSONObjectWithData(
jsonData, options:[]) as? NSMutableArray
} catch let error as NSError {
err = error
self.postArray = nil
}
print(err)
// テーブル更新
self.tableView.reloadData()
}
}
// 接続開始
socket.connect()
// 投稿
@IBAction func pushPostButton(sender: AnyObject) {
let post : Dictionary<String, String> =
[ "name":self.nameTextField.text!, "text":self.postTextField.text!]
self.socket.emit("post", post);
}
ボタンが押された時に”post”という名前で投稿内容をサーバーに送ります。
サーバーに投稿の内容が送られると”addedPost”という名前でサーバーから最新のデータが送られてくるのでデータ取得しテーブルのデータを更新します。
全体のコードはこんな感じです。
//
// ViewController.swift
//
import UIKit
import Socket_IO_Client_Swift
class ViewController: UIViewController {
let SocketURL = "http://localhost:8080/"
@IBOutlet weak var nameTextField: UITextField!
@IBOutlet weak var postTextField: UITextField!
@IBOutlet weak var tableView: UITableView!
var socket: SocketIOClient!
var postArray: NSMutableArray!
// MARK: - LifeCycle
override func viewDidLoad() {
super.viewDidLoad()
postArray = NSMutableArray()
socket = SocketIOClient(socketURL: SocketURL, options: nil)
socket.on("connect") { data in
print("socket connected!!")
}
socket.on("disconnect") { data in
print("socket disconnected!!")
}
socket.on("addedPost") { (data, emitter) in
if let message = data as? [String] {
print(message[0])
let jsonData: NSData = message[0].dataUsingEncoding(NSUTF8StringEncoding)!
var err:NSError?
do {
self.postArray = try NSJSONSerialization.JSONObjectWithData(
jsonData, options:[]) as? NSMutableArray
} catch let error as NSError {
err = error
self.postArray = nil
}
print(err)
self.tableView.reloadData()
}
}
socket.connect()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Action
@IBAction func pushPostButton(sender: AnyObject) {
let post : Dictionary<String, String> = [ "name":self.nameTextField.text!, "text":self.postTextField.text!]
self.socket.emit("post", post);
}
// MARK: - TableView
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.postArray.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell: UITableViewCell = UITableViewCell(style: UITableViewCellStyle.Subtitle, reuseIdentifier: "Cell")
cell.backgroundColor = UIColor.clearColor()
let data : Dictionary<String, String> = self.postArray.objectAtIndex(indexPath.row) as! Dictionary<String, String>
print(data)
cell.textLabel?.text = data["text"]
cell.textLabel?.font = UIFont.boldSystemFontOfSize(17.0)
cell.detailTextLabel?.text = data["name"]
return cell
}
func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
return 80
}
}
$node server.js でサーバーを起動しアプリを動かしてみます。
できました!!
簡単な実装ですがiOSアプリからnode.js+Socket.IO間で双方向通信が実現できました。
今度はもっと複雑な処理に挑戦してみようと思います。
参考URL