smartphone development guide with coffeescript + node + html5 technology, for perl programmers

47
Perlプログラマのための スマートフォン開発ガイド CoffeeScript / Node / HTML5 Naoya Ito

Upload: naoya-ito

Post on 20-Aug-2015

8.798 views

Category:

Technology


2 download

TRANSCRIPT

Perlプログラマのための スマートフォン開発ガイド

CoffeeScript / Node / HTML5

Naoya Ito

キーワード

• PhoneGap

• Titanium Mobile

• CoffeeScript

• Node.js

• Socket.IO

• Express

• npm

• …

半年ほど前

一ヶ月前

今週

“Embedded Web Vies”

Web UI

モチベーション

ネイティブと Web App のハイブリッドへ

• HTML5アプリケーションをネイティブで補う...

• ネイティブをWeb技術 (スクリプト言語) で作る...

アジェンダ

• クライアントサイド

• PhoneGap

• Titanium Mobile

• Scripting Layer for Android

• サーバーサイド

• Node or Perl

クライアントサイド

PhoneGap, Titanium Mobile, Scripting Layer for Android

スクリプト言語で iOS/Android アプリ

• HTML5

• Web開発、同様スクリプト言語で書きたい!

• JavaScript, CoffeeScript

• スクリプト言語な俺たち歓喜 \(^o^)/

• Perl で書ける?

PhoneGap

PhoneGap

• UIWebView ベースのアプリ開発 F/W

• JavaScript / HTML / CSS

• UIWebView の js に Native Bridge な API

• Phone"Gap"

navigator.camera.getPictures(onSuccess, onFail) onSuccess = function (base64data) { var img = document.getElementById('myImage'); img.src = "data:image/jpeg;base64;" + base64data; }

例: Photo Receiver

• PhoneGap (+ jQuery mobile) + Node (+ Express + Socket.IO)

iOS app with PhoneGap Node

WebSocket (Socket.IO)

Photo Receiver (sender, index.html)

<html> <head> ... <script type="text/javascript" src="phonegap-1.0.0.js"></script> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript" src="socket.io.min.js"></script> ... <script type="text/javascript" src="sender.js"></script> </head> <body> <div data-role="page"> <div data-role="header" data-theme="b"> <h1>Photo Sender</h1> </div> ...

Photo Receiver (sender, sender.coffee)

onDeviceReady = -> socket = io.connect 'http://localhost:3000/sender' onSuccess = (data) -> socket.emit 'pushPhoto', data ... $('#camera').click -> navigator.camera.getPicture onSuccess, onFailure, opt $(document).ready -> $(document).bind 'deviceready', onDeviceReady

# sender.coffee の変更を watch → sender.js を生成 $ coffee -cw *.coffee

Photo Receiver (receiver, app.coffee)

express = require "express" app = module.exports = express.createServer() app.get "/", (req, res) -> res.render "index", title: "Photo Receiver" app.listen 3000 io = require('socket.io').listen app sender = io.of('/sender').on 'connection', (socket) -> socket.on 'pushPhoto', (data) -> data_uri = "data:image/jpeg;base64," + data receiver.emit 'showPhoto', data_uri

PhoneGap あれこれ

• HTML + JS = "HTML5 ready" • jQuery / jQuery mobile

• CoffeeScript

• socket.io

• sass, less, stylus

• Facebook/Google+ と似ているが... • UIKit の制御は bridge しない

• UIWebView は Safari より遅い • UIWebView = not Nitro

• JITコンパイラなし

• Adobe が買収 • Native → HTML5 アプローチとして PhoneGap モデルは有力

Titanium Mobile

Titanium Mobile

• ネイティブアプリを JavaScript で

• Titanium Studio でビルド

• インタプリタ上で動く

• iOS : JavascriptCore / Android : Rhino

• JSエンジンがUIKitを操作

• 動的に動作確認できる

例: Cover Flow

Cover Flow

