2012年8月10日金曜日

PhoneGapってかCordova 2.0.0

2.0になってインストール方法が少し変わりましたね。

とりあえず、今週末にLion上にインストールして試してみる予定です。

どうせまたハマると思いますので…お楽しみにorz

2012年7月12日木曜日

ADT 20でプロジェクトが作れない

会社のLionにAndroid開発キットをインストールしました。EclipseはForce.com IDE用にすでに入れてあったので、adnからインストールし、SDK ManagerからAPI 8, 10, 15、それにIntel HAXを選択。

さて、Hello worldを…と思ったら、Android Application Projectで、最後のFinishが押せません。いや、押してもすぐに戻ってきてしまって終わらない。

ググってみると、どうもADT 20の問題みたいで、いろいろwork aroundが出ている。

  • android-sdk-macosx/extras/compatibility -> supportにrename
    • すでにsupportだった
  • sdk managerからsupport libraryを削除してもう一度create new project、ライブラリがないって言われたらそこでinstallをクリック
    • 変化なし
でも、結局、症状は同じでした…。ADT 20よりも古いツールからインストールしていたマシンでは問題ありません。

とりあえず、当面Androidいじる予定ないから良いんですが…何とか早く解決してほしいものです。また何か思いついたら対策してみます。

2012年7月10日火曜日

会社にMacが来た! ・その後

標準の500GB HDDをPlextor PX-256M5Sに換装しました。外付けUSBは禁止されているので、東映のアダプタを使ってDVD Driveのところに500GB HDDをセットして移行完了。やー、廉価版SSDとはいえ、HDDとは比べものにならないぐらい爆速ですね。立ち上がりが早すぎてXPのスリープ復帰より早いです(いやマジで)。移行が終わったところで、またHDをDVD Driveに戻しました。
外したねじ置き場。まぁ右奥3本が長いだけですが。
Excelとかパワポを使わずにはいられない会社なので、BootcampにWindows7を入れました。

ツールでパーティションを切って、Windows7のDVDを入れて待つことしばし。ってか、「展開中xx%」で止まること3度。00%, 53%, 68%だっけかな。68%では30分以上止まっていたのでWindowsに詳しい人に「もうリセットしちゃおうかしら」って話に行って戻ってきたら進んでいたというオチ。しかし、インストール後、Bootcampはそのままでは暗号化できず、暗号化しないと会社の規則で持ち出せず、暗号化するとVMWareからは起動できなくなる、ということで没。

再びBootcampツールを使って、パーティションを消す。サイズを変えることはできないけど、消すことはできるのね。で、改めて、VMWareでインストール。そしたら、CPUを2個しか割り当ててないのに8分でインストール終了。さっきの「展開中」は何だったんでしょう。

MacのパーティションはFilevault 2で暗号化済なのでその上のVMWareもセキュリティ的には問題ない。ただ、MacOS上にもWindows上にもSymantec EndProtectionを入れたらとても重い。特にMac側でファイルをダウンロードした後のスキャンが異様に遅くて泣けます。Mac界で比較的評価の高いSophosとかじゃダメか聞いてみようと思います。

さて、あとは入社以来使っていたXP(Core 2 Duo / 2GB / HDD 64GB)の中身を載せ替えれば移行完了です。

インストールが一段落したら、もう一度DVD-DriveをHDDに換装して、HDDをTimeMachine用に使おうと思ってます。実は今回、超お買い得なRetinaを諦めた理由の一つがこれです。セキュリティのため普通の会社ではプロテクションのない外付けUSBは禁止されていると思いますが、TimeMachineなしでMacを使うのも不便、ならば無理矢理2スピンドル化して使おう、というココロです。

まぁTimeMachineも暗号化できるので、そこを説得できれば良いのかもしれませんが、説得するのめんどくさいのよ。

2012年7月6日金曜日

会社にMacが来た!

そういえば、このブログのタイトルには「MacもGoogle docも使えないのでここに書く。会社をやめる理由はたぶん『Macが使えないから』になる予定w」とか書いていたのですが、MacBook pro 15" mid 2012さんが来ちゃいました。

