2013年2月14日木曜日

DDMS post-create initでフリーズ

何か今日は沢山のBad Know-howが収集できて嬉しいorz

ADT/Eclipseを普通に終了してからMac(Lion)を再起動、再度ADTを起動したらstatusに

  DDMS post-create init

という表示が出てそのままフリーズしてしまった。Eclipseを強制終了して再起動してもダメ。

ググったら、StackOverflowでwork aroundが見つかりました。ありがたやありがたや。Eclipseがしっかり終了しているのを確認し(生き残っている場合には強制終了)、ターミナルでWorkspaceへ移動し、以下のコマンドを実行します。

  rm .metadata/.lock

これでEclipseは起動しました。いやはや。

2013年2月10日日曜日

userIdの取得

■userIdを知る■

自分がポストしたデータは表示しない、という処理を実装する場合にuserIdを知る必要があります。

古いForce.com SDKでは

AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSString *userId = [[[app coordinator] credentials] userId];

と書くこともできましたが、今はAppDelegateからSFOAuthCredentialsのインスタンスを見ることができません。最新のSDKで同じ事をする場合には

NSString *userId = [[[[SFRestAPI sharedInstance] coordinator] credentials] userId];

と書けばOKです。

■Xcodeバージョンアップ■

Xcode 4.4で作ったプロジェクトを4.5に持って行ったらエラーの山が出来てしまいました(今更ですが)。結局プロジェクトを修正するのは諦めて、最新のForce.com mobile SDKを入れて新しくプロジェクトを作りました。リソースなどをコピー、AppDelegateなどはソースをにらめっこして必要なところだけをコピーしましたが、ViewControllerについてはそのまま上書きです。その作業中に上記のエラーに遭遇した次第。

あとは「認証中」画面のxibからstoryboardの置き換えが残っています。以前のテンプレートではSFNativeRootViewController.mのsetupAuthorizingViewControllerを書き換えればStoryboardに置き換えるのも簡単だったんですが…app delegate上でオーバーライドするのも面倒くさい。

起動時に一度呼び出されるだけで他の実行には影響のない画面なので、ここはそのままxibで済ませましたm(_ _)m

2013年2月9日土曜日

マクドナルドのレジ



マクドナルドのレジは、コーヒーひとつ買うのに会話が多すぎてめんどくさい。最近は日本語があまり得意でない店員や不慣れな店員も多くて「えーと、ホットコーヒーのM、持ち帰り、砂糖ミルク袋要らない、Edy払い」なんてのが一発で通るのも珍しいぐらい。

「注文所要時間を短くするためにメニューを無くしました」なんて的はずれなことばっかりやっていないで、マクドナルドのレジがこんな具合になってたらもっと使いやすいんだがなぁ。

  1. 事前にスマフォ上でメニュー、支払い方法、袋はどうするか?などすべて入力
  2. レジにかざすとオーダ情報がすべて伝達、Edyで決済
  3. あとは品物を受け取るだけ

注文が5秒で終わるw

情報の伝達は既存レジだとEdyが付いているから、アプリからクラウド上に注文あげておいて、EdyのIDから引っ張ってくればおk

時間帯にもよるんだろうけど、繁華街にある店だと1/3-1/2ぐらいの客がスマフォ/ケータイのクーポンを見せているような感じかな? そのうちの半分がアプリで注文するようになれば、せっかちな客の満足度は上がるしレジの流れも早くなる。

さらに、「1週間分のランチ予約でクーポン!」などの販促もリンクしやすいし精度が高くなる。A店が空いているなとなったら「今から17時までA店限定でポテトが半額!」なんてpush notificationを流せば特定の店の稼働率をコントロールすることも可能になる。プリペイと組み合わせれば事前予約がキャンセルされにくくなる。

マクドナルドに限らず、苦手意識のあるヒトが少なからず存在するというスターバックスでも売上増につながると思うけどね。

2013年2月1日金曜日

Android:今日ハマったこと

■layout.xmlが壊れる■ 

Graphical Layoutでの作業。画面の最上部にRelativeLayoutを置きます。

その中に「左端にボタンA、真ん中にTextView、右端にボタンB」を配置しました。ボタンAは左寄せ、ボタンBは右寄せ、TextViewはAの右かつBの左を指定します。

ソースを保存してもエラーなし。


で、実行しようとするとエラー。TextViewのandroid:layout_toLeftOfで「そんなidない」って言われる。

原因は…xml上で、ボタンA,TextView,ボタンBの順番で並んでいるのにTextViewが後にあるボタンBを参照しているから…でした。


そりゃそうなんですけどね…Graphical Layout上で作業しているとエラーが出ない、でも一度エラーになるとXMLのソースを見ても手動でIDを付け替えてみても、どうにもなりません。現象だけ見ると、開発ツールがバグっててID管理テーブルが壊れているような感じなもので「+id/buttonA」と定数を対応付けているのはどこだろう、なんて無駄な探索をしてしまいました…。いやはや…。


