-
Notifications
You must be signed in to change notification settings - Fork 0
/
feed.xml
551 lines (472 loc) · 33 KB
/
feed.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Blog Name</title>
<subtitle>Blog subtitle</subtitle>
<id>http://blog.url.com/</id>
<link href="http://blog.url.com/"/>
<link href="http://blog.url.com/feed.xml" rel="self"/>
<updated>2013-12-12T23:34:00Z</updated>
<author>
<name>Blog Author</name>
</author>
<entry>
<title>Android で意図された順序の JSON を Ti.Netwrok.HTTPClient で送信してみよう</title>
<link rel="alternate" href="/blog/2013/12/13/titaniumadventcalendar2013.html"/>
<id>/blog/2013/12/13/titaniumadventcalendar2013.html</id>
<published>2013-12-12T23:34:00Z</published>
<updated>2013-12-12T23:34:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p>こちらは <a href="http://www.adventar.org/calendars/78">Titanium™ Advent Calendar 2013</a> 用の記事になります。
余談ですが、企画された <a href="https://twitter.com/astronaughts">@astronaughts</a> さんと、最近 Facebook で友達になりました。
やったね!</p>
<h3 id="section">はじめに</h3>
<p>ぼくもちょこっとポエムを書かせてもらうと、今年は自分にとって大きな大きな 1 年でした。
JavaScript で iOS / Android アプリが書けちゃうなんて!と、ゆるい気持ちで使い始めたのですが、なんと会社まで立ち上げて Titanium 三昧でございます(最近はモジュールばかり書いていますけど)。
人生どうなるかわかりませんね。</p>
<h3 id="section-1">それでは本題に</h3>
<p>外部ウェブサービス API へ POST する際、JSON の中身が意図されている順序で送信しないと受け付けられない場合があります。
AWS S3 へ直接ファイルをアップロードする場合等がそれですね。</p>
<p>iOS の場合は <code>Ti.Network.HTTPClient</code> の <code>send()</code> メソッドで意図されている順序の JSON を渡せばその順序で送信されますが、Android の場合そうはいきません。
<a href="https://github.com/appcelerator/titanium_mobile/blob/master/android/modules/network/src/java/ti/modules/titanium/network/TiHTTPClient.java#L1095">Titanium</a> のソースコードを見てみると、Android の <code>send()</code> メソッドは <code>HashMap</code> で受け取っているため JSON の順序が保持されていません。
<code>LinkedHashMap</code> であれば保持されるそうで、この問題は起きないのですがいつかこちらに切り替わるのでしょうか(期待できません)。</p>
<p>と、言うわけで、意図した通りの順序の JSON を送信する方法を探ってみましょう。
ここでは S3 へ直接ファイルをアップロードする方法を例にあげます。</p>
<h4 id="tinetworkhttpclient--send--json-">まずはいつも通り <code>Ti.Network.HTTPClient</code> で <code>send()</code> する際に JSON を渡してしてみます</h4>
<p>file はカメラで撮影した写真のデータ(<code>Ti.Blob</code>)が格納されており、その他、各変数は S3 へアップロードするために必要な情報となります。</p>
<pre><code>var xhr = Ti.Netwrok.createHTTPClient({
onload: function(){},
onerror: function(){}
});
xhr.open(url, 'POST');
xhr.send({
"key": key,
"AWSAccessKeyId": AWSAccessKeyId,
"acl": acl,
"Content-Disposition": ContentDisposition,
"Content-Type": ContentType,
"success_action_redirect": successActionRedirect,
"x-amz-server-side-encryption": xAmzServerSideEncryption,
"policy": policy,
"signature": signature,
"file": file
});
</code></pre>
<p>iOS はこれで問題なくアップロードできます。
key から始まって file まで <code>send()</code>メソッドへ渡した際、JSON の順序が保持されているからです。
Android の場合は S3 から順序が正しくないとエラーが返却されてきます。
悲しいですね。</p>
<p><a href="http://docs.appcelerator.com/titanium/latest/#!/api/Titanium.Network.HTTPClient-method-send">リファレンス</a>を見てみましょう。
<code>send()</code> メソッドは <code>Object</code> / <code>String</code> / <code>Ti.Filesystem.File</code> / <code>Ti.Blob</code> を指定することができます。
上記の例では JSON、つまり、<code>Object</code> ですね。</p>
<h4 id="android--http-">Android で順序を保持したデータを渡すには HTTP リクエストの中身を自分で記述していきます</h4>
<p>早速 JSON から離れますが <code>String</code> で送信してみます。</p>
<p>送信データを自前で記述する場合はいくつかのお作法があります。
ファイルを送信するのでリクエストヘッダは <code>Content-Type: multipart/form-data</code> となります(JSON で渡した場合は <code>Ti.Blob</code> が入っていると、このヘッダを勝手につけてくれます)。
さらに送信する内容一つずつに自前で区切りのサインを付けていかないとなりません。
下記の例では <code>boundary</code> という変数で用意しております。
こちらは任意の文字列となりますが、頭に必ず <code>--</code> を付けてください。
例ではタイムスタンプを <code>Ti.Utils.md5HexDigest()</code> しています。
また、一番最後の区切りには末尾にも <code>--</code> が必要となります。
改行コード(<code>\r\n</code>)も自分で記述しないといけません。
とても面倒ですね…。</p>
<pre><code>// 区切り文字
var boundary = Ti.Utils.md5HexDigest('' + Date.now());
// 写真を Ti.Stream で開いて Ti.Buffer 化
var stream = Ti.Stream.createStream({
mode : Ti.Stream.MODE_READ,
source: file
});
var buffer = Ti.Stream.readAll(stream);
stream.close();
// 送信データを文字列で組み立てる
var data = '--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="key"\r\n\r\n' +
key + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="AWSAccessKeyId"\r\n\r\n' +
AWSAccessKeyId + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="acl"\r\n\r\n' +
acl + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="Content-Disposition"\r\n\r\n' +
ContentDisposition + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="Content-Type"\r\n\r\n' +
ContentType + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="success_action_redirect"\r\n\r\n' +
successActionRedirect + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="x-amz-server-side-encryption"\r\n\r\n' +
xAmzServerSideEncryption + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="policy"\r\n\r\n' +
policy + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="signature"\r\n\r\n' +
signature + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="file"; filename="image.jpg"\r\n' +
'Content-Type: binary/octet-stream\r\n\r\n' +
buffer.toString() + '\r\n' + // Ti.Buffer を文字列化
'--' + boundary + '--\r\n';
// 送信
var xhr = Ti.Netwrok.createHTTPClient({
onload: function(){},
onerror: function(){}
});
xhr.open(url, 'POST');
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
xhr.send(data);
</code></pre>
<p>写真データのファイルを <code>Ti.Stream</code> で開いて、<code>readAll()</code> で全て読み込んで <code>Ti.Buffer</code> にし、<code>toString()</code> で文字列化しています。
これでどうでしょうか。</p>
<p>アップロードは成功しますが、画像ファイルの <code>Ti.Buffer</code> を <code>toString()</code> するとゴミが付くらしく、ファイルが壊れてしまいます(自前のサーバにアップロードしたファイルをバイナリエディタで開いて正常な画像と比較して確認しました)。
これでは意味がありませんね。</p>
<p>メールをプログラムから送信したことがある方は、似たような記述をしますのでピンときたかと思います。
<code>Ti.Buffer</code> が <code>toString()</code> すると壊れてしまうのなら、<code>Ti.Blob</code> なファイルを <code>Ti.Utils.base64encode().toString()</code> し、<code>Content-Transfer-Encoding: base64</code> を付けて Base64 で送れば良いじゃない、と。
こんな感じですかね。</p>
<pre><code> 'Content-Disposition: form-data; name="file"; filename="image.jpg"\r\n' +
'Content-Type: binary/octet-stream\r\n' +
'Content-Transfer-Encoding: base64\r\n\r\n' +
Ti.Utils.base64encode(file).toString() + '\r\n' +
'--' + boundary + '--\r\n';
</code></pre>
<p>…そもそも <code>Content-Transfer-Encoding</code> は<a href="https://forums.aws.amazon.com/thread.jspa?threadID=108144">メール用</a>なんですね。
もちろん S3 はこのヘッダを受け付けてくれませんので、テキストファイルとしてアップロードされてしまいます。</p>
<p>それではどうするのか。</p>
<h4 id="send--tiblob-"><code>send()</code> メソッドに <code>Ti.Blob</code> として送信データを渡します</h4>
<pre><code>// 区切り文字
var boundary = Ti.Utils.md5HexDigest('' + Date.now());
// 送信データを Ti.Buffer で組み立てる
data = Ti.createBuffer({
value: '--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="key"\r\n\r\n' +
key + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="AWSAccessKeyId"\r\n\r\n' +
AWSAccessKeyId + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="acl"\r\n\r\n' +
acl + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="Content-Disposition"\r\n\r\n' +
ContentDisposition + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="Content-Type"\r\n\r\n' +
ContentType + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="success_action_redirect"\r\n\r\n' +
successActionRedirect + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="x-amz-server-side-encryption"\r\n\r\n' +
xAmzServerSideEncryption + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="policy"\r\n\r\n' +
policy + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="signature"\r\n\r\n' +
signature + '\r\n' +
'--' + boundary + '\r\n' +
'Content-Disposition: form-data; name="file"; filename="image.jpg"\r\n' +
'Content-Type: binary/octet-stream\r\n\r\n'
});
// 写真を Ti.Stream で開いて Ti.Buffer 化し、送信データへ追加
stream = Ti.Stream.createStream({
mode : Ti.Stream.MODE_READ,
source: file
});
data.append(Ti.Stream.readAll(stream));
stream.close();
// 最後の区切り文字を追加
data.append(Ti.createBuffer({
value: '\r\n--' + boundary + '--\r\n'
}));
// 送信
var xhr = Ti.Netwrok.createHTTPClient({
onload: function(){},
onerror: function(){}
});
xhr.open(url, 'POST');
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
xhr.send(data.toBlob());
</code></pre>
<p>これでどうでしょう。
見事ファイルも壊れずアップロードすることができました。</p>
<p>ザックリと何をしているかというと、<code>Ti.Buffer</code> として送信データを作って、最後に <code>toBlob()</code> で <code>Ti.Blob</code> 化して送信しています。
正直、何を書いているのか、わけがわからなくなりますね。</p>
<h4 id="html-">最後にHTML のフォームに例えてみましょう</h4>
<pre><code>&lt;form action="url" method="post" enctype="multipart/form-data"&gt;
&lt;input type="hidden" name="key" value="key"&gt;
&lt;input type="hidden" name="AWSAccessKeyId" value="AWSAccessKeyId"&gt;
&lt;input type="hidden" name="acl" value="acl"&gt;
&lt;input type="hidden" name="Content-Disposition" value="ContentDisposition"&gt;
&lt;input type="hidden" name="Content-Type" value="ContentType"&gt;
&lt;input type="hidden" name="success_action_redirect" value="successActionRedirect"&gt;
&lt;input type="hidden" name="x-amz-server-side-encryption" value="xAmzServerSideEncryption"&gt;
&lt;input type="hidden" name="policy" value="policy"&gt;
&lt;input type="hidden" name="signature" value="signature"&gt;
&lt;input type="file" name="file"&gt;
&lt;input type="submit" value="send"&gt;
&lt;/form&gt;
</code></pre>
<p>HTML だととても簡単ですね!</p>
<h3 id="section-2">〆</h3>
<p>少々コードが煩雑になってしまうのであまりオススメできませんが、どうしてもという方はこちらの方法で送信することができます。
ぼくは早く <code>LinkedHashMap</code> にならないかと、首を長くして待っております(まったく期待できません)。</p>
<h3 id="section-3">14日目の方</h3>
<p><a href="https://twitter.com/h5y1m141">@h5y1m141</a> さんです。
ACS ネタ、楽しみですね!</p>
</content>
</entry>
<entry>
<title>Titanium で DKLiveBlur を使おう</title>
<link rel="alternate" href="/blog/2013/09/02/tidkliveblur.html"/>
<id>/blog/2013/09/02/tidkliveblur.html</id>
<published>2013-09-02T08:22:00Z</published>
<updated>2013-09-02T08:22:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p>みなさま、iOS7 対応いかがでしょうか?
ぼくはいま作っている趣味アプリを iOS7 風な見た目にするべくがんばっている最中です。</p>
<p>さて、今回は <a href="https://github.com/k0sukey/TiDKLiveBlur">TiDKLiveBlur</a> のご紹介です。</p>
<p><img src="/images/blog/TiDKLiveBlur.png" alt="TiDKLiveView" /></p>
<p><a href="https://github.com/kronik/DKLiveBlur">DKLiveBlur</a> という、スクロールできるビューの背景画像へ、スクロールさせると動的に曇ったような、スリガラス効果を加えてくれるライブラリを Titanium でも利用できるようにしたモジュールです。
これで iOS7 風なビューを作ることができますね!</p>
<p>それでは簡単な使い方をご説明します。
このモジュールはソースコード内で require する必要はありません。
tiapp.xml の &lt;module&gt; に記述するだけで Ti.UI.TableView と Ti.UI.ListView にスリガラス効果を提供します。</p>
<pre><code>&lt;modules&gt;
&lt;module platform="iphone"&gt;be.k0suke.tidkliveblur&lt;/module&gt;
&lt;/modules&gt;
</code></pre>
<p>Ti.UI.TableView を例にしてみましょう。</p>
<pre><code>var tableView = Ti.UI.createTableView({
backgroundBlurImage: '/background.png',
glassColor: '#fff', // optional, default #fff
data: [
{ title: 'row0' },
{ title: 'row1' },
{ title: 'row2' },
{ title: 'row3' },
{ title: 'row4' },
{ title: 'row5' },
{ title: 'row6' },
{ title: 'row7' },
{ title: 'row8' },
{ title: 'row9' }
]
});
</code></pre>
<p>Ti.UI.TableView(Ti.UI.ListView)に backgroundBlurImage と glassColor というプロパティが指定できるようになります。
backgroundBlurImage にはスリガラス効果を加えたい背景画像を指定してください(backgroundImage と同じように、リモートの画像を指定することはできません)。
glassColor は色を指定できます。
デフォルトは白ですが、Titanium で指定できるカラーコードならなんでも指定することができますので、色々お試しください。</p>
<p>一点注意が必要で、ある程度のデータ数がないとスクロールできる縦幅が発生しないので、データ数が少ない場合スリガラス効果が発生しないでスクロールが終了してしまう可能性があります。
Ti.UI.TableView であれば、setContentInsets メソッドで top のマージンをある程度確保してあげれば、良い感じに効果が発生するかと思います(現時点での最新版 SDK3.1.2.GA で Ti.UI.ListView の setContentInsets は残念ながら未実装です)。</p>
<pre><code>tableView.setContentInsets({
top: 400,
right: 0,
bottom: 0,
left: 0
});
</code></pre>
<p>というわけで、DKLiveBlur を Titanium で使えるようにするモジュールのご紹介でした。</p>
</content>
</entry>
<entry>
<title>Titanium で ISRefreshControl を使おう</title>
<link rel="alternate" href="/blog/2013/08/22/tiisrefreshcontrol.html"/>
<id>/blog/2013/08/22/tiisrefreshcontrol.html</id>
<published>2013-08-22T07:30:00Z</published>
<updated>2013-08-22T07:30:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p>Titanium で Pull-to-Refresh、イベント処理(scroll / dragend)やフラグ管理が面倒ですよね。
最近だと <a href="https://twitter.com/FokkeZB">@FokkeZB</a> さん作の <a href="https://github.com/FokkeZB/nl.fokkezb.pullToRefresh">nl.fokkezb.pullToRefresh</a> が Alloy の Widget として使えて、ずいぶん便利になってきています。</p>
<p>ただ、やっぱり iOS6 から使える、UIRefreshControl が使いたいところです。
びよーんって伸びて無駄に引っ張りたくなっちゃいます。
Titanium でも使いたくて UIRefreshControl したくて<a href="https://github.com/k0sukey/TiExtendView">モジュール</a>を書いたりしましたが、iOS6 のみなのがネックでした。</p>
<p><img src="/images/blog/TiISRefreshControl.png" alt="TiISRefreshControl" /></p>
<p>そこで <a href="https://github.com/ishkawa/ISRefreshControl">ISRefreshControl</a> の力を借りてしまおうということです。
これは iOS4 / iOS5 でも UIRefreshControl の様に振る舞ってくれる、素敵なライブラリです。
何としてでも Titanium で使いたいところです。</p>
<p>と、言うわけで、<a href="https://github.com/k0sukey/TiISRefreshControl">TiISRefreshControl</a> を書きました。
それでは簡単な使い方をご説明します。
このモジュールはソースコード内で require する必要はありません。
tiapp.xml の &lt;module&gt; に記述するだけで Ti.UI.TableView と Ti.UI.ListView に Pull-to-Refresh を提供します。</p>
<pre><code>&lt;modules&gt;
&lt;module platform="iphone"&gt;be.k0suke.tiisrefreshcontrol&lt;/module&gt;
&lt;/modules&gt;
</code></pre>
<p>Ti.UI.TableView を例にしてみましょう。以下のコードだけで簡単に Pull-to-Refresh の挙動を実現することができます。</p>
<pre><code>var tableView = Ti.UI.createTableView({
data: [
{ title: 'row0' },
{ title: 'row1' },
{ title: 'row2' },
{ title: 'row3' },
{ title: 'row4' },
{ title: 'row5' },
{ title: 'row6' },
{ title: 'row7' },
{ title: 'row8' },
{ title: 'row9' }
]
});
tableView.addEventListener('refreshstart', function(){
setTimeout(function(){
tableView.refreshFinish();
}, 5000);
});
</code></pre>
<p>では、実際にデータを取得してからの処理はどうでしょうか。
Alloy のデータバインディングとあわせてご覧ください。</p>
<h2 id="view">View</h2>
<pre><code>&lt;Window&gt;
&lt;ListView id="lists" defaultItemTemplate="list"&gt;
&lt;Templates&gt;
&lt;ItemTemplate name="list"&gt;
&lt;Label bindId="name" class="name"/&gt;
&lt;/ItemTemplate&gt;
&lt;/Templates&gt;
&lt;ListSection id="section" dataCollection="lists" dataTransform="doTransform"&gt;
&lt;ListItem template="list" name:text="{name}"/&gt;
&lt;/ListSection&gt;
&lt;/ListView&gt;
&lt;/Window&gt;
</code></pre>
<h2 id="controller">Controller</h2>
<pre><code>var lists = Alloy.Collections.lists;
function doTransform(model) {
return model.toJSON();
}
$.lists.addEventListener('refreshstart', function(){
lists.fetch({
success: function(){
$.lists.refreshFinish();
},
error: function(){
$.lists.refreshFinish();
}
});
});
$.index.addEventListener('open', function(){
$.lists.refreshBegin();
});
$.index.open();
</code></pre>
<p>ウィンドウである $.index を開くと同時に Ti.UI.ListView の refreshBegin メソッドを実行します。
このメソッドは、ListView を引っ張る挙動をコードから実行してくれます。
データの受信が完了したら refreshstart イベントが発火すると lists コレクションのフェッチが実行されます。
データの受信が成功失敗にかかわらずインジケータを消してあげないといけませんので、success / error 両方で refreshFinish メソッドを実行します。</p>
<p>というわけで、簡単に UIRefreshControl を Titanium で使えるようにするモジュールのご紹介でした。
他にも細かなメソッドやイベントがありますので、詳しくは <a href="https://github.com/k0sukey/TiISRefreshControl">GitHub の README</a> をご覧ください。</p>
</content>
</entry>
<entry>
<title>Alfred と Dash の連携で Titanium API ドキュメントを見よう</title>
<link rel="alternate" href="/blog/2013/07/18/titanium-in-alfred-and-dash.html"/>
<id>/blog/2013/07/18/titanium-in-alfred-and-dash.html</id>
<published>2013-07-17T23:30:00Z</published>
<updated>2013-07-17T23:30:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p>最近教えていただいて、すごく捗るようになったのでご紹介します。
今までは <a href="http://docs.appcelerator.com/titanium/latest/">Appcelerator の公式サイト</a>を読むことが多かったのですが、ネット環境がない場所では見ることさえできなくて困っていました。
Sublime Text 2 でオフラインアクセスできるプラグインを作ったりもしましたが、どうにも見辛い…。</p>
<p>たまたま参加した <a href="http://talknote.me/vol8/event/">TalkNote × Frontrend</a> で、JavaScript のドキュメントは <a href="http://kapeli.com/dash">Dash</a> で簡単にオフラインで見ることができますよ、しかも <a href="http://www.alfredapp.com/">Alfred</a> と連携すると捗りますよとお聞きしました。
普段から Titanium で JavaScript を書いていますので、これは良いことを聞いたと早速設定していたら… Titanium もあったー!と、いうことなのです。</p>
<p><img src="/images/blog/2013-07-18/dash-hud.png" alt="dash-hud" /></p>
<ol>
<li>
<p>まずは Alfred と Dash をインストールしましょう。これがないと始まりません。
Dash は有償ですが、たまに出てくる広告付きで無償のまま利用できます</p>
</li>
<li>
<p>Dash を起動して、Downloads の中から Appcelerator Titanium x.x.x をダウンロードします。
この状態で、すでに Dash 単体で Titanium の API ドキュメントが閲覧可能です
(Alloy な方はついでに BackboneJS と UnderscoreJS もダウンロードしておくと更に捗りますね)。
Automatically download and install updates にチェックをしておくと、ドキュメントがバージョンアップした時勝手に更新してくれて便利です
<img src="/images/blog/2013-07-18/dash-download.png" alt="dash-download" /></p>
</li>
<li>
<p>Alfred を起動して、Preferences から Fetures → Web Search を選択し、右下にある Add Custom Search をクリックします。
Search URL は画像の通り入力してください。
Title は他のものとあわせてあります。
Keyword はお好みのもので。
ぼくの場合はいつも無意識でタイプする、おなじみの「ti」ですね
<img src="/images/blog/2013-07-18/alfred-setting.png" alt="alfred-setting" /></p>
</li>
<li>
<p>以上で完了です。
おもむろにホットキーで Alfred を呼び出し、「ti window」と入力してエンターを叩いてください。
冒頭のスナップショットのように、Dash が表示されましたか?
ダメだった方は 3. の設定を見なおしてみてください
<img src="/images/blog/2013-07-18/alfred-dash.png" alt="alfred-dash" /></p>
</li>
</ol>
<p>余談ですが、ぼくは Dash の表示を HUD モードにしています。
コードを書きながら、調べたい時に Dash でドキュメントを表示→エディタに戻る→きれいサッパリ Dash がいなくなっている。
この、コーディングをじゃまされない感が本当に快適で、そろそろ Dash にお金を支払おうと思っているところでした
(HUD モードは、Dash の General → Window style から変更することができます)</p>
</content>
</entry>
<entry>
<title>Titan になりました</title>
<link rel="alternate" href="/blog/2013/07/11/titan.html"/>
<id>/blog/2013/07/11/titan.html</id>
<published>2013-07-11T07:49:00Z</published>
<updated>2013-07-11T07:49:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p>みなさまこんにちは。
本日は特別なご挨拶をさせていただきます。
この度、Titanium Titans の一員に加えさせてもらえることになりました(<a href="http://developer.appcelerator.com/devlink/profile/1233606">DevLink のプロフィールページ</a>をご覧ください)。</p>
<p>思い起こせば私が Titanium Mobile と出会ってからもうすぐ、2 年と半年を迎えようとしております。
飽きっぽい性格の私がここまで一つの技術を追い続けてこられたのも、Titanium Mobile 自体が面白いこともさることながら、日本の Titanium コミュニティが最高だということです。</p>
<p>Titan の名に恥じぬよう、微力ながら引き続き Titanium コミュニティへ貢献して参りますので、今後ともよろしくお願いいたします!</p>
</content>
</entry>
<entry>
<title>iOS のプリセットサウンドを鳴らそう</title>
<link rel="alternate" href="/blog/2013/06/24/ios.html"/>
<id>/blog/2013/06/24/ios.html</id>
<published>2013-06-24T05:01:00Z</published>
<updated>2013-06-24T05:01:00Z</updated>
<author>
<name>Article Author</name>
</author>
<content type="html"><p><a href="/blog/2013/06/23/ticameraview.html">TiCameraView</a> の副産物で iOS のプリセットサウンドを鳴らすモジュールを作りました。
そもそも Titanium Mobile で API が用意されていると思ったのですがありませんでした。
このモジュールのソースコードは GitHub にありますのでご自由にお使いください。
<a href="https://github.com/k0sukey/TiSystemSound">k0sukey/TiSystemSound</a></p>
<h3 id="section">使い方</h3>
<p><a href="https://github.com/k0sukey/TiSystemSound/blob/master/example/app.js">example/app.js</a> をビルドすると、このモジュールで鳴らすことのできるすべてのサウンドを Ti.UI.TableView で表示&確認できます。
モジュールを require したら <code>play()</code> するだけです。
簡単ですね。
<small class="muted">typo があるかもしれませんので、発見したらぜひご連絡ください。</small></p>
<pre><code>var TiSystemSound = require('be.k0suke.tisystemsound');
TiSystemSound.play(TiSystemSound.NEW_MAIL);
</code></pre>
<h3 id="section-1">プロパティとメソッド</h3>
<h3 id="section-2">プロパティ</h3>
<p>ありません。</p>
<h3 id="section-3">メソッド</h3>
<h4 id="play">play</h4>
<p>プリセットサウンドを再生します。
TiSystemSound.<code>NEW_MAIL</code> / <code>MAIL_SENT</code> / <code>VOICEMAIL</code> / <code>RECEIVED_MESSAGE</code> / <code>SENT_MESSAGE</code> / <code>ALARM</code> / <code>LOW_POWER</code> / <code>SMS_RECEIVED1</code> / <code>SMS_RECEIVED2</code> / <code>SMS_RECEIVED3</code> / <code>SMS_RECEIVED4</code> / <code>SMS_RECEIVED5</code> / <code>SMS_RECEIVED6</code> / <code>TWEET_SENT</code> / <code>ANTICIPATE</code> / <code>BLOOM</code> / <code>CALYPSO</code> / <code>CHOO_CHOO</code> / <code>DESCENT</code> / <code>FANFARE</code> / <code>LADDER</code> / <code>MINUET</code> / <code>NEWS_FLASH</code> / <code>NOIR</code> / <code>SHERWOOD_FOREST</code> / <code>SPELL</code> / <code>SUSPENSE</code> / <code>TELEGRAPH</code> / <code>TIPTOES</code> / <code>TYPEWRITERS</code> / <code>UPDATE</code> / <code>USSD</code> / <code>SIMTOOLKITCALLDROPPED</code> / <code>SIMTOOLKITGENERATEBEEP</code> / <code>SIMTOOLKITNEGATIVEACK</code> / <code>SIMTOOLKITPOSITIVEACK</code> / <code>SIMTOOLKITSMS</code> / <code>TINK</code> / <code>CT_BUSY</code> / <code>CT_CONGESTION</code> / <code>CT_PATH_ACK</code> / <code>CT_ERROR</code> / <code>CT_CALL_WAITING</code> / <code>CT_KEYTONE2</code> / <code>LOCK</code> / <code>UNLOCK</code> / <code>TOCK</code> / <code>BEEP_BEEP</code> / <code>RINGER_CHANGED</code> / <code>PHOTO_SHUTTER</code> / <code>SHAKE</code> / <code>JBL_BEGIN</code> / <code>JBL_CONFIRM</code> / <code>JBL_CANCEL</code> / <code>BEGIN_RECORD</code> / <code>END_RECORD</code> / <code>JBL_AMBIGUOUS</code> / <code>JBL_NO_MATCH</code> / <code>BEGIN_VIDEO_RECORD</code> / <code>END_VIDEO_RECORD</code> / <code>VC_INVITATION_ACCEPTED</code> / <code>VC_RINGING</code> / <code>VC_ENDED</code> / <code>DTMF_0</code> / <code>DTMF_1</code> / <code>DTMF_2</code> / <code>DTMF_3</code> / <code>DTMF_4</code> / <code>DTMF_5</code> / <code>DTMF_6</code> / <code>DTMF_7</code> / <code>DTMF_8</code> / <code>DTMF_9</code> / <code>DTMF_STAR</code> / <code>DTMF_POUND</code> / <code>LONG_LOW_SHORT_HIGH</code> / <code>SHORT_DOUBLE_HIGH</code> / <code>SHORT_LOG_HIGH</code> / <code>SHORT_DOUBLE_LOW</code> / <code>MIDDLE_9_SHORT_DOUBLE</code> から選択してください。</p>
<h3 id="section-4">参考にさせていただいたサイト</h3>
<ul>
<li><a href="http://iphonedevwiki.net/index.php/AudioServices">AudioServices - iPhone Development Wiki</a></li>
</ul>
</content>
</entry>
</feed>