Symantecさんを入れなければいけないなど、いろいろ制約もあるのですが…ともかくきれいなフォントを見ながら仕事できるだけでもうれしいざます。

でも、「Macは印刷業界ぐらいしか使えないじゃんw」という古い人もまだまだ多いよね。実際のところ、Macとは関係ない技術会議でもほんと冗談みたいにみんなMacBook Airだもん。先日の「ヒッグス粒子発表か?」を取り上げたニュースでも、技術者が使っているのはMacばっかりだったし。Salesforceの中の人も技術職はAirがやったらと多い。

スライド上映中に会場に浮かびあがる無数のアップルロゴ、こんな日が来るなんてちょっと感無量ですわ。

というわけで、今後もこのブログは続きます。

2012年7月3日火曜日

Painless Mobile App Development Webinar


Facebookのタイムラインに新しいWebinarが出てました。しばらくForce.com Mobile SDKをアップデートしていなかったのですが、いろいろ変わっていました。Webinarの中身を紹介します。英語力ほぼ皆無なので聞き違えていたりするところがあればご指摘ください。なお、私の主観的なコメントは黄色で表示しています。

  • Database.comに関して
    • Database.com概要
    • Apexの流し込み
    • workbenchの使い方(SOQL、REST APIのURLの作り方)
  • ここで急におっさんに声が変わって、Mobile SDKの説明に
  • まずMobileSDKの技術要素の説明(Push notification対応してたんだなぁ)
  • Native/Hybrid/HTML5の位置づけ
  • mobile SDKはOpenSourceで開発されている
  • OAuthについての説明
    • 認証不成立時のスライドになぜか日本のファミリーマートがw
    • OAuthの各Flowについて
      • UserAgentfFlow/RefreshFlowの動作フロー
  • 実際にXcodeを使ってのデモ
    • SDKのインストールが結構めんどくさいのだけど、そこは省略
      • みんなそこでハマったことがあると思うんだけどなぁ
    • NativeProjectをスタート
    • ハマりやすいRemote Access設定についての説明がわりとしっかり
    • build&run→User-Agent FlowのOAuthがしっかり動作。良かった良かった。
    • ソースを読んでいく
      • やっぱりまだStoryboardには対応していないんですね。
      • view controllerについての説明など。
  • RESTについての説明。
  • 28分頃、オンラインでのSOQLクエリについての説明
  • その下にオフラインのサンプルが出ている。
    • あとで読もうと思う。
    • クエリとJSONの対比。
    • JSONでの戻りの説明。
    • JSONからtableへデータをセット。
  • SmatStoreはオフラインでの動作をサポートするメカニズム
    • SQLiteとJSONベースのdocument store。
    • device level hardware encryption対応
    • SmartStore Phonegap Pluginが用意されている
    • SQLCipherにも対応。
  • HyblidはJASONベースのみ。
    • ブラウザ組み込みSecure SQLのサポートの関係で?
  • 36分あたりからSecureなJASONベースのストレージについて
    • Newton 'Soups'な話がでてきた。懐かしい。
    • 使い方についての説明。
    • サンプルではrequest:didLoadResponseでSoupと同期をとっている。
    • Soapに対するQueryについて説明。
  • 各リソースについて紹介
    • サンプルはこれ。
    • https://github.com/tomgersic/CrumpRealEstate
  • Q&A
    • Upsertした場合の同期について質問が出ていたけど聞き取れない。


だいたいこんな内容です。Androidでの開発は出てきませんし、Hybidについても概要だけで実例のデモはありません。

すでに開発経験のある人の場合、とりあえずSmartStoreについての概要を把握するのに良いかもしれません。これからiOS+Force.comで開発しようという方は、もしハマったら私の過去ログなどでインストール方法を確認してみてくださいませ。

2012年7月1日日曜日

jQueryで一部ページだけローテーション禁止にする

この週末、同僚氏からの質問を受けて、ちょっと調べてみました。

