Swiftで分割したStoryboardの呼び出し方
チームでアプリを開発する場合や一つのStoryboardが大きくなりすぎるのが嫌な場合など、Storyboardを分割したくなるけど、じゃあどうやって呼び出すの?となるので書いておく。
- 基本的にはObjective-Cの時と同じ
- UINavigationControllerを使っている場合はちょっと違うので注意
- Storyboard上で
Is Initial View Controller
のチェックを入れるのを忘れずに
//UIViewControllerの場合 @IBAction func hogeButtonTapped(sender: AnyObject) { let story = UIStoryboard(name: "Hoge", bundle: nil) let vc = story.instantiateInitialViewController() as HogeViewController self.presentViewController(vc, animated: true, completion: nil) } //UINavigationControllerの場合 @IBAction func hogeButtonTapped(sender: AnyObject) { let story = UIStoryboard(name: "Hoge", bundle: nil) let nc = story.instantiateInitialViewController() as UINavigationController self.presentViewController(nc, animated: true, completion: nil) }
ファイル単位でARCを有効にする
ファイル単位でARCを有効にする
cocos2d-xでもSocket.IOでリアルタイム通信をやろうとした場合、
v3には標準のクラスに追加されたからそれを使えばなんとかなる。
ただし、Socket.IOのバージョンは0.9で1.0には対応してないしWebSocketオンリー。
C++でよいライブラリはないか探したけど見つからないので、
iOSからはこのobj-cのライブラリを使うことにした。
https://github.com/pkyeck/socket.IO-objc
ただし、一部ARCを有効にしないといけないファイルがあり、
//SocketRocket/SRWebSocket.m #error SocketRocket must be compiled with ARC enabled
cocos2d-xで作成したプロジェクトは基本無効になっているためどうしようかと思っていたら、
ファイルごとに設定出来ることを発見。
Build Phases > Compile Sources で対象ファイルに-fobjc-arc
を指定すればOK。
こちらを参考にさせて頂いた。
http://lab.dolice.net/blog/2013/05/10/objc-arc-switch/
UnityでiOSでもAndroidでもSocket.IOでリアルタイム通信
僕は別にアプリエンジニアじゃなかったんだけど、やらないといけなくなり、検証したのでメモ。
(Node.jsはv0.10.28、Socket.IOは0.9.17、Unityは4.3.4、iOSは7.1.2、Androidは4.4.2で検証)
スマホでSocket.IOを使いたい場合、ネイティブではこの辺のライブラリを使うと思う。
https://github.com/pkyeck/socket.IO-objc
https://github.com/Gottox/socket.io-java-client
ネイティブプラグインはよくわからなかったのでC#で書いてiOS,Android両方で使えるのはないかなと思っていたら
https://github.com/NetEase/UnitySocketIO
これが見つかった。他にはあまりなさそう。
で、一個問題があって、iOSだとEXC_BAD_ACCESSやら--aot-onlyと言われてうまく動かない。
SimpleJson.dllが古い、かつiOSでは使えないオプションが付いていたみたいなので、
SimpleJsonを自分でビルドし直した。
SimpleJson.csで#define SIMPLE_JSON_NO_LINQ_EXPRESSION
をアンコメントする必要がある。
ここが参考になった。
https://github.com/kaistseo/UnitySocketIO-WebSocketSharp
こっち使ってもよかったかも。
まあどちらにしてもSocket.IOといいつつWebSocketしか使えないし、1.0系に対応するかどうかはよくわからない。。
ちなみにDLLを更新した版はフォークしてここに置いた。
https://github.com/take4/UnitySocketIO
C#のサンプルコード※サーバー側はよくあるサンプルチャットなので割愛。
using UnityEngine; using System.Collections; using System.Collections.Generic; public class NewBehaviourScript : MonoBehaviour { public GUIText text1; public string text = ""; SocketIOClient.Client socket; // Use this for initialization void Start () { Debug.Log ("start"); socket = new SocketIOClient.Client ("http://xxx.xxx.xxx.xxx:3000/"); socket.On ("connect", (fn) => { Debug.Log("connect - socket"); }); socket.On ("message:receive", (data) => { Debug.Log(data.Json.ToJsonString()); text = data.Json.ToJsonString() + "\n" + text; }); socket.Connect(); } // Update is called once per frame void Update () { text1.text = text; } void OnGUI() { if (GUI.Button( new Rect (30, 30, 120, 50), "PUSH")) { Dictionary<string, string> args = new Dictionary<string, string>(); args.Add("message", "YO"); socket.Emit("message:send", args); } } }
追記
やっぱりこっちを使ったほうがよさげ
https://github.com/kaistseo/UnitySocketIO-WebSocketSharp
https://github.com/KLab/websocket-unitymobile
NginxによるWebSocketの負荷分散
Node.js、Socket.IOを使ってリアルタイムなWebアプリなんかを作っていて、分散構成はどうすればいいのか試行錯誤しているメモ。
Nginxは1.3.13からWebSocketのプロキシに対応したので以下を参考にサクッとやってみる。 http://nginx.org/en/docs/http/websocket.html
upstream chatserver { server xxx.xxx.xxx.xxx:3000; server yyy.yyy.yyy.yyy:3000; } server { listen 3000; server_name localhost; location / { proxy_pass http://chatserver; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; } }
この設定でも確かにプロキシされたし、分散もされた。
しかし、接続先のサーバーが頻繁に変わってしまうようで、アプリの挙動がおかしくなった。
なのでセッションごとに同じサーバーに接続する仕組みが必要。
ip_hashだとなんとなくサーバーが偏りそうな気がしたのでstickyを試す。
http://nginx.org/en/docs/http/ngx_http_upstream_module.html
ここを見ているとstickyが標準で入っているっぽいが、実際には入っていないのでNginxをビルドし直してサードパーティモジュールとして組み込む。
(Nginx Plusなら入ってるのかな?)
stickyのダウンロード先、ビルド方法は以下を参照。
https://bitbucket.org/nginx-goodies/nginx-sticky-module-ng
設定はほとんど変わらず、sticky
を追記するだけ。
upstream chatserver { sticky; server xxx.xxx.xxx.xxx:3000; server yyy.yyy.yyy.yyy:3000; }
今のところこれでいけそう。
ちなみに各バージョンは
Nginx : 1.6.0 Node.js : v0.10.28 Socket.IO : 0.9.17
Nodeを分散するとNodeプロセス間でのデータの共有が必要で、それにはRedisのPub/Subがよいらしい。
以上、アリーヴェデルチ!
sentinel利用時の注意点
ipの変更があった時にsentinel.confのsentinel monitor
で新しいmasterのipを指定して再起動したが、勝手にslaveに変えられてしまってハマった。
sentinelはfailover時、以下のように情報をsentinel.confに追記する。
# Generated by CONFIG REWRITE dir "/hoge/fuga" sentinel known-slave mymaster xxx.xxx.xxx.xxx 6379 sentinel known-sentinel mymaster yyy.yyy.yyy.yyy 26379 e80c02f0a7899dcb69f01ff5050a88ded04c6f6c sentinel current-epoch N
これが残っていると古いipを元にレプリケーションしてしまう。
dump.rdbも容赦なく上書きされた。。定期的にバックアップ取るべきだった。。
なので残っていないか要チェック。ec2インスタンスタイプ変更などで陥るかも。
ちゃんとSentinel commandsも覚えるべきかな。。
参考
http://d.hatena.ne.jp/rx7/20140410/p1
http://redis.io/topics/sentinel