2012年11月30日金曜日

[Titanium奮闘記4日目]そういえば誕生日でした #TitaniumJP


○ついに嫌いなJSONさんに挑む

JSONにてデータベースを作成したのちにテストをしてみたところ、謎のエラーが出てくる。

[ERROR] Script Error = Unable to parse JSON string at app.js (line 16).

JSONをパースが出来ない?
なんでやねん!と思ったらJSONファイルの書き方がおかしかっただけだった。ぐぬぬ。

JSONは、JavaScript Object Notation の名前からわかるように、JSととても親和性のあるデータ形式なんですよね。

名前と値がワンセットになっていて、「"name":"Vista7010"」とか、「"number": 123」とかいう書き方。

オブジェクトは{ }←このカッコで閉じてあげる。配列は[ ]←このカッコで閉じてあげる。

なので、まとめるとこういうふうな書き方です。


{
     "name":"Vista7010",
     "status": "やばい",
     "number": 123,
     "like": ["game","reading","travel"]
}



○2回に1回出るエラー

あと気になるのは最近出るこのエラー

[ERROR] Error: Traceback (most recent call last):
  File "/Users/(ユーザー名)/Library/Application Support/Titanium/mobilesdk/osx/2.1.3.GA/iphone/builder.py", line 1341, in main
    cleanup_app_logfiles(ti, log_id, iphone_version)
  File "/Users/(ユーザー名)/Library/Application Support/Titanium/mobilesdk/osx/2.1.3.GA/iphone/builder.py", line 503, in cleanup_app_logfiles
    os.remove(i)
OSError: [Errno 2] No such file or directory: 'bad path 4ACC2000-0000-0000-0000-006B00000000'

要するにそんなファイルねーよボケってこと?
でもこのエラーが出た後にもう一度走らせるとなぜか通るんだよなぁ…。