結論としては、無理です。mobile Safariが対応していません。jQuery/PhoneGapでは1つのアプリを1本のhtmlで処理しますが、htmlごとなら「ロックする/しない」を設定できるものの毎度おなじみの<div data-role="page">のブロック内だけで切り替えることはできません。

ただ、まったく方法がないわけではなくて、一つは、PhoneGapのプラグインをobjective-cで書いて、まいどおなじみのこれを実行する方法です。たぶんこれが正攻法。

 (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
    return NO;
}

もう一つは「ローテートしたら無理矢理view内部を逆方向に90度ローテートして打ち消す」という力業。ここのページの一番下にコードが出ていますが、iPhoneを回転させると、追従して回転した後でまた無理矢理元に戻るところがいとおかし。

ということで、jQuery mobileでアプリを作る場合は、「一部だけ回転禁止はできないよ」ということを念頭においといた方が良いですね、というお話でした。

基本的に役に立たない情報ですいませんm(_ _)m

2012年6月17日日曜日

Dreamweaver CS6 + PhoneGap 1.7

表題の通り、DW CS6を使い始めています。まぁ無料評価版ですが。なんかものすごい重いけど、それはまぁ最新のMacなら問題ないのでしょう。

で、今日はさくっと簡単にアプリをiPhoneの上で走らせて、そこまでの紆余曲折なんかも公開して、「いやー、ちょっとハマりましたけど、簡単ですね。はははははは」とか書こうと思っていたのですが、最後の最後、iPhoneにインストールするところで失敗してしまいます。

Androidはエミュレータ上で普通に起動するんですが。

というわけで、表題のDreamweaver CS6 + PhoneGap 1.7>iPhone4については、また今度の週末チャレンジ致します。

それにしても、これまでPhoneGap苦手ってかJavaScript苦手なんであんまり触っていなかったんですが…覚えることがたくさんあり過ぎて涙目です。

いや、まだ別にPhoneGapで行くと決めたわけではないのですが。

2012年6月9日土曜日

Salesforce季節の変わり目にありがちなこと:APIが違う

さてもうすぐSummer '12です。

新規に取得したDev環境はSummer '12になってますね。その上で一部リリースされた新機能を試したりチャットのポップアップがうぜぇwなどと言いつつ作業し、できあがったパッケージを本番環境に移そうとしたのですが…「API違うから駄目っすw」と言われました。

パッケージもForce.com IDEも駄目。同じことをSpring '12の時期にもやっていたような気がする…でも、Dev環境取得する時点でAPI選べないのでどうにもなりません。

で、エラーを細かくチェックしていくと、

  • カスタムオブジェクトやレイアウトに関しては移植可能
  • エラーが出るのはVisualforce, Apex, Triggerなどのメタファイル

という状態でした。

ということでwork around。

  1. 稼働環境用サンドボックスへカスタムオブジェクトやレイアウトをすべて移植
  2. 同サンドボックスへ手動でVisualforce, Apex, Triggerをコピペ
  3. サンドボックスから本番環境へDeployment
まぁ当たり前の手順ですけども、ハマった方のご参考になれば幸いです。

なお、今回ソース数本だったので手動で対応できましたが、本数が多いと依存関係もあって大変です。とりあえずは以下の順番でコピペしてみます。
  1. Trigger
  2. 通常のApex
  3. Visualforce
  4. テストコード
ひっかかったら適宜入れ替えます。また、どうしても依存関係が解消できない場合には、先にクラス名定義だけコピーしておいて、あとから実装部分をコピーするという方法もあります。最後の手段として、ソースの数だけブラウザにタブを開いておいて、依存関係のないところから片っ端からQuick Saveして少しずつ埋めていく、なんてのもあります。

申し遅れましたが、この手の作業はForce.com IDEよりもブラウザ経由の方がレスポンスが良くて作業しやすいような気がします。

2012年5月10日木曜日

Chatter APIにまつわる愚痴

会社で作業していると目的のAPIがなかなか出てこない。自宅で作業していると同じGoogle先生を使っているのに「FeedItem」でサクッとREST APIが出てくる。

