ActionScript 3.0 , AIR , FLEXからCocoa, OpenGL
25 Feb
以前、名古屋のFxugにて少し発表した内容なんですが、ずっと記事にできてなかったので、今更ながらまとめます。
密かに前から社内用発表会のネタとして作ってはいたのですが、僕個人的にも、なかなか披露する機会がないまま、時間が過ぎてしまいました。
概要としては、
1. iPhone上でボタンをタップすると、AIR 2で作ったサーバーに、iPhoneからSocket経由で信号を送ります。
2. AIR 2のサーバーが、信号を受け取り、信号に応じた処理を行います。
これが作ったアプリのキャプチャです。
iPhoneとAIR 2サーバーの関係は、この通りです。
簡単に行ってしまえば、これだけです。
では、ここから説明します。
1. AIR 2のサーバー部分を作成
AIRでサーバーを作るには、UDPとTCPのサーバーがありますが、今回はTCPで通信するので、flash.net.ServerSocketクラスを使用します。
宣言〜受付開始
<pre>import flash.net.ServerSocket; // 接続してきたSocketを保持する var socks:Vector. = new Vector.(); // インスタンス生成 var server:ServerSocket = new ServerSocket(); // 接続時のイベントハンドラ作成 server.addEventListener(ServerSocketConnectEvent.CONNECT, serverSocketConnectHandler, false, 0, false); // 待ち受けポートを指定(43243番で受け付ける) server.bind(43243); // 待ち受け開始 server.listenen();</pre>
接続時:
function serverSocketConnectHandler(event:ServerSocketConnectEvent):void
{
// 接続してきたSocket
var socket:Socket = event.socket;
// 接続してきたSocketにデータを返すため、イベント設定
socket.addEventListener(ProgressEvent.SOCKET_DATA, receiveHandler, false, 0, false);
// 接続してきたSocketを保持する
socks.push(socket);
}
受信時:(本来は宛先を指定するべきだが、特に指定せず、全てのSocketに送信しています)
function receiveHandler(event:ProgressEvent):void
{
// データを送信したSocketを取得
var socket:Socket = event.target as Socket;
if(socket!=null) // nullチェック
{
// 受信データを取得
var recv:String = socket.readUTFBytes(socket.bytesAvailable);
// 操作対象のVideoPlayerを取得
var target:VideoPlayer = getCurrentVideo(); // 自作のメソッドです
// コマンドを取得し、操作を実行。コマンドを取得するため、indexOfを使っています。
if( recv.indexOf("prev") >= 0) {
setPos("prev");
} else if( recv.indexOf("next") >= 0) {
setPos("next");
} else if( recv.indexOf("play") >= 0) {
if( target.playing ) {
target.pause();
} else {
target.play();
}
}
}
}
AIRで作るサーバー周りは、こんなところです。エラー処理や切断時の処理などは書いてなくてごめんなさい。
iPhone側アプリケーションのSocket処理
では、次。iPhoneのほう。これも簡単な書き方でごめんなさいね。と、いうかCで最低限の実装しかしていないです。
TCPSendClient.m
接続:
-(void)connect:(NSString *)ip toPort:(NSInteger)port
{
if(_connected) // TCPSendClientが持っている、接続状態を保持する変数
{
return;
}
_connected = NO;
// IPアドレスを取得
servIP = [ip UTF8String];
// portを取得
servPort = port;
// socketが正しく生成できているかチェック
if((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
{
NSLog(@"socket creation error.");
return;
}
// socketの設定
memset(&servAddr, 0, sizeof(servAddr));
servAddr.sin_family = AF_INET;
servAddr.sin_addr.s_addr = inet_addr(servIP);
servAddr.sin_port = htons(servPort);
// 接続
if(connect(sock, (struct sockaddr *)&servAddr, sizeof(servAddr)) < 0)
{
NSLog(@"connect error.");
return;
}
_connected = YES;
NSLog(@"connect succeed.");
}
送信:
-(void)send:(NSString *)message
{
mes = [message UTF8String];
mesLen = strlen(mes);
// 送信
if(send(sock, mes, mesLen, 0) != mesLen) {
NSLog(@"send failed.");
}
}
ちなみに、
TCPSendClientクラスは、Socket処理を受け持つクラスで、自作しています。
TCPSendClient.hはこんな風に書いています。
#import <Foundation/Foundation.h>
#import <stdio.h>
#import <sys/socket.h>
#import <arpa/inet.h>
#import <stdlib.h>
#import <string.h>
#import <unistd.h>
@interface TCPSendClient : NSObject {
int sock;
struct sockaddr_in servAddr;
unsigned short servPort;
const char *servIP;
const char *mes;
unsigned int mesLen;
BOOL _connected;
}
-(void)connect:(NSString *)ip toPort:(NSInteger)port;
-(void)send:(NSString *)message;
-(void)close;
-(BOOL)getConnected;
@property(readonly) BOOL connected;
@end
このサンプルでは、このようにTCPSendClientを使っています。
PagerViewController.m
-(IBAction) processConnect:(id)sender // ボタンをタップした時のAction
{
if([connectSwitch isOn]) // これは、接続のon/offを切り替えるUISwitchです。
{
[sendc connect:@"10.0.2.1" toPort:43243]; // sendcというのがTCPSendClientです
stateField.text = @"connect";
}
else
{
[sendc close]; // 本文では紹介しなかったですが、切断します。
stateField.text = @"disconnect";
}
}
データ送信:
-(IBAction) btnUp:(id)sender // 各ボタンのTouchUpInsideと関連づけています。
{
isPress = NO;
prevValue = 0;
if( (UIButton*)sender == btn) // btnとは、一つ前の動画にフォーカスをあてるためのボタンです。
{
dir = @"prev";
[sendc send:dir];
}
else if((UIButton*)sender == nextBtn) { // nextBtnとは、一つ次の動画にフォーカスをあてるためのボタンです。
dir = @"next";
[sendc send:dir];
}
else if((UIButton*)sender == playBtn) { // playBtnとは、フォーカスがあたっている動画を再生するためのボタンです。
dir = @"play";
[sendc send:dir];
}
}
ちなみに、こちらがiPhoneアプリの画面です。(すごい地味ですね。。。笑えない)
Interface Builderのキャプチャです。
Macをルーターにする
最後に、iPhoneとAIRサーバーを接続するための設定をします。Macなら「インターネット共有」を使えば簡単にルーターにして連携させる事が可能です。こういうときに、一つのメーカーが作っている事が良い事に思えますね。
今回は、AirMac経由で共有します。
1. 「システム環境設定」を開く
2. 「共有」を開く
3. 「インターネット共有」を選択する
4. 「共有する接続回路」がAirMac以外であることを確認。なっていなければ変更します。
→iPhoneとMacをAirMac(無線)で接続する
5. 「インターネット共有」のチェックを入れると、共有を開始するか確認してきますので、開始をクリックします。すると、画面右のAirmacのアイコンがこのようになります。
開始順としては、AIRサーバーとiPhoneが接続する必要があるので、
1. Macをルーターにする
2. AIRサーバーアプリを起動する
3. iPhoneアプリを起動して接続する。
4. iPhone上で操作する。
というところです。
今回簡単に紹介しすぎててすみません。このままでわかりにくいなどご意見ありましたら整理した上で、ソース込みで全て公開します。
18 Feb
さて、先日2009.02.14-02.15の間、自分のちょっとしたつぶやきから始まった『iPhoneアプリ開発合宿』に行ってきました。
場所は箱根、強羅 一の湯。
http://www.ichinoyu.co.jp/gora/
twitter上で呼びかけ、twitter上でやりとりしている方や知り合いの方合計5人で開催されました。
参加者は実際にiPhoneアプリを作っている人だけで、普段はなかなかきくことができないObjective-Cの話をする事ができました。
今回の合宿は、あくまで各自作りたいもの、やりたいことがあって、同じ場所でそれぞれの目標に向かって一日作りましょう、という主旨でした。
それぞれが作った(作ろうとした)アプリについてはどこまで何を書いてよいのかわからないので、大まかに書いておくと、
で、僕はここ最近取り組んでいるOpenALを使ったアプリの開発を続けました。(完成にはたどり着けなかったですが、そこそこ進めることができました)
なんと『インターネットが使えない』という問題があったものの、豊富な経験とバックグラウンドを持っているメンバーが集まったおかげで、各自メインテーマが違っていたり、ネットが使えなかったりしながらもみんなで協力しながら開発を続けることができ、いい刺激になりました。
特に、appleのサンプルソースがいかに優れているかという事を実感しました。
また、チェックイン15:00のチェックアウト12:00であることもあり、夜中まで頑張っていました。
途中で温泉につかったり、飲める人はお酒を呑んで開発を続けたり。意外とお酒を呑んでもみんな開発を続けていたのがとても印象的でした。
何より、みんなで集まってiPhoneアプリ作りができる、という環境が今まで無かったのでとても濃く、充実した時間を過ごす事ができました。
これからiPhone合宿が色々と開催されたり、この会も第二回目が開催されますが、iPhone開発している人と沢山であって、良い刺激を受けたいと思っています。

夜中の風景。広い部屋に5人なのでそれぞれ自分のスペースで作業してました。
飲酒後ですが意外にもエンジンがかかってました。

合宿 朝の風景
そして朝。Emobileが赤いのが何とも残念ですね。(EMobileが圏外という事です)

箱根登山鉄道
箱根登山鉄道。スイッチバックを堪能しまくりでした。
また次回も開催予定ですので、今回参加された方&興味のあるかたは是非一緒に合宿しましょう!
参加された方へ:初幹事でいろいろと御迷惑おかけしてと思いますがありがとうございました。これからもよろしくお願いします。
23 Jul
さて、7.22はadobeにてspark勉強会でした。
会社を早めに出勤して、そうそうに向かったのですが、若干の遅刻。
やっぱり時間は苦手だなあ。
到着すると、Adobeの方からFlash Playerやpixel Benderなどの紹介がありました。
pixel Benderは是非試してみたいのですが、あいにく僕が持っているのはMacBookなので、まだ試す事はできなさそうです。。
MovieClipだけでなく、動画にもエフェクトがつけれるらしいですし、さらには噂では音にもエフェクトをつけられるという話しを聞いているので、とても興味があるのですが。。
Flash Player10は、Dynamic Sound Generationや、縦書きテキストの対応など、とても期待をしております。
ただ、いづれも最先端過ぎるのか、文献が少ないので習得するのは大変そうですね。
あと、FlashのSEO対策は、外部XMLとかも検索対象にしてくれるようだ、という話しを聞けたので、今後FlashはSEOに弱い!という通説が覆りそうで、楽しみです。
で、発表会。
はじめは、主催者でもある、yossy@beintaractiveさん。
Spark Projectの今までの経緯と、Actionscriptで疑似スレッドを実現する、ActionScript Thread Library 1.0 (そうめん)の紹介をされていました。
非同期処理を処理の流れ通りに記述できたり、割り込み処理や例外処理など、使いこなすとかなりASの開発が便利になりそうでした。
次は、seagirlさんの「Genius Framework」のご紹介。
シンプルで使い勝手が良さそうでした。Flexの方は一度触られてみてはいかがでしょうか?
あとは、コマンドラインでスケルトンコードを作ってくれる機能は、かなり便利なんじゃないかと思っています。
つぎは、mutsuさんのFrocessing。
テキストの扱いとか、3Dとかが比較的書きやすそうなのと、これで覚えれば本家Processingも使えるようになりそうですので、一度触ってみたいですね。
つぎは、arkwさん。
今まで全く考えていなかったような深い、深すぎるフレームについての話しが聞けて、すごく勉強になりました。
そして、最近Dynamic Sound Genrerationに興味を持っている僕が特に楽しみにしていた、
どこかでみたようなおもちゃから繰り出される音には、ただただ感激するのみでした。
勉強になります!
これがspark projectにコミットされているだなんて。すごいですね。
あまりにも文献が少ないサウンド系の情報を充実させよう!と思っていらっしゃるようです。
僕も何か力になれればと思うのですが、なかなか壁は高そうです。
サイトは、ksakaiさんの発表。
Swfを埋め込む時のタグについてや今後の方向性など、詳しいレベルでご説明いただいて、とても勉強になりました。
とってもためになる勉強会で、満足しつつ、2次会へ。
うーん。反省ですわ。。かなり気持ち悪い事を言っていたような気が。。。
しまった。
でも楽しかったです。
AIRとしょこたん。
なんか自分のやるべき事が見えた気がしました。
AIRでなんかしないとなあ。
お断り:
タグとかカテゴリーについては、無視して下さい。
21 Jul
7/21、Kayacさん主催の「ごはんとFlash 2杯目」に行ってきました。
場所が鎌倉は由比ケ浜、DONBURI BEACH CAFE bowls @鎌倉・由比ガ浜海岸でした。
http://www.crocs-bowls.com/access/
最近やろうとしては苦労していたSound周りをすでにやっていらっしゃる方や、興味のある方、システムの人やデザインの人、Flash界の著名人の方達といろんな方が参加されていました。
bowlsさんのおいしいごはんを食べつつFlashの話しなどをする、という僕にとってはこれ以上ない幸せなイベントです。
で、最後にプレゼントコーナーがありまして、
ART-Meterさんで販売している作品や、
Kayac代表の柳澤さんの書籍など、素敵な品物が次々とプレゼントされているのを見ながら、
「どうせ自分はこんなのはあたらないのよね」
とか、
「元気玉があたったら僕の夢を叶えてもらおう(*)」とか考えていたのですが、当然あたらないまま、最後へ。
発売したばっかりの、『Adobe Flash CS3 詳細!Actionscript 3.0 入門ノート』(大重美幸 著)!
全然想像もしてなかったので、驚きながらも興奮しながら頂きにステージへ。
なんと本人様からの手渡し。うれしいですね。
さらにはコメントも求められ、取り乱してしまったのですが、
「でかっ」とかおいしいところ持って行った、と行っていただけたので、個人的には大満足でした。
Flashでちゃんとなんか作りますね。

前回のごはんとFlash、さらにはおかわりと参加させて頂いていますが、本当にいいイベントを開いていただいて心から感謝いたしますよ。Kayacさんをはじめとする主催者の皆様に。
さらには昨日は京都でも開催されていて、そちらも盛り上がったようです。
このようなつながり感とか、デザインよりの人とシステムよりの人がFlashを通して一緒に話しができること、さらには音楽の人とかいろんな人とFlashというアプリケーションを通じて交流ができる、この流れがきっと(しっかり調査したわけではありませんが)他の言語とかにはない、魅力だな、と感じています。
もちろん他の技術とかも楽しいし大好きですが、こういう交流が生まれるのは本当すごいことだと思います。
ほんと本日出会えた皆様、ありがとうございました。今後ともよろしくです。
あと、
こういっといて何なのですが、最近はiPhoneの勉強会やりたいなあ、って思ってるんですが、やっぱり「Cocoa勉強会」に参加するべきですよね?
iPhoneのCocoaは、GCとかないみたいなので(Mac OS X 10.5になって、GCが搭載されるようになったようです。)
*:ここで書くと気持ち悪い人、と思われそうなので控えておきます。