2011年11月18日金曜日

Visualforceが憎いいいい



■簡単なこと■


てな感じの罫線入った表を表示したいとします(今回はグラデーション入れませんが)。まぁ日本のWeb屋さんにはごく日常的な作業で、処理系によって違いはあるけど

  • ループを回しながらコントロール・ブレークで行を出力していく
  • 先にコントロール・ブレーク済みの行データを配列にいれておいて出力

のどっちかで対応しますわな。

Visualforceだとループ内側では動的な評価ができないので後者で作ります。作りました。


■Visualforce困ったちゃん■

で、分類と詳細の行はレイアウトが違うので、分類の行だったら分類用のタグ、詳細行には詳細用のタグ…を出力させます。

そのために多くのフレームワークには「この内側のタグsを出力するか否か」をスイッチする機能が用意されてます。史上最高のWebフレームワークたるWebObjectsにはWOConditionalがあって(以下長いので省略

しかし。

Force.comってかVisualforceにはありません。ので、<apex:include>とか<apex:component>などを用いてコンポーネントとして作った要素を埋め込みrenderedでon/offします。

これでHTMLを生成すると…見事に表が崩れます。ソースを読んでみると…componentの前後に勝手に<span></span>が挿入されており、結果として以下のようなソースが生成されてしまいます。
<Table>
  <TR><SPAN><TH>品目</TH><TH>金額</TH></SPAN></TR>
  <TR><SPAN><TD>Mac</TD><TD>128,000</TD></SPAN></TR>
</Table>
そりゃ崩れるわなorz。


■しかし天才はいる■

で、困った時のGoogle先生ってことで apex:component span で検索してみたら、一発でworkaroundが見つかりました。「apex:component rendered in SPAN」、いやー、その手は思いつかなかった。まさに天才です。

さっそく実装してみたら、

<Table>
  <TR>
    <SPAN></SPAN>
    <TH>品目</TH><TH>金額</TH>
    <SPAN></SPAN>
  </TR>
  <TR>
    <SPAN></SPAN>
    <TD>Mac</TD><TD>128,000</TD>
    <SPAN></SPAN>
  </TR>
</Table>
となり、ブラウザ上では意図した通りの表示が出ました。

喜び勇んでrenderAs="PDF"を実行したら…。



…はい、終了。お疲れ様でした。まぁ、そらそうよね、<TR>の内側だしねorz

さて、TABLEを全部DIVで書き直すかな。CSSも全部再定義だ…。ああもう朝だ…。

私の夜はまだ明けそうにないがorz

2011年11月13日日曜日

PhoneGap 1.2.0 + Salesforce SDK(hyblid)


■Salesforce mobile SDK 2011-11版■

ちょっと試してみたいことがあって久しぶりにSalesforce mobile SDK for iOS / hyblidを使ってみようと思ったら、11月の頭にSalesforce mobile SDKのアップデータが出ていました(リビジョン番号とかないのかしら)

そのまま放置していたらPhoneGapからは1.2.0が出てました。ついでなので、先にこっちをアップデートします。


■PhoneGap 1.2.0■

それにしてもOpenSourceはバージョン進むの速いな。おっさんは着いていくだけで精一杯だわ。というわけで、1.2.0を落とします。Xcodeは終了しておくこと。

iOSフォルダの中を見ると例によってdmgパッケージになっているのでダブルクリックしてマウント、Uninstall PhoneGap.appで古いヤツを消してから、インストーラを起動します。

#uninstallするのは必須ではないですが、まぁ古いMacOSユーザの習性です#

インストールはサクサク進む、はず。あとは例によって
  • Xcodeを起動
  • PhoneGap-Based Applicationをテンプレートとして新プロジェクトを作る
  • できたプロジェクトをFinderで開いて中のwwwフォルダをXcodeの新プロジェクト上にDrag & Dropして"create folder reference"で追加
  • PhoneGap.plistのExternal hostsに*を追加
  • ビルド
ってことで、無事デモアプリが起動します。「あれkitchen sinkはどこだっけ…?」と思ってしまった自分が悔しい。それはTitanium mobileやがな。PhoneGapでもああいうの欲しいなぁ。


■あらためてSalesforce mobile SDK、の前に■

SDKはgithubに公開されていますので、メンテナンス情報などを取得する意味でもgithubアカウントがあると便利です。というか無いと不便すぎてストレス溜まります。無料なので、取ってしまいましょう。かくいう私もつい先日作ったのですが、便利すぎて今までの苦労があほらしくなりました。githubアカウントを使うには公開鍵が必要ですので、もしまだ作っていなければ、作ります。
で、ここから無料のアカウントを作ります。特に難しいこともないので、省略しますが、さっき作った公開鍵はgithubにログインしてAccount Settings>SSH Public Keysに登録します。あなたのマシンとgithubはsshで通信するので、そのための暗号キーを設定するわけですね。なお、ものすごく蛇足ですが、秘密キーは絶対公開したりヒトに見せたりしてはいけません。

さて、次。Macからgithubを扱うのであれば、GitHub for Macがあると圧倒的に便利ですので、これも入れます。インストールしてセットアップを終えると、あら不思議、githubのsalesforce SDKのページにさっきまで無かった「Clone in Mac」のアイコンが出てきます。クリックするとGitHub for Macがダウンロードを開始します。便利すぎて笑えます。

次に、もしまだgit入れてない人は、入れましょう。サブモジュールなどをgitから取ってくる形式になったので、gitないとうまく使えません。そしてgitを入れるにはMacPortってのがあると簡単です。MacPortをインストールして、それからgitをインストールし、そこからSalesforce mobile SDK 2011年11月版を入れましょう。




■今度こそSDK…のビルド■

…いやー、準備が長かったw というわけで、GitHub for Macのおかげで安全かつ迅速に、SalesforceMobileSDK-iOSが用意できました。ターミナル.appを起動して、SDKをインストールします。とりあえず私は安易にDesktopに置きましたが、そうでない方は水色の部分を変えてください。
cd
cd Desktop/SalesforceMobileSDK-iOS
./install.sh
だーっと滝のように文字が流れます。マシンの性能によって違いますが、数分間続きます。最後に:
all:

BUILD SUCCESSFUL
Total time: 10 seconds
と表示されればOKです(secondsは変わると思いますが)。お疲れ様でした。


■ようやくサンプル(今度こそ)■

SalesforceMobileSDK-iOS/hyblid/SampleApps/ContactExplorerの中にあるContactExplorer.xcodeprojをダブルクリックするとXcodeが起動します。

さくっとビルドすると警告が出てしまいます。そうです、Consumer Keyなどが未登録ですね。というわけで、AppDelegate.hを開き、RemoteAccessConsumerKey, OAuthRedirectURI, OAuthLoginDomainを登録します。
  • RemoteAccessConsumerKey
ここに説明が書いてありますが詳細すぎてわかりにくいですね。Salesforceにログインして 設定>アプリケーションの設定>リモートアクセス>新規 で適当なアプリケーション名、コールバックURL(後述)、連絡先メールアドレスを登録してください。コンシューマ鍵として長い記号のような文字列が表示されますので、それを設定します。
  • OAuthRedirectURI
上記コールバックURLと同じものです。OAuthの認証には暗唱方式とコールバックURL方式があって…と説明すると長いですが、mobileアプリの場合には https://login.salesforce.com/services/oauth2/success を設定します。これでないと、認証を中断した時などに二度とログイン画面が出てこなくなります(経験者は語る)。
  • OAuthLoginDomain
これはSalesforceにログインする時にお馴染みの login.salesforce.com をセットします。デフォルトではサンドボックスに接続するために test.salesforce.com になっていますが、サンドボックスを使う場合と本環境とではここで切り替わるようになっているようです。ただし、本番とサンドボックスを切り替える場合には、上記コンシューマ鍵もそれぞれの環境で作った別のものが必要ですのでご注意ください。
これでようやくcmd+Rできます。長かった…orz

ビルドが終わるとエミュレータが起動し、スプラッシュ画面の後、Salesforceのログイン画面になります。ここであなたのSalesforce idとpasswordを入力します。ログインに成功すると、このアプリからSalesforceへのアクセスを許可するかどうか確認する画面になります。認証すれば、このページの冒頭に貼ったような画面に切り替わるはずです。

お疲れ様でした。

いやー、読むのも大変だったと思いますが、いろいろググって正しい記述かどうかを確認しながらこれを書いたので、休憩を除いて4時間ぐらいかかりっきりでした。

…冒頭、「調べたいことがあったので」と書きましたが…今日はもういいや。忘れないようにモニタにポストイットを貼って(アナログだな)、また後日。

お疲れ様でした(大事なことなので(ry

2011年11月12日土曜日

MacBook proメモリ増設

■8GBで4980円■

というVintage Computerの広告を見て反射的に注文してしまいました。注文の時「送料ヤケに高いな」と思ったらカリフォルニアの会社だったw ともかく税金などあわせて7000円弱なので、まぁOKかなと。注文してから約1週間で届きました。


■さっそく、開腹■

何はなくともアップルのサポートページで段取りを確認しておきます。iPadなどに表示しておくと安心です。

システム終了後、バッテリ抜いて、電源(MagSafe)はもちろんつながっているコネクタも全部外して、8本のネジを全部外します。紛失は論外ですが、3種類ありますのでどこからどのネジを外したか間違えないように。



特殊工具っぽいのが写ってますが、ただの精密ドライバです。昔のMacは特殊なドライバーを使わないと分解できなかったんですが、民主的になったものです。しみじみ。ちなみに手前左側にあるのはHDD、バッテリベイからアクセスできます。そういや、このMacBookはまだHDDのままだった…。

開いたついでにブロワなどでホコリを掃除しておきます。ユニボディは密封構造なのでほとんどホコリはついてないと思いますが。

金属部分に触れて静電気を逃がした後、メモリの両側のレバーを指で広げるとメモリが起きてきますので(この時のメモリの起きてきた角度を忘れないように)、メモリ板をそっと引っ張り出します。昔と違ってゴリゴリやらなくても出て来ます。力の目安としてはUSBコネクタなどより弱い力で抜けますので、それより力を入れても抜けないようであれば、レバーの開き方が悪いなど何か間違っている、ということです。よくレバーの爪などを観察して、どうすれば抜けるかを考えてから再挑戦してください。


■復旧へ■

届いたメモリを静電気除去袋から取り出し、切り欠きの位置を合わせてさっき取り出した時の角度でメモリを差し込みます。これもUSBコネクタより弱い力で、メモリの金色の端子部分が隠れる程度まで差し込めばOKです。差し込んだら真下に水平になるまで押し下げると左右のレバーとメモリの切り欠きがだいたい一致して固定されます。一枚終わったら同じ手順でもう一枚。

終わったら、アルミフタをかぶせて、ネジ締めます。かぶせた状態だと周辺に少し隙間がありますが、0.5-1mmぐらいの均一の隙間なら問題ありません。ユニボディは立て付けが良いので、よほど間違った場所に置いたりゴミが挟まったりしていない限りはOKです。蛇足ですが、アルミフタが薄いので、ネジを一気に締めてはいけません。「☆」の一筆書きのような順番でアルミがひずまないように順次気長に少しずつネジ締めていきます。

バッテリを戻して(私はリチウム電池の劣化防止のため50%充電状態で外してますが)フタを締め、コネクタも元通りにつなぎます。ここで一つお祈りをしてから、電源スイッチON。起動して「このMacについて」で意図した通りのメモリサイズになっていればOK。


さて、朝飯にしよう。

#サポートページのリンクが切れていたので訂正しました(2011-11-18)

2011年11月9日水曜日

画像が消える…?

所沢航空記念公園 YS-11 2011-10-06
何度か続けて、Bloggerに貼った画像が消えるという現象が起きて困っておりました。

スクリーンショットが消えてしまうので、「こうすると治りますよ」の説明がとてもわかりにくいものに…。


■現象■

これまでは、スクリーンショットをプレビューで開いて全選択してコピー、Blogger上にそのままペーストしていました。ずっとそれで特に問題なかったのですが…10月後半ぐらいからは貼って数時間は問題なくても、その後消えて「?」になってしまうという現象が起きるようになりました。


■解消方法■

編集画面の画像アイコンをクリックして画像ファイルをアップロードし、アップロードした画像から選択する…というごく当たり前の手順ならば、上記の現象は起きないようです。

htmlソースを見ると、コピペで貼った場合には画像データがシリアライズされてそのままテキストに挿入されています。以前はそれでも問題なかったんですが、サーバにかかる負担は大きいので使わない方が良いですわね。

ということで。

2011年11月6日日曜日

Xcode 4.2 + iOS 5 + Force.com mobile SDK


■今週もまたXcode三昧■

このところ休日はXcode上でobjective-c三昧です。ようやくツールに馴染んできて、昔WebObjectsで散々使っていたクラスたちにも再会し、Google先生頼みですがとりあえず「iOSアプリとはこういうもの」というのが分かってきました。まぁ、過去30年+に及ぶプログラミング経験上、この時期が一番楽しいのですけどね。

過去の経験上、何か新しいツールを始める時には、とりあえず動くものをベースにしてイジり倒し、次にテンプレートなどを使わないで同じものを作ってみる、という段階を踏むと手っ取り早く習得できるように思います。一応本も読むのですが、それは前にも書いたようにそのツールの世界観をつかむためで、習得するためには動くものを少しずつ改造していくのが良です。


■しかしまたハマる:まずXcode 4.1■

さて、とりあえずメシの種にしようと思っているForce.com / Database.com + iOS方面、一応Salesforce mobile SDKのテンプレートから作ったプロジェクトに関しては、re-authentificationやCRUDはひと通り動き、DescriptionなどFlash toolkitでハマった一連の処理も片付いたので、次の段階としてまっさらなプロジェクトを作りその上でSalesforce対応アプリを書いていく練習に移りました。

まぁ真っさらなプロジェクトとはいえ、Xcodeだとテンプレートが基本的な構成作ってくれるんですけどね。考えてみりゃGUIをプログラムで生成してたのはMS-DOS上でcでアプリ書いてた頃ぐらいのもので、そのあとのVisualbasic, VisualC++, Symantec C/C++, Xcode+WOBuilderなど、ずっとGUI Builder頼みの人生だったな(遠い目)。

で、Xcode 4.1にアップデートしたのですが…ここの追記に書きましたが、Xcode 4.1 + iOS5では、Salesforce mobile SDKから生成したプロジェクトがうまく動いてくれませんでした。世間様でもiOS5になって日本語入力できなくなったアプリが何本がありましたが、これもそれと似たような感じでOAuthの認証画面でキーボードが出てこなくてidもpasswordも入力できないという現象です。

4.0.2に戻すのも面倒だし、せっかくなのでダメ元でXcode 4.2にアップデートしました。Salesforce mobile SDKテンプレートからのプロジェクト生成でも一発で動きました。やれやれ。

そういえば上記SDKのドキュメントには「このSDK使う時には Other Linker Flags-Obj_c -all_load と設定しろ」って書いてありますが、ありましたが、これは「-ObjC -all_load」の間違いですね。ええハマりましたともさ。
#修正されていました(2011/11/13)


■次にStoryboardにハマった■

先に書いておきますがStoryboardさんが悪いわけではないです、その特性などをよく調べないままに使って、私が勝手に「動かねー」と泣いていただけです。はい。

経緯は
  1. Xcode 4.2でMaster-DetailテンプレートからStoryboard対応のアプリを生成
  2. Salesforce mobile SDKテンプレートから生成したプロジェクトから必要箇所をコピペ
  3. Table View Cellを従来のnibからカスタマイズして実装 →It just works.
  4. 次に、また新しくMaster-DetailテンプレートからStoryboard対応のアプリを生成
  5. 上記2と同じく必要箇所をコピペ
  6. Table View CellをStoryboard上のTable View Cellに対してカスタマイズ
  7. OAuthが終わり、requestSOQLが返って来て、TableViewをreloadしようとしてSIGABRT
上記1-6については2-3時間でしたが、7は金曜日の夜一晩徹夜しても解決できませんでした。

Master-Detail + Storyboardの真っさらなプロジェクトを作り、手作りのArray of Dictionaryを単純にTable View Cell上に表示するだけなら動くので、問題はmobile SDKが何かdelegateを呼び出していて、それをインプリメントしていない等の原因で落ちているのだろう、と結論付けました。

とりあえずStoryboardにあるTableView下のTableView SectionとCellを削除すれば普通にTable Viewとして動きますし、Cellをカスタマイズする際には以前と同様にnib+implement classで実装できます。Cellをカスタマイズする際にStoryboard上に直接TableViewCellを置くことができればStoryboardの画面遷移が使えて今後何かと便利だと思うのですが、できないっすね。

まぁそのうち、何かwork aroundが出てくるでしょう。

この週末ずっとXcode 4.2をいじって、プロダクツという意味では何も成果なかったんですが、上記7を調べるためにアプリの挙動をずっと追いかけたりググりまくったりしたので、とりあえず、勉強にはなった、はず。

先週は本業でずっとApex+Visualforceを書いていて、週末はXcode三昧、体重は増えたけど、久しぶりに充実した日々でした。今週は…要件聴取が多いなぁ…。

#追記:スクリーンショットが消えるなぁ…PNGじゃなくてJPEGで貼って見ました(11月8日)。
#また消えた…:コピペじゃなくてアップロードしてみた(11/08 19:00)