何ででしょう? 昨日30分ぐらい「あれ、Chatterのメッセージにコメントがいくつついているかを返すメンバーって何だっけ? Comments?」ってGoogle先生をお供にさまよっていたんですが…今検索したら一発でFeedItemのCommentCountが出てきました。

見つかれば文句ないんですけどねぇ…。

それにしても個人で提出したiPhoneアプリ。今までの経験から「審査待ちまですくなくとも1週間」ってのはわかっているんですが、それにしても待ち遠しい。

2012年5月6日日曜日

Native iOSアプリをChatterの「いいね!」に対応

■FourChatter絶賛改良中■

Chatter上の文言をサクっと検索する倉橋屋謹製アプリFourChatterを改良してます。今更ですが。主な改良のポイントは以下の2点:
  1. iPad対応
  2. 「いいね!」の実装
iPad対応は、同じGUIそのままならそんなに苦労はないけれど、このFourChatterは「iPhoneの向きを変えるだけでキーワードを切り替えて検索できる」ってのがウリです(電車の中ではちょっと恥ずかしいけどね)。が。iPadで向きを変えるのは結構ウザい。というよりも、五十肩の私にはしんどい。というわけで、Segmented Controlを導入しました。

…iPhone版もこれでいいんじゃね? Segmented Controlなら4つに限らなくても良いんじゃない??という声もありますが。


■「いいね!」の実装■

Chatterの「いいね!」はFeedLikeというオブジェクトを使ってます。NewsFeedまたはFeedCommentへのto one relationshipになっていて

  • CreatedByID - 「いいね!」をクリックしたユーザのID
  • FeedItemID - 「いいね!」の対象となるNews Feed ID
  • FeedEntityID - 「いいね!」の対象となるFeedまたはCommentのID
  • InsertedById - このオブジェクトを作ったユーザのID
もともとFeedEntityIDはなかったと思うけど、最近FeedCommentへの「いいね!」がサポートされたことにともなって追加された、ような気がします。


■まず「いいね!」はこんな感じ■

SFRestRequest *requestInsert;

NSString *fId = [feed objectForKey:@"Id"];

NSDictionary* dic = [NSDictionary 
    dictionaryWithObjectsAndKeys:fId, @"FeedItemId", nil];

requestInsert = [[SFRestAPI sharedInstance] 
    requestForCreateWithObjectType:@"FeedLike" fields:dic];
[[SFRestAPI sharedInstance] send:requestInsert delegate:self];

これでOK。実行結果は例によって以下が呼び出されます。

- (void)request:(SFRestRequest *)request didLoadResponse:(id)jsonResponse ;
- (void)request:(SFRestRequest*)request didFailLoadWithError:(NSError*)error ;
- (void)requestDidCancelLoad:(SFRestRequest *)request ;
- (void)requestDidTimeout:(SFRestRequest *)request ;

要するに「いいね!」をしたいfeedのidを"FeedItemId"にセットしたNSDictionaryを用意して、それをFeedLikeとしてinsertするだけです。


■いいね!を取り消すには■

上記で作ったFeedLikeを削除します。最初、SELECTで該当するFeedItemIDとCreatedByIDを持つFeedLikeを検索しようとしたのですが、FeedLikeは直接fetchできないというエラーが出ました。ので、NewsFeedをfetchする時に、一緒にFeedLikesもfetchしておきます。

NSString *strQuery = [NSString stringWithFormat:
     @"SELECT Id, (SELECT Id, CreatedById From FeedLikes) 
       From NewsFeed Where Id = '%@' Limit 1", fId];

で、FeedLikesの中から自分のUser IDと同じCreatedByIdを持つFeedLikeを探し出して消します。

fId = (NSString *)[feedLike objectForKey:@"Id"];
requestDeleteLike = [[SFRestAPI sharedInstance] 
    requestForDeleteWithObjectType:@"FeedLike" objectId:fId];
[[SFRestAPI sharedInstance] send:requestDeleteLike delegate:self];

とても簡単。なお、自分以外のユーザの「いいね!」を消せるかどうかは試してません。