Edited at
TitaniumDay 11

「LINEで送る」をTitaniumで(2014年版)

More than 3 years have passed since last update.

Titanium製のアプリからLINEへ画像を送るといえば、@yagi_さんのこのブログエントリですね。異論はありません。

ただ残念ながらこの記事の内容、今は動きませんでした。。。正確に言うと、iOS7以降の端末では動かないんです。記事内で紹介されているTiCustomPasteboardがラップしているUIPasteboardがiOS7のタイミングで大幅に仕様を変更したことが原因です。このときの変更以来、アプリをまたいでのクリップボード共有にはGeneralPasteboardという仕組みを使うことが必須となっています。

最近つくったアプリで必要になったため色々調べて動くようにした顛末をまとめました。


TiCustomPasteboardでアプリ間共有

ここを長々と書いてもしょうがないので結論だけ。モジュールを改修しました。まだ本家にマージされていませんのでここにおいてあるのをダウンロードすれば使えます。なお、きっと近いうちに@donayamaさんがマージしてくれると思いますので、マージされたら本家のほうから落としてくることをオススメします。 変更したコードを@donayamaさんにTiCustomPasteboardにマージしていただきましたので、最新版を落としてくれば大丈夫です。(12/13追記)


本題:LINEへ画像をおくる(2014年版)

Alloyを使った場合の実装例です。画面に表示したImageViewをタップするとその画像をLINEに送るシンプルなものです。なお画像ファイルはapp/assets/stamp.pngのファイル名で格納しておくものとします。


alloy.js

Alloy.Globals.Pasteboard = require('jp.hsj.ticustompasteboard');



views/index.xml

<Alloy>

<Window>
<ImageView id="stamp"></ImageView>
</Window>
</Alloy>


style/index.tss

"#stamp": {

height: 320,
image: 'stamp.png',
width: 370
}


controllers/index.js

var PB_NAME = Alloy.Globals.Pasteboard.getGeneralPasteboardName();

$.stamp.addEventListener('click', function(e) {
if (Ti.Platform.canOpenURL('line://msg/text/a')) {
Alloy.Globals.Pasteboard.setGeneralImage(e.source.toBlob());
Ti.Platform.openURL('line://msg/image/' + PB_NAME);
} else {
alert('LINEがインストールされていません。');
}
});

$.index.open();


ここで出てくるsetGeneralImage()というのが今回のキモです。他のアプリから上書きされる可能性がある領域なので、openURL()を実行する直前に画像のバイナリを渡してあげます。なおLINEに送信するPastboardNameはgetGeneralPasteboardName()で取得できます。


ちなみにiOS・Android両対応版は

せっかくTitaniumでつくるんだからAndroidにも対応したいですよね。こちらは画像ファイルをテンポラリ領域にコピーしてパスを渡せばいいだけなので簡単です。ということで、両プラットフォーム対応版にするとこんな感じになります。


alloy.js

if (OS_IOS) {

Alloy.Globals.Pasteboard = require('jp.hsj.ticustompasteboard');
}


views/index.xml

<Alloy>

<Window>
<ImageView id="stamp"></ImageView>
</Window>
</Alloy>


style/index.tss

"#stamp": {

height: '320dp',
image: 'stamp.png',
width: '370dp'
}


controllers/index.js

if (OS_IOS) {

var PB_NAME = Alloy.Globals.Pasteboard.getGeneralPasteboardName();
}

$.stamp.addEventListener('click', function(e) {
if (OS_IOS) {
if (Ti.Platform.canOpenURL('line://msg/text/a')) {
Alloy.Globals.Pasteboard.setGeneralImage(e.source.toBlob());
Ti.Platform.openURL('line://msg/image/' + PB_NAME);
} else {
alert('LINEがインストールされていません。');
}
} else {
var src = Ti.Filesystem.getFile(Ti.Filesystem.resourcesDirectory + '/stamp.png');
var tmp = Ti.Filesystem.tempDirectory + '/tmp_stamp.png';
src.copy(tmp);
if (!Ti.Platform.openURL('line://msg/image/' + tmp)) {
alert('LINEがインストールされていません。');
}
}
});

$.index.open();


実際にアプリに組み込むときには複数の画像から選択して、それを送るようなフローになることが多いかと思います。その場合、AndroidではTi.Filesystem.tempDirectoryの中に保存するファイル名を都度変えてあげる必要があるようです。キャッシュが残っているのか、送信元の端末のLINE画面には別々の画像が表示されているのに、送信先のユーザの手元には最初に送ったものと同じ画像が表示される現象が発生しました。詳しく検証できていませんが要注意ということで。

さて、明日のTitanium Advent Calendarはstar__hoshiさんです。