■Activityが見つからないエラー■

またやってしまった>マニュフェストへの登録忘れ。

1日1回、忘れたころにやってしまう…。

今日はいくつもREST APIコールを書いたので、おかげさまでthreadとかrunnableとかhandler.postなんてのがソラで書けるようになりました。でもListViewのAdapterについては原理は何とか理解したものの、コードは覚えられない。

2013年1月31日木曜日

ACS Android SDKでハマる

ACSでググっても化学とか冠状動脈とかばっかりで、なかなか情報にたどり着けないのが困ったもんです。Appcelerator Cluod ServicesだとTitaniumばっかりだし(当たり前だけど)。ということで、ACS Android SDKでのハマりねた。

■Whereをどう書けば?■

Titanium mobileのSDKと違って、Android SDKはほとんど素のREST API SDKです。iOS SDKだと、あまり便利とはいえないけどCCWhereなんてクラスもあって、それなりにラップしてくれます。でもAndroidだと、こんな感じで書く必要があります。

    Map<String, Object> q = new HashMap<String, Object>();
    q.put("order", "-updated_at");
    q.put("where", "{\"email\":\"" + strEmail + "\"}");
    CCResponse r = sdk.sendRequest("users/query.json", 
                                   CCRequestMethod.GET, q);


…なんかperlでも書いている気分だ…書いたことないけど…。

まぁでも「ほぼREST」だと思ってしまえば、ある意味気は楽です。

ところで、Android 4以降はネットワークアクセスを別スレッドにしないと動いてくれません。

    public void acsThread() {
        listFriendsRequest = null;
            
        new Thread(new Runnable() {
            @Override
            public void run() {
                acsProcess();
            }
        }).start();
    }

そして終了後に画面切り替えたりするにはHandlerを使う必要があります。

以上をひとまとめにしてACSへのログインをActivity上に書くとこんな感じ。会社で使っているコードを貼るわけにはいかないので、記憶などを頼りにADT上で書いたもの。実働ソースではないので、もし不具合が出たらすみません。

    public void acsLogin(String inEmail, String inPassword) {
        final String email    = inEmail;
        final String password = inPassword;
        final Handler handler = new Handler();
        
        final JSONObject result = null;
        
        new Thread(new Runnable() {

            @Override
            public void run() {
                CCResponse r = null;
                
                Map<String, Object> q = new HashMap<String, Object>();
                q.put("login",    email);
                q.put("password", password);
        
                try {
                    r = sdk.sendRequest("users/login.json", 
                                        CCRequestMethod.POST, q);
                    CCMeta m = r.getMeta();
                    if ("ok".equals(m.getStatus()) 
                            && m.getCode() == 200 
                            && "loginUser".equals(m.getMethod())) 
                    {
                        result = r.getResponseData()
                                  .getJSONArray("users")
                                  .getJSONObject(0);
                    }
                }
                catch (CocoafishError e) {
                    e.getMessage();
                }
                catch (IOException e) {
                    e.getMessage();
                }
                catch (Exception ex) {}

                if (result != null) {
                    handler.post(new Runnable() {
                        @Override
                        public void run() {
                            jsonUser = result;
                            Intent intent = new Intent(MainActivity.this, 
                                                       NextActivity.class);
                            startActivity(intent);
                        }
                    });
                }
            }
        }).start();
    }

何かもう1歩あるくたびにつまずいてググらないと進めない。

まぁiOSアプリ書いている時もそうですけどねorz

2013年1月30日水曜日

Android開発、いいとこ探し

Xcodeでの開発とくらべて、サクサク感に足りないところが多すぎるADTですが、とりあえずいいところを見つけました。

それはUI上のラベルなどを文字リソースとして追加しやすいということ。文字拡大するほどのことじゃないかw


たとえば、ボタンのラベルを文字リソースにする場合、PropertiesのText右端にある「…」をクリックするとResource Chooserが出てくる。



ここでNew Stringボタンをクリックすると「Create New Android String」、リソース名と文字列を入力すればおk


で、ここで追加したリソースは、javaソース上でも「R.id.」と入力すれば、入力補完してくれる。私は入力補完が便利になるようにリソース名を付けているので、とても楽。

Xcodeだと文字定数の入力補完が効かないので、それだけは羨ましい。

2013年1月26日土曜日

IBM Cast Iron


■IBM Cast Ironハンズオンセミナー■

IBM Cast Ironのハンズオンセミナーに行きました。