win = Ti.UI.currentWindow() view = Ti.UI.createCoverFlowView images: [ '../images/01.jpg' '../images/02.jpg' '../images/03.jpg' '../images/04.jpg' '../images/05.jpg' ] backgroundColor: '#000' win.add view

例: HBFav

https://github.com/naoya/HBFav

HBFav

• クライアント

• Titanium Mobile

• CoffeeScript

• サーバー

• Node.js

• Express

• xml2json

• Heroku

HBFav コード断片

require 'lib/underscore' Ti.include 'feed.js' class AbstractState toString : () -> 'AbstractState' constructor: (@feedView) -> getFeed : (url) -> self = @ onload = @.onload onerror = @.onerror xhr = Ti.Network.createHTTPClient() xhr.timeout = 100000 xhr.open 'GET', url xhr.onload = -> data = JSON.parse @.responseText onload.apply(self, [ data ]) xhr.onload = null xhr.onerror = null xhr = null xhr.onerror = (err) -> onerror.apply(self, [ err ]) xhr.send()

Titanium Mobile あれこれ

• JavaScript ready

• CoffeeScript

• CommonJS ・・・ underscore, socket.io etc.

• Titanium Mobile != HTML5

• JavaScript だからといって HTML5 へ向かってるわけではない

• 「JS でネイティブ書ける」

• 現時点では、現実的な解

• 実用的だが当然、トレードオフも – メモリ管理不要、ダイナミック更新、ラピッドに開発可

– ネイティブとは速度差 / 細かなチューニングが難しい

– デバッグ環境がこなれていない

Scripting Layer for Android (SL4A)

• Androidアプリを Perl で

• ここは YAPC だぜ?

use Android my $android = Android->new; $android->makeToast( "Hello, Android!" );

SL4A

• PhoneGap, Titanium とも別アプローチ

• Java アプリが "Scripting Layer" と JSON-RPC で通信

• Java アプリのAPIがネイティブの機能をブリッジ

• 本格的なアプリを作るのには向かない

• 速度、安定性...

クライアントサイドまとめ

• JavaScript によるネイティブブリッジFWは発展途上

• この方向性のフレームワークは増える

• PhoneGap, Titanium Mobile は"そこそこ" 実用的

• ※ debug しんどい

• Facebook/G+ の言う "Embedded Web Views" のFWはまだ

• UIWebView アプリを作りつつ

• ネイティブの "UI" と橋渡し

• Perl でクライアントサイドは、さすがに ...

• SL4A はおもちゃの領域を出ない

サーバーサイド

Node vs Perl

サーバサイド

• これまで通り Perl で書いても良いですが・・・

• クライアントを JS で、なら、サーバも JSで

• この流れは止められない

• Node.js : server-side JavaScript が現実的に

Node.js

• Perl と比較しながら見ていきたい

perl vs Node

Perl Node.js

プリプロセッサ N/A CoffeeScript

言語 Perl言語 JavaScript

実行環境 perlインタプリタ node

ウェブ実行環境 mod_perl, PSGI middleware, etc.

http.Server, connect etc.

Web Framework Catalyst, Mojolicious::Lite, Dancer etc.

Express, etc.

パッケージ管理 cpan npm

主なWebアプリのモデル prefork (同期) Single Process Event Driven (非同期)

Node.js

• Single Process Event Driven な server-side JavaScript Engine – Perl : POE, AnyEvent

http = require 'http' http.createServer (req, res) -> res.writeHead 200, 'Content-Type':'text/plain' res.end 'Hello World!¥n' .listen 8080

• Perl でできないことをやってるわけではない

• 一方の「手軽さ」、JavaScript との相性

% node-dev hello.coffee

npm

$ npm install express

cpanm Mojolicious::Lite

search.npmjs.org

underscore.js

require 'underscore' pow = _([1, 2, 3]).map (n) -> n * 2 max = _([1, 2, 3]).max() sum = _([1, 2, 3]).reduce (memo, num) -> memo + num use List::Util qw/max reduce/; my $pow = map { $_ * 2 } (1, 2, 3); my $sum = reduce { $a + $b } (1, 2, 3); my $max = max(1, 2, 3);