ググったら全く同じエラーで悩んでる方がいた。
コードが悪いのかといろいろ変えてみたが症状おさまらず。ググってみたら、開発環境のバグらしい。
http://developer.appcelerator.com/question/131296/crash-every-2nd-time-i-launch
あれ、でもbuilder.pyがないんですが…(´・ω・`)

結局いろんなサイトを見ても分からずじまい…Xcode再インストールしてみるか…?

2012年11月29日木曜日

[Titanium奮闘記3回目]今日は情報量少ないから見なくてもいいよ #TitaniumJP


○やっぱり難しい位置情報

一度Android端末を起動し直して、アプリを起動し直してみると、「位置情報を取得できませんでした」のアラートが。
まだ起動してから一度も位置情報を取っていないから、Nullでも返ってきたのかなぁ。
2回目でも言ったように、Androidでは常にGPSが動いてくれる訳ではなく、最近取ったGPSデータをとりあえず返しているみたいだし…。

これはもう、一度適当なアプリを開いてもらって、そのアプリで緯度と経度をとってもらうしか…(´・ω・`)
いや、回避方法はいくつかあるんだろうけど、もうめんどくさ(ry

昨日書いたコードは多分うまく通ったハズ。


○Git/GitHubとSourceTreeでバージョン管理

Titaniumを教えてもらおうと思ったとき、バージョン管理をしてたら便利だなーGitHubとかかっこいいなーとかぼんやり思ってたので、せっかくだからやってみる。
いちいちコードをあげていけばいいんですが、もっとボタン一つで追加できるようにしたい。

というわけでGitHubでユーザー登録したあと、GUIがかなり良いと言われているSourceTreeをダウンロード。

基本的なところは下のサイトを参考にしました。

↓Gitの基本とファイルのコミットまで
http://www.backlog.jp/git-guide/

↓GitHubと連携してリモートリポジトリを作成
http://tande.jp/lab/2012/08/1870



なんとか出来上がったけど、これ大丈夫なのかしら…(´・ω・`)
さっきいつの間にかapp.jsが消えてたけど…多分変なボタンを押したんだよね僕が多分…。
うーむ、やっぱり取っ付きにくいなぁGitHub…。

そもそもBacklogの入門ページを参考にしてたのに結果違うのを使ってるってどんだけよ俺。

あ、出来上がったGitHubはこちらです。

https://github.com/Vista7010/git_fuk_app



○ところでデータベースどうすんの?

TitaniumではSQLiteと呼ばれるデータベースが使えるようです。
でも今回のアプリでは別にそれ使わなくてもいいんじゃないか?と感じています。
JSだったらJSONのほうが親和性高いだろうし、そんなにセキュリティを上げる必要も無いですしね。

うーん、でも実際Titanium+JSONってどうなんだろ(;´Д`)

よし、ここを読みながら勉強しようジャマイカ!

http://thinkit.co.jp/article/70/1



○明日の予定

・仮データベースを作る
・データベースの読み込み+距離の表示
・リスト(テーブルビュー)の実装
・あとは本番用のデータベースもExcelで作っていきます(あとでJSONにする)

うーん、今日は本当に進まなかったぞ…(´・ω・`)

2012年11月28日水曜日

[Titanium奮闘記2回目]どっちのOSでも位置情報を連続取得! #TitaniumJP



○いきなりエラー

昨日のやつをAndroid実機で載せたらエラー吐いた。

Location:[47.22] find.js
Message:Uncaught ReferencError: cLocLat is not defined.

これはvarが抜けてたからでした。

ところでなんでgetCurrentPosition書いてるのか忘れてましたが、地図を拡大&スクロールさせるためでした。

それで思い出したけど、地図を拡大してほしいのに全く拡大してくれない謎エラーがあったっけ。
どうすればいいか分からなかったので、とりあえず昨日まで使ってたsetLocationを使わず、代わりにこのように書きました。

Ti.Geolocation.getCurrentPosition(
    function(e) {
        if (!e.success || e.error){
            alert('位置情報が取得できませんでした');
            return;
        }
       
          var cLocLat = e.coords.latitude;
          var cLocLong = e.coords.longitude;

        mapview.show(); // 地図を表示する

        mapview.region = {   // 現在地まで地図をスクロールする
            latitude:cLocLat,
            longitude:cLocLong,
            latitudeDelta:0.01,
            longitudeDelta:0.01
        }
    }
);
うん、なんとかうまく行った。
ただ、Android実機ではiPhoneのように現在地が出てこないので、出てくるように変更したいなぁ…。



○Androidで位置情報取得は難しい?

Androidではなぜか位置情報をうまく拾ってくれない。iPhone(エミュだけど)ではうまく取ってきてくれるのにね。
ここの部分は前からずっと調べてるんですが…この記事がその問題に該当しそうなんだけど…

基本的に裏でサービスが走って、衛星から電波が取れて、位置情報が取れたらアプリにイベントを返す仕組みになっていると思います。
アプリ側はサービスに対して、取得の頻度などを要求できますが、要求通りいくかどうかは、衛星の状態とか、端末のGPSの性能とか、いろいろな条件で変わってくると思われます。なので、不確定な要素があるんです。
http://ti.masuidrive.jp/topic.php?id=2499

マジですか…orz

位置情報の継続的な取得は、下記URLに掲載されているように、
Titanium.Geolocationのlocationイベントを利用すると良いのではないでしょうか。
http://docs.appcelerator.com/titanium/2.1/#!/guide/Tracking_Position_and_Heading-section-29004915_TrackingPositionandHeading-ContinuallymonitortheGPSpositionhttp://ti.masuidrive.jp/topic.php?id=2499

英語読めない…orz
つか、Ti.Geolocation.Androidとかあったのね(´・ω・`)

とりあえずドキュメントのサンプルコードを参考に書いてみた。

var win = Ti.UI.createWindow({
          backgroundColor:'#ffffff'
     });

var providerGps = Ti.Geolocation.Android.createLocationProvider({
    name: Ti.Geolocation.PROVIDER_GPS,
    minUpdateDistance: 0.0,
    minUpdateTime: 0
});

Ti.Geolocation.Android.addLocationProvider(providerGps);
Ti.Geolocation.Android.manualMode = true;

var labelPos = Ti.UI.createLabel({
     text: 'hogehoge',
     height: 70,
     top: 280
});

win.add(labelPos);

var locationCallback = function(e) {
    if (!e.success || e.error) {
          labelPos.text = 'error:' + JSON.stringify(e.error);
    }

     var cLocLat = e.coords.latitude;
     var cLocLong = e.coords.longitude;
     labelPos.text = cLocLat+'\n'+cLocLong ;
};

Titanium.Geolocation.addEventListener('location', locationCallback);

win.open();

これで念願のGPS情報を取り続ける部分が実現できました。


○OSで場合分けをするには

さて問題はiOSではこれは動かないというところ。
とりあえずOSで場合分けが出来たはずなのでやってみることに。

なぜかTi.Platform.modelではだめで、Ti.Platform.osnameだとうまく行きました。
うーん、KitchenSinkだとmodelでも行ってたのになぁ。へんなの。



○二点間の距離を出そう

コードには起こしていませんが、2点間の距離を取るには下のページが参考になりそうですね。

東西の距離(touzaiKyori)= 測定値(大阪)の緯度の半径 × 大阪東京の緯度の差(idoSa)
= コサインaIdo × 地球の半径(earth_r)× 大阪東京の緯度の差(idoSa)

南北の距離(nanbokuKyori)= 地球の半径(earth_r) × 大阪東京の経度の差(keidoSa)

この二つが求まればxの2乗 + yの2乗 = 求める距離の2乗となり、その平方根をもとめることで距離dが求まります。http://www.kiteretsu-so.com/archives/1183

現在地の緯度と経度を「cLocLat」「cLocLong」、仮に福岡タワーまでの距離を求めるとすると、JSではこうなるのか。
PHPで使えるdeg2radは関数にしちゃえ。

var earth_r = 6378.137;

var bLat = 33.593332; //福岡タワーの緯度
var bLong = 130.351408;//福岡タワーの経度
var latSa = deg2rad(bLat - cLat);
var longSa = deg2rad(bLong - cLong);

var nanboku = earth_r * latSa;
var touzai = Math.cos(deg2rad(cLat)) * earth_r * longSa;
var d = Math.sqrt(Math.pow(touzai,2) + Math.pow(nanboku,2));

function deg2rad(deg)
{
    return deg*Math.PI / 180;
}

元のサイトをほぼまねて作っただけでした。ごめんなさい。



○その他雑多メモ

Androidを動かすときにエラーが出たのでそれを覚え書き程度ですが書いときます。

[INSTALL_FAILED_MISSING_SHARED_LIBRARY]
多分直前にAndroidからGoogleAPIに変えたからかな。
これはTitaniumの「環境設定→AptanaStudio→Titanium」で設定したDefaultAndroidSDKと、プロジェクトの「プロパティ→Run/Debug Setting」で設定したAndroidAPIが違うと出るみたい。一緒にしときましょ。

[INSTALL_FAILED_INSUFFICIENT_STORAGE]
これは単純に容量が足りませんよーという意味でしょう。
実機のいらないファイルを消したら消えました。



○明日の予定

・距離がとれるかテスト
・closeを押したら位置情報取得をやめさせる方法(テスト版だし飛ばしてもいいかも
・データベース…(´・ω・`)
・addEventListenerのお勉強
・ドットインストールでGitの勉強をしよう

現段階でWPのインストールもろくに終わってないからすることたくさんだなぁ…(´・ω・`)

2012年11月27日火曜日

[Titanium1日目]JSSとかエラーとかLabelとか #TitaniumJP


実際には1日目ではないんですが、更新スタートということで…w

○JSSのバグ

JSSを導入して見た目をiPhoneとandroidで異なるようにしようと思ったら、何度ビルドしてもうまく反映されない。
調べてみると、どうもバグみたいですね。

JSSは変更を保存してもビルド時に反映されない場合があります.
(反映されている時もある.不安定.)
上で例に挙げたソースコードで説明すると, colorを’#000′から’#333′に変えて保存, 実行してもエミュレータ上で何も変わらない, といった現象です.
http://markovlabo.net/?p=901

おいおい。

こういうときは現在のProjectをCleanして再ビルドしましょう.
メニューバー>Project>Clean を選択.
http://markovlabo.net/?p=901

うーん、面倒。

さらに別のところでJSSが反映されない。
JSファイルでTi.Map.createViewのプロパティにid:'mapview'を記述。
JSSファイル
#mapview{
     width:320px;
     height:240px;
}
を記述しても、マップが画面の半分だけ表示にならず、下まで表示される…。

ここはもう普通にJSSを使わずにTi.Map.createViewのプロパティで解決することに。



○変なエラー

謎なのが毎回へんなエラーが出てエミュレータが起動しません。

[ERROR] Application Installer abnormal process termination. Process exit value was 1
[ERROR] Timed out waiting for emulator to be ready, you may need to close the emulator and try again

しかし前に作ったHelloWorldではエミュレータが起動する…なんでや。

まぁどっちみちエミュレータだとGPSのテストが出来ないからいいんだけどさ。
これも余裕のあるときに検証するかぁ。



○Androidで位置情報を取得する時に気をつけること

Titaniumで位置情報を取る方法は2つあります。
ひとつはgetCurrentPosition関数を使う方法。

Ti.Geolocation.getCurrentPosition(function(e) {
    var cLat = e.coords.latitude;
    var cLong = e.coords.longitude;
});
ただしこの方法だと一度しか取得してくれません。
ずっと取り続けてほしいときは、addEventListenerを使います。

Ti.Geolocation.addEventListener('location',function(e){
  var cLat = e.coords.latitude;
  var cLong = e.coords.longitude;
});
まぁ自分が知っていたのはこれまでなんですが、気になる記事を発見。

Androidアプリで位置情報を取得したい場合、通常AndroidManifest.xmlにuses-permission"ACCESS_FINE_LOCATION"を追加する必要があります。
ですが、Titanium MobileではgetCurrentPositionという関数名がソースコード内に含まれていれば自動でpermissionを追加するようになっており、Androidアプリ独自の部分をあまり意識しなくても済むようになっています。
しかし、addEventListenerを用いた方法だと、このpermissionの自動追加が適応されないため(中略)位置情報を取得できません。
http://tech-sketch.jp/2012/01/titanium-mobile.html

TiApp.xmlに追加しないといけない内容は元記事をお読みください。
これは盲点ですね…早速追加しときました。



○Labelってどう変更するのよ

とりあえず、Android実機を持ってちゃんと緯度と経度がはかれるかどうかを調べるために、緯度と経度をラベル表示させるようプログラムを組みます。

そこでぶつかったのが「Label内の値を変更するにはどうすればいいか」。
「そんなのも分からんのかい」と思ったそこのアナタ。そのくらいド素人なので許してください。

とりあえず書いたのが下のコード。
find.js

(前略)

var labelPos = Ti.UI.createLabel({
     text: 'hogehoge',
     height: 70,
     top: 280
});

win.add(labelPos);

Ti.Geolocation.addEventListener("location", function(e) {
     cLocLat = e.coords.latitude;
     cLocLong = e.coords.longitude;
     Ti.API.info(cLocLat);
     Ti.API.info(cLocLong);
     labelPos.text(cLocLat+'\n'+cLocLong);
});
(後略)

するとこんなエラーが。

'hogehoge' is not a function (evaluating 'labelPos.text(cLocLat+'\\n'+cLocLong)')

text()っていう関数は存在しないってこと?

とりあえず別の方法として、上の部分を

labelPos.text = cLocLat+'\n'+cLocLong ;

に変えるとすんなり通りました。

※ちなみにこのバグ、text()があると思い込んでたせいで修正するだけで1時間使ってます。なんで気づかなかったんや...(´・ω・`)



○その他雑多なメモ

改行は\nを使う。逆スラッシュのやつ。ここはJSでも一緒。""で囲むことを忘れずに。



○明日の予定

・Android実機でちゃんと継続的に位置情報がとれているかを確認。
・とれていれば2地点間の距離を計算するやつを書く。
・ついでにcloseを押したら位置情報を取るのをやめさせる方法も考える。
・時間があればデータベースまで…無理かな(´・ω・`)
・JSDeferredが分からん。
・GitとGitHubでバージョン管理をしたい。

2012年11月26日月曜日

はじめにお読みください

このブログについて

ここはワタクシ、ビスタがTitaniumMobileを使ってあれやこれや思案しているさまを、他のスーパープログラマーの方々に見ていただき、無事プログラムを完成させるためのブログです。

修了するには年内にプログラムを完成させなければなりません!
マジでヤバいんです(´・ω・`)

正直自分が助けてもらうために作っていますが、自分と同じような失敗にぶつかった人のために、情報をシェアできたらいいなとか思っています。

自分はTitaniumはもちろんJSも初心者なので、ある程度組める方には有益な情報が得られないかもしれません。

とりあえず、温かい目で見ててください、お願いします><

お前誰やねん

ビスタです。今年の11月30日で25歳になります。

某大学院でデザインを勉強しているはずなんですが、いつの間にかプログラムをすることになりました。

HTML、CSS、JS、PHP、Perlを色々触った結果、どれも半分くらい分かる程度になりました。

プログラム歴は浅いですがそれなりに頑張ってます。

作りたいプログラムの概要

全体的なこと

・Androidで動くもの(出来ればiPhone)→実機で動かせるのはAndroidのほうが楽だし。
・開発環境はMac OS X 10.7、サブでWindows7(Vistaじゃねーのかよ!とか言わない)
・Androidは基本実機で試すようにする。
・iOS端末はiPodTouch(第三世代)を所持。多分使わない。

アプリの流れ

・タイトル画面が表示され、ユーザーの現在地を検出する。
・ボタンを押すと現在地を取得し、そこから一定距離内(半径1kmを想定)にあるスポットをリスト表示
・ユーザーはそのリストの中から一つを選択し、移動を開始する。
・画面にはそのスポットと距離、方角が表示されている。
・スポットまでの距離が10m以内になったら「到着」ボタンを押し、到着フラグを立てる。

アプリのシステム用件(ToDo)

現在位置を移動しても取り続けなければならない!
・店舗・スポットのデータベースの制作
・データベースとの連携
・今いる場所から目的地までの距離と方角を計算
・(追加予定)

これでいまいちどんなものを作るかわからない方は直接僕に連絡して下さい。