ドラッグ&ドロップ+設定ベースで、例えば「あるディレクトリをポーリングする。CSVファイルが投げ込まれたらこれに演算処理を加えて、条件によって異なるXMLファイルとして出力する」「ローカルのDBを読んで、必要な項目だけをSalesforceにUpsertする」なんてことが出来てしまう。一つ一つの処理要素をアクティビティと呼ぶのだけど、このアクティビティにはとにかく種類が沢山あって、「こんなことはできないか?」ということがすべて網羅されている。

■Apple, MS, IBM■

昔OS|2とかOpenDoc、最近はWork lightとCast IronしかいじったことないIBM童貞の感想なんですが…Appleの対局にあるのはMSやAndroidじゃなくてIBMじゃないかと思う今日このごろ。

昔から「正しいことをダメな方法でやるのがヒッピー(ジョブズ)、間違ったことを真面目にやっちゃうのがオタク(ゲイツ)」って言われたりしてたけど、IBMは「正しいことを徹底的に真面目に美しくやる」って感じですかね。「これはダメ」ってなったときの方向転換は小売店並に速いし。

ともかく、Appleが少ないルールでシンプルに、MSはとにかくスペックや機能を網羅しまくる方向であまり綺麗でない仕事をする、そしてIBMは徹底的に網羅するという点ではMSと似ているけどMSのように「あ、XXは出来ないんだねw」と15分でバレるような仕事をしないし網羅しまくっていても要素が整理されているので「コントロールパネルのどこで設定すりゃ良いんだよおおおお(怒」となることもない。

まぁくどいですが、あくまでもWork lightとCast Ironをハンズオンセミナーで少しいじっただけの感想です。実際の現場は涙目になるのがこの業界のお約束ってもんだけどね。

■アクティビティ■

よくある「モバイル☓クラウド」な案件でAndroid屋さんとCast Iron屋さんが同席して技術的な話をしたらお互いに一瞬ニヤッとする…はず>アクティビティ / Activity

もっとも、Cast Ironのアクティビティというネーミングはとても納得がいくんだけど、AndroidのActivityは未だに違和感ある。

2013年1月25日金曜日

Xcode 4.5でiOS 5.1対応プロジェクトを作る

サマリー:

  • Xcode 4.5で作ったアプリがiOS 5.1上でクラッシュ
  • Deployment TargetをSDK 5.1にしたけどそれでもクラッシュ
  • Autolayoutが原因じゃった
  • 余談:Android開発は辛いよ

■いきなりクラッシュ■

Xcode 4.5移行後に作ったプロジェクトをまだiOS 6でしか動かしていないことに気づき、iOS 5.1 SDKを入れて試したところ、即死しました。iOS 6なら動きます。iOS 6固有の機能なんて何も追加した覚えがないのになーと真っ青になりました。

■原因■

Autolayout機能を使ったことが原因でした。エラーメッセージの中に出てきたNSLayoutConstraintでググって判明しました。いやはや…。



■SDK 5.1の組み込み方■

一応書いておきます。iOS SDK 5.1はXcode 4.4に含まれていますので、
  • developer.apple.comのdownloadsからXcode 4.4をダウンロード
  • xcode_4.4.1_xxxxxxx.dmgをマウントし、Xcode.appを右クリック「パッケージの内容を表示」を選び、 Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKsにあるiPhoneOS5.1.sdkを /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs にコピーします。ディレクトリ深いわ。
  • Xcodeを再起動
これでiOS Deployment Targetとして「5.1」を選べるようになります。ProjectのPROJECTとTARGETSにある「iOS Deployment Target」を5.1にセットしてください。エミュレータで5.1を選べるようになります。


■対策 - Autolayoutを切る■

Storyboardをクリックし、Identity and Typeの「Interface Builder Document」にある「Use Autolayout」のチェックボックスをoffにします。


これで、Xcode 4.5で作ったプロジェクトをiOS 5.1で起動しても落ちなくなります。

なお、MainStoryboard_iPhone.storyboardだけでなくMainStoryboard_iPad.storyboardも直しておくことをお忘れなく(と経験者は語る…)

■Autolayout■

Autolayoutがonだと余計な補助線が出てきてウザいです。これ、Androidの開発ツールにも似たような機能があるんですが…ご安心ください、Androidのはもっとウザいです。縦横比の異なるiPhone5をサポートするにはリキッドレイアウトが一番無難ではあるわけですが…

■余談■

最近気づいて驚いたのですが。Androidってソフトキーボードが出た/引っ込んだを検出するイベントがないのね…。ソフトキーボードが出てくると、真ん中辺に置いたEditTextは自動的に縮むんだけど、移動はしてくれない。移動はプログラマがやらないといけないんだけど、「キーボード出たよ」ってイベントがない。「viewが縮んだ」ってイベントを使って間接的に検知するしかない。間接的だから副作用を避けるためにはいろいろ小細工しなければならない。iOSならこんなにイベントあるのに。


  • UIKeyboardWillChangeFrameNotification
  • UIKeyboardWillHideNotification
  • UIKeyboardDidChangeFrameNotification
  • UIKeyboardDidHideNotification
  • UIKeyboardWillChangeFrameNotification
  • UIKeyboardWillShowNotification
  • UIKeyboardDidChangeFrameNotification
  • UIKeyboardDidShowNotification


Android開発、しんどいです…。優しい上司は「難しければ、iPhone版を先に出して、Android版外注にしようかねぇ」と言ってくださるのですが…社内にiPhoneユーザが少ないので、iPhoneだと十分なテストが出来ないです。困った…。

2013年1月21日月曜日

Titanium mobileその後、とMonaca


今回の要約:
  • Titanium Updates Available
  • Titanium mobile:異常の原因
  • Monacaを試した

■Titanium Updates Available■

Titanium Studio起動時に、自分ちのMacではログイン認証求められないのに会社のMacだとid/passwordを入れないとダメってのは何が原因なのか未だに不明。

それとTitanium Studioを起動したら、Titanium Updadates Availableが出ました。「もしかして、今抱えている問題がこれで片付くかも!」とwktkしながらクリックしたら…Alloy 0.3.6だったorz

いやいや「orz」したら失礼ってかAlloyには少しは期待しているんだけど、でも、そろそろTitanium 3.0.1とか出ても良いんでないの?出てくれないかな??出てくれるよね???と思っていたものですから。すいません。

今のところMVC3層モデル対応のmobileアプリ用JavaScriptフレームワークというとSenchaが先行している感じだけど、UIレイアウトツールのないTitaniumがAlloyによってリキッドレイアウトとMVCモデルを同時に取り込むことができたら、少なくともビジネス系モバイルアプリ開発にもっと踏み込むことができる、はず。期待してます。

■Titanium mobile:異常の原因■

さて、本題。結局不具合はイベントの異常によるものでした。

selfがwindowで、すでにfocusがあるにも関わらずwindows上のTextFieldがタップされた時にself.addEventListener('focus', function() {});が呼び出されてしまうことが原因。selfのfocusイベントで初期値を設定していますが、password/emailをタップするたびに初期化されるのだからそりゃ入力できないのも当たり前。

iOSとAndroidで挙動が違いますね。iOSではTextFieldをタップしてもfocusが発火することはありません。

こういうのを潰すのは大変です…。

■Monacaを試した■

jQuery mobileというよりHTML5ならAndroidのフラグメントをいくらか吸収できるので、とりあえずお試し。以前XCodeの上でPhoneGap+jQuery mobileを動かしたことはあるものの今回のプロジェクトではAndroidが対象なので開発環境を用意しなければなりません。

一応、クロスプラットフォームであまり面倒なことなしに使える、ということでまずはMonacaを試してみました。

Monaca.mobiにアクセスしてアカウントを登録、するとすぐにブラウザ(私はSafari 6.0.2+Mountain Lion)上でIDEを使えます。このIDEがとてもブラウザ上で動いているとは思えないほど、というかEclipse上のADTよりもサクサク動くから泣けます。

IDEに付属しているスマフォビューワは必要最小限の機能で再現性も低いので、とりあえずAndroid用アプリとして提供されているMonacaデバッガを使います。今回はエミュレータ上にデバッガをインストール。
  1. Androidエミュレータ上でブラウザを起動
  2. ブラウザにMonaca.mobiのデバッガ配布URLを入力→自動的にダウンロード
  3. Downloadsからファイルをタップすればインストール完了
  4. 起動して、さっきMonaca.mobiに登録したアカウントを設定
  5. アプリ一覧が表示→デバッグしたいアプリをタップすればすぐ起動
  6. IDE上で更新したら、デバッガ上の更新ボタンをタップすればすぐに更新
もう恐ろしいほどスムーズです。

で、さくさくと試験用のGUIを作って、さてACSを読み込もうとしたら…jQueryの対象バージョンがMonacaとACSとで異なるのでアウトでしたorz

というわけで、ACSについてはダメでしたが、jQuery mobile開発環境としてはとてもよくできていますので、今後時間を見つけて試そうと思ってます。

2013年1月20日日曜日

ムービーアプリがリジェクト

お友達からの依頼で作ったiPhoneアプリ、リジェクトされました。

理由:「ムービーだけならiTunes Storeから売れや」

昔は良かった…。

というわけで、お友達から「参考にして」と言われて買った「AKB48」アプリや「We are the world」アプリを眺めつつ、機能を大幅アップ中。AKB48はともかくWe are the worldなら技術的にはそう難しくないんだけど、ちょこっとしたアニメーションとか配色なんぞのさりげないセンスが難しい…。