【A1】Delphiチュートリアルセッション「Windows開発者のためのFireMonkeyモバイル開発入門」
エンバカデロ・テクノロジーズ
エヴァンジェリスト 高橋智宏

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

アジェンダ• Delphi + FireMonkeyの仕組み– 各種コンポーネント, スタイル, プロジェクトマネージャ• iOSアプリの開発– 準備するもの– 実機に転送• Androidアプリの開発– 準備するもの– 実機に転送• iOS/Android共通の話題– iOS or Android ?
– 画面サイズと画面密度– タブレット or スマホ ?
– 画面の回転(Portrait or Landscape ?)– ロギング– OnPaintとTCanvas

2

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

13

Delphi + FireMonkeyの仕組み

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

従来のVCLの場合
Delphi 統合開発環境(IDE)(エディタ、デバッガ、フォームデザイナ etc.)
Intel/AMD x86用
Delphi コンパイラ

Delphi RTLIntel/AMD x64用
Delphi コンパイラ

VCL

各種コンポーネント

Win32/Win64 API
XP, Vista, 7, 8, 2008, 2012 etc
4

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

iOSの場合
Delphi 統合開発環境(IDE)(エディタ、デバッガ、フォームデザイナ etc.)
iOSシミュレータ(Intel x86)用
Delphi コンパイラ

Delphi RTL

5

iOSデバイス(ARMv7)用
Delphi コンパイラ

FireMonkey

各種コンポーネント

iOS API / POSIX

OpenGL ES

iOSシミュレータ

iOSデバイス

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

Androidの場合
Delphi 統合開発環境(IDE)(エディタ、デバッガ、フォームデザイナ etc.)

Android(ARMv7 + NEON)用 Delphi コンパイラ
Delphi RTL

FireMonkey

各種コンポーネント

Android SDK

Android NDKOpenGL ES

Androidエミュレータ
6

Androidデバイス

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

すぐに試せるデモプロジェクト
iPhone(iPod touch)向け

Android

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

7

iOS 7用スタイルも準備済み
iOS 7の正式リリース後に提供します

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

8

Delphi XE5〜 新しいプロジェクトマネージャ 〜

アプリの転送先を選択可能。デバイスを自動認識• Android• ターゲット: 全デバイスおよび全エミュレータ• iOSシミュレータ• ターゲット: iPad, iPhone, iPhone5• iOSデバイス• ターゲット: 全デバイス
DelphiPAServerTCP/IP接続

USB接続

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

9USB接続2
10iOSアプリの開発本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

準備するもの• Mac OS X Lion(10.7)以降のMacマシン• Xcode 4.6.3 または Xcode 5(Beta)• iOS 6.0以降が動作している iPad または iPhone– iOSシミュレータ または iOS実機• Apple iOS Developer Programへの加入– 証明書作成, iOS実機の登録, プロファイルのインストール etc…

• XE5のRAD PAServerをMacマシンにインストール&起動
それと…
• Windows 7(32bit/64bit)などのPCまたは仮想マシン• Delphi XE5(モバイル開発機能)
11

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

Macマシンや実機がなくても• MacinCloud.comが使えます– 無料トライアルまたは有料のMac OS X環境の時間貸し• Remote Desktop接続なのでレスポンスは良くない• さすがに、iOSシミュレータのみ
http://www.macincloud.com/12

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

Remote Desktop Client

313

Androidアプリの開発

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

準備するもの• Windows 7(32bit/64bit)などのPCまたは仮想マシン– Mac OS Xは非サポート• Delphi XE5(モバイル開発機能)• Android 2.3.3以降が動作しているAndroid実機– ARMv7互換CPU• Intel x86およびMIPSは除く– NEON命令をサポートしないNVIDIA Tegra2は除く• なので、Android 3.x(Honeycomb)は除く• USBケーブルとWindows用USBドライバ– [開発者向けオプション]で[USBデバッグ]を[ON]にしておく

あと…
• 自前でWindowsにインストールしてもOKのもの– JDK7(32bit/64bit)– Android SDK(ADT Bundle, 32bit/64bit)– Android NDK(32bit/64bit)
14

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

Android実機がなくても• エミュレータは遅すぎるので実用的ではありません!!
– Intel x86エミュレータも使えません…
• SciroccoCloud(シロッコ・クラウド)等のサービスが使えます– 無料トライアルまたは有料のAndroid端末時間貸し• Webブラウザ経由で日本製各種Android実機を操作• エンバカデロでも製品テストに使ってます!!

Webブラウザ

http://www.scirocco‐cloud.com/ja/

Android端末100機種以上
15

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

4
16

iOS/Android
共通の話題

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

iOS or Android ?
• コンパイル時に決める{$IFDEF ANDROID}...
{$ENDIF}{$IFDEF IOS}...
{$ENDIF}• 実行時に判定する

17var
os: TOSVersion;
beginif os.Platform = pfiOS then
Button1.Text := 'iOS'else if os.Platform = pfAndroid then
Button1.Text := 'Android'else
Button1.Text := 'Windows 8 Tablet?';
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。
end;画面サイズと画面密度•