Express

express = require "express" app = module.exports = express.createServer() app.configure -> app.set 'view engine', "jade" app.use express.compiler src: __dirname + "/public" enable: [ "sass" ] app.get "/", (req, res) -> res.render "index", title: "Hello, Express"

• Web framework, Sinatra inspired

• Perl ... Mojolicious::Lite etc

• SASS/LESS/Stylus, Coffee, Jade/EJS, Socket.IO ready – emerging web technologies...

vows

vows = require 'vows' assert = require 'assert' test = vows.describe('ゼロでの割り算').addBatch '任意の数をゼロで割った時' : topic: -> 42 / 0 '無限大になる' : (topic) -> assert.equal topic, Infinity 'ただし、ゼロをゼロで割った場合' topic: -> 0/ 0 '以下となる' : '数値でない' : (topic) -> assert.isNan topic '自分自身とは等価でない' : -> assert.notEqual topic, topic do test.run

• Perl : Test::More, Test::Base, Test::Declare

• vows : Asynchronous BDD

xml2js

parser = new xml2js.Parser() parser.addListener 'end', (json) -> console.log json parser.parseString xml

• Perl : XML::Simple + JSON

aws-lib

aws = require 'aws-lib' aws = aws.createProdAdvClient( accessKey, secretKey, associateId, region: "JP" host: 'ecs.amazonaws.jp' ) aws.call "ItemSearch", SearchIndex: "Books" Title: "Perl" ItemPage: 1 ResponseGroup: 'Medium' (result) -> console.log result

• Perl : Net::Amazon

Node modules

https://github.com/joyent/node/wiki/modules

Socket.IO

• WebSocket-like API

– 抽象化 : WebSocket, xhr-polling, xhr-multipart, jsonp-polling ....

• Node.js の急先鋒

/* client (jade w/ express) */ script(src='/socket.io/socket.io.js') :coffeescript socket = io.connect 'http://localhost’ socket.on 'recv', (data) -> console.log data socket.emit 'send', "Hello!"

/* server (app = express object) */ io = require('socket.io').listen app io.sockets.on 'connection', (socket) -> socket.on 'send', (data) -> console.log data socket.emit 'recv', data

pocketio

• Perl の Socket.IO server – JS ⇔ Perl

– JS ⇔ Perl ⇔ Perl modules

use PocketIO; use Plack::Builder; builder { mount '/socket.io' => PocketIO->new handler => sub { my $self = shift; $self->on( 'recv' => sub { my ($socket, $data) = @_; $socket->emit('send', $data); }); ...

サーバサイドまとめ

• Node きてる – スマートフォン開発のバックエンドを Node にする"必然性"はないが

– クライアントを JS / Coffee で書くなら"優位性"はある

• npm++

• CommonJS ウマー

• node ・・・ 新しいn実装が多い

• Socket.IO

• CSS frameworks

• 一方の perl ・・・ 莫大な資産 = CPAN

• node / perl の pro/cons を比較して

• (1) アーキテクチャ

• 共存させるアプローチ ・・・ RPC, pocketio

まとめ

• スマートフォン : 今後、ネイティブからHTML5へ • Facebook/Google+

• × 100% HTML5 ○ ハイブリッド

• JS (Coffee) のみでアプリが開発できるように • PhoneGap, Titanium Mobile

• クライアントからサーバまで一気通関 • クライアントが JS なら、Node 利用の動機は大きい

• Native → HTML5 への移行は JavaScript の進化にアリ

• Node.js = Web Dev の梁山泊に (beyond Rails...?) • socket.IO / express / jade, stylus, coffeekup, CSS FW / coffee ...

• ただし、Node だけではサポートできない領域もまだまだ

• Perl の莫大な資産は活かしたい • pocketio などのアプローチ