論理的(デバイス非依存)なサイズ(dp)なのでデザインが楽– ただし、画素の細かさには注意が必要(例: TImageのMultiResBitmap)
var
ws: IFMXWindowService;
begin
Label1.Text := '幅:'+IntToStr(Screen.Size.Width) + ',高:'+IntToStr(Screen.Size.Height);
ws := TPlatformServices.Current.GetPlatformService(IFMXWindowService) as IFMXWindowService;
Button1.Text := 'スケール:' + FloatToStr(ws.GetWindowScale(Self));
end;
Portraitの状態

18

機種

幅(dp)

高さ(dp)

スケール

規格

iPhone 4, iPhone 4S

3204802.0Retina

iPhone 5320568

2.0Retina

iPad 2, iPad mini

768

1024

1.0

Non‐retina

iPad 3, iPad 4768

1024

2.0

Retinaau HTC EVO WiMAX

320533

1.5hdpi

au HTC EVO 3D360

640

1.5hdpi

LG Nexus 4384592

2.0xhdpi

au HTC J One

3605923.0xxhdpi

Dropad A8480800

1.0mdpi

ASUS Nexus 7 (2012)

6009051.331tvdpi

Kindle Fire HD

533

853

1.5

hdpi

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

SAMSUNG Nexus 10752

1280

2.0xhdpi

iOSAndroid

タブレット or スマホ ?
• iOSは判別が簡単!!
var
device: IFMXDeviceService;
begin
device := TPlatformServices.Current.GetPlatformService(IFMXDeviceService) as IFMXDeviceService;
if Pos('iPad', device.GetModel) > 0 thenApplication.CreateForm(TFormForiPad, Form2)// iPadelse
Application.CreateForm(TFormForiPhone, Form1); // iPhone,iPod touch• Androidには明確な基準が無い??
– Tablet > Phablet > Phone– 幅または高さが480dp以上ならタブレットだと想定する
1280dp

360dp

592dp

19

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

752dp

画面の回転(Portrait or Landscape ?)• フォームのOnResizeイベントをフックして回転を検知
uses FMX.Platform;
procedure TForm1.FormResize(Sender: TObject);var
ss: IFMXScreenService;ori: TScreenOrientation;
begin
ss := TPlatformServices.Current.GetPlatformService(IFMXScreenService) as IFMXScreenService;ori := ss.GetScreenOrientation;if (ori = TScreenOrientation.soPortrait) OR (ori = TScreenOrientation.soInvertedPortrait) then
Button1.Text := 'Portrait'
else
Button1.Text := 'Landscape';end;• フォームのレイアウトは?
– 同一フォーム内で各GUI部品のレイアウトを調整
または– 縦横別々のフォームを Form.Show; して、丸ごと切り替え
20

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。

ロギング
• iOS
– DelphiのUnicodeStringが最終的にはNSString型として出力– iOSシミュレータ: コンソール.appで確認– iOSデバイス: Xcode付属のOrganizerで確認• Android– DelphiのUnicodeStringが最終的にはPAnsiCharとして出力– Android SDKのmonitorユーティリティで確認
procedure TForm1.FormCreate(Sender: TObject);
begin{$IFDEF ANDROID}
System.DefaultSystemCodePage := 65001; // UTF-8: PAnsiChar(Android){$ENDIF}end;

vari: Integer;
f: Single;
e: Extended; // Double
log: IFMXLoggingService;
begin
i := Random(100);f := 123.456;
e := Random;
log := TPlatformServices.Current.GetPlatformService(IFMXLoggingService) as IFMXLoggingService;
log.Log('%s:%d:%f:%f', ['これはログメッセージ!', i, f, e]);//または FMX.Types.Log.d('%s:%d:%f:%f', ['これはログメッセージ!', i, f, e]);
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。
21
end;

OnPaintイベントとTCanvas• 画面への描画はWindowsOS向けVCL(GDI,HDC)とは異なる– 必ずOnPaintイベントとそのCanvasパラメータを使用すること!!
– Repaintメソッドの呼び出しも必要
procedure TForm1.FormCreate(Sender: TObject);
begin
paint_color := TAlphaColorRec.Black;end;
procedure TForm1.Button1Click(Sender: TObject);begin
if paint_color = TAlphaColorRec.Black thenpaint_color := TAlphaColorRec.Red
else
paint_color := TAlphaColorRec.Black;
PaintBox1.Repaint;
end;

22

procedure TForm1.PaintBox1Paint(Sender: TObject; Canvas: TCanvas);
begin
Canvas.BeginScene();Canvas.Fill.Color := paint_color;
Canvas.FillRect(RectF(0, 0, PaintBox1.Width, PaintBox1.Height), 0, 0, [], 1);
Canvas.EndScene;
本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。
end;

Q&A23

本文書の一部または全部の転載を禁止します。本文書の著作権は、著作者に帰属します。