Mobile SDK 開発ガイド - Salesforce.com Help Portal

Mobile SDK 開発ガイド
Salesforce Mobile SDK 3.1
バージョン 33.0, Spring ’15
@salesforcedocs
最終更新日: 2015/3/27
© Copyright 2000–2015 salesforce.com, inc. All rights reserved. Salesforce およびその他の名称や商標は、salesforce.com,
inc. の登録商標です。本ドキュメントに記載されたその他の商標は、各社に所有権があります。
目次
このドキュメントについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
Salesforce Platform モバイルサービス . . . . . . . . . . . . . . . . . . . . . .
Force.com のモバイルサービス . . . . . . . . . . . . . . . . . . . . . .
Salesforce Mobile SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
ID . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Salesforce1 のカスタマイズかカスタムアプリケーションの作成か .
本書について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
フィードバックの送信 . . . . . . . . . . . . . . . . . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
2
3
3
3
4
5
6
第 1 章: Salesforce モバイル開発の概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7
ネイティブ、HTML5、およびハイブリッド開発について . . . . . . . . . . . . . . . . . . . . . . . . 8
クイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11
第 2 章: Mobile SDK の使用開始 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
Developer Edition 環境か Sandbox 環境か . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13
開発の前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
Force.com のサインアップ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
接続アプリケーションの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
接続アプリケーションを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15
Mobile SDK のインストール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Mobile SDK npm パッケージ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
Mobile SDK GitHub リポジトリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21
Mobile SDK サンプルアプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
サンプルアプリケーションのインストール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
最新情報 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
第 3 章: ネイティブ iOS の開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26
iOS ネイティブクイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
ネイティブ iOS の要件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
iOS プロジェクトの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
Xcode プロジェクトのテンプレートアプリケーションを実行する . . . . . . . . . . . . . 28
CocoaPods と Mobile SDK の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29
ネイティブ iOS アプリケーションの開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
ログインとパスコードについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
メモリ管理について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30
アプリケーションフローの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31
SalesforceSDKManager クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32
AppDelegate クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
ビューコントローラについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
目次
RootViewController クラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Salesforce REST API について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
認証エラーの処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
チュートリアル: ネイティブ iOS Warehouse アプリケーションの作成 . . . . . . . . . . . . . . 56
ネイティブ iOS アプリケーションを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
リスト画面をカスタマイズする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 64
詳細画面を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
iOS ネイティブサンプルアプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
第 4 章: ネイティブ Android の開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
Android ネイティブクイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
ネイティブ Android の要件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Android プロジェクトの作成 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 82
Eclipse でのサンプルプロジェクトの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
Android プロジェクトファイル . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
ネイティブ Android アプリケーションの開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
Android アプリケーションの構造 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86
ネイティブ API パッケージ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
ネイティブクラスの概要 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88
パスコードの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
リソースの処理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
REST API の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
Android テンプレートアプリケーション: 詳細 . . . . . . . . . . . . . . . . . . . . . . . . . . . 103
チュートリアル: ネイティブ Android Warehouse アプリケーションの作成 . . . . . . . . . . 106
前提条件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106
ネイティブ Android アプリケーションを作成する . . . . . . . . . . . . . . . . . . . . . . . . 108
リスト画面をカスタマイズする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111
詳細画面を作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 115
Android ネイティブサンプルアプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
第 5 章: HTML5 およびハイブリッド開発 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125
はじめに . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
HTML5 および JavaScript の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
HTML5 の開発要件 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
マルチデバイス戦略 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126
サポートされるブラウザ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130
HTML5 開発ツール . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
モバイル UI 要素 (ベータ) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
Visualforce を使用した HTML5 コンテンツの配信 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
Salesforce データへのアクセス: コントローラと API . . . . . . . . . . . . . . . . . . . . . . . . . . 138
ハイブリッドアプリケーションのクイックスタート . . . . . . . . . . . . . . . . . . . . . . . . . . 140
ハイブリッドアプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
ハイブリッド開発について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142
Cordova を使用したハイブリッドアプリケーションの開発 . . . . . . . . . . . . . . . . . 142
目次
ハイブリッドリモートアプリケーションの開発 . . . . . . . . . . . . . . . . . . . . . . . . . 145
ハイブリッドサンプルアプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 147
ContactExplorer ハイブリッドサンプルの実行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
iOS 7 ハイブリッドアプリケーションでのステータスバーの制御 . . . . . . . . . . . . . . . . . 159
ハイブリッドアプリケーションの JavaScript ファイル . . . . . . . . . . . . . . . . . . . . . . . . . 160
バージョン設定および JavaScript ライブラリの互換性 . . . . . . . . . . . . . . . . . . . . . . . . . 161
ハイブリッドアプリケーションでのセッション管理 . . . . . . . . . . . . . . . . . . . . . . . . . . 163
Android ハイブリッドアプリケーションからの SmartStore と SmartSync の削除 . . . . . . . 166
例: 適切な JavaScript ライブラリの提供 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
第 6 章: オフライン管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 168
SmartStore を使用したオフラインデータの安全な保存 . . . . . . . . . . . . . . . . . . . . . . . . 169
SmartStore について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169
ハイブリッドアプリケーションでの SmartStore の有効化 . . . . . . . . . . . . . . . . . . . 170
既存の Android アプリケーションへの SmartStore の追加 . . . . . . . . . . . . . . . . . . . . 171
スープの登録 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171
スープからのデータの取得 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 174
スマート SQL クエリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
カーソルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
データの操作 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179
スープの管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
SmartStore インスペクタを使用したテスト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 188
擬似 SmartStore の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 189
NativeSqlAggregator サンプルアプリケーション: ネイティブアプリケーションでの
SmartStore の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 190
SmartSync を使用した Salesforce オブジェクトへのアクセス . . . . . . . . . . . . . . . . . . . . 193
ネイティブ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
ハイブリッド . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
第 7 章: ファイルとネットワーキング . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
アーキテクチャ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
ファイルのダウンロードと共有の管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
ファイルのアップロード . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
暗号化とキャッシュ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
Android アプリケーションでのファイルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262
要求キューの管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 263
iOS ネイティブアプリケーションでのファイルの使用 . . . . . . . . . . . . . . . . . . . . . . . . 264
要求の管理 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 265
ハイブリッドアプリケーションでのファイルの使用 . . . . . . . . . . . . . . . . . . . . . . . . . 266
第 8 章: 転送通知と Mobile SDK . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
転送通知について . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
ハイブリッドアプリケーションでの転送通知の使用 . . . . . . . . . . . . . . . . . . . . . . . . . 268
コードの変更 (ハイブリッド) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
目次
Android での転送通知の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 269
GCM (Android) 用に接続アプリケーションを設定する . . . . . . . . . . . . . . . . . . . . . 269
コードの変更 (Android) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
iOS での転送通知の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 271
APNS (iOS) 用に接続アプリケーションを設定する . . . . . . . . . . . . . . . . . . . . . . . . 272
コードの変更 (iOS) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 273
第 9 章: モバイルアプリケーションでの認証、セキュリティ、ID . . . . . . . . . . . . 275
OAuth の用語 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
OAuth2 認証フロー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
OAuth 2.0 ユーザエージェントフロー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 277
OAuth 2.0 更新トークンフロー . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
範囲パラメータの値 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
ID URL の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
カスタムログインサーバの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
OAuth トークンの取り消し . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287
Android ネイティブアプリケーションでの更新トークンの取り消し . . . . . . . . . . . 287
接続アプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
PIN セキュリティについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288
OAuth 2.0 サイトおよび Force.com サイトを使用したポータル認証 . . . . . . . . . . . . . . . 289
第 10 章: Mobile SDK アプリケーションでの Communities の使用 . . . . . . . . . . . . 290
コミュニティと Mobile SDK アプリケーション . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
「API の有効化」プロファイルを設定する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 291
権限セットを設定する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 292
API アクセス権をユーザに付与する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 293
ログインエンドポイントを設定する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 294
コミュニティのブランド設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
コミュニティのログイン、ログアウト、およびセルフ登録のカスタマイズ . . . . . . . . . 296
コミュニティでの外部認証の使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 296
外部認証プロバイダについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 297
コミュニティ URL パラメータの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 298
Scope パラメータの使用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 299
Facebook 認証プロバイダの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
Salesforce 認証プロバイダの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 303
OpenID Connect 認証プロバイダの設定 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
例: Mobile SDK アプリケーションからアクセスできるようにコミュニティを設定する . . 309
プロファイルに権限を追加する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 309
コミュニティを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 310
コミュニティに API ユーザプロファイルを追加する . . . . . . . . . . . . . . . . . . . . . . 310
新しい取引先責任者およびユーザを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . 311
新しいコミュニティログインをテストする . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
例: Facebook 認証できるようにコミュニティを設定する . . . . . . . . . . . . . . . . . . . . . . . 313
Facebook アプリケーションを作成する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 313
目次
Salesforce 認証プロバイダを定義する . . . . . . . . . .
Facebook アプリケーションを設定する . . . . . . . . .
認証プロバイダの Apex クラスをカスタマイズする
Salesforce コミュニティを設定する . . . . . . . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
313
314
315
316
第 11 章: Mobile SDK でのマルチユーザのサポート . . . . . . . . . . . . . . . . . . . . . . . . 317
マルチユーザのサポートについて . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
マルチユーザのサポートの実装 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
Android ネイティブ API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
iOS ネイティブ API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 326
ハイブリッド API . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
第 12 章: 以前のリリースからの移行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 332
ハイブリッドアプリケーションを 3.0 から 3.1 に移行する . . . . . . . . . . . . . . . . . . . . . 333
Android ネイティブアプリケーションを 3.0 から 3.1 に移行する . . . . . . . . . . . . . . . . . 333
iOS ネイティブアプリケーションを 3.0 から 3.1 に移行する . . . . . . . . . . . . . . . . . . . . 333
Mobile SDK ライブラリパッケージを 3.0 から 3.1 に更新する . . . . . . . . . . . . . . . . 334
ハイブリッドアプリケーションを 2.3 から 3.0 に移行する . . . . . . . . . . . . . . . . . . . . . 334
Android ネイティブアプリケーションを 2.3 から 3.0 に移行する . . . . . . . . . . . . . . . . . 335
iOS ネイティブアプリケーションを 2.3 から 3.0 に移行する . . . . . . . . . . . . . . . . . . . . 335
Mobile SDK ライブラリパッケージを更新する . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
SalesforceSDKManager を使用するようにアプリケーションブートストラップフロー
を更新する . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
以前のリリースからの移行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 337
ハイブリッドアプリケーションを 2.2 から 2.3 に移行する . . . . . . . . . . . . . . . . . 338
Android ネイティブアプリケーションを 2.2 から 2.3 に移行する . . . . . . . . . . . . . . 341
iOS ネイティブアプリケーションを 2.2 から 2.3 に移行する . . . . . . . . . . . . . . . . 342
Mobile SDK Android アプリケーションを 2.1 から 2.2 に移行する . . . . . . . . . . . . . . 343
Mobile SDK iOS アプリケーションを 2.1 から 2.2 に移行する . . . . . . . . . . . . . . . . . 343
バージョン 2.0 からバージョン 2.1 への移行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
バージョン 1.5 からバージョン 2.0 への移行 . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
第 13 章: リファレンス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 357
REST API リソース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 358
iOS アーキテクチャ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
ネイティブ iOS オブジェクト . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 360
Android アーキテクチャ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
Android パッケージおよびクラス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 361
ライブラリ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 368
Android リソース . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
Files API リファレンス . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
FileRequests メソッド (Android) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 372
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS) . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
ハイブリッドアプリケーションの Files メソッド . . . . . . . . . . . . . . . . . . . . . . . . . 385
目次
forceios パラメータ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 391
forcedroid パラメータ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
このドキュメントについて
モバイルデバイスによって、仕事や娯楽の手段が急速に変化しています。幅広い接続デバイスでデータが使
用、作成、共有されています。作業者は、連絡手段、顧客や同僚とのやり取り、ソーシャルネットワークおよ
びアプリケーションの利用のためにスマートフォンとタブレットを使用しています。
しかし、多くの企業では今もなお、モバイル環境では動作しないエンタープライズアプリケーションによる業
務を継続しています。これらの従来のアプリケーションは企業イントラネット内に隔離されたままで、従業員
が外部で必要なときに使用できません。最新のユーザ環境には対応しておらず、コンシューマアプリケーショ
ンのようにソーシャルグラフを利用することもありません。
従来のプラットフォームは、モバイル環境の需要を満たすようには設計されていません。大規模なモノリシッ
クスタックと固定された統合パターンには、モバイル技術で必要とされる拡張性と柔軟性がありません。PC
の Web アプリケーション用として 1990 年代に発展した技法は、モバイルアプリケーションには適用されませ
ん。モバイルアプリケーションには新しいアーキテクチャとソフトウェア設計が必要であり、モバイルアプリ
ケーション開発とワイヤレス接続用に構築されたプラットフォーム上で実行する必要があります。今日では、
従来の企業アプリケーションが急速にモバイル対応クラウドアプリケーションに取って代わられています。
表 1 : PC/Web アプリケーションと最新モバイルアプリケーションの比較
カテゴリ
一般的な PC / Web アプリケーション
接続および可用性 • 高速で信頼性の高い LAN
ユーザ操作
境界のセキュリ
ティ
モバイル/最新アプリケーション
• さまざまな接続
• 待ち時間が短い
• 長い待ち時間
• 高帯域幅
• 低帯域幅
• 接続されていることが前提
• オフライン操作が必要
• キーボードとマウス
• タッチスクリーン
• 時間のかかるデスクトップ操作
• すばやい焦点を絞ったアクション
• 企業 VPN または LAN によるアプリケー • モバイルデバイスからの VPN が必要であるた
ションアクセス
め煩雑
• 公開モバイルネットワークでは IP 制限が無
効
デバイスの標準化 • 通常は IT 部門が購入および管理
• 多くの場合個人所有デバイス (BYOD)
• 複数のプラットフォーム
フォーム要素
• 大きい (PC) 画面
• アプリケーションは携帯電話、タブレット、
デスクトップをサポートする必要がある
1
このドキュメントについて
Salesforce Platform モバイルサービス
カテゴリ
一般的な PC / Web アプリケーション
モバイル/最新アプリケーション
ソーシャル
• 通常はサイロ化されたアプリケー
ション
• ネイティブユーザコラボレーション
• 直感的な共有とコラボレーション
• メールベースのコラボレーション
複数デバイス
• データがサーバ (Web) に保存される • デバイス間の即時共有
クライアント-サーバアーキテクチャ • デバイス間のデータ伝達
デバイス連携
• アプリケーションはテレフォニー、 • モバイルデバイスのカメラ、連絡先、カレ
カメラ、その他のメディアデバイス
ンダー、場所をネイティブで使用
をほとんど利用しない
位置情報
• Web アプリケーションではほとんど • 位置情報とデータの関連付け、および位置
使用されない
情報に基づくデータとサービスの絞り込み
に一般的に使用
Salesforce は、CRM モバイルアプリケーションを作成するための最先端のクラウドベースプラットフォームを提
供します。Salesforce Mobile SDK では、モバイルデバイス機能、オフラインサポート、データ同期、モバイルソ
フトウェア設計を詳細に制御できます。
Salesforce Platform モバイルサービス
今日のエンタープライズ IT 部門は、エンタープライズデータおよびサービスと、モバイル環境の従業員をつな
ぐという困難な課題に直面しています。Salesforceでも、エンタープライズ CRM およびサービスアプリケーショ
ンをモバイル環境に移行したときにこの問題に直面しました。この変換には、複数のプラットフォーム (iOS、
Android) と複数のフォーム要素 (携帯電話、タブレット、PC) 全体で、エンタープライズレベルの信頼性、可用
性、セキュリティを備えたSalesforceのアプリケーションをサポートするために、基盤となる技術と実装の根本
的な変更が必要でした。Salesforceのアプリケーションをモバイル用に変換するために得た知識と構築した技術
は、現在 Salesforce クラウドを使用するあらゆる企業が利用できるようになっています。
Salesforce Platform モバイルサービスは、モバイルアプリケーションの課題に対応するように設計されていま
す。
Salesforce Platform モバイルサービスは Salesforce モバイルアプリケーションを強化する次世代のプラットフォー
ムであり、企業が独自の Android、iPhone、iPad アプリケーションを作成できます。これらのサービスは、Salesforce
プラットフォームの機能、および実績のあるエンタープライズアプリケーションのセキュリティ、信頼性、拡
張性を活用します。
Salesforce Platform モバイルサービスは 3 つのコアコンポーネントで構成されます。
• Force.com のモバイルサービス
• Salesforce Mobile SDK
• ID
2
このドキュメントについて
Force.com のモバイルサービス
Force.com のモバイルサービス
Force.comのモバイルサービスは、エンタープライズモバイルアプリケーションの開発と管理に焦点を絞ってい
ます。
• モバイル REST API は、標準 Web プロトコルを利用し、エンタープライズデータおよびサービスへのアクセス
を可能にします。開発者はREST APIを使用してビジネスデータにすばやくアクセスし、そのデータを携帯電
話、タブレット、および Web ユーザインターフェースで利用できます。REST API では、すべてのデバイス種
別のアクセス、セキュリティ、共通ポリシーを 1 か所で設定できます。
• ソーシャル (Chatter) REST API では、開発者がアプリケーションにソーシャルネットワークおよびコラボレー
ション機能をすばやく追加できます。Chatter REST API は、フィード、およびユーザ接続のソーシャルグラフ
へのアクセスを可能にします。モバイルアプリケーションは、使用やユーザまたはグループへの項目の投
稿が非常に簡単で、ソーシャルグラフを利用して接続ユーザ間のコラボレーションをすぐに実行できます。
• モバイルポリシー管理では、システム管理者が境界のセキュリティなしに世界中のモバイルアプリケーショ
ンにエンタープライズセキュリティポリシーを適用できます。システム管理者は、2 要素認証、デバイス
PIN 保護、パスワードローテーションなどのセキュリティ機能を有効にできます。また、モバイルアプリ
ケーションへのユーザアクセスを有効化/無効化することもできます。
• 地理位置情報は、位置ベースの情報を提供し、地理空間データでオンラインビジネスプロセスを強化しま
す。Salesforce のすべてのオブジェクトには、地理位置情報の複合項目が含まれています。プラットフォー
ム全体が位置情報に対応しているため、区域ベースの検索や他の空間クエリを実行できます。
Salesforce Mobile SDK
Salesforce Mobile SDK を使用して、iOS 用のネイティブ Objective-C アプリケーションと Android 用の Java アプリケー
ションを開発できます。また、HTML5 と JavaScript で記述されたハイブリッドアプリケーション用のネイティブ
コンテナを提供することもできます。iOS および Android 用の npm スクリプトは、ネイティブアプリケーション
やハイブリッドアプリケーションの開発を始めるときに役立ちます。Salesforce Mobile SDK には、次の機能があ
ります。
• ネイティブのデバイスサービス。幅広い iOS および Android デバイスのカメラ、GPS、連絡先などのデバイス
機能にアクセスできます。
• セキュアなオフラインストレージとデータ同期。ネットワーク接続が限定されているか、ネットワーク接
続がない場合でも、継続して機能するアプリケーションを作成できます。デバイスに保存されたデータは、
セキュアに暗号化され、デバイスの紛失や盗難時も安全です。
• クライアント OAuth 認証サポート。モバイルアプリケーションでログインページや汎用的な認証を再作成
する必要がありません。Mobile SDKでは、アプリケーションをエンタープライズセキュリティ管理とすばや
く容易に統合できます。
ID
ID は、モバイルデバイスをエンタープライズデータおよびサービスと接続するための単一のエンタープライズ
ID およびサインオンサービスです。ID には、次の利点があります。
• アプリケーションおよびデバイス全体のシングルサインオン。ユーザが複数のユーザ名とパスワードを作
成する必要はありません。
3
このドキュメントについて
Salesforce1 のカスタマイズかカスタムアプリケーション
の作成か
• すべてのエンタープライズプラットフォームまたはアプリケーションで利用可能な信頼できる ID プロバイ
ダ。
• 企業が ID サービスをホワイトラベル化し、会社固有の外観とブランドを使用できるようにするクラウド
ディレクトリ。
• Facebook などのコンシューマ ID プロバイダを利用可能。この機能により、顧客向けアプリケーションで顧
客のソーシャルデータをすばやく活用できます。
Salesforce1 のカスタマイズかカスタムアプリケーションの作成か
Salesforce モバイルユーザ用の機能を開発する場合には、2 つのオプションがあります。このマニュアルでは、
Mobile SDK 開発のみを取り上げていますが、Salesforce にはモバイルアプリケーション開発用に Salesforce1 Platform
も用意されています。
Salesforce1 の拡張と Mobile SDK を使用したカスタムアプリケーションの作成には違いがいくつかあります。
Salesforce1 についての詳細は、developer.salesforce.com/docs を参照してください。
Salesforce1 のカスタマイズ
• 定義済みのユーザインターフェースがある。
• Salesforce データにフルアクセスできる。
• Salesforce1 Platform で開発された機能と統合された環境を作成できる。
• アクションバーにより、独自のアプリケーション/機能を含める方法が提供される。
• ポイント & クリックまたはプログラムによるカスタマイズのいずれかを使用して Salesforce1 をカスタマイズ
できる。
• Visualforce ページまたは Force.com Canva アプリケーションを使用して、プログラムにより機能を追加できる。
• Salesforce1のカスタマイズまたはアプリケーションは、Salesforce1ナビゲーションに準拠する。このため、た
とえば Visualforce ページなどをナビゲーションメニューまたはアクションバーからコールできます。
• 既存の Salesforce 開発手法 (ポイント & クリックおよびプログラムの両方) を活用できる。
• すべての Salesforce エディションに含まれ、Salesforce でサポートされている。
カスタムモバイルアプリケーションの開発
カスタムアプリケーションは、Salesforce Mobile SDK で作成する独立型アプリケーションの場合と、プレーン
HTML5 および JQuery Mobile/Ajax を使用するブラウザアプリケーションの場合があります。カスタムアプリケー
ションでは、次のことができます。
• カスタムユーザ環境を定義する。
• ネイティブおよびハイブリッドのローカルアプリケーションで REST API を使用するか、JavaScript Remoting を
使用するハイブリッドアプリケーションで Visualforce を使用して、Salesforce データにアクセスする。HTML5
アプリケーションでは、JQueryMobile および Ajax を使用して同じ操作を行います。
• 顧客向け公開用のユーザインターフェースをブランド設定する。
4
このドキュメントについて
本書について
• Java for Android または Objective-C for iOS を使用するネイティブ API を使用するか、JavaScript および HTML5 を使
用するハイブリッドコンテナを使用して、スタンドアロンモバイルアプリケーションを作成する (Mobile SDK
のみ)。
• Apple App Store や Google Play などのモバイル業界チャネルを使用して、アプリケーションを配布する (Mobile
SDK のみ)。
• 複雑なオフライン動作を設定および制御する (Mobile SDK のみ)。
• 転送通知を使用する。
• 独自の OAuth モジュールを使用して、カスタムセキュリティコンテナを設計する (Mobile SDK のみ)。
• Mobile SDK のその他の重要な考慮事項:
– オープンソース SDK は、npm インストーラおよび GitHub から無料でダウンロードできます。ライセンス
は必要ありません。
– アプリケーションを外部開発環境 (iOS の場合は Xcode、Android の場合は Eclipse またはそれに類似するも
の) で開発およびコンパイルする必要があります。
– 開発費用は 0 ~ 100万ドルまたはそれ以上で、さらにメンテナンス費用がかかります。
Mobile SDK は、以下を提供することで Force.com クラウドアーキテクチャを Android および iOS アプリケーション
に統合します。
• JavaScript を介して Salesforce データにアクセスして同期する SmartSync Data Framework
• Salesforce 接続アプリケーションポリシーの実装
• 永続化機能や更新機能を含む、OAuth ログイン情報管理
• Salesforce REST API のラッパー
• ハイブリッドアプリケーション用の Cordova ベースのコンテナ
• ハイブリッドアプリケーションのデータ同期
• SmartStore を使用した安全なオフラインストレージ
• ネイティブおよびハイブリッドアプリケーションの転送通知のサポート
• Salesforce Communities のサポート
• 複数ユーザログインのサポート
本書について
本書では、Salesforce Mobile SDK を紹介し、クラウド用モバイルアプリケーションの設計、開発、管理方法につ
いて説明します。HTML5 および JavaScript から始まり、ハイブリッドアプリケーション、さらに最終的にはネイ
ティブ iOS および Android 開発に至るまで、さまざまなスキルセットを持つユーザ向けの幅広い開発方法を網羅
しています。
各開発パラダイムは、クイックスタートチュートリアル形式で提供されます。ほとんどのチュートリアルは、
REST API を使用して Salesforce にアクセスする単純な主従アプリケーションの作成手順を説明しています。次の
チュートリアルがあります。
• ContactExplorer ハイブリッドサンプルの実行
• チュートリアル: ネイティブ Android Warehouse アプリケーションの作成
5
このドキュメントについて
フィードバックの送信
• チュートリアル: ネイティブ iOS Warehouse アプリケーションの作成
• チュートリアル: SmartSync アプリケーションの作成
Mobile SDK サンプルアプリケーションへのポインタ、コミュニティの使用およびハイブリッドアプリケーショ
ンの管理のヒントと手法、次のような Mobile SDK 機能の説明も含まれています。
• SmartStore を使用したオフラインデータの安全な保存
• SmartSync を使用した Salesforce オブジェクトへのアクセス
• ファイルとネットワーキング
• 転送通知と Mobile SDK
Salesforce Mobile SDK を思う存分探索してください。
メモ: 本書のオンラインバージョンは、developer.salesforce.com/docs で参照できます。
フィードバックの送信
本書に関するご質問またはコメントがある場合や、今後のバージョンで追加するトピックのご提案がある場
合、次のことを行えます。
• SalesforceMobileSDK コミュニティ (plus.google.com/communities) に参加する
• Salesforce 開発者ディスカッションフォーラム (https://developer.salesforce.com/forums) で意見を
投稿する
• [email protected] に直接メールを送信する
6
第1章
トピック:
•
ネイティブ、
HTML5、およびハイ
ブリッド開発につ
いて
•
クイックスタート
Salesforce モバイル開発の概要
Salesforce Mobile SDK を使用すると、スタンドアロンモバイルアプリケーション内で
Force.com の機能を活用できます。
Force.com には、Salesforce クラウドコンピューティング用のわかりやすく生産的なプ
ラットフォームが備えられています。開発者は Force.com を使用して、カスタムオブ
ジェクトとカスタム項目、ワークフロールール、Visualforce ページ、Apex クラス、ト
リガなどの Salesforce アプリケーションコンポーネントを定義できます。定義したコ
ンポーネントは、画期的なブラウザベースのデスクトップアプリケーションに組み
込むことができます。
Mobile SDKアプリケーションでは、デスクトップアプリケーションと異なり、ブラウ
ザではなくモバイルデバイスのネイティブオペレーティングシステム経由でSalesforce
データにアクセスします。モバイルユーザが満足する生産性の高いの操作性を確保
するために、オンライン/オフライン状態をシームレスに切り替えられるよう Mobile
SDK アプリケーションを設定できます。開発に着手する前に、モバイル開発の仕組
みを確認し、重要な Salesforce 開発者リソースについて学習します。
7
Salesforce モバイル開発の概要
ネイティブ、HTML5、およびハイブリッド開発について
ネイティブ、HTML5、およびハイブリッド開発について
Salesforce Mobile SDK では、アプリケーションの開発方法を選択できます。選択できるオプションは、開発スキ
ル、デバイスおよびテクノロジの要件、目的、スケジュールによって変わります。
Mobile SDK では、3 通りの方法でモバイルアプリケーションを作成できます。
• ネイティブアプリケーションは、特定のモバイルプラットフォーム (iOS または Android) に固有であり、それ
ぞれのプラットフォームでサポートする開発ツールと言語 (iOS の Xcode と Objective-C、Android の Eclipse と Java
など) を使用します。ネイティブアプリケーションは、外観とパフォーマンスは最高ですが、最も多くの開
発作業を必要とします。
• HTML5 アプリケーションでは、標準の Web テクノロジ (通常、HTML5、JavaScript および CSS) を使用し、モバ
イル Web ブラウザを通してアプリケーションを提供します。この「Write Once, Run Anywhere (一度書けば、ど
こでも実行できる)」というモバイル開発へのアプローチでは、複数のデバイスで動作するクロスプラット
フォームのモバイルアプリケーションが作成されます。開発者は、HTML5 と JavaScript のみを使用して高度
なアプリケーションを作成することもできますが、セッション管理、安全なオフラインストレージ、ネイ
ティブデバイス機能 (カメラ、カレンダー、通知など) へのアクセスなど、いくつかの難題も残ります。
• ハイブリッドアプリケーションは、Salesforceコンテナ内の Web アプリケーションをラップすることにより、
HTML5 Web アプリケーションの開発の容易さをネイティブプラットフォームの機能と結合します。この結
合手法では、デバイスのネイティブ機能を利用でき App Store から提供できるアプリケーションが作成され
ます。また、Salesforce ハイブリッドコンテナを通して提供される Visualforce ページを使用して、ハイブリッ
ドアプリケーションを作成することもできます。
ネイティブアプリケーション
ネイティブアプリケーションは、使い勝手、機能、全体的なモバイルの操作性の点において最良です。ネイ
ティブアプリケーションでしか実現できないことがいくつかあります。
8
Salesforce モバイル開発の概要
ネイティブ、HTML5、およびハイブリッド開発について
• 高速グラフィック API — ネイティブプラットフォームでは最も高速なグラフィックを実現できます。限ら
れた要素のみを含む静的画面を表示する場合には重要でないかもしれませんが、大量のデータを使用し、
かつすばやい更新を必要とする場合には効果的です。
• 流動的なアニメーション — 高速グラフィック API と関連し、流動的なアニメーションを実現する機能です。
これは、ゲーム、非常にインタラクティブなレポート、写真や音を変換する強度の演算アルゴリズムには
特に重要です。
• 組み込みコンポーネント — カメラ、アドレスブック、地理位置情報、およびデバイスに対してネイティブ
なその他の機能を、モバイルアプリケーションにシームレスに統合できます。他の重要な組み込みコンポー
ネントとして、暗号化されたストレージもありますが、これについては後で説明します。
• 使いやすさ — ユーザはネイティブプラットフォームを使い慣れています。この使い慣れた操作感をユーザ
が期待するネイティブ機能に追加することで、アプリケーションがさらに使いやすくなります。
ネイティブアプリケーションの開発には通常、統合開発環境 (IDE) を使用します。IDE には、作成、デバッグ、
プロジェクト管理、バージョン設定用のツール、およびプロの開発者が必要とする他のツールが備えられてい
ます。ネイティブアプリケーションの開発は他のアプリケーションより難しいため、これらのツールが必要で
す。同様に、他の開発シナリオに比べてより高い経験レベルが要求されます。プロの開発者は、実証済みの
API やフレームワーク、定義済みコンポーネントを使用した簡単な特殊効果、すべてのコードを 1 箇所にまと
めることの利点に必ずしも価値を見出しません。
HTML5 アプリケーション
HTML5 モバイルアプリケーションは、基本的には小さいモバイルデバイス画面で動作するように設計された単
一または一連の Web ページです。HTML5 アプリケーション自体はデバイスにとらわれず、最新のどのモバイル
ブラウザでも開くことができます。コンテンツは Web に存在するため検索可能であり、特定のタイプのアプ
リケーション (ショッピングなど) では大きな利点となります。
HTML5 は、ネイティブ開発やハイブリッド開発に比べて簡単に開始できます。ただし、すべてのモバイルデバ
イスは、使用可能な画面サイズおよび解像度が独自のアイデアに基づいて構成されています。この多様性によ
り、異なるデバイスやオペレーティングシステムをテストする場合の負担が大きくなります。
「Write Once, Run Anywhere」という HTML5 手法の重要な点は、配布とサポートがネイティブアプリケーションに
比べて非常に簡単に行えるということです。バグ修正または機能の追加が必要な場合でも、すべてのユーザに
対して行われ、導入されます。ネイティブアプリケーションでは開発期間とテスト期間が長くなります。通常
コンシューマは、その期間を経た後にストアにログインして新バージョンをダウンロードし、最新の修正を取
得する必要があります。
HTML5 アプリケーションは、他のアプリケーションよりも開発とサポートが簡単で、最も広範囲にわたるデバ
イスを使用できますが、次のような欠点もあります。
• 安全なオフラインストレージ — HTML5 ブラウザでは、オフラインのデータベースとキャッシュをサポート
していますが、標準の暗号化はサポートされません。Mobile SDK ネイティブアプリケーションでは、3 つの
機能をすべて使用できます。
• セキュリティ — 一般に、ネイティブプラットフォームで単純なセキュリティ対策を実装する場合でも、モ
バイル Web 開発者にとっては複雑な作業となることがあります。また、ユーザにとっても不便な場合があ
ります。たとえば、認証を必要とする Web アプリケーションでは、アプリケーションを再起動するたび、
またはバックグラウンド状態から戻るたびに、ユーザはログイン情報を入力する必要があります。
9
Salesforce モバイル開発の概要
ネイティブ、HTML5、およびハイブリッド開発について
• ネイティブ機能 — カメラ、アドレスブック、その他のネイティブ機能は、アクセスが可能であっても、ブ
ラウザのプラットフォームが制限されます。
• ネイティブのデザイン — HTML5 はネイティブの外観しかエミュレートできず、顧客は使い慣れた複合操作
を使用できません。
ハイブリッドアプリケーション
ハイブリッドアプリケーションは、ネイティブプラットフォーム機能へのアクセスを提供するシンコンテナ内
でラップされた HTML5 および JavaScript を使用して作成されます。ハイブリッドアプリケーションのほとんどの
部分では、両方のアプリケーションの最良の特性が提供されます。つまり、開発は HTML5 アプリケーションと
ほぼ同じくらい簡単で、ネイティブアプリケーションのすべての機能が提供されます。また、ハイブリッドア
プリケーションでは、JavaScript で SmartSync Data Framework を使用して、次の操作を行うことができます。
• Salesforce データをモデル化、クエリ、検索、編集する
• オフラインで使用できるように Salesforce データを安全にキャッシュする
• ローカルにキャッシュされたデータを Salesforce サーバと同期する
ネイティブアプリケーションはデバイスにインストールされますが、HTML5 アプリケーションは Web サーバに
存在するため、ハイブリッドアプリケーションのファイルがデバイスとサーバのどちらに保存されるのか疑問
に思われるかも知れません。 ハイブリッドアプリケーションは、ローカルまたはリモートで実装できます。
ローカル
HTML と JavaScript のコードは、ネイティブアプリケーションと同様の構造で、モバイルアプリケーションバ
イナリ内でパッケージ化できます。この場合、REST API および Ajax を使用して、デバイスとクラウド間で
データを移動します。
リモート
完全な Web アプリケーションをサーバから実装することもできます (パフォーマンス向上のためオプション
としてキャッシュもできます)。コンテナアプリケーションは、完全なアプリケーションをサーバから取得
し、それをブラウザウィンドウに表示します。
このガイドでは、両方のタイプのハイブリッド開発について説明します。
ネイティブ、HTML5、およびハイブリッドのまとめ
次の表に、3 つのモバイル開発シナリオの比較の概要を示します。
ネイティブ
HTML5
ハイブリッド
グラフィック
ネイティブ API
HTML、キャンバス、SVG
HTML、キャンバス、SVG
パフォーマンス
最速
高速
高速
デザイン
ネイティブ
エミュレート
エミュレート
配布
App Store
Web
App Store
カメラ
はい
ブラウザに依存
はい
通知
はい
いいえ
はい
10
Salesforce モバイル開発の概要
クイックスタート
ネイティブ
HTML5
ハイブリッド
連絡先、カレンダー
はい
いいえ
はい
オフラインストレージ
安全なファイルシス 安全ではない、共有 SQL、 安全なファイルシステム、
テム
キー - 値ストア
共有 SQL
地理位置情報
はい
はい
はい
スワイプ
はい
はい
はい
ピンチ、スプレッド
はい
はい
はい
接続
オンライン、オフラ ほぼオンライン
イン
オンライン、オフライン
開発手段
Objective C、Java
HTML5、CSS、JavaScript
HTML5、CSS、JavaScript
クイックスタート
詳細を後で確認したいという方のために、このガイドではネイティブ開発シナリオごとに「クイックスター
ト」トピックを用意しています。
• ハイブリッドアプリケーションのクイックスタート (ページ 140)
• iOS ネイティブクイックスタート (ページ 27)
• Android ネイティブクイックスタート (ページ 82)
11
第2章
トピック:
•
Developer Edition 環
境か Sandbox 環境
か
•
開発の前提条件
•
接続アプリケー
ションの作成
•
Mobile SDK のイン
ストール
•
Mobile SDK サンプ
ルアプリケーショ
ン
•
最新情報
Mobile SDK の使用開始
カスタムモバイルアプリケーションを作成してみましょう。まだ Force.com にサイン
アップして Mobile SDK 開発ツールをインストールしていない場合は、まずこのサイ
ンアップとインストールを実行します。
どの開発オプションを選択する場合でも、サインアップすることに加え、接続アプ
リケーションを定義する必要があります。ハイブリッドおよびネイティブアプリケー
ションの場合は、サポートする予定のプラットフォームごとに Mobile SDK npm パッ
ケージをインストールします。
12
Mobile SDK の使用開始
Developer Edition 環境か Sandbox 環境か
Developer Edition 環境か Sandbox 環境か
Salesforceでは、開発者向けにさまざまな環境を提供しています。最適な環境は、次のような多くの要因によっ
て開発者ごとに異なります。
• 作成しているアプリケーションのタイプ
• アプリケーションの利用者
• 会社のリソース
開発環境の使用目的は、アプリケーションの開発およびテストに限定されています。この環境には、ビジネス
に不可欠ではないテストデータが含まれます。開発は、ブラウザ内で行うことも、Eclipse 開発ツールに基づい
た Force.com IDE を使用して行うこともできます。開発環境には、Developer Edition と Sandbox の 2 種類がありま
す。
開発者環境の種別
Developer Edition (DE) 環境は、無料で利用できる全機能が搭載された Enterprise Edition 環境のコピーで、ストレージ
容量とユーザ数に制限があります。DE は論理的に独立した環境で、最初の開発環境として理想的です。必要
な数の DE 組織にサインアップできます。そのため、どの Salesforce 本番環境向けに設計されたアプリケーショ
ンでも作成できます。
Partner Developer Edition は、無料で利用できる DE のライセンスバージョンで、より多くのストレージ容量、機能、
ライセンスが含まれます。Partner Developer Edition は、登録済みの Salesforce パートナーに無料で提供されます。
Sandbox は本番環境とほぼ一致するコピーであり、Enterprise Edition または Unlimited Edition の顧客が使用できま
す。Sandbox コピーには、データ、設定、またはその両方を含めることができます。さまざまな目的のために、
本番環境のデータとアプリケーションに影響を与えることなく、複数の Sandbox を本番環境で作成できます。
環境の選択
このガイドでは、すべての練習で Developer Edition (DE) 組織を使用することを想定しています。ただし、実際に
は Sandbox 環境でも開発作業を行うことができます。次に、最適な環境の決定に役立つ情報を示します。
Developer Edition が最適な場合
• 商用 Force.com アプリケーションの構築を目的に、AppExchange や Trialforce で配布する管理パッケージを作成
するパートナーが利用する。
メモ: 管理パッケージを作成できるのは、Developer Edition 環境または Partner Developer Edition 環境のみで
す。
• Professional Edition、Group Edition、または Personal Edition を持ち、Sandbox へのアクセス権がない Salesforce.com カ
スタマーが利用する。
• Force.com プラットフォームを無料で検証しようとする開発者が利用する。
Partner Developer Edition が最適な場合
• すべてのソースコードを管理するマスタ環境を必要とする開発チームが利用する。この場合、開発者ごと
に Developer Edition 環境を設定し、このマスタリポジトリ環境との間でコードをチェックインおよびチェッ
クアウトできます。
13
Mobile SDK の使用開始
開発の前提条件
• 開発とテストのために 3 人以上の開発者がログインする可能性がある。
• 大量のデータセットに対して多くのユーザがロバストテストを実行できる大規模な環境を必要とする。
Sandbox が最適な場合
• Enterprise Edition、Unlimited Edition、または Sandbox を含む Force.com Edition を持つ Salesforce.com カスタマーが利
用する。
• 本番環境用の Force.com アプリケーションを開発している。
• 市販する Force.com アプリケーションを作成する予定がない。
• AppExchange に載せたり、Trialforce を使用して配布したりする意図がない。
開発の前提条件
ある程度の予備知識の習得やシステム設定を経験してから Mobile SDK アプリケーションの作成を始めることを
お勧めします。
Force.com に関するある程度の経験があると役立ちます。Force.com Developer Edition 組織が必要です。
Mobile SDKアプリケーションの設計やデバッグを行うには、OAuth、ログインおよびパスコードフロー、Salesforce
接続アプリケーションについて熟知している必要があります。「モバイルアプリケーションでの認証、セキュ
リティ、ID」を参照してください。
次の要件は、特定のプラットフォームおよびテクノロジに適用されます。
• iOS アプリケーション (ハイブリッドまたはネイティブ) の作成方法については、「ネイティブ iOS の要件」
を参照してください。
• Android アプリケーション (ハイブリッドまたはネイティブ) の作成方法については、「ネイティブ Android の
要件」を参照してください。
• リモートハイブリッドアプリケーションを作成するには、Visualforce を持つ組織が必要です。
Force.com のサインアップ
すべてのSalesforce開発者プログラムの豊富なチュートリアル、ブログ、およびサポートフォーラムにアクセス
するには、Force.com に参加します。
1. ブラウザで https://developer.salesforce.com/signup にアクセスします。
2. 各項目にユーザ情報と会社情報を入力します。
3. [Email Address (メールアドレス)] 項目には、Web ブラウザから簡単に確認できる公開アドレスを使用
してください。
4. 一意の [Username (ユーザ名)] を入力します。ユーザ名もメールアドレスの形式にする必要があります
が、メールアドレスと同じにする必要はなく、通常は違うものを入力することをお勧めします。ユーザ名
は developer.salesforce.com でのログイン情報および ID であるため、担当する作業を説明するユーザ
名 ([email protected]) や自分自身を表すユーザ名 ([email protected]) を選ぶことで、よ
り有益に使用できます。
5. [Master Subscription Agreement (マスターサブスクリプション契約)] を読み、チェックボックスを
オンにします。
14
Mobile SDK の使用開始
接続アプリケーションの作成
6. 表示された画像認証文字列を入力し、[Submit Registration (登録を実行)] をクリックします。
7. その後まもなく、ログインリンクを記載したメールが届きます。リンクをクリックし、パスワードを変更
します。
接続アプリケーションの作成
モバイルアプリケーションからSalesforceサービスに接続できるようにするには、接続アプリケーションを作成
する必要があります。接続アプリケーションには、このガイドのすべての開発シナリオの前提条件となるコン
シューマ鍵が含まれます。
接続アプリケーションを作成する
接続アプリケーションを作成するには、Salesforce アプリケーションを使用します。
1. Force.com インスタンスにログインします。
2. [設定] で、[作成] > [アプリケーション] に移動します。
3. [接続アプリケーション] で、[新規] をクリックします。
4. 「基本情報」の手順を実行します。
5. 「API (OAuth 設定の有効化)」の手順を実行します。
6. [保存] をクリックします。
転送通知をサポートする予定の場合、追加の接続アプリケーション設定については、転送通知と Mobile SDK
(ページ 267)を参照してください。現在必要な情報がない場合は、後でこれらの設定を追加できます。
メモ:
• OAuth 用に提供される [コールバック URL] は、有効な URL である必要はありません。必要なのは、ア
プリケーションでこの項目に期待する内容と一致していることだけです。「sfdc://」など、任意の
カスタムプレフィックスを使用できます。
• 接続アプリケーションの詳細ページに、コンシューマ鍵が表示されます。このキーは後で必要になる
ため、コピーしておくことをお勧めします。
• 新しい接続アプリケーションを作成したら、トークンが伝搬されるまで数分待ってから、アプリケー
ションを実行します。
基本情報
このセクションでは、アプリケーション名、ロゴ、連絡先情報など、アプリケーションに関する基本情報を指
定します。
1. [接続アプリケーション名] を入力します。この名前が接続アプリケーションのリストに表示されます。
メモ: 現在の接続アプリケーションの名前は、組織内で一意にする必要があります。接続アプリケー
ションが Spring '14 以降のリリースを使用して作成された場合は、削除済み接続アプリケーションの名
前を再使用できるようになりました。接続アプリケーションが Spring '14 より前のリリースを使用して
作成された場合は、削除済み接続アプリケーションの名前は再使用できません。
15
Mobile SDK の使用開始
接続アプリケーションを作成する
2. プログラムからアプリケーションを参照するときに使用する [API 参照名] を入力します。API 参照名は、
デフォルトの空白を除いた名前になります。使用できるのは、文字、数字、アンダースコアのみであるた
め、元のアプリケーション名に他の記号などが含まれている場合は、デフォルトの名前を編集する必要が
あります。
3. Salesforce からアプリケーション提供者またはそのサポートチームへの連絡に使用する [取引先責任者 メー
ル] を入力します。このアドレスは、アプリケーションをインストールするシステム管理者には提供され
ません。
4. Salesforce から連絡する必要がある場合に使用する [取引先責任者 電話] を入力します。この番号は、アプ
リケーションをインストールするシステム管理者には提供されません。
5. 接続アプリケーションのリストや、認証時にユーザに表示される同意ページにロゴを表示するには、[ロゴ
画像 URL] を入力します。URL には HTTPS を使用する必要があります。ロゴは、高さ 125 ピクセル以下、幅
200 ピクセル以下、ファイルサイズ 100 KB 以下の GIF、JPG、または PNG ファイル形式にする必要があります。
デフォルトは雲のロゴです。カスタムロゴを追加するには複数の方法があります。
• [ロゴ画像をアップロード] をクリックして、独自のロゴ画像をアップロードできます。ローカルファイ
ルシステムからロゴのサイズ要件を満たす画像を選択します。アップロードが成功すると、ロゴへの
URL が [ロゴ画像 URL] 項目に表示されます。表示されない場合は、ロゴのサイズ要件を満たしている
ことを確認します。
• [いずれかのサンプルロゴを選択] をクリックして、提供されているサンプルからロゴを選択することも
できます。Salesforceアプリケーション、サードパーティアプリケーション、標準化団体のロゴなどを使
用できます。目的のロゴをクリックし、表示される URL をコピーして [ロゴ画像 URL] 項目に貼り付け
ます。
• Salesforce サーバで公開されてホストされるロゴを使用できます。これを行うには、[ドキュメント] タブ
を使用して、ロゴファイル要件 (高さ 125 ピクセル以下、幅 200 ピクセル以下、ファイルサイズ 100 KB 以
下の GIF、JPG、または PNG ファイル形式) を満たす画像をドキュメントとしてアップロードします。次
に、画像を表示して URL を取得し、その URL を [ロゴ画像 URL] 項目に入力します。
6. ユーザがアプリケーションを初めて使用するときに表示される OAuth 承認ページにロゴを表示するには、
[アイコン URL] を入力します。ロゴは、16×16 ピクセル (高さ×幅) で、背景色は白にします。サンプルロゴ
はアイコンにも使用できます。
[いずれかのサンプルロゴを選択]をクリックして、提供されているサンプルからアイコンを選択できます。
目的のアイコンをクリックし、表示される URL をコピーして [アイコン URL] 項目に貼り付けます。
7. アプリケーションについての詳細が記載された Web ページがある場合、[情報 URL] を入力します。
8. 接続アプリケーションのリストに表示される [説明] を入力します。
Winter '14 より前では、[開始 URL] と [モバイル開始 URL] はこのセクションで定義されていました。現在、
これらの項目は、以下の [Web アプリケーション設定] および [モバイルアプリケーション設定] にあります。
API (OAuth 設定の有効化)
このセクションでは、アプリケーションがSalesforceと通信する方法を管理します。認証設定を定義するには、
[OAuth 設定の有効化] を選択します。
16
Mobile SDK の使用開始
接続アプリケーションを作成する
1. Salesforce が OAuth 時にアプリケーションにコールバックする [コールバック URL] (エンドポイント) を入力
します。これは、OAuth redirect_uri です。使用する OAuth フローに応じて、これは通常、認証が成功し
た後にユーザのブラウザがリダイレクトされる URL になります。この URL は一部の OAuth フローでアクセス
トークンを渡すために使用されるため、URL はセキュア HTTP (HTTPS) またはカスタム URI スキームを使用する
必要があります。複数のコールバック URL を入力すると、[コールバック URL] のいずれかの値を使用して
アプリケーションで指定されたコールバック URL の値が、Salesforce により実行時に照合されます。検証テ
ストに通過するには、いずれか 1 つの値と一致する必要があります。
2. JWT OAuth フローを使用している場合は、[デジタル署名を使用] を選択します。アプリケーションが証明書
を使用する場合は、[ファイルを選択] をクリックして、証明書のファイルを選択します。
3. サポートされているすべての OAuth 範囲を [選択した OAuth 範囲] に追加します。これらの範囲は、接続
アプリケーションを実行するユーザによって付与される権限を示し、その後に続く括弧内には OAuth トー
クン名が表示されます。
Chatter フィードへのアクセスと管理 (chatter_api)
Chatter REST API リソースへのアクセスのみを許可します。
データへのアクセスと管理 (api)
REST API や Bulk API などの API を使用したログインユーザの取引先へのアクセスを許可します。この値に
は、Chatter REST API リソースへのアクセスを許可する chatter_api も含まれます。
基本情報へのアクセス (id、profile、email、address、phone)
ID URL サービスへのアクセスを許可します。
カスタム権限へのアクセス (custom_permissions)
接続アプリケーションに関連付けられている組織のカスタム権限へのアクセスを許可し、現在のユーザ
で各権限が有効かどうかを示します。
一意の識別子へのアクセスを許可 (openid)
ログインユーザの OpenID Connect アプリケーションの一意の識別子へのアクセスを許可します。
フルアクセス (full)
ログインユーザがアクセスできるすべてのデータへのアクセスを許可し、その他すべての範囲が対象と
なります。full は更新トークンを返しません。更新トークンを取得するには、refresh_token の範
囲を明示的に要求する必要があります。
ユーザに代わっていつでも要求を実行 (refresh_token、offline_access)
更新トークンを受信できる場合に、それを返すように指定します。これにより、ユーザがオフラインの
ときにアプリケーションがユーザのデータを操作できます。refresh_token 範囲は、offline_access
と同じです。
カスタムアプリケーションへのアクセスの提供 (visualforce)
Visualforce ページへのアクセスを許可します。
Web 経由のデータへのアクセスを提供 (web)
Web で access_token を使用することを許可します。これには visualforce も含まれ、Visualforce ペー
ジへのアクセスが許可されます。
Spring '12 リリースより前に、組織でリモートアクセスに対して [この組織のユーザにはユーザ承認は必要ありま
せん] オプションが選択されていた場合、アプリケーションが作成された組織と同じ組織のユーザは、引き続
きアプリケーションで自動的に承認されます。参照のみの [この組織のユーザにはユーザ承認は必要ありませ
17
Mobile SDK の使用開始
Mobile SDK のインストール
ん] チェックボックスがオンで表示されている場合は、この状態であることを示します。接続アプリケーショ
ンの場合、アプリケーションを作成したら、システム管理者がアプリケーションをインストールし、[許可さ
れているユーザ] を [管理者が承認したユーザ] に設定することをお勧めします。当初リモートアクセスオプ
ションがオフだった場合、チェックボックスは表示されません。
関連トピック:
範囲パラメータの値
Mobile SDK のインストール
Salesforce Mobile SDK には、2 つのインストールパスがあります。
• (推奨) Node Packaged Module (npm) スクリプトを使用して、用意された開発設定に SDK をインストールできま
す。
• Mobile SDK オープンソースコードを GitHub からダウンロードし、独自の開発環境を設定できます。
Mobile SDK npm パッケージ
モバイル開発者のほとんどは、Mobile SDK を「ブラックボックス」として使用することで、できるだけ早くア
プリケーションの作成を開始することができます。そのため、Salesforce には、iOS 用の forceios と、Android 用の
forcedroid という 2 つの npm パッケージが用意されています。
Mobile SDK npm パッケージには、SDK リリースの静的スナップショットが含まれています。iOS の npm パッケー
ジでは、未コンパイルのソースコードではなくバイナリモジュールがインストールされます。Android の npm
パッケージでは、バイナリではなく SDK ソースコードのスナップショットがインストールされます。npm スク
リプトでは、Mobile SDK をインストールするだけでなく、新しいテンプレートプロジェクトも作成します。
Salesforce Mobile SDK 用の npm パッケージは、https://www.npmjs.org にあります。
メモ: npm パッケージではソース制御がサポートされないため、新しいリリース用にインストールを動的
に更新することはできません。代わりに、リリースごとに別個にインストールします。新しいバージョ
ンの SDK にアップグレードするには、npmjs.org の Web サイトにアクセスして、新しいパッケージをダウン
ロードしてください。
最初の作業: Node.js および npm をインストールする
Mobile SDK npm インストーラを使用するには、Node.js をインストールします。Node.js インストーラにより、npm
が自動的にインストールされます。
1. www.nodejs.org/download から Node.js をダウンロードします。
2. ダウンロードしたインストーラを実行して Node.js および npm をインストールします。インストールの許可
を求めるプロンプトをすべて承諾します。
3. コマンドプロンプトで「npm」と入力して Enter または Return キーを押し、インストールをテストしま
す。コマンドの使用状況情報のページが表示されない場合、ステップ 2 に戻り、何が欠落しているのかを
調べます。
18
Mobile SDK の使用開始
Mobile SDK npm パッケージ
これで、npm スクリプトをダウンロードして、Salesforce Mobile SDK for Android および iOS をインストールできる
ようになりました。
iOS のインストール
最も迅速で簡単に iOS 開発をはじめるには、forceios npm パッケージを使用して Salesforce Mobile SDK をインストー
ルしてください。
1. コマンドプロンプトで、forceios パッケージを使用して、Mobile SDK をグローバル (推奨) またはローカルでイ
ンストールします。
a. グローバルインストールの場合: sudo コマンドを使用して、「グローバル」オプション -g を追加しま
す。
sudo npm install forceios -g
-g オプションでは、npm install を任意のディレクトリから実行できます。npm ユーティリティによ
りパッケージが /usr/local/lib/node_modules にインストールされ、/usr/local/bin のバイナ
リモジュールにリンクされます。大部分のユーザは /usr/local の「参照・更新」権限がないため、
sudo オプションが必要になります。
b. ローカルインストールの場合: ディレクトリを目的のインストールフォルダに変更して、sudo や –g の
ない npm コマンドを使用します。
npm install forceios
このコマンドにより、現在のフォルダの下にある node_modules フォルダに Salesforce Mobile SDK がイン
ストールされます。バイナリモジュールは、./node_modules/.bin/ でリンクされます。このシナリ
オでは、すでに「参照・更新」権限のあるローカルフォルダにインストールすることが多いため、sudo
を使用することはほとんどありません。
Android のインストール
最も迅速で簡単にAndroid 開発をはじめるには、forcedroid npm パッケージを使用して Salesforce Mobile SDK をイン
ストールしてください。
1. forcedroid パッケージを使用して Mobile SDK をグローバル (推奨) またはローカルにインストールします。
a. グローバルインストールの場合:コマンドの最後に「グローバル」オプション -g を追加します。 Windows
以外の環境の場合、sudo コマンドを使用します。
sudo npm install forcedroid -g
Windows の場合:
npm install forcedroid -g
-g オプションを使用して、任意のディレクトリから npm install を実行します。Windows 以外の環境
の場合、npm ユーティリティにより、/usr/local/lib/node_modules にパッケージがインストール
され、/usr/local/bin でバイナリモジュールがリンクされます。大部分のユーザは /usr/local の
「参照・更新」権限がないため、sudo オプションが必要になります。 Windows 環境の場
19
Mobile SDK の使用開始
Mobile SDK npm パッケージ
合、%APPDATA%\npm\node_modules にグローバルパッケージがインストールされ、%APPDATA%\npm
でバイナリがリンクされます。
b. ローカルインストールの場合: ディレクトリを目的のインストールフォルダに変更して、sudo や –g オ
プションのない npm コマンドを使用します。
npm install forcedroid
このコマンドにより、Salesforce Mobile SDK が現在のディレクトリの下にある node_modules ディレクト
リにインストールされます。バイナリモジュールは、./node_modules/.bin/ でリンクされます。 こ
のシナリオでは、すでに「参照・更新」権限のあるローカルフォルダにインストールすることが多いた
め、sudo を使用することはほとんどありません。
Mobile SDK npm パッケージのアンインストール
npm パッケージをアンインストールする必要がある場合は、npm スクリプトを使用します。
forcedroid パッケージのアンインストール
forcedroid パッケージのアンインストール手順は、パッケージをグローバルにインストールしたか、ローカルに
インストールしたかによって異なります。
パッケージをグローバルにインストールした場合、任意のフォルダから uninstall コマンドを実行できま
す。–g オプションを必ず使用してください。Mac OS X などの Unix ベースのプラットフォームの場合は、sudo
を使用してください。
$ pwd
/Users/joeuser
$ sudo npm uninstall forcedroid -g
$
パッケージをローカルにインストールした場合、パッケージをインストールしたフォルダから uninstall コ
マンドを実行します。次に例を示します。
cd <my_projects/my_sdk_folder>
npm uninstall forcedroid
誤ったディレクトリからローカルインストールをアンインストールしようとすると、次のようなエラーメッ
セージが表示されます。
npm WARN uninstall not installed in /Users/joeuser/node_modules:
"my_projects/my_sdk_folder/node_modules/forcedroid"
forceios パッケージのアンインストール
forceios パッケージのアンインストール手順は、パッケージをグローバルまたはローカルのどちらでインストー
ルしたかによって異なります。パッケージをグローバルにインストールした場合、任意のフォルダから
uninstall コマンドを実行できます。sudo および –g オプションを必ず使用してください。
$ pwd
/Users/joeuser
20
Mobile SDK の使用開始
Mobile SDK GitHub リポジトリ
$ sudo npm uninstall forceios -g
$
ローカルでインストールしたパッケージをアンインストールするには、パッケージをインストールしたフォル
ダから uninstall コマンドを実行します。次に例を示します。
$ pwd
/Users/joeuser
cd <my_projects/my_sdk_folder>
npm uninstall forceios
誤ったディレクトリからローカルインストールをアンインストールしようとすると、次のようなエラーメッ
セージが表示されます。
npm WARN uninstall not installed in /Users/joeuser/node_modules:
"my_projects/my_sdk_folder/node_modules/forceios"
Mobile SDK GitHub リポジトリ
開発者は、GitHub からオープンソースリポジトリをコピーし、SDK を探求して、変更を最新に保ち、さらに SDK
開発に貢献するなどを積極的に行うことができます。GitHub を使用すれば、公開されたプレリリースの開発環
境でソースコードを監視できます。この場合、iOS と Android の両方のアプリケーションに、アプリケーション
と共に構築される SDK ソースコードが含まれます。
Mobile SDK にアクセスするために GitHub にサインアップする必要はありませんが、このソーシャルコーディン
グコミュニティに参加することをお勧めします。https://github.com/forcedotcom
最新の Mobile SDK リリースは、次の公開リポジトリからいつでも入手できます。
• https://github.com/forcedotcom/SalesforceMobileSDK-iOS
• https://github.com/forcedotcom/SalesforceMobileSDK-Android
iOS: Mobile SDK GitHub リポジトリのコピー (省略可能)
1. OS X ターミナルアプリケーションで git clone
git://github.com/forcedotcom/SalesforceMobileSDK-iOS.git コマンドを発行して、Mobile SDK
iOS リポジトリをローカルファイルシステムにコピーします。
メモ: Mac OS X 用の GitHub アプリケーションの場合は、[Clone in Mac (Mac でクローン)] をクリックしま
す。ブラウザで、Mobile SDK iOS GitHub リポジトリ
(https://github.com/forcedotcom/SalesforceMobileSDK-iOS) に移動します。
2. OS X ターミナルアプリケーションで、コピーしたリポジトリをインストールしたディレクトリにこれを変
更します。デフォルトでは、これは SalesforceMobileSDK-iOS ディレクトリです。
3. コマンドラインからインストールスクリプト ./install.sh を実行します。
Android: Mobile SDK GitHub リポジトリのコピー (省略可能)
1. ブラウザで、Mobile SDK Android GitHub リポジトリ https://github.com/forcedotcom/SalesforceMobileSDK-Android に移
動します。
21
Mobile SDK の使用開始
Mobile SDK サンプルアプリケーション
2. git clone git://github.com/forcedotcom/SalesforceMobileSDK-Android.git コマンドを使用
して、リポジトリをローカルファイルシステムにコピーします。
3. コピーしたリポジトリがインストールされたディレクトリでコマンドプロンプトを開き、コマンドライン
./install.sh からインストールスクリプトを実行します。
メモ: Windows ユーザの場合: cscript install.vbs を実行します。
コピーされた GitHub リポジトリを使用した Android プロジェクトの作成
コピーされた SalesforceMobileSDK-Android リポジトリを使用して Android のネイティブおよびハイブリッドプロ
ジェクトを作成するには、native/README.md および hybrid/README.md ファイルの手順に従います。
コピーされた GitHub リポジトリを使用した iOS プロジェクトの作成
コピーされた SalesforceMobileSDK-iOS リポジトリを使用してネイティブおよびハイブリッドプロジェクトを作成
するには、リポジトリのルートディレクトリにある build.md の手順に従います。
Mobile SDK サンプルアプリケーション
Salesforce Mobile SDK には、主要な機能を示す豊富なサンプルアプリケーションが含まれています。iOS および
Android 用のハイブリッドサンプルとネイティブサンプルは、独自のアプリケーションの基盤として使用した
り、参考のために検討したりできます。
サンプルアプリケーションのインストール
GitHub では、サンプルアプリケーションは対象プラットフォームの Mobile SDK リポジトリに存在します。この
リポジトリには直接アクセスできます。Android の場合は SalesforceMobileSDK-Shared リポジトリから共有ソース
コードをインポートできます。
GitHub プラットフォームリポジトリからサンプルアプリケーションへのアクセ
ス
Mobile SDK を GitHub から直接コピーすると、すべてのサンプルファイルが hybrid/SampleApps および
native/SampleApps ディレクトリに配置されます。次に、Cordova プロジェクト、SalesforceSDK プロジェ
クト、SmartStore プロジェクト、サンプルプロジェクトを Eclipse ワークスペースにインポートすると、Android
サンプルを作成できます。
Android の場合:リポジトリのコピー後に、リポジトリルートフォルダにある Windows の cscript install.vbs
または Mac の ./install.sh を必ず実行してください。これらのスクリプトによって、サンプルが
native/SampleApps フォルダおよび hybrid/SampleApps フォルダに配置されます。
iOS の場合: リポジトリのコピー後に、リポジトリルートフォルダにある ./install.sh を必ず実行してくだ
さい。Xcode で SalesforceMobileSDK-iOS/SalesforceMobileSDK.xcworkspace ファイルを開き、Native
SDK および Hybrid SDK プロジェクトフォルダのサンプルアプリケーションを検索します。
22
Mobile SDK の使用開始
サンプルアプリケーションのインストール
Cordova でのハイブリッドサンプルアプリケーションの作成
ハイブリッドサンプルアプリケーションを作成するには、Cordova コマンドラインと SalesforceMobileSDK-Shared
リポジトリのソースファイルを使用します。手順は、「ハイブリッドサンプルアプリケーションを作成する
(ページ 147)」を参照してください。
Android サンプルアプリケーション
ネイティブ
RestExplorer: SalesforceSDK の OAuth および REST API 機能を示します。また、REST API アクションをタブレットから
調べる場合にも便利です。
NativeSqlAggregator: SQL と SmartSQL の統合を示します。また、そのようなアプリケーションとして SmartStore の
ネイティブ実装の方法も示します。
FileExplorer: Files API および基盤となる Google Volley のネットワーキングの機能強化を示します。
ハイブリッド
• AccountEditor: SmartSync Data Framework を使用して Salesforce データにアクセスする方法について説明します。
• ContactExplorer: ContactExplorer サンプルアプリケーションでは、PhoneGap (Cordova とも呼ばれる) を使
用して、ローカルデバイスの取引先責任者を取得します。また、forcetk.mobilesdk.js ツールキット
を使用して、Salesforce REST API で REST トランザクションを実装します。アプリケーションでは、Salesforce SDK
の OAuth2 サポートを使用して OAuth ログイン情報を取得し、JavasScript イベントを送信することによって、
そのログイン情報を forcetk.mobilesdk.js に伝搬します。
• HybridFileExplorer: Files API を示します。
• SmartStoreExplorer: SmartStore API を探索できます。
• SimpleSync:: SmartSync プラグインの使用方法を示します。
• VFConnector: ネイティブコンテナ内の Visualforce ページのラップ方法を示す VFConnector サンプルアプリケー
ションです。この例では、BasicVFTest というVisualforceページが組織に存在することを想定しています。
アプリケーションではまず、Salesforce SDK OAuth2 サポートを使用して OAuth のログイン情報を取得し、その
ログイン情報を使用して、Visualforce ページにアクセスするための適切な Web ビュー Cookie を設定します。
iOS サンプルアプリケーション
ネイティブ
• RestAPIExplorer では、ネイティブのすべての REST API ラッパーが実行されます。これは、
native/SampleApps/RestAPIExplorer の Mobile SDK for iOS にあります。
• NativeSqlAggregator には、SQL の集約例と、ネイティブ SmartStore の実装が表示されます。このサンプルア
プリケーションは、native/SampleApps/NativeSqlAggregator の SDK for iOS にあります。
• FileExplorer には、Files API と、その基盤となる MKNetwork ネットワーク機能強化が示されます このサンプル
アプリケーションは、native/SampleApps/FileExplorer の SDK for iOS にあります。
23
Mobile SDK の使用開始
最新情報
• SmartSyncExplorerには、 iOS 上でのネイティブ SmartSync ライブラリの機能が示されます。このサンプルアプ
リケーションは、native/SampleApps/SmartSyncExplorer の Mobile SDK for iOS にあります。
ハイブリッド
• AccountEditor: SmartSync Data Framework を使用して Salesforce データにアクセスする方法について説明します。
• ContactExplorer: ContactExplorer サンプルアプリケーションでは、PhoneGap (Cordova とも呼ばれる) を使
用して、ローカルデバイスの取引先責任者を取得します。また、forcetk.mobilesdk.js ツールキット
を使用して、Salesforce REST API で REST トランザクションを実装します。アプリケーションでは、Salesforce SDK
の OAuth2 サポートを使用して OAuth ログイン情報を取得し、JavaScript イベントを送信することによって、
そのログイン情報を forcetk.mobilesdk.js に伝搬します。
• HybridFileExplorer: Files API を示します。
• SmartStoreExplorer: SmartStore API を探索できます。
• VFConnector: ネイティブコンテナ内の Visualforce ページのラップ方法を示す VFConnector サンプルアプリケー
ションです。この例では、BasicVFTest というVisualforceページが組織に存在することを想定しています。
アプリケーションではまず、Salesforce SDK OAuth2 サポートを使用して OAuth のログイン情報を取得し、その
ログイン情報を使用して、Visualforce ページにアクセスするための適切な Web ビュー Cookie を設定します。
最新情報
Dreamforce '13 で発表された Salesforce 開発者ツールは、2014 年の間も顕著な進化を遂げています。Salesforce Mobile
SDK の機能および設定により、あらゆるレベルのモバイル開発者の Salesforce モバイル開発の限界が押し上げら
れています。
Salesforce Mobile SDK の最新バージョンでは、ログインおよび特にハイブリッドアプリケーションの柔軟性が向
上しています。主な特長は次のとおりです。
• iOS および Android ネイティブアプリケーションの SmartSync (Mobile SDK 3.0 で導入)。
• iOS ネイティブアプリケーションのフロー管理の開始 (Mobile SDK 3.0 で導入)。
• 独立した Cordova プラグインを介してハイブリッドアプリケーションの Salesforce 固有の機能にアクセスし、
Cordova コマンドラインからハイブリッドアプリケーションを作成する機能。開発者は、Mobile SDKのリリー
スとは関係なく、Cordova の最新バージョンで Salesforce OAuth2 ID、SmartStore のセキュアなオフラインデータ
ベース、転送プラグインをいつでも使用できます (Mobile SDK 2.3 で導入)。
• ハイブリッドリモートアプリケーションについては、HTML、JavaScript、CSS の各リソースをローカルでホス
ト。リモートの Visualforce サーバではランディングページのみをホストし、アプリケーションの残りの部分
はモバイルデバイスに格納できます (Mobile SDK 2.3 で導入)。
• ネイティブアプリケーションの転送通知のサポート (Mobile SDK 2.1 で導入)。
• ハイブリッドアプリケーションの転送通知のサポート (Mobile SDK 2.3 で導入)。
• スープの再インデックス付けおよび情報の収集を行う新しい SmartStore API (Mobile SDK 2.3 で導入)。
• マルチユーザのサポートにより、ユーザが複数のアカウントに同時にログイン可能 (Mobile SDK 2.2 以降に導
入)。
• 柔軟な認証。アプリケーションのライフサイクル上の任意の論理的な時点まで Salesforce のログインを延期
できます (Mobile SDK 2.2 で導入)。
24
Mobile SDK の使用開始
最新情報
Mobile SDK の最新リリースの新機能一覧は、https://developer.salesforce.com/page/Mobile_SDK_Release_Notes でいつで
も確認できます。
25
第3章
トピック:
ネイティブ iOS の開発
Salesforce Mobile SDK では、iOS でモバイルアプリケーションを開発するためのライブ
ラリとサンプル Xcode プロジェクトが提供されます。
•
iOS ネイティブク
イックスタート
•
ネイティブ iOS の要
件
• OAuth2 ログインプロセスの自動化。これにより、OAuth をアプリケーションに統
合しやすくなります。
•
iOS プロジェクトの
作成
•
CocoaPods と
Mobile SDK の使用
• REST API へのアクセス。アクセスをできるかぎり簡略化するすべてのインフラス
トラクチャクラス (MKNetworkKit ライブラリなどのサードパーティのライブラリを
含む) が使用されます。
•
ネイティブ iOS アプ
リケーションの開
発
•
チュートリアル: ネ
イティブ iOS
Warehouse アプリ
ケーションの作成
•
iOS ネイティブサン
プルアプリケー
ション
iOS ネイティブ SDK では、次の 2 つの重要な機能が提供されます。
forceios アプリケーションを使用してネイティブアプリケーションを作成すると、完
全に機能するネイティブサンプルアプリケーションとしてプロジェクトが開始しま
す。この単純なアプリケーションでは、Salesforce 組織に接続し、簡単なクエリを実
行できます。多くの操作はできませんが、設計どおりに動作することを確認できま
す。
26
ネイティブ iOS の開発
iOS ネイティブクイックスタート
iOS ネイティブクイックスタート
すばやく開始する手順は、次のとおりです。
1. ネイティブ iOS 要件をすべて満たしていることを確認します。
2. Mobile SDK for iOS をインストールします。必要に応じて、代わりに GitHub から Mobile SDK for iOS をインストー
ルすることもできます。
3. テンプレートアプリケーションを実行します。
ネイティブ iOS の要件
Mobile SDK 3.1 を使用した iOS の開発には、次のソフトウェアが必要です。
• Xcode — バージョン 6.0 以降 (最新バージョンを推奨)。
• iOS 7.0 以降。
Salesforce 側には、以下も必要です。
• Salesforce Mobile SDK 3.1 for iOS。「iOS のインストール」を参照してください。
• 接続アプリケーションが存在する Salesforce Developer Edition 組織。
iOS プロジェクトの作成
新しいアプリケーションを作成するには、コマンドラインで forceios を再度使用します。アプリケーションを
設定する方法は 2 つあります。
• forceios アプリケーションからプロンプトが表示されたときに、アプリケーションオプションを対話形式で
設定する。
• 直接コマンドラインでアプリケーションオプションを指定する。
対話形式でのアプリケーションオプションの指定
対話形式でアプリケーションオプションを入力するには、次のいずれかを実行します。
• Mobile SDK をグローバルにインストールした場合は、「forceios create」と入力する。
• Mobile SDK をローカルにインストールした場合は、「<forceios_path>/node_modules/.bin/forceios
create」と入力する。
設定値ごとに、forceios ユーティリティによってプロンプトが表示されます。
27
ネイティブ iOS の開発
Xcode プロジェクトのテンプレートアプリケーションを
実行する
アプリケーションオプションの直接指定
必要に応じて、コマンドラインから直接 forceios パラメータを指定できます。使用方法に関する情報を表示す
るには、引数を指定せずに「forceios」と入力します。使用可能なオプションのリストが表示されます。
$ forceios
Usage:
forceios create
--apptype=<Application Type> (native, hybrid_remote, hybrid_local)
--appname=<Application Name>
--companyid=<Company Identifier> (com.myCompany.myApp)
--organization=<Organization Name> (Your company's name)
--startpage=<App Start Page> (The start page of your remote app.
Only required for hybrid_remote)
[--outputdir=<Output directory> (Defaults to current working
directory)]
[--appid=<Salesforce App Identifier> (The Consumer Key for your
app. Defaults to the sample app.)]
[--callbackuri=<Salesforce App Callback URL (The Callback URL
for your app. Defaults to the sample app.)]
この情報を使用して、「forceios create」の後にオプションと値を続けて入力します。次に例を示します。
$ forceios create --apptype="native" --appname="package-test"
--companyid="com.acme.mobile_apps" --organization="Acme Widgets, Inc."
--outputdir="PackageTest" --packagename="com.test.my_new_app"
XCode で新規プロジェクトを開く
forceios テンプレートを使用して作成されたアプリケーションは、「標準で」実行準備が整っています。アプリ
ケーションの作成スクリプトが完了したら、プロジェクトを Xcode で開いて実行できます。
1. Xcode で [File (ファイル)] > [Open (開く)] を選択します。
2. 指定した出力フォルダに移動します。
3. アプリケーションの xcodeproj ファイルを開きます。
Xcode プロジェクトのテンプレートアプリケーションを実行する
Xcode プロジェクトのテンプレートには、すぐに実行できるサンプルアプリケーションが含まれています。
1. [Command-R] キーを押すと、デフォルトのテンプレートアプリケーションが iOS シミュレータで実行されま
す。
2. アプリケーションは、起動時に OAuth 認証フローで開始し、認証ページが表示されます。ログイン情報を
入力し、[Login (ログイン)] をクリックします。
3. 許可を求められたら、[許可] をタップします。
28
ネイティブ iOS の開発
CocoaPods と Mobile SDK の使用
これで、サンプルプロジェクトをコンパイルし、実行できるようになりました。これは、OAuth2 を介して組織
にログインし、select Name from Account SOQL クエリを発行し、結果を UITableView インスタンスに
表示する簡単なアプリケーションです。
CocoaPods と Mobile SDK の使用
既存の iOS アプリケーションに Mobile SDK を追加するには、CocoaPods を使用できます。
CocoaPodsには、外部コードパッケージまたはモジュールを既存の Xcode プロジェクトにマージするための便利
なメカニズムが備えられています。CocoaPodsの知識や使用経験がない方は、www.cocoapods.orgにあるドキュメ
ントをまずお読みください。
Mobile SDK は、forcedotcom/SalesforceMobileSDK-iOS GitHub リポジトリに
SalesforceMobileSDK-iOS.podspec を提供しています。この podspec は、Salesforce Mobile SDK for iOS のすべ
てのモジュールをインストールする SalesforceMobileSDK-iOS というマスタ仕様を定義します。また、
個々の SDK モジュール用にサブ仕様も定義します。Mobile SDK 3.0 には、次のサブ仕様が含まれています。
• SalesforceCommonUtils
• MKNetworkKit
• SalesforceSecurity
• SalesforceOAuth
• SalesforceSDKCore
• SalesforeNetworkSDK
• SalesforceRestAPI
• SmartSync
Podfile を使用してマスタ仕様ではなくいずれかのサブ仕様をマージすると、CocoaPodsにより連動モジュールも
すべてマージされます。
CocoaPods を通じて Mobile SDK を使用する手順は、次のとおりです。
1. www.cocoapods.org の説明に従って cocoapods Ruby gem がインストールされていることを確認します。
2. プロジェクトの Podfile で、アプリケーションにマージする Mobile SDK podspec を参照します。たとえば、す
べてのモジュールをアプリケーションに追加する場合は、次の宣言を Podfile に追加します。
pod 'SalesforceMobileSDK-iOS'
3. ターミナルウィンドウで、プロジェクトディレクトリから pod install を実行します。CocoaPodsにより、
要求された pod の連動関係のダウンロード、プロジェクトへのマージ、新しくマージされたプロジェクト
を含むワークスペースの作成が行われます。
重要: CocoaPodsの実行後、プロジェクトへのアクセスは、常に pod install で作成された新しいワー
クスペースから行います。たとえば、MyProject.xcodeproj を開く代わりに、
MyProject.xcworkspace を開きます。
4. マージされたアプリケーションでMobile SDK API を使用する場合は、次の重要なヒントを考慮してください。
29
ネイティブ iOS の開発
ネイティブ iOS アプリケーションの開発
a. 二重引用符ではなく山かっこ (「<」および「>」) を使用して、ヘッダーファイルをインポートします。
次に例を示します。
#import <SFRestAPI.h>
b. AppDelegate クラスで SalesforceSDKManager ワークフローを実装します。このタスクを最も容易
に行うには、任意の Mobile SDK ネイティブサンプルアプリケーションの AppDelegate クラスからブー
トストラップロジックをコピーします。
c. ネットワークにアクセスする Mobile SDK API をコールする前に、アプリケーションの論理ポイントに認証
を追加します。
完全に実装された例については、Mobile SDK ネイティブサンプルアプリケーションを参照してください。
ネイティブ iOS アプリケーションの開発
ネイティブ iOS の Salesforce Mobile SDK には、Apple モバイルデバイスのアプリケーションを構築するために必要
なツールが備えられています。SDK には、次の特性があります。
• Salesforce REST API コールを簡単にするクラスとインターフェース
• 完全に実装された OAuth ログインとパスコードのプロトコル
• ユーザデータをオフラインで安全に管理するための SmartStore ライブラリ
ネイティブ iOS SDK では、Objective-C コーディングに精通している必要があります。また、iOS アプリケーショ
ンの開発原則とフレームワークに関する知識も必要です。初めて使用する場合は、「Start Developing iOS Apps
Today」を使用して学習を開始することをお勧めします。他の前提条件は、「ネイティブ iOS の要件」を参照し
てください。
一部のMobile SDKインターフェースでは、いくつかのメソッドとプロパティを上書きする必要があります。SDK
ヘッダー (.h) ファイルには、必須の上書きと省略可能な上書きを示すコメントが含まれています。
ログインとパスコードについて
Mobile SDK アプリケーションから Salesforce オブジェクトにアクセスするには、ユーザが Salesforce サーバで組織
にログインする必要があります。ログインフローが開始すると、アプリケーションの接続アプリケーション設
定が Salesforce に送信されます。Salesforce は、ログイン画面をモバイルデバイスに投稿して応答します。
必要に応じて、Salesforce システム管理者は、ログイン後にパスコードを必要とするように接続アプリケーショ
ンを設定することができます。Mobile SDKでは、ログイン画面とパスコード画面の表示、および認証ハンドシェ
イクの処理が行われます。これらの画面を表示するために、アプリケーションで何らかの操作をする必要はあ
りません。ただし、ログインフローおよび OAuth トークンの処理方法を理解しておく必要はあります。「PIN
セキュリティについて」および「OAuth2 認証フロー」を参照してください。
メモリ管理について
Mobile SDK 2.0 以降では、ネイティブ iOS アプリケーションで Automatic Reference Counting (ARC) を使用して、オブ
ジェクトメモリが管理されます。オブジェクトを割り当てたあとに、割り当て解除することを覚えておく必要
30
ネイティブ iOS の開発
アプリケーションフローの概要
はありません。ARC の構文、ガイドライン、ベストプラクティスについては、「Mac Developer Library」 の「Mac
Developer Library」を参照してください。
アプリケーションフローの概要
forceios アプリケーションを使用してプロジェクトを作成すると、新しいアプリケーションで AppDelegate、
InitialViewController、および RootViewController という 3 つのクラスが定義されます。AppDelegate
オブジェクトでは、最初に表示するビューとして InitialViewController が読み込まれます。認証プロセ
スが完了すると、AppDelegate オブジェクトにより、RootViewController に関連付けられたビューがア
プリケーションのエントリポイントとして表示されます。
Mobile SDK を使用して構築されたネイティブ iOS アプリケーションは、他の iOS アプリケーションと同じ設計に
なります。main.m のソースファイルでは、アプリケーションの残りの部分のルートオブジェクトとなる
UIApplicationMain オブジェクトが作成されます。UIApplicationMain コンストラクタでは、アプリケー
ションのライフサイクルを管理する AppDelegate オブジェクトが作成されます。
AppDelegate では、アプリケーションの起動フローを整理するため、Mobile SDK サービスオブジェクト
(SalesforceSDKManager) が使用されます。このサービスにより、Salesforce 認証およびパスコードの活動が調
整されます。ユーザが認証されると、AppDelegate から RootViewController オブジェクトに制御が移り
ます。
メモ: テンプレートアプリケーションで示すワークフローは一例にすぎません。AppDelegate およびサ
ポートクラスをカスタマイズして、目的のワークフローにすることができます。たとえば、Salesforce認証
を後の時点まで延期することができます。REST API コールを使用したデータの取得、データの表示、他の
ビューの起動、サービスの実行などを行うことができます。アプリケーションは、ユーザがアプリケー
ションを明示的に終了するか、デバイスが再起動されるまでメモリ内でアクティブのままになります。
関連トピック:
SalesforceSDKManager クラス
31
ネイティブ iOS の開発
SalesforceSDKManager クラス
SalesforceSDKManager クラス
SalesforceSDKManager クラスは、アプリケーション ID とブートストラップ設定を 1 つのコンポーネントに
統合します。アプリケーション開発者によって提供された設定を使用して、認証とパスコード間の複雑なやり
とりを管理します。つまり、SalesforceSDKManager によって、開発者がブートストラッププロセスを制御
する必要がなくなります。
Mobile SDK テンプレートアプリケーションは、SalesforceSDKManager クラスを使用して開発者に代わって
ほとんどの Salesforce 固有の起動時の機能を実装します。SalesforceSDKManager は、PIN コード、OAuth 設
定、その他のブートストラッププロセスを含む、アプリケーションに起動に関与するすべてのオブジェクトを
管理および調整します。SalesforceSDKManager を使用することで、これらのプロセス間の複雑なやりとり
が適切な順序で行われることが保証され、起動フローの個々の部分はこれまで通り自由にカスタマイズできま
す。Mobile SDK 3.0 以降では、すべての iOS ネイティブアプリケーションで SalesforceSDKManager を使用し
てアプリケーション起動時の動作を管理する必要があります。
メモ: Mobile SDK 3.0 の新しい SalesforceSDKManager クラスは、既存の認証管理オブジェクトまたはイ
ベントに代わるものではありません。むしろ、既存の起動管理オブジェクトのスーパーマネージャと言
えます。既存のコードは、以前のリリースと同様に機能し続けます。
ライフサイクル
SalesforceSDKManager はシングルトンオブジェクトです。このオブジェクトにアクセスするには、
sharedManager クラスメッセージを送信します:
[SalesforceSDKManager sharedManager]
この共有オブジェクトは、アプリケーションが [SalesforceSDKManager sharedManager] を初めてコー
ルしたときに一度だけ作成されます。他の 3 つのMobile SDKマネージャオブジェクトの代理として機能します。
• SFUserAccountManager
• SFAuthenticationManager
• SFPasscodeManager
アプリケーションは次の 2 つのシナリオで SalesforceSDKManager オブジェクトを使用します。
1. アプリケーション起動時に、AppDelegate の init および
application:didFinishLaunchingWithOptions: メソッドで使用
2. アプリケーションの実行中に、ログアウト、トークンの期限切れ、またはトークンの取り消しが原因で現
在のユーザの OAuth トークンが無効になるたびに使用
1 番目のシナリオのイベントは、アプリケーションのライフサイクルで 1 回のみ発生します。2 番目のシナリ
オは何度でも発生する可能性があります。Mobile SDK は現在のユーザのトークンが無効であることを検出する
と、SalesforceSDKManager アプリケーション起動フローを再実行します。このフローには、アプリケー
ションで提供されるすべての関連イベントハンドラも含まれます。アプリケーションが再初期化されるときに
望ましくないデータ損失や状態が発生することを避けるため、これらのイベントハンドラは慎重にコード化し
てください。
32
ネイティブ iOS の開発
SalesforceSDKManager クラス
アプリケーション起動フロー
application:didFinishLaunchingWithOptions: メッセージを受信したら、launch メッセージを共有
SalesforceSDKManager インスタンスに送信してアプリケーションを起動します。アプリケーションの接続
アプリケーションによってパスコードが要求される場合は、ブートストラッププロセスを続行する前に、
SalesforceSDKManager によってユーザへのパスコード確認画面が表示されます。次のダイアグラムに、こ
のフローを示します。
このダイアグラムに示されている重要なポイントは次のとおりです。
• 接続アプリケーション定義の OAuth 設定でパスコードが要求されない場合、フローは直接 Salesforce 認証に
進みます。
• 有効なアクセストークンが検出された場合、フローは Salesforce 認証をスキップします。
33
ネイティブ iOS の開発
SalesforceSDKManager クラス
• アクセストークンが検出されず、デバイスがオフラインの場合、認証モジュールによりエラーが発生し、
ログイン画面に戻ります。SalesforceSDKManager によってこのイベントがアプリケーションに反映さ
れることはありません。
• postLaunch イベントは、すべてのログイン情報とパスコードチャレンジが確認された後にのみ発生しま
す。
このダイアグラムに表示されている内容の他に、アプリケーションでユーザの切り替えと転送通知設定がサ
ポートされている場合、SalesforceSDKManager 起動プロセスはそれらの機能もアプリケーションに委任し
ます。ユーザがパスコードチャレンジか、Salesforce ログインを失敗またはキャンセルした場合、postLogout
イベントが起動されてから、制御が AppDelegate に戻されます。
postLaunch イベント後、ユーザがログアウトするかユーザの切り替えイベントが発生するまで、
SalesforceSDKManager オブジェクトは再表示されません。このいずれかのイベントが発生すると、
SalesforceSDKManager からアプリケーションに通知されます。その時点で、アプリケーションのMobile SDK
の状態をリセットしてアプリケーションを再起動できます。
SalesforceSDKManager 起動イベント
SalesforceSDKManager は、アプリケーションとデバイスの状態に応じてアプリケーションのブートスト
ラッププロセスを指示します。ブートストラッププロセス中、起動シーケンスの重要な時点でいくつかのイベ
ントが起動されます。これらのイベントを使用して、SalesforceSDKManager フローの完了後に独自のロ
ジックを実行できます。フォアグラウンドの場合、アプリケーションのロジックを再開する前に、アプリケー
ションが postAppForeground イベントを受信するまで待機してください。
表 2 : 起動イベント
イベント
説明
postLaunch
すべての起動アクティビティの完了後に受信します。
アプリケーションはビジネスプロセスを続行できま
す。
launchError
起動プロセス中に致命的なエラーが発生した場合に送
信されます。
postLogout
現在のユーザがログアウトした後、またはユーザがパ
スコードテストやログイン認証に失敗した場合に受信
します。
postAppForeground
アプリケーションがフォアグラウンドに戻り、パス
コード (該当する場合) が確認された後に受信します。
このイベントは、認証が有効であることを示します。
アプリケーションがこのイベントを受信したら、フォ
アグラウンドで処理する追加アクションを実行できま
す。
switchUser
現在のユーザが変更された後に受信します。
34
ネイティブ iOS の開発
SalesforceSDKManager クラス
特定のイベントは他のイベントよりも優先されます。たとえば、起動中にパスコードの確認に失敗した場合、
postLogout イベントが起動されますが、postLaunch イベントは起動されません。優先度レベル間で、ラン
クの高いイベントがランクの低いイベントの代わりに起動されます。優先度の一覧を次に示します。1 が最も
高い優先度レベルです。
表 3 : 起動イベントの優先度レベル
優先度レベル
イベント
コメント
1
postLogout、switchUser
これらのイベントは他のすべての
イベントよりも優先されます。
2
postLaunch、launchError
これらのイベントは常に
postAppForeground よりも優先
されます。たとえば、アプリケー
ションをバックグラウンドに送信
してからログイン中にフォアグラ
ウンドに戻した場合、ログインに
成功すると postLaunch が起動さ
れますが、postAppForeground
は起動されません。
3
postAppForeground
ランクが最も低いこのイベントは、
その他すべてのイベントに取って
代わられる可能性があります。
SalesforceSDKManager プロパティ
アプリケーションの起動時の動作を設定するには、AppDelegate の init メソッドで SalesforceSDKManager
プロパティを設定します。これらのプロパティには、アプリケーションの次のような起動設定が含まれていま
す。
• 接続アプリケーション識別子
• 必要な OAuth 範囲
• 認証動作および関連付けられたカスタマイズ
少なくとも接続アプリケーションと OAuth 範囲設定を指定する必要があります。
SalesforceSDKManager プロパティは、起動イベントのハンドラブロックの定義にも使用します。イベント
ハンドラのプロパティは省略可能です。このプロパティを定義しない場合、イベントの発生時にアプリケー
ションのログに実行時警告が記録されます。通常は、アプリケーションフローを詳細に制御できるようにする
ため、これらのブロックを実装することをお勧めします。
もう 1 つの特に便利なプロパティは、省略可能な authenticateAtLaunch です。アプリケーションの実行が
開始されてから特定の時点まで Salesforce 認証を延期する必要がある場合、このプロパティを NO に設定しま
す。authenticate メッセージを SalesforceSDKManager に送信することで、認証プロセスを任意の時点
で実行できます。ただし、この場合も常に AppDelegate の init メソッドで起動プロパティを設定し、
application:didFinishLaunchingWithOptions: メソッドで launch メッセージを
SalesforceSDKManager に送信する必要があります。
35
ネイティブ iOS の開発
SalesforceSDKManager クラス
次の表は、SalesforceSDKManager プロパティについて説明したものです。
表 4 : SalesforceSDKManager プロパティ
プロパティ
説明
connectedAppId
(必須) 関連付けられた Salesforce 接続アプリケーション
のコンシューマ ID。
connectedAppCallbackUri
(必須) 関連付けられた Salesforce 接続アプリケーション
のコールバック URI。
authScopes
(必須) アプリケーションに必要な OAuth 範囲。
postLaunchAction
(必須) 起動の完了後アプリケーションが機能を再開す
る方法を制御します。
authenticateAtLaunch
(省略可能) SalesforceSDKManager が起動時に認証
を試行するかどうかを示します。デフォルトは YES で
す。認証をアプリケーションの別のフェーズに延期す
る場合はこの値を NO に設定し、authenticate メッ
セージを SalesforceSDKManager に送信して適切な
時点で認証を開始します。
launchErrorAction
(省略可能) 定義した場合、このブロックは起動プロセ
ス中に発生したすべてのエラーに応答します。
postLogoutAction
(省略可能) 定義した場合、このブロックは現在のユー
ザがログアウトしたときに実行されます。
switchUserAction
(省略可能) 定義した場合、このブロックは現在のユー
ザから既存のユーザまたは新規ユーザへの切り替えを
処理します。
メモ: アプリケーションがユーザの切り替えを
サポートしている場合、このプロパティは必須
です。
postAppForegroundAction
(省略可能) 定義した場合、このブロックは Mobile SDK
がフォアグラウンド後のタスクを完了した後に実行さ
れます。
useSnapshotView
(省略可能) アプリケーションがバックグラウンドで実
行されているときにスナップショットビューを使用す
る場合は、YESに設定します。このビューにより、ユー
ザがホーム画面からバックグラウンドアプリケーショ
ンを参照したときに表示されるアプリケーションのプ
レビュー画面で、機密コンテンツが覆い隠されます。
デフォルトは YES です。
36
ネイティブ iOS の開発
AppDelegate クラス
プロパティ
説明
snapshotView
(省略可能) アプリケーションがバックグラウンドで実
行されているときに、ホーム画面から参照されるアプ
リケーションの機密コンテンツを覆い隠すビューを指
定します。デフォルトのビューは、白の不透明な画面
です。
preferredPasscodeProvider
(省略可能) 異なるパスコードプロバイダを設定し、異
なるパスコード暗号化スキームを使用できます。デ
フォルトは Mobile SDK PBKDF2 プロバイダです。
AppDelegate クラス
AppDelegate クラスは、iOS アプリケーションの実際のエントリポイントです。Mobile SDK アプリケーション
では、AppDelegate によって標準の iOS UIApplicationDelegate インターフェースが実装されます。この
クラスは、共有 SalesforceSDKManager オブジェクトを使用して Mobile SDK を初期化し、アプリケーション
の起動フローを監視します。
OAuth 機能は、独立したモジュールに保存されています。この分離によって、Salesforce 認証のオンデマンドで
の使用が可能になります。ログインプロセスは、AppDelegate の実装内から開始することも、実際に必要に
なるまで (サブビューから OAuth をコールするなど) 延期することもできます。
設定
AppDelegate テンプレートをカスタマイズするには、まず次の静的変数を Force.com 接続アプリケーションの
値に再設定します。
• RemoteAccessConsumerKey
static NSString * const RemoteAccessConsumerKey =
@"3MVG9Iu66FKeHhINkB1l7xt7kR8...YFDUpqRWcoQ2.dBv_a1Dyu5xa";
この変数は、接続アプリケーションのコンシューマ鍵に対応します。
• OAuthRedirectURI
static NSString * const OAuthRedirectURI = @"testsfdc:///mobilesdk/detect/oauth/done";
この変数は、接続アプリケーションのコールバック URL に対応します。
初期化
次に、テンプレートアプリケーションで実装される init メソッドを示します。この後に、
application:didFinishLaunchingWithOptions: メソッドで SalesforceSDKManager の launch メソッ
ドへのコールが続きます。
- (id)init
{
self = [super init];
37
ネイティブ iOS の開発
AppDelegate クラス
if (self) {
[SalesforceSDKManager sharedManager].connectedAppId = RemoteAccessConsumerKey;
[SalesforceSDKManager sharedManager].connectedAppCallbackUri =
OAuthRedirectURI;
[SalesforceSDKManager sharedManager].authScopes = @[ @”web”, @”api” ];
__weak AppDelegate *weakSelf = self;
[SalesforceSDKManager sharedManager].postLaunchAction =
^(SFSDKLaunchAction launchActionList) {
[weakSelf log:SFLogLevelInfo
format:@"Post-launch: launch actions taken: %@",
[SalesforceSDKManager
launchActionsStringRepresentation:launchActionList]];
[weakSelf setupRootViewController];
};
[SalesforceSDKManager sharedManager].launchErrorAction =
^(NSError *error, SFSDKLaunchAction launchActionList) {
[weakSelf log:SFLogLevelError
format:@"Error during SDK launch: %@", [error localizedDescription]];
[weakSelf initializeAppViewState];
[[SalesforceSDKManager sharedManager] launch];
};
[SalesforceSDKManager sharedManager].postLogoutAction = ^{
[weakSelf handleSdkManagerLogout];
};
[SalesforceSDKManager sharedManager].switchUserAction =
^(SFUserAccount *fromUser, SFUserAccount *toUser) {
[weakSelf handleUserSwitch:fromUser toUser:toUser];
};
return self;
}
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
[[SalesforceSDKManager sharedManager] launch];
}
init メソッドで、SalesforceSDKManager オブジェクトは次のことを行います。
• SalesforceSDKManager 共有インスタンスを使用して、接続アプリケーション識別子や OAuth 範囲などの
設定項目を初期化する。次に例を示します。
[SalesforceSDKManager sharedManager].connectedAppId = RemoteAccessConsumerKey;
[SalesforceSDKManager sharedManager].connectedAppCallbackUri = OAuthRedirectURI;
[SalesforceSDKManager sharedManager].authScopes = @[ @"web", @"api" ];
• postLaunchAction、launchErrorAction、postLogoutAction、switchUserAction イベントを処理
するプロパティにコードブロックを割り当てる。ブロックの実装で weak self が使用されていることに注意
してください。サイクルに対してコードを保護することに加え、この使用例は SalesforceSDKManager
が単なるマネージャであるという重要な点を示しています。つまり、永続的な self を必要とする実際の処理
はすべて、作業を実際に実行する代理メソッド内で行われます。次の表に、AppDelegate テンプレートに
よる各イベントの処理方法をまとめます。
38
ネイティブ iOS の開発
AppDelegate クラス
イベント
Delegate メソッド
デフォルトの動作
postLaunch
setupRootViewController
アプリケーションのルートビュー
コントローラをインスタンス化
し、それを AppDelegate の
window.rootViewController
プロパティに割り当てます。
launchError
initializeAppViewState
ルートビューコントローラを初期
ビューコントローラにリセットし
ます。
postLogout
handleSdkManagerLogout
有効なユーザアカウントが複数あ
る場合、以前に認証されたアカウ
ントをユーザが選択できるように
するため、ルートビューコント
ローラをマルチユーザビューコン
トローラに変更します。有効なア
カウントが 1 つしかない場合は、
そのアカウントに自動的に切り替
えられます。有効なアカウントが
ない場合は、ログイン画面が表示
されます。
switchUser
handleUserSwitch:toUser:
ルートビューコントローラを初期
ビューコントローラにリセット
し、起動フローを再度開始しま
す。
このプロセスのどの部分もカスタマイズできます。 少なくとも、認証後に独自のコントローラが表示される
ように setupRootViewController を変更してください。 また、initializeAppViewState をカスタマイ
ズして独自の起動ページを表示したり、ニーズに合わせて InitialViewController をカスタマイズするこ
ともできます。 さらに、アプリケーションにとって最も適切な場所に認証の詳細を移動することもできま
す。 Mobile SDK では、アクションの実行時期 (または実行するかどうか) は規定されませんが、標準の iOS 規則
は適用されます。たとえば、self.window には、application:didFinishLaunchingWithOptions: が完
了するまでに rootViewController が必要です。
UIApplication イベントハンドラ
アプリケーションの代理クラスを使用して、UIApplication イベントハンドラを実装することもできます。
実装またはカスタマイズを考慮すべき重要なイベントハンドラは、次のとおりです。
application:didFinishLaunchingWithOptions:
アプリケーションの起動時の最初のエントリポイントです。プロセスが最初に開始したとき (バックグラウ
ンド/フォアグラウンドサイクルの後ではない) にのみコールされます。テンプレートアプリケーションで
は、次の処理を行うためにこのメソッドが使用されます。
39
ネイティブ iOS の開発
AppDelegate クラス
• window プロパティを初期化する
• ルートビューコントローラを初期ビューコントローラに設定する (initializeAppViewState を参照)
• 初期ウィンドウを表示する
• 起動メッセージを共有 SalesforceSDKManager インスタンスに送信することにより、認証を開始する
applicationDidBecomeActive
アプリケーションがフォアグラウンドになるたびにコールされます。iOS SDK にはデフォルトの親動作はあ
りませんが、それを使用する場合は下から順に実装する必要があります。
application:didRegisterForRemoteNotificationsWithDeviceToken:、
application:didFailToRegisterForRemoteNotificationsWithError:
Salesforce からの受信転送通知の処理に使用されます。
すべての UIApplication イベントハンドラのリストは、「iOS Developer Library」の「UIApplicationDelegate Protocol
Reference」を参照してください。
遅延ログインについて
ユーザログインの認証を、postLaunch イベント発生後の任意の論理ポイントに延期することができます。認
証を延期する手順は、次のとおりです。
1. AppDelegate クラスの init メソッドで、SalesforceSDKManager の authenticateAtLaunch プロパ
ティを NO に設定します。
2. launch メソッドを SalesforceSDKManager に送信します。
3. SFAuthenticationManager の loginWithCompletion:failure: メソッドを遅延ログインポイントで
コールします。
認証を延期する場合、ログインの完了および失敗を処理するロジックは、アプリケーションによって判断され
ます。
既存のアプリケーションのアップグレード
Mobile SDK 2.3 以前からアプリケーションをアップグレードする場合、起動イベントを処理するカスタムコード
はすべて再利用できますが、若干異なるコンテキストに移動する必要があります。たとえば、
SFAuthenticationManagerDelegate の authManagerDidLogout: メソッドを実装した以前のコードは、
SalesforceSDKManager の postLogoutAction ブロックに移動します。同様に、
SFUserAccountManagerDelegate の useraccountManager:didSwitchFromUser:toUser: を実装した
コードは、SalesforceSDKManager の switchUserAction ブロックに含まれます。
最後に、AppDelegate の実装で、SFAuthenticationManager の loginWithCompletion:failure: メ
ソッドへのすべてのコールを、SalesforceSDKManager の launch メソッドに置き換えます。完了ブロック
のコードを postLaunchAction プロパティに移動し、失敗ブロックのコードを launchErrorAction プロパ
ティに移動します。
関連トピック:
iOS での転送通知の使用
40
ネイティブ iOS の開発
ビューコントローラについて
ビューコントローラについて
AppDelegate クラスに記載されているビューおよびビューコントローラに加え、Mobile SDK では
SFAuthorizingViewController クラスが公開されます。このコントローラでは、必要に応じてログイン画
面が表示されます。
ログイン画面の表示をカスタマイズする手順は、次のとおりです。
1. カスタム表示ロジックを実装するように SFAuthorizingViewController クラスを上書きします。
2. カスタマイズしたクラスのインスタンスに [SFAuthenticationManager
sharedManager].authViewController プロパティを設定します。
アプリケーションで最も重要なビューコントローラは、ログイン後または (ログインが延期されている場合は)
起動後に表示される最初の画面を管理するビューコントローラです。このコントローラはアプリケーションで
行われる他のすべてのものを制御するため、ルートビューコントローラと呼ばれます。iOS プロジェクトテン
プレートの Mobile SDK には、最低限必要な実装を示す RootViewController という名前の骨格のみのクラス
が備えられています。
アプリケーションで追加のビューコントローラが必要な場合は、必要に応じて自由に作成できます。Mobile SDK
プロジェクトで使用されるビューコントローラには、いくつかのオプションが可能です。たとえば、Mobile SDK
iOS テンプレートプロジェクトは UITableViewController インターフェースのルートビュークラスを基にし
ていますが、RestAPIExplorer サンプルプロジェクトでは UIViewController インターフェースが使用さ
れます。iOS 自体および Objective-C 言語によってのみ、技術的な制限が加えられます。
RootViewController クラス
RootViewController クラスは、テンプレートプロジェクトおよびそこから生成されるプロジェクトの一部
としてのみ存在します。このクラスでは、アプリケーションが Salesforce REST API とやり取りするためのフレー
ムワークを設定する SFRestDelegate プロトコルが実装されます。ルートビューコントローラの定義方法に
関係なく、SFRestDelegate を使用して REST API 経由で Salesforce データにアクセスする場合は、SFRestDelegate
を実装する必要があります。
RootViewController のデザイン
Mobile SDKを使用して作成される非常に基本的なアプリケーションの要素として、RootViewController クラ
スでは重要項目のみが取り扱われます。主要な 2 つのタスクは次のとおりです。
• Salesforce REST API を使用して Salesforce データをクエリする
• Salesforce データをテーブルに表示する
以上の操作を行うため、このクラスは UITableViewController を継承して、SFRestDelegate プロトコル
を実装します。このアクションは、UIViewController:viewDidLoad メソッドの上書きで開始します。
- (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Mobile SDK Sample App";
//Here we use a query that should work on either Force.com or Database.com
SFRestRequest *request =
41
ネイティブ iOS の開発
RootViewController クラス
[[SFRestAPI sharedInstance] requestForQuery:@"SELECT Name FROM User LIMIT 10"];
[[SFRestAPI sharedInstance] send:request delegate:self];
}
ビューがメモリに初めて読み込まれると、iOS ランタイムにより viewDidLoad がビューのライフサイクルで
1 回のみコールされます。この骨格のみのアプリケーションの目的は、アプリケーションで定義済みの唯一の
ビューに 1 セットのデータのみを読み込むことにあります。他のビューを作成するには、別の場所でクエリを
実行する必要がある場合もあります。たとえば、ルートビューに表示されるデータをユーザが編集できる詳細
ビューを追加する場合は、ルートビューに値が再表示されるときに値を更新します。この場合、
viewWillAppear など、より適切なメソッドでクエリを実行できます。
スーパークラスメソッドをコールすると、ビューのタイトルが設定され、非同期の SOQL クエリの形式で REST
要求が発行されます。この場合のクエリは、各 User オブジェクトから Name プロパティを取得する単純な SELECT
ステートメントで、返される行は 10 行に制限されます。requestForQuery および send:delegate: メッ
セージが、SFRestAPI クラスの単一の共有インスタンスに送信されます。この単一オブジェクトをすべての
REST 要求に使用します。このオブジェクトでは、単一の SFAccountManager オブジェクトの認証済みログイ
ン情報を使用して、認証済み要求の作成と送信が行われます。
Salesforce REST API は、送信メッセージに示される代理オブジェクトに状況メッセージとデータ (可能な場合) を
渡すことによって応答します。この場合、RootViewController 自体が代理オブジェクトになります。
[[SFRestAPI sharedInstance] send:request delegate:self];
RootViewController オブジェクトは、SFRestDelegate プロトコルを実装するため、SFRestAPI の代理
オブジェクトとしての役割を果たすことができます。このプロトコルでは、4 つの可能な応答コールバックが
宣言されます。
• request:didLoadResponse: — 要求が処理されました。代理オブジェクトは JSON 形式の応答を受信しま
す。成功を示すコールバックはこれだけです。
• request:didFailLoadWithError: — 要求を処理できませんでした。代理オブジェクトはエラーメッセー
ジを受信します。
• requestDidCancelLoad — 管理者による操作、ネットワーク障害、他の予期しないイベントなど、外部
要因により要求がキャンセルされました。代理オブジェクトは戻り値を受信しません。
• requestDidTimeout — Salesforce サーバが時間内に応答しませんでした。代理オブジェクトは戻り値を受
信しません。
応答は、RootViewController で実装したいずれかのコールバックで受信されます。Salesforce データを処理
するコードを request:didLoadResponse: コールバックに配置します。次に例を示します。
- (void)request:(SFRestRequest *)request
didLoadResponse:(id)jsonResponse {
NSArray *records = [jsonResponse objectForKey:@"records"];
NSLog(@"request:didLoadResponse: #records: %d", records.count);
self.dataRows = records;
[self.tableView reloadData];
}
id データ型の使用で提示されるように、このコードでは JSON 応答が汎用的な Objective-C 形式で処理されます。
jsonResponse オブジェクトは NSDictionary のインスタンスとして処理され、そのレコードは NSArray
オブジェクトとして扱われます。RootViewController では UITableViewController が実装されるため、
抽出されたレコードを使用してテーブルを入力するのは簡単です。
42
ネイティブ iOS の開発
Salesforce REST API について
次のいずれかの条件で、request:didFailLoadWithError: がコールされます。
• 無効な要求パラメータを使用すると、kSFRestErrorDomain エラーコードが返されます。例:
requestForQuery: に nil を渡したり、存在しないオブジェクトを更新しようとした。
• OAuth アクセストークンが期限切れになると、フレームワークで新しいアクセストークンを取得しようと
し、成功するとクエリが再試行されます。新しいアクセストークンまたはセッション ID の要求に失敗する
と、kSFOAuthErrorDomain エラーコードが返されます。例: アクセストークンが期限切れであり、OAuth
更新トークンが無効。このような状況になることはまずありません。
• 低レベルの HTTP 要求に失敗すると、RKRestKitErrorDomain エラーコードが返されます。例: Salesforce
サーバが一時的にアクセスできなくなる。
他のコールバックは自己説明的であり、エラーコードは返されません。エラーメッセージの表示、ログへの書
き込み、要求の再試行など、結果の処理方法を自由に選択できます。
Salesforce REST API について
Salesforce Mobile SDK を使用したネイティブアプリケーションの開発は、Salesforce REST API の使用が中心になって
います。Salesforce では、REST パラメータを指定した URI で広範囲にわたるオブジェクトベースのタスクを使用
できます。Mobile SDK では、要求を書式設定する低レベルのほとんどの作業を処理するインターフェースで、
これらの HTTP コールがラップされます。
Mobile SDK for iOS では、すべての REST 要求が非同期に実行されます。REST ラッパークラスの代理バージョンまた
はブロックバージョンを選択して、要求をさまざまなシナリオに適用できます。REST 応答は、要求に成功した
場合は NSArray または NSDictionary オブジェクトとして書式設定され、要求に失敗した場合は NSError
オブジェクトとして書式設定されます。
Salesforce REST の応答形式についての詳細は、『Force.com REST API 開発者ガイド』を参照してください。
サポートされている操作
iOS REST API は、Salesforce REST および SOAP API で提供される標準のオブジェクト操作をサポートしています。
Salesforce Mobile SDK には、その REST 要求 API の代理バージョンとブロックバージョンが備えられています。代理
要求メソッドは SFRestAPI クラスで定義されますが、ブロック要求メソッドは SFRestAPI (Blocks) カテ
ゴリで定義されます。ファイル要求は、SFRestAPI (Files) カテゴリで定義されます。「SFRestAPI
(Files) カテゴリ」を参照してください。
サポートされる操作は次のとおりです。
操作
Manual REST request
Delegate メソッド
Block メソッド
send:delegate:
sendRESTRequest:
failBlock:
completeBlock:
requestForQuery:
performSOQLQuery:
failBlock:
completeBlock:
ユーザが作成した要
求を実行する
SOQL query
43
ネイティブ iOS の開発
操作
Salesforce REST API について
Delegate メソッド
Block メソッド
特定の SOQL 文字列
を実行し、結果の
データセットを返す
SOSL search
requestForSearch:
performSOSLSearch:
failBlock:
completeBlock:
requestForSearchResultLayout:
performRequestForSearchResultLayout:
failBlock:
completeBlock:
requestForSearchScopeAndOrder
performRequestForSearchScopeAndOrderWithFailBlock:
特定の SOSL 文字列を
実行し、結果のデー
タセットを返す
Search Scope and
Order
検索結果レイアウト
を取得する要求を実
行する
Search Scope and
Order
failBlock:
completeBlock:
検索範囲と検索順序
を取得する要求を実
行する
Metadata
requestForMetadataWithObjectType:
performMetadataWithObjectType:
failBlock:
completeBlock:
requestForDescribeGlobal
performDescribeGlobalWithFailBlock:
completeBlock:
requestForDescribeWithObjectType:
performDescribeWithObjectType:
failBlock:
completeBlock:
requestForRetrieveWithObjectType:
performRetrieveWithObjectType:
objectId:
オブジェクトのメタ
データを返す
Describe global
組織で使用できるす
べてのオブジェクト
とそのメタデータの
リストを返す
Describe with object
type
1 つのオブジェクト
種別の説明を返す
Retrieve
44
ネイティブ iOS の開発
操作
オブジェクト ID 別に
単一レコードを取得
する
Salesforce REST API について
Delegate メソッド
Block メソッド
fieldList:
failBlock:completeBlock:
objectId:
fieldList:
Update
指定された対応付け
でオブジェクトを更
新する
Upsert
外部 ID が外部 ID 項
目に現在存在してい
るかどうかに基づい
requestForUpdateWithObjectType:
objectId:
fields:
requestForUpsertWithObjectType:
externalIdField:
externalId:
45
performUpdateWithObjectType:
objectId:
fields:
failBlock:
completeBlock:
performUpsertWithObjectType:
externalIdField:
externalId:
fields:
failBlock:
completeBlock:
ネイティブ iOS の開発
操作
Salesforce REST API について
Delegate メソッド
て、外部データから
オブジェクトを更新
または挿入する
Create
fields:
requestForCreateWithObjectType:
指定したオブジェク
トに新しいレコード
を作成する
Delete
fields:
requestForDeleteWithObjectType:
指定された ID を持つ
特定のタイプのオブ
ジェクトを削除する
Versions
Block メソッド
objectId:
requestForVersions
performCreateWithObjectType:
fields:
failBlock:
completeBlock:
performDeleteWithObjectType:
objectId:
failBlock:
completeBlock:
performRequestForVersionsWithFailBlock:
Salesforce バージョン
のメタデータを返す
Resources
completeBlock:
requestForResources
performRequestForResourcesWithFailBlock:
リソース名および
URI を含む、指定さ
れた API バージョン
で使用可能なリソー
スを返す
completeBlock:
SFRestAPI インターフェース
SFRestAPI は、Salesforce REST 要求を作成および書式設定するためのネイティブインターフェースを定義しま
す。 これは、要求を書式設定し、Salesforce サービスに送信してから、SFRestDelegate プロトコルの実装エ
ントリに非同期応答をリレーすることによって動作します。
SFRestAPI は、SFRestRequest インスタンスのファクトリとしての役割を果たし、Salesforce REST API でサポー
トされる要求種別を表すメソッドグループを定義します。各 SFRestAPI メソッドは、1 つの要求種別に対応
します。各メソッドでは、要求が SFRestRequest インスタンス形式で返されます。その戻り値を使用して、
要求を Salesforce サーバに送信します。HTTP コーディングレイヤはカプセル化されるため、REST API 構文を考慮
する必要はありません。
サポートされるクエリファクトリメソッドのリストについては、「サポートされている操作」を参照してくだ
さい。
46
ネイティブ iOS の開発
Salesforce REST API について
SFRestDelegate プロトコル
クラスで SFRestDelegate プロトコルが採用されると、Salesforce サーバから送信される REST 応答のターゲッ
トとなります。REST 要求をサーバに送信するときに、応答を受信するオブジェクトを共有 SFRestAPI インス
タンスに示します。サーバから応答が送信されると、Mobile SDK によって、指定されたオブジェクトの適切な
プロトコルメソッドに応答が転送されます。
SFRestDelegate プロトコルでは、4 つの可能な応答が宣言されます。
• request:didLoadResponse: — 要求が処理されました。代理オブジェクトは JSON 形式の応答を受信しま
す。成功を示すコールバックはこれだけです。
• request:didFailLoadWithError: — 要求を処理できませんでした。代理オブジェクトはエラーメッセー
ジを受信します。
• requestDidCancelLoad — 管理者による操作、ネットワーク障害、他の予期しないイベントなど、外部
要因により要求がキャンセルされました。代理オブジェクトは戻り値を受信しません。
• requestDidTimeout — Salesforce サーバが時間内に応答しませんでした。代理オブジェクトは戻り値を受
信しません。
応答は、いずれかの代理メソッドの実装環境で受信されます。どの応答種別が受信されるかは不明なため、す
べてのメソッドを実装する必要があります。
request:didLoadResponse: メソッド
request:didLoadResponse: メソッドは、成功条件を処理する唯一のプロトコルメソッドであるため、
Salesforce データを処理するコードをこのメソッドに含めます。次に例を示します。
- (void)request:(SFRestRequest *)request
didLoadResponse:(id)jsonResponse {
NSArray *records = [jsonResponse objectForKey:@"records"];
NSLog(@"request:didLoadResponse: #records: %d", records.count);
self.dataRows = records;
[self.tableView reloadData];
}
サーバでは、すべての応答が JSON 文字列として作成されます。Mobile SDK では、このような未加工の応答を受
信し、iOS SDK オブジェクトとして再度書式設定してから、request:didLoadResponse: メソッドに渡しま
す。このため、jsonResponse ペイロードは、NSDictionary オブジェクトまたは NSArray オブジェクトと
して受信されます。オブジェクト種別は、返される JSON データのデータ型によって異なります。サーバ応答
の最上位レベルが JSON オブジェクトを表している場合、jsonResponse は NSDictionary オブジェクトで
す。最上位レベルが他のデータの JSON 配列を表している場合、jsonResponse は NSArray オブジェクトで
す。
要求のデータ型をメソッドで推測できない場合は、[NSObject isKindOfClass:] を使用してデータ型を判
断します。次に例を示します。
if ([jsonResponse isKindOfClass:[NSArray class]]) {
// Handle an NSArray here.
} else {
// Handle an NSDictionary here.
}
47
ネイティブ iOS の開発
Salesforce REST API について
応答を NSDictionary オブジェクトとして指定し、そのレコードを NSArray オブジェクトに抽出すること
ができます。これを行うには、キー「records」を使用して NSDictionary:objectForKey: メッセージを送
信します。
request:didFailLoadWithError: メソッド
次のいずれかの条件で、request:didFailLoadWithError: コールバックがコールされます。
• 無効な要求パラメータを使用すると、kSFRestErrorDomain エラーコードが返されます。例:
requestForQuery: に nil を渡したり、存在しないオブジェクトを更新しようとした。
• OAuth アクセストークンが期限切れになると、フレームワークで新しいアクセストークンを取得しようと
し、成功するとクエリが再試行されます。新しいアクセストークンまたはセッション ID の要求に失敗する
と、kSFOAuthErrorDomain エラーコードが返されます。例: アクセストークンが期限切れであり、OAuth
更新トークンが無効である。このような状況になることはまずありません。
• 低レベルの HTTP 要求に失敗すると、RKRestKitErrorDomain エラーコードが返されます。例: Salesforce
サーバが一時的にアクセスできなくなる。
requestDidCancelLoad および requestDidTimeout メソッド
requestDidCancelLoad および requestDidTimeout 代理メソッドは自己説明的であり、エラーコードは返
されません。エラーメッセージの表示、ログへの書き込み、要求の再試行など、結果の処理方法を自由に選択
できます。
REST 要求の作成
Salesforce Mobile SDK for iOS では、多くの種類の SOQL 要求と SOSL REST 要求がネイティブでサポートされます。
SFRestAPI クラスには、構文に関する詳細のほとんどを処理するファクトリメソッドが備えられています。
また、Mobile SDK では、REST 要求をかなり柔軟に作成することもできます。
• 標準の SOQL クエリおよび SOSL 検索の場合、SFRestAPI メソッドにより、最小限のデータ入力に基づいて
クエリ文字列が作成され、Salesforce サーバに送信可能な SFRestRequest オブジェクトにクエリ文字列が
パッケージ化されます。
• SOQL または SOSL に基づいていない Salesforce REST API を使用している場合は、SFRestRequest メソッドで、
API 形式と一致する要求そのものを設定できます。
• SFRestAPI (QueryBuilder) カテゴリには、自由形式の SOQL クエリ文字列や SOSL 検索文字列を作成す
るメソッドが備えられているため、クエリ文字列または検索文字列を手動で書式設定する必要はありませ
ん。
• SFRestAPI (Blocks) カテゴリの要求メソッドでは、代理オブジェクトを使用する代わりに、コールバッ
クコードをブロックメソッドとして渡すことができます。
REST 要求の送信
Salesforce Mobile SDK for iOS では、多くの種類の SOQL 要求と SOSL REST 要求がネイティブでサポートされます。
SFRestAPI には、構文に関する詳細のほとんどを処理するファクトリメソッドが備えられています。
48
ネイティブ iOS の開発
Salesforce REST API について
Mobile SDK は、実行時に SFRestAPI の単一インスタンスを作成します。このインスタンスを使用して、
SFRestRequest オブジェクトを取得し、そのオブジェクトを Salesforce サーバに送信します。
REST 要求を SFRestAPI 代理オブジェクトから Salesforce サーバに送信する手順は、次のとおりです。
1. SOQL、SOSL、または他の REST の要求文字列を作成します。
標準の SOQL クエリおよび SOSL クエリの場合、最も便利で信頼できる方法は、SFRestAPI クラスのファク
トリメソッドを使用することです。「サポートされている操作」を参照してください。
2. 要求文字列を使用して、SFRestRequest オブジェクトを作成します。
ニーズに合った要求ファクトリメソッドを使用して、SFRestAPI の単一インスタンスにメッセージを送信
します。たとえば、次のコードでは、SOQL クエリを準備する SFRestAPI:requestForQuery: メソッド
を使用しています。
// Send a request factory message to the singleton SFRestAPI instance
SFRestRequest *request = [[SFRestAPI sharedInstance]
requestForQuery:@"SELECT Name FROM User LIMIT 10"];
3. send:delegate: メッセージを共有 SFRestAPI インスタンスに送信します。新しい SFRestRequest オ
ブジェクトを send: パラメータとして使用します。2 つ目のパラメータは、サーバ応答を受信する
SFRestDelegate オブジェクトを指定します。次の例では、クラス自体で SFRestDelegate プロトコル
が実装されるため、delegate: が self に設定されます。
// Use the singleton SFRestAPI instance to send the
// request, specifying this class as the delegate.
[[SFRestAPI sharedInstance] send:request delegate:self];
SFRestRequest クラス
Salesforce Mobile SDK には、アプリケーションに便利なクラスとして SFRestRequest インターフェースがあり
ます。SFRestAPI には、入力内容から要求を作成する要求メソッドが備えられています。この要求は、
SFRestRequest インスタンスとしてパッケージ化され、アプリケーションに返されます。ほとんどの場合、
SFRestRequest オブジェクトを操作する必要はありません。通常、変更を加えずにそのまま
SFRestAPI:send:delegate: メソッドに渡すだけで十分です。
Chatter REST API を使用するなど、Mobile SDKで直接サポートされない REST 要求を送信する場合は、SFRestRequest
オブジェクトを手動で作成および設定できます。
SFRestRequest メソッドの使用
SFRestAPI ツールは、SOQL および SOSL ステートメントをネイティブでサポートしており、文法を理解し、ア
プリケーションからの最小限の入力に基づいて有効な要求を書式設定することができます。ただし、Salesforce
には、SOQL クエリや SOSL 検索とは関係ない製品固有の REST API も一部含まれています。このような要求にも
Mobile SDK リソースを使用して、設定と送信を行うことができます。この処理は、SOQL クエリ要求の送信と類
似しています。主な違いは、SFRestAPI メソッドに依存するのではなく、SFRestRequest オブジェクトの
作成と入力を直接行うことにあります。
Mobile SDK を使用して非 SOQL および非 SOSL REST の要求を送信する手順は、次のとおりです。
1. SFRestRequest のインスタンスを作成します。
49
ネイティブ iOS の開発
Salesforce REST API について
2. SFRestRequest オブジェクトで、必要なプロパティを設定します。
3. SFRestAPI の単一インスタンスで send:delegate: をコールし、作成した SFRestRequest オブジェク
トを最初のパラメータとして渡します。
次の例は、GET 操作を実行して、特定の Chatter フィードにすべての項目を取得します。
SFRestRequest *request = [[SFRestRequest alloc] init];
[request setDelegate:self];
[request setEndpoint:kSFDefaultRestEndpoint];
[request setMethod:SFRestMethodGET];
[request setPath:
[NSString stringWithFormat:@"/v26.0/chatter/feeds/record/%@/feed-items",
recordId]];
[[SFRestAPI sharedInstance] send:request delegate:self];
4. また、requestWithMethod:path:queryParams クラスメソッドを使用して、同じ要求を作成すること
もできます。
SFRestRequest *request =
[SFRestRequest
requestWithMethod:SFRestMethodGET
path:
[NSString
stringWithFormat:
@"/v26.0/chatter/feeds/
record/%@/feed-items",
recordId]
queryParams:nil];
[[SFRestAPI sharedInstance] send:request delegate:self];
5. パラメータのある要求を実行するには、パラメータ文字列を作成してから、
SFJsonUtils:objectFromJSONString 静的メソッドを使用して NSDictionary オブジェクトでパラメー
タ文字列をラップします (必要に応じて、NSDictionary オブジェクトをインラインで作成するのではな
く、メソッドコールの前に直接作成してもかまいません)。
次の例は、Chatter フィードにコメントを追加する POST 操作を実行します。
NSString *body =
[NSString stringWithFormat:
@"{ \"body\" :
{\"messageSegments\" :
[{ \"type\" : \"Text\",
\"text\" : \"%@\"}]
}
}",
comment];
SFRestRequest *request =
[SFRestRequest
requestWithMethod:SFRestMethodPOST
path:[NSString
stringWithFormat:
@"/v26.0/chatter/feeds/
record/%@/feed-items",
50
ネイティブ iOS の開発
Salesforce REST API について
recordId]
queryParams:
(NSDictionary *)
[SFJsonUtils objectFromJSONString:body]];
[[SFRestAPI sharedInstance] send:request delegate:self];
6. 要求の HTTP ヘッダーを設定するには、setHeaderValue:forHeaderName メソッドを使用します。このメ
ソッドは、HTML 表示用に事前にエンコードされている Chatter フィードを表示する場合に役立ちます。ネイ
ティブアプリケーションの Chatter コメントに不要なエスケープシーケンスが表示されている場合、要求を
送信する前に次のように X-Chatter-Entity-Encoding ヘッダーを「false」に設定します。
...
[request setHeaderValue:@"false" forHeaderName:@"X-Chatter-Entity-Encoding"];
[[SFRestAPI sharedInstance] send:request delegate:self];
SFRestAPI (Blocks) カテゴリ
必要に応じて、代理オブジェクトの代わりにブロックを使用してコールバックコードを実行できます。ネイ
ティブ iOS の Salesforce Mobile SDK には、SFRestAPI 要求メソッドごとに付随ブロックがあります。これらのメ
ソッドは、SFRestAPI (Blocks) カテゴリで定義されます。
ブロック要求メソッドは、代理要求メソッドに酷似しています。どのメソッドからも、SFRestRequest を指
すポインタが返され、同じパラメータを必要とします。ブロック要求メソッドは、次の点で代理要求メソッド
と異なります。
1. REST API パラメータのコピーに加え、各メソッドには、予期される応答データに応じて、SFRestFailBlock
タイプの失敗ブロックと、SFRestDictionaryResponseBlock タイプまたは SFRestArrayResponseBlock
タイプの完了ブロックの 2 つのブロックが必要です。
2. ブロックベースのメソッドから要求が送信されるため、別個の送信メソッドをコールする必要はありませ
ん。要求に失敗した場合は、SFRestRequest * 戻り値を使用して要求を再試行できます。これを行うに
は、SFRestAPI:sendRESTRequest:failBlock:completeBlock: メソッドを使用します。
ブロックおよび代理メソッドを適切に使用することで、アプリケーションの読みやすさを調整し、メンテナン
スを簡単にするのに役立ちます。ブロックの使用に最適な条件は、C++ でのインライン関数や Java での匿名関
数を要求する条件と一致することがよくあります。ただし、これはあくまでも一般的な目安です。最終的に
は。アプリケーションの実際の動作を調べたうえで判断する必要があります。
SFRestAPI (QueryBuilder) カテゴリ
SOQL クエリまたは SOSL 検索の正しい構文が明確でない場合は、SFRestAPI (QueryBuilder) カテゴリメソッ
ドを利用できます。これらのメソッドでは、指定した基本条件からクエリ文字列が作成され、書式設定された
文字列が返されます。返された値を次のいずれかの SFRestAPI メソッドに渡すことができます。
• – (SFRestRequest *)requestForQuery:(NSString *)soql;
• – (SFRestRequest *)requestForSearch:(NSString *)sosl;
SFRestAPI (QueryBuilder) には、SOQL クエリと SOSL 検索にそれぞれ 2 つの静的メソッドがあります。1 つ
は最小限のパラメータを受け入れ、もう 1 つはすべてのオプションを受け入れます。
51
ネイティブ iOS の開発
Salesforce REST API について
SOSL メソッド
SOSL クエリビルダーメソッドは、次のとおりです。
+ (NSString *) SOSLSearchWithSearchTerm:(NSString *)term
objectScope:(NSDictionary *)objectScope;
+ (NSString *) SOSLSearchWithSearchTerm:(NSString *)term
fieldScope:(NSString *)fieldScope
objectScope:(NSDictionary *)objectScope
limit:(NSInteger)limit;
SOSL 検索メソッドのパラメータは、次のとおりです。
• term は、検索文字列です。この文字列には任意の値を指定できます。メソッドでは、検索を処理する前に
SOSL 予約文字がすべてエスケープされます。
• fieldScope は、検索する項目を示します。これは、nil またはいずれかの IN 検索グループ式 (「IN ALL
FIELDS」、「IN EMAIL FIELDS」、「IN NAME FIELDS」、「IN PHONE FIELDS」、または「IN SIDEBAR FIELDS」) になり
ます。デフォルトでは nil の値は「IN NAME FIELDS」になります。「Salesforce Object Search Language (SOSL)」を
参照してください。
• objectScope は、検索するオブジェクトを指定します。有効な値は次のとおりです。
– nil — 範囲に制限はありません。検索可能なすべてのオブジェクトが検索されます。
– NSDictionary オブジェクトポインタ — SOSL RETURNING fieldspec に対応します。各キーは sObject 名で
す。各値は、項目リストおよびキーオブジェクトの省略可能な WHERE、ORDER BY、LIMIT 句を含む文字列
です。
NSDictionary オブジェクトを使用する場合、各値には少なくとも項目リストが含まれている必要があ
ります。たとえば、ディクショナリエントリで次の SOSL ステートメントを表すとします。
FIND {Widget Smith}
IN Name Fields
RETURNING Widget__c (name Where createddate = THIS_FISCAL_QUARTER)
この場合は、キーを “Widget__c” に設定し、値を “name WHERE createddate = “THIS_FISCAL_QUARTER” に設
定します。次に例を示します。
[SFRestAPI
SOSLSearchWithSearchTerm:@"all of these will be escaped:~{]"
objectScope:[NSDictionary
dictionaryWithObject:@"name WHERE
createddate="THIS_FISCAL_QUARTER"
forKey:@"Widget__c"]];
– NSNull — 範囲が指定されていません。
• limit — 返される結果数を制限するには、このパラメータを、受信する結果の最大数に設定します。
52
ネイティブ iOS の開発
Salesforce REST API について
SOQL メソッド
SOQL 文字列を作成する SOQL QueryBuilder メソッドは、次のとおりです。
+ (NSString *) SOQLQueryWithFields:(NSArray *)fields
sObject:(NSString *)sObject
where:(NSString *)where
limit:(NSInteger)limit;
+ (NSString *) SOQLQueryWithFields:(NSArray *)fields
sObject:(NSString *)sObject
where:(NSString *)where
groupBy:(NSArray *)groupBy
having:(NSString *)having
orderBy:(NSArray *)orderBy
limit:(NSInteger)limit;
SOQL メソッドのパラメータは、SOQL クエリの構文に対応します。fields と sObject を除くすべてのパラ
メータは、nil に設定することができます。
パラメータ名
説明
fields
クエリする項目名の配列。
sObject
クエリするオブジェクトの名前。
where
1 つ以上のクエリ条件を指定する式。
groupBy
結果レコードのグループ化に使用する項目名の配列。
having
グループ化した結果を絞り込むための式 (通常、集計
関数を使用)。groupBy でのみ使用されます。
orderBy
結果レコードの並び替えに使用する項目名の配列。
limit
返されるレコードの最大数。
「SOQL SELECT の構文」 を参照してください。
SOSL のサニタイズ
QueryBuilder カテゴリには、SOSL 検索語をクリーンアップするためのクラスメソッドも用意されています。
+ (NSString *) sanitizeSOSLSearchTerm:(NSString *)searchTerm;
このメソッドでは、入力文字列に含まれているすべての SOSL 予約文字がエスケープされ、エスケープされた
バージョンが返されます。次に例を示します。
NSString *soslClean = [SFRestAPI sanitizeSOSLSearchTerm:@"FIND {MyProspect}"];
このコールは、“FIND \{MyProspect\}” を返します。
53
ネイティブ iOS の開発
Salesforce REST API について
sanitizeSOSLSearchTerm: メソッドは、SOSL および SOQL QueryBuilder メソッドの実装でコールされるため、
QueryBuilder メソッドに渡す文字列でこのメソッドをコールする必要はありません。ただし、独自のクエリを手
動で作成しているなどの場合は、このメソッドを使用できます。SOSL 予約文字は、次のとおりです。
\?&|!{}[]()^~*:"'+-
SFRestAPI (Files) カテゴリ
SFRestAPI (Files) カテゴリには、ファイル操作要求を作成するメソッドが備えられています。各メソッド
は、新しい SFRestRequest オブジェクトを返します。アプリケーションは、このオブジェクトを Salesforce
サービスに送信して要求を処理します。たとえば、次のコードスニペットは
requestForOwnedFilesList:page: メソッドをコールして SFRestRequest オブジェクトを取得します。
次に、そのオブジェクトが所有するオブジェクトを、応答を受信する代理オブジェクトとして指定して、要求
オブジェクトをサーバに送信します。
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForOwnedFilesList:nil page:0];
[[SFRestAPI sharedInstance] send:request delegate:self];
メモ: この例では、最初のパラメータ (userId) に nil を渡します。この値で、コンテキスト (ログインして
いる) ユーザの ID を使用するように requestForOwnedFilesList:page: メソッドに指示します。pageNum
パラメータに 0 を渡すと、最初のページを取得するようメソッドに指示します。
Files 機能およびネットワーキング機能についての詳細は、「ファイルとネットワーキング」を参照してくださ
い。
メソッド
SFRestAPI (Files) カテゴリでは、以下の操作がサポートされています。このカテゴリの詳細は、「SFRestAPI
(Files) カテゴリ — 要求メソッド (iOS)」を参照してください。REST リクエストボディおよびレスポンスボディに
ついての詳細は、[Chatter REST API Resources (Chatter REST API リソース)] > [FilesResources]
(http://www.salesforce.com/us/developer/docs/chatterapi) を参照してください。
メソッド
- (SFRestRequest *)
requestForOwnedFilesList:(NSString *)
userId page:(NSUInteger)page
- (SFRestRequest *)
requestForFilesInUsersGroups:(NSString
*)userId
page:(NSUInteger)page
- (SFRestRequest *)
requestForFilesSharedWithUser:(NSString
*)userId
page:(NSUInteger)page
説明
指定されたユーザが所有するファイルのリストから
ページを取得する要求を構築します。
ユーザのグループが所有するファイルのリストから
ページを取得する要求を構築します。
ユーザと共有しているファイルのリストからページを
取得する要求を構築します。
54
ネイティブ iOS の開発
メソッド
- (SFRestRequest *)
requestForFileDetails:(NSString *)sfdcId
forVersion:(NSString *)version
- (SFRestRequest *)
requestForBatchFileDetails:(NSArray
*)sfdcIds
- (SFRestRequest *)
requestForFileRendition:(NSString *)sfdcId
version:(NSString *)version
renditionType:(NSString *)renditionType
page:(NSUInteger)page
- (SFRestRequest *)
requestForFileContents:(NSString *)
sfdcId version:(NSString*) version
- (SFRestRequest *)
requestForFileShares:(NSString *)sfdcId
page:(NSUInteger)page
- (SFRestRequest *)
requestForAddFileShare:(NSString *)fileId
entityId:(NSString *)entityId
shareType:(NSString*)shareType
- (SFRestRequest *)
requestForDeleteFileShare:(NSString
*)shareId;
- (SFRestRequest *)
requestForUploadFile:(NSData *)data
name:(NSString *)name
description:(NSString *)description
mimeType:(NSString *)mimeType
認証エラーの処理
説明
特定のバージョンのファイルの詳細を取得する要求を
構築します。
1 つの要求で 1 つ以上のファイルの最新の詳細を取得
する要求を構築します。
ファイル (およびバージョン) の特定のページのプレ
ビュー/変換を取得する要求を構築します。
この特定のファイルの実際のバイナリコンテンツを取
得する要求を構築します。
このファイルを共有するエンティティのリストから
ページを取得する要求を作成します。
指定されたファイル ID のファイル共有を指定された
エンティティ ID に追加する要求を構築します。
指定されたファイル共有を削除する要求を構築しま
す。
新しいファイルをサーバにアップロードする要求を構
築します。バージョンが 1 に設定された新しいファイ
ルを作成します。
認証エラーの処理
Mobile SDK には、認証エラーが発生したときにメッセージを表示し、アプリケーションフローを迂回させるデ
フォルトのエラーハンドラが備えられています。これらのエラーハンドラは、SFAuthErrorHandler クラス
のインスタンスです。すべての認証エラーハンドラへの参照を保存する SFAuthErrorHandlerList クラス
55
ネイティブ iOS の開発
チュートリアル: ネイティブ iOS Warehouse アプリケー
ションの作成
によって管理されます。エラーハンドラでは、次のプロトタイプを使用する匿名ブロックにその実装が定義さ
れます。
typedef BOOL (^SFAuthErrorHandlerEvalBlock)(NSError *, SFOAuthInfo *);
戻り値 YES は現在のエラー状況にこのハンドラが使用されたことを示します。他のどのエラーハンドラも適
用されません。ハンドラから NO が返された場合は、このブロックが使用されておらず、エラー処理プロセス
はリスト内の次のハンドラに進みます。エラーハンドラの実装の詳細は、開発者の判断に委ねられます。Mobile
SDK でこれらのブロックがどのように定義されるかを確認するには、SalesforceSDKCore プロジェクトの
SFAuthenticationManager.m ファイルを参照してください。
独自のエラー処理メカニズムに置き換えるには、次の操作を実行します。
• 独自のハンドラをエラーハンドラスタックの先頭 (インデックス 0) に追加して、Mobile SDK のデフォルトの
エラーハンドラを上書きします。
SFAuthErrorHandler *authErrorHandler =
[[SFAuthErrorHandler alloc] initWithName:@"myAuthErrorHandler"
evalBlock:^BOOL(NSError *error, SFOAuthInfo *authInfo) {
// Add your error-handling code here
}];
[[SFAuthenticationManager sharedManager].authErrorHandlerList
addAuthErrorHandler:authErrorHandler atIndex:0];
• Mobile SDK の汎用「万能」エラーハンドラをリストから削除します。このようにすると、起動プロセス時の
SalesforceSDKManager 実装の launchErrorAction ブロック、または遅延ログインを実装した場合は
loginWithCompletion:failure: 定義の failure: ブロックに認証エラーがそのまま進みます。次に、
汎用エラーハンドラを無効化する方法を示します。
SFAuthErrorHandler *genericHandler =
[SFAuthenticationManager sharedManager].genericAuthErrorHandler;
[[SFAuthenticationManager sharedManager].authErrorHandlerList
removeAuthErrorHandler:genericHandler];
チュートリアル: ネイティブ iOS Warehouse アプリケーションの
作成
前提条件
• このチュートリアルでは、基本的な在庫データベースを含む Warehouse アプリケーションを使用します。こ
のアプリケーションを DE 組織にインストールする必要があります。既存の DE 組織にインストールする場
合、作成した既存の Warehouse コンポーネントをすべて削除してからインストールしてください。
1. インストール URL リンク http://bit.ly/package100 をクリックします。
2. すでにログインしている場合は、DE 組織のユーザ名とパスワードを入力します。
3. [Package Installation Details (パッケージインストールの詳細)] ページで、[Continue (次へ)] をクリックします。
4. [Next (次へ)] をクリックし、[Security Level (セキュリティレベル)] ページで [Next (次へ)] をクリックします。
56
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
5. [Install (インストール)] をクリックします。
6. [Deploy Now (今すぐデプロイ)] をクリックしてから、[Deploy (デプロイ)] をクリックします。
7. インストールが完了したら、右上のアプリケーションピッカーから [Warehouse (倉庫)] アプリケーショ
ンを選択できます。
8. データを作成するには、[データ] タブをクリックします。
9. [データを作成] ボタンをクリックします。
• 最新バージョンの Xcode と iOS SDK をインストールします。
• npm を使用して Salesforce Mobile SDK をインストールします。
1. Node.js および npm がすでに正常にインストールされている場合は、ステップ 4 に進みます。
2. Node.js をシステムにインストールします。Node.js インストーラにより、npm が自動的にインストールさ
れます。
i. www.nodejs.org/download から Node.js をダウンロードします。
ii. ダウンロードしたインストーラを実行して Node.js および npm をインストールします。インストール
の許可を求めるプロンプトをすべて承諾します。
3. ターミナルウィンドウで、「npm」と入力して Return キーを押し、インストールが成功していること
を確認します。使用状況情報のページが表示されない場合、ステップ 2 に戻り、何が欠落しているのか
を調べます。
4. ターミナルウィンドウで「sudo npm install forceios -g」と入力します。
このコマンドは、forceios パッケージを使用して Mobile SDK をグローバルにインストールします。-g オプ
ションでは、npm install を任意のディレクトリから実行できます。npm ユーティリティによりパッ
ケージが /usr/local/lib/node_modules にインストールされ、/usr/local/bin のバイナリモ
ジュールにリンクされます。大部分のユーザは /usr/local の「参照・更新」権限がないため、sudo
オプションが必要になります。
ネイティブ iOS アプリケーションを作成する
このチュートリアルでは、Salesforce Mobile SDK の使用を開始する方法 (SDK のインストール方法や DE 組織を使用
したネイティブプロジェクトテンプレートのツアーを含む) を学習します。後続のチュートリアルでは、テン
プレートアプリケーションを変更して、Warehouse スキーマと連携させる方法について説明します。
57
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
ステップ 1: 接続アプリケーションを作成する
このステップでは、Force.com で接続アプリケーションを設定する方法を学習します。これを行うことで構築す
るモバイルアプリケーションが認証され、ユーザの代わりに業界標準の OAuth 2.0 プロトコルを介して Force.com
と安全に通信し、Force.com API にアクセスできるようになります。
1. DE 組織で あなたの名前 > [設定] をクリックし、[アプリケーションの設定] で [作成] > [アプリケーション] を
クリックします。
2. [接続アプリケーション] で、[新規] をクリックして、[新規接続アプリケーション] ページを表示します。
3. [基本情報] で、フォームに次のように入力します。
• 接続アプリケーション名: My Native iOS App (私のネイティブ iOS アプリケーション)
• API 参照名: 推奨値を受け入れます。
• 取引先責任者 メール: メールアドレスを入力します。
4. OAuth 設定で、[OAuth 設定の有効化] チェックボックスをオンにします。
5. [コールバック URL] を mysampleapp://auth/success に設定します。
6. [利用可能な OAuth 範囲] で、[データへのアクセスと管理] (api) および [ユーザに代わっていつでも要求を実
行] (refresh_token) をオンにして、[追加] をクリックします。
7. [保存] をクリックします。
設定を保存すると、作成した接続アプリケーションの詳細が表示されます。
• コールバック URL およびコンシューマ鍵を記録します。これらは、次のステップでネイティブアプリケー
ションを設定するときに使用します。
• モバイルアプリケーションではコンシューマの秘密は使用しないため、この値は無視できます。
ステップ 2: ネイティブ iOS プロジェクトを作成する
新しい Mobile SDK プロジェクトを作成するには、ターミナルウィンドウで forceios ユーティリティを再度使用し
ます。
1. プロジェクトを作成するディレクトリに変更します。
58
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
2. iOS プロジェクトを作成するには、「forceios create」と入力します。
設定値ごとに、forceios ユーティリティによってプロンプトが表示されます。
3. アプリケーション種別に、「native」と入力します。
4. アプリケーション名に、「MyNativeiOSApp」と入力します。
5. 会社の識別子に、「com.acme.goodapps」と入力します。
6. 組織名に、「GoodApps, Inc.」と入力します。
7. 出力ディレクトリに、「tutorial/iOSNative」と入力します。
8. 接続アプリケーション ID に、接続アプリケーション定義からコンシューマ鍵をコピーして貼り付けます。
9. 接続アプリケーションのコールバック URI に、接続アプリケーション定義からコールバック URL をコピーし
て貼り付けます。
入力画面は次のように表示されます。
ステップ 3: 新しい iOS アプリケーションを実行する
1. Xcode で [File (ファイル)] > [Open (開く)] を選択します。
2. 指定した出力フォルダに移動します。
3. アプリケーションの xcodeproj ファイルを開きます。
4. 左上隅にある [Run (実行)] ボタンをクリックすると、新しいアプリケーションが iOS シミュレータに表示さ
れます。Xcode メニューで [Product (製品)] > [Destination (対象)] > [iPhone 6.0 Simulator (iPhone 6.0 シミュレー
タ)] が選択されていることを確認してください。
5. アプリケーションを起動すると、初期スプラッシュ画面が表示された後で Salesforce ログイン画面が表示さ
れます。DE のユーザ名とパスワードを使用してログインします。
59
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
6. プロンプトが表示されたら、アプリケーションの左にある [Allow (許可)] をクリックして、Salesforce のデー
タにアクセスします。DE 組織で定義されているユーザ名のリストを示す表が表示されます。
60
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
ステップ 4: iOS アプリケーションの仕組みを探索する
ネイティブ iOS アプリケーションは、簡単な Model View Controller (MVC) アーキテクチャを使用します。
• モデルは、Force.com データベーススキーマです。
• ビューは、プロジェクト内の nib ファイルおよび実装ファイルから取得されます。
• コントローラの機能は、iOS SDK クラス、Salesforce Mobile SDK、および各自のアプリケーションを接続するこ
とです。
AppDelegate クラスとルートビューコントローラ
アプリケーションが起動すると、AppDelegate クラスが初めに実行フローを制御します。ログインプロセス
が完了すると、AppDelegate インスタンスからルートビューに制御が移ります。テンプレートアプリケーショ
ンでは、ルートビューコントローラクラスの名前は RootViewController になっています。このクラスは
AppDelegate.m ファイルでアプリケーションのルートビューとなり、ビュー間のナビゲーションを制御する
UINavigationController インスタンスによって組み込まれます。
- (void)setupRootViewController
{
61
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
RootViewController *rootVC = [[RootViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navVC = [[UINavigationController alloc]
initWithRootViewController:rootVC];
self.window.rootViewController = navVC;
}
ただし、カスタマイズするまでは、アプリケーションに他のビューやタッチイベントハンドラは含まれていま
せん。Salesforce にログインし、Salesforce Mobile SDK と REST API を使用して要求を発行し、ルートビューに応答を
表示するのみです。
UITableViewController クラス
RootViewController は、UITableViewController クラスを継承します。継承されたビューに含まれる
テーブルはカスタマイズしないため、nib ファイルまたは xib ファイルは不要です。コントローラクラスは
tableView プロパティにデータを読み込むだけで、ほとんどの表示タスクはスーパークラスが処理します。
ただし、RootViewController は、tableView:cellForRowAtIndexPath: メソッドをコールすることに
より、セルの一部の基本的な書式設定を追加します。新しいセルを作成し、それに汎用的な ID
(@”CellIdentifier”) を割り当て、セルの左側にアイコンを配置し、右側に矢印を追加します。最も重要な
のは、REST 応答オブジェクトから現在の行の Name 値を想定するためのセルの表示ラベルを設定する点です。
次にコードを示します。
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView_ cellForRowAtIndexPath:(NSIndexPath
*)indexPath {
static NSString *CellIdentifier = @"CellIdentifier";
// Dequeue or create a cell of the appropriate type.
UITableViewCell *cell = [tableView_ dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
reuseIdentifier:CellIdentifier] autorelease];
}
//if you want to add an image to your cell, here's how
UIImage *image = [UIImage imageNamed:@"icon.png"];
cell.imageView.image = image;
// Configure the cell to show the data.
NSDictionary *obj = [self.dataRows objectAtIndex:indexPath.row];
cell.textLabel.text = [obj objectForKey:@"Name"];
//this adds the arrow to the right hand side.
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
return cell;
}
62
ネイティブ iOS の開発
ネイティブ iOS アプリケーションを作成する
SFRestAPI 共有オブジェクトと SFRestRequest クラス
RootViewController.viewDidLoad メソッドを確認すると、REST 要求がアプリケーションでどのように作
成および送信されるかがわかります。アプリケーションでは SOQL クエリのリテラル文字列が定義され、
SFRestAPI:requestForQuery: インスタンスメソッドに渡されます。このメソッドをコールするために、
アプリケーションは共有シングルトン SFRestAPI インスタンスにメッセージを送信します。メソッドは、
SOQL クエリをラップする書式設定済みの適切な SFRestRequest オブジェクトを作成し、それを返します。
次に、send:delegate: メッセージを共有 SFRestAPI オブジェクトに送信することで、アプリケーションは
このオブジェクトをサーバに転送します。
//Here we use a query that should work on either Force.com or Database.com
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForQuery:@"SELECT Name
FROM User LIMIT 10"];
[[SFRestAPI sharedInstance] send:request delegate:self];
SFRestAPI クラスは、SFRestRequest インスタンスのファクトリとしての役割を果たします。このクラス
は、要求オブジェクトを簡単に作成するためにコールできる一連の要求メソッドを定義します。必要に応じて
SFRestRequest インスタンスを直接作成することもできますが、ほとんどの場合は手動による作成は不要で
す。
アプリケーションでは、delegate 引数に self が指定されます。これにより、RootViewController クラ
スで実装された代理メソッドに応答を送信するようサーバに指示されます。
SFRestDelegate インターフェース
REST 応答の受け入れを可能にするため、RootViewController では SFRestDelegate インターフェースが
実装されます。このインターフェースでは、4 つメソッド (考えられる応答種別ごとに 1 つ) が宣言されます。
要求に成功すると、request:didLoadResponse: 代理メソッドが実行されます。RootViewController で
request:didLoadResponse: コールバックが受信されると、返されたレコードがデータ行にコピーされ、
Warehouse ビューに表示されたデータが再度読み込まれます。次に、RootViewController クラスで
SFRestDelegate インターフェースを実装するコードを示します。
#pragma mark - SFRestAPIDelegate
- (void)request:(SFRestRequest *)request didLoadResponse:(id)jsonResponse {
NSArray *records = [jsonResponse objectForKey:@"records"];
NSLog(@"request:didLoadResponse: #records: %d", records.count);
self.dataRows = records;
[self.tableView reloadData];
}
- (void)request:(SFRestRequest*)request didFailLoadWithError:(NSError*)error {
NSLog(@"request:didFailLoadWithError: %@", error);
//add your failed error handling here
}
- (void)requestDidCancelLoad:(SFRestRequest *)request {
NSLog(@"requestDidCancelLoad: %@", request);
//add your failed error handling here
}
63
ネイティブ iOS の開発
リスト画面をカスタマイズする
- (void)requestDidTimeout:(SFRestRequest *)request {
NSLog(@"requestDidTimeout: %@", request);
//add your failed error handling here
}
コメントで示されるように、このコピーは、request:didLoadResponse: で代理メソッドが成功した場合に
のみ完全に実装されます。成功以外の応答の場合は、このテンプレートアプリケーションはメッセージをログ
記録するのみです。
リスト画面をカスタマイズする
このチュートリアルでは、Warehouse スキーマ固有のアプリケーションとなるようにルートビューコントロー
ラを変更します。また、Merchandise カスタムオブジェクトから必要なすべての情報を取得できるように、既存
の SOQL クエリを適合させます。
ステップ 1: ルートビューコントローラを変更する
Warehouse 設計にテンプレートプロジェクトを適合させるため、RootViewController クラスの名前を変更し
ましょう。
1. プロジェクトナビゲータで、RootViewController.h ファイルを選択します。
2. エディタで、次の行の「RootViewController」という名前をクリックします。
@interface RootViewController : UITableViewController <SFRestDelegate>{
3. Ctrl+クリックメニューを使用して、[Refactor (再構成)] > [Rename (名前を変更)] を選択します。[Rename Related
Files (関連ファイルの名前を変更)] がオンになっていることを確認します。
4. 「RootViewController」を「WarehouseViewController」に変更します。[Preview (プレビュー)] をクリックします。
Xcode に新しいウィンドウが表示され、左側に「RootViewController」という名前を含むすべてのプロジェクト
ファイルのリストが表示されます。中央のペインには、変更されたファイルごとに、既存のバージョンと
提案された新バージョンとの相違が表示されます。
5. [Save (保存)] をクリックします。
6. リファクタリングする前に自動スナップショットを取得するかどうかを Xcode から尋ねられたら、[Enable
(有効化)] をクリックします。
スナップショットが完了すると Refactoring ウィンドウが非表示になり、リファクタリングされたプロジェクト
に戻ります。RootViewController.h および RootViewController.m というファイル名が、
WarehouseViewController.h および WarehouseViewController.m になりました。プロジェクトコード
内の RootViewController のすべてのインスタンスも、WarehouseViewController に変更されました。
ステップ 2: アプリケーションのルートビューを作成する
ネイティブ iOS テンプレートアプリケーションでは、標準 User オブジェクトから Name 項目を抽出する SOQL ク
エリが作成されます。ただし、このチュートリアルでは、カスタムオブジェクトのレコードを使用します。
[Name (名前)]、[Quantitiy (数量)]、[Price (価格)] 項目を表示する詳細画面は、後から作成します。また、レコード
ID も必要です。
64
ネイティブ iOS の開発
リスト画面をカスタマイズする
カスタム Merchandise__c オブジェクトを操作する SOQL クエリを更新し、詳細画面に必要な項目を取得してみま
しょう。
1. プロジェクトナビゲータで、WarehouseViewController.m を選択します。
2. viewDidLoad メソッドまでスクロールします。
3. ビューの表示名を「Warehouse App」に更新します。次の行を変更します。
self.title = @"Mobile SDK Sample App"
変更後
self.title = @"Warehouse App"
4. 次の行で SOQL クエリを変更します。
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForQuery:@"SELECT Name
FROM User LIMIT 10"];
変更後
SELECT Name, Id, Quantity__c, Price__c FROM Merchandise__c LIMIT 10
ステップ 3: アプリケーションを試す
アプリケーションを作成して実行します。プロンプトが表示されたら、DE 組織にログインします。初期ペー
ジに、次のような画面が表示されます。
65
ネイティブ iOS の開発
詳細画面を作成する
この時点で Merchandise レコードをクリックしても何も起きません。次のチュートリアルでこれを修正します。
詳細画面を作成する
前のチュートリアルで、起動後に最大 10 個の Merchandise レコードを一覧表示するようにテンプレートアプリ
ケーションを変更しました。このチュートリアルでは、詳細ビューおよびコントローラを作成して作業を終了
します。また、リストビューコントローラと詳細ビューコントローラ間の通信も確立します。
ステップ 1: アプリケーションの詳細ビューコントローラを作成する
Warehouse ビューでユーザが Merchandise レコードをタップすると、IBAction はレコード固有の情報を生成し、
この情報を表示する DetailViewController からビューを読み込みます。ただし、このビューはまだ存在し
ないので作成しましょう。
1. [File (ファイル)] > [New (新規)] > [File... (ファイル...)] > [Cocoa Touch] > [Objective-C class (Objective-C クラス)] を
クリックします。
2. UIViewController をサブクラス化する DetailViewController という名前の新しい Objective-C クラス
を作成します。[With XIB for user interface (ユーザインターフェースに XIB を使う)] がオンになっていること
を確認します。
66
ネイティブ iOS の開発
詳細画面を作成する
3. [Next (次へ)] をクリックします。
4. [Groups (グループ)] ドロップダウンメニューの Mobile Warehouse アプリケーションのクラスグループに新し
いクラスを配置します。
Xcode により、Classes フォルダに 3 つの新しいファイル (DetailViewController.h、
DetailViewController.m、DetailViewController.xib) が作成されます。
5. プロジェクトナビゲータで DetailViewController.m を選択し、次のメソッド宣言を削除します。
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
このアプリケーションでは、NIB ファイルまたはバンドルを指定しないため、この初期化メソッドは必要あ
りません。
6. プロジェクトナビゲータで DetailViewController.xib を選択し、Interface Builder を開きます。
7.
[Utilities (ユーティリティ)] ビュー
から、3 つの表示ラベル、2 つのテキスト項目、および 1 つ
のボタンをビューレイアウトにドラッグします。次のような画面になるようにコントロールを並び替えて
サイズを変更します。
67
ネイティブ iOS の開発
詳細画面を作成する
最上部の表示ラベルを今後名前表示ラベルと呼ぶことにします。この表示ラベルは動的です。次のチュー
トリアルでは、実行時にこれを適切な値にリセットするコントローラコードを追加します。
8. [Attributes (属性)] インスペクタで、価格および数量の静的な表示ラベルの表示テキストに下図の表示値を設
定します。Interface Builder で各表示ラベルを個別に選択し、[Text (テキスト)] ドロップダウンメニューの下に
ある名前のない入力項目で表示テキストを指定します。
メモ: 必要に応じて表示ラベルの幅を調整し、表示テキストがすべて表示されるようにします。
9. [Attributes (属性)] インスペクタで、更新ボタンの表示テキストを下図の表示値に設定します。Interface Builder
でボタンを選択し、[Title (タイトル)] ドロップダウンメニューの下にある名前のない入力項目でその表示テ
キストを指定します。
68
ネイティブ iOS の開発
詳細画面を作成する
10. 構築して実行し、エラーを確認します。まだ変更は表示されません。
詳細ビューの設計には、[Price (価格)] 項目、[Quantitiy (数量)] 項目、およびレコードの数量を更新するためのボタ
ンが表示されています。ただし、現時点では何も機能しません。次のステップでは、この設計を Warehouse レ
コードに接続する方法を学習します。
ステップ 2: DetailViewController を設定する
ビュー要素とそれらのビューコントローラ間の接続を確立するには、Xcode Interface Builder を使用して、UI 要素
とコード要素を接続します。
インスタンスプロパティを追加する
1. DetailViewController.h に、WarehouseViewController によって渡される値を格納するプロパティ
(名前、数量、価格、ID) を作成します。これらのプロパティを @interface ブロック内に配置します。次
の名前を使用して、それぞれの nonatomic および strong を宣言します。
@interface DetailViewController : UIViewController
@property
@property
@property
@property
(nonatomic,
(nonatomic,
(nonatomic,
(nonatomic,
strong)
strong)
strong)
strong)
NSNumber
NSNumber
NSString
NSString
*quantityData;
*priceData;
*nameData;
*idData;
@end
2. DetailViewController.m の @implementation タグの直後に各プロパティを合成します。
@implementation DetailViewController
@synthesize
@synthesize
@synthesize
@synthesize
nameData;
quantityData;
priceData;
idData;
IBOutlet 変数を追加する
IBOutlet メンバー変数を使用すると、コントローラが各非静的コントロールを管理できます。手動でこれら
をコーディングする代わりに、Interface Builder を使用して作成できます。Interface Builder には、便利な横並びの
69
ネイティブ iOS の開発
詳細画面を作成する
編集ウィンドウがあるアシスタントエディタが用意されています。アシスタントエディタ用の領域を確保する
には、使用していないコントロールを非表示にして画面領域を再要求します。
1. プロジェクトナビゲータで、DetailViewController.xib ファイルをクリックします。
DetailViewController.xib ファイルが標準エディタで開きます。
2.
[View (表示)] ツールバー
の [Hide or Show Navigator (ナビゲータを表示/非表示)] をクリックして、
ナビゲータを非表示にします。または、Xcode メニューの [View (表示)] > [Navigators (ナビゲータ)] > [Hide
Navigators (ナビゲータを非表示)] を選択することもできます。
3.
[Editor (エディタ)] ツールバー
の [Show the Assistant editor (アシスタントエディタを表示)] をク
リックして、アシスタントエディタを開きます。または、Xcode メニューの [View (表示)] > [(Assistant Editor
(アシスタントエディタ)] > [Show Assistant Editor (アシスタントエディタを表示)] を選択することもできます。
標準エディタで DetailViewController.xib を開いたため、アシスタントエディタには
DetailViewController.h ファイルが表示されます。アシスタントエディタは、一緒に使用する可能性
の最も高いファイルを推測します。別のファイルを開く必要がある場合、アシスタントエディタの右上隅
にある [Related Files (関連ファイル)] コントロールをクリックします。
4. DetailViewController.h のインターフェースブロックの上部に、空の中括弧のペアを追加します。
@interface DetailViewController : UiViewController <SFRestDelegate>
{
70
ネイティブ iOS の開発
詳細画面を作成する
}
5. 標準エディタで、Ctrl キーを押しながら [Price (価格)] テキスト項目コントロールをクリックし、
DetailViewController.h ファイルの新しい中括弧ブロックにドラッグします。
6. ポップアップダイアログボックスで、新しいアウトレット _priceField に名前を付けて [Connect (接続)]
をクリックします。
7. [Quantity (数量)] テキスト項目についてステップ 2 と 3 を繰り返し、そのアウトレット _quantityField に
名前を付けます。
8. 名前表示ラベルについてステップ 2 と 3 を繰り返し、そのアウトレット _nameLabel に名前を付けます。
これで、インターフェースコードに次のブロックが含まれるようになりました。
@interface
{
__weak
__weak
__weak
}
DetailViewController : UIViewController
IBOutlet UITextField *_priceField;
IBOutlet UITextField *_quantityField;
IBOutlet UILabel *_nameLabel;
更新ボタンイベントを追加する
1. Interface Builder で、[更新] ボタンを選択し、[Connections (接続)] インスペクタ
を開きます。
2. [Connections (接続)] インスペクタで、[Touch Up Inside (タッチアップ (内))] の横にある円を選択し、
DetailViewController.h ファイルにドラッグします。閉じ中括弧の下にドロップしてください。
updateTouchUpInside という名前を付けて [接続] をクリックします。
Touch Up Inside イベントは、ユーザが更新ボタンに触れている指をボタン領域内で上げたことを通知します。
この通知を受信するたびにレコードの更新を実行します。
ステップ 3: 指定のイニシャライザを作成する
では、コーディングに取り掛かりましょう。まず、名前、ID、数量、および価格を取得する
DetailViewController に新しいイニシャライザメソッドを追加します。メソッド名は、命名規則に従って
「init」で開始する必要があります。
1. [Show the Standard Editor (標準エディタを表示)] をクリックして、ナビゲータを開きます。
2. この宣言を DetailViewController.h ファイルにある @end マーカーのすぐ上に追加します。
- (id) initWithName:(NSString *)recordName
sobjectId:(NSString *)salesforceId
quantity:(NSNumber *)recordQuantity
price:(NSNumber *)recordPrice;
後で、このメソッドを使用してデータを DetailViewController に渡すように
WarehouseViewController をコーディングします。
71
ネイティブ iOS の開発
詳細画面を作成する
3. DetailViewController.m ファイルを開き、前のステップで作成した署名をファイルの最後にある @end
マーカーのすぐ上にコピーします。
4. 実装ブロックのために、終了を示すセミコロンを中括弧のペアで置き換えます。
- (id) initWithName:(NSString *)recordName
sobjectId:(NSString *)salesforceId
quantity:(NSNumber *)recordQuantity
price:(NSNumber *)recordPrice {
}
5. メソッド本文で、init メッセージをスーパークラスに送信します。戻り値を self に割り当てます。
self = [super init];
この init メッセージで、戻り値として機能する基本的な実装を備えた機能オブジェクトを提供します。
6. スーパークラスの初期化が成功しているかどうかを確認し、成功している場合はメソッド引数を対応する
インスタンス変数に割り当てるためのコードを追加します。最後に、self を返します。
if (self) {
self.nameData = recordName;
self.idData = salesforceId;
self.quantityData = recordQuantity;
self.priceData = recordPrice;
}
return self;
次に、完成したメソッドを示します。
- (id) initWithName:(NSString *)recordName
sobjectId:(NSString *)salesforceId
quantity:(NSNumber *)recordQuantity
price:(NSNumber *)recordPrice {
self = [super init];
if (self) {
self.nameData = recordName;
self.idData = salesforceId;
self.quantityData = recordQuantity;
self.priceData = recordPrice;
}
return self;
}
7. ビューが表示されるたびにコントロールが更新されていることを確認するには、viewDidLoad メソッド実
装の後に新しい viewWillAppear: イベントハンドラを追加します。まず、スーパークラスのメソッドを
コールします。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
72
ネイティブ iOS の開発
詳細画面を作成する
8. プロパティ変数の値を対応する動的なコントロールにコピーします。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[_nameLabel setText:self.nameData];
[_quantityField setText:[self.quantityData stringValue]];
[_priceField setText:[self.priceData stringValue]];
}
9. プロジェクトを構築して実行し、すべてのコーディングが完了していて、コンパイルエラーが発生してい
ないことを確認します。詳細ビューを起動するコードをまだ追加していないため、アプリケーションは最
初の状態と変わらないように見えます。
メモ: initWithName: メソッドで使用される [super init] メッセージは、内部的に [super
initWithNibName:bundle:] をコールします。NIB 名またはバンドルを渡さないため、ここでは [super
init] を使用します。独自のプロジェクトでこれらのリソースを指定する場合、[super
initWithNibName:bundle:] を明示的にコールする必要があります。
ステップ 4: ビューコントローラ間の通信を確立する
Salesforce コンテンツを使用するビューは、SFRestAPI 代理オブジェクトを使用してそのコンテンツを取得し
ます。アプリケーションのすべてのビューを一元管理する代理オブジェクトとして 1 つのビューを指定できま
すが、ビューコントローラ間の正確な通信が必要となります。この練習課題では、WarehouseViewController
と DetailViewController をそれぞれ独自のSFRestAPI 代理オブジェクトとして機能させる少し簡単な方
法を使用します。
WarehouseViewController を更新する
まず、WarehouseViewController を用意して、選択したレコードの数量および価格の値を詳細ビューに渡
し、そのビューを表示しましょう。
1. WarehouseViewController.m の @implementation ブロックの上に次の行を追加します。
#import "DetailViewController.h"
2. #pragma mark – Table view data source マーカーの後にある新しい行で、UITableView 代理メソッ
ドのリストを表示する次の開始テキストを入力します。
- (void)tableView
3. リストから、tableView:didSelectRowAtIndexPath: メソッドを選択します。
4. tableView パラメータの名前を itemTableView に変更します。
- (void)tableView:(UITableView *)itemTableView didSelectRowAtIndexPath:(NSIndexPath
*)indexPath
5. 署名の最後に、開き中括弧 ({) を入力して Enter キーを押し、メソッド実装ブロックにスタブを作成します。
73
ネイティブ iOS の開発
詳細画面を作成する
6. メソッド本文の上部で、標準 iOS コーディングプラクティスごとに、行の選択解除を行う次のコールを追加
します。
[itemTableView deselectRowAtIndexPath:indexPath animated:NO];
7. 次に、選択したデータ行に関連付けられている NSDictionary オブジェクトへのポインタを取得します。
NSDictionary *obj = [self.dataRows objectAtIndex:indexPath.row];
8. メソッド本文の最後で、DetailViewController.initWithName:salesforceId:quantity:price:
メソッドをコールして DetailViewController のローカルインスタンスを作成します。NSDictionary
オブジェクトに保存されているデータを使用して、名前、Salesforce ID、数量、および価格の引数を設定しま
す。完成したコールは次のようになります。
DetailViewController *detailController =
[[DetailViewController alloc] initWithName:[obj objectForKey:@"Name"]
salesforceId:[obj objectForKey:@"Id"]
quantity:[obj objectForKey:@"Quantity__c"]
price:[obj objectForKey:@"Price__c"]];
9. 詳細ビューを表示するには、初期化した DetailViewController を UINavigationController スタッ
クにプッシュするコードを追加します。
[[self navigationController] pushViewController:detailController animated:YES];
これで、UINavigationController スタックを使用して、2 つのビューのセットを処理します。ルート
ビューコントローラは、常にスタックの下部にあります。他のビューを有効化するには、そのコントロー
ラをスタックにプッシュします。ビューを閉じるときに、そのコントローラをポップします。これにより、
その下のビューが再表示されます。
10. アプリケーションを構築して実行します。詳細を表示する Warehouse 項目をクリックします。
更新機能を追加する
これで WarehouseViewController が設定されたので、REST 要求を使用してユーザの更新を Salesforce に送信
するように DetailViewController クラスを変更する必要があります。
1. DetailViewController.h ファイルで、インスタンスメソッドを DetailViewController に追加し、
ユーザが価格および数量の項目を更新できるようにします。このメソッドは、レコード ID、更新する項目
名、新しい数量と価格の値、および更新するオブジェクト名を送信する必要があります。インターフェー
スブロックの後 (@end マーカーのすぐ上) にこの宣言を追加します。
- (void)updateWithObjectType:(NSString *)objectType
objectId:(NSString *)objectId
quantity:(NSString *)quantity
price:(NSString *)price;
メソッドを実装するには、入力値を使用して SFRestRequest オブジェクトを作成し、要求オブジェクト
を SFRestAPI の共有インスタンスに送信します。
74
ネイティブ iOS の開発
詳細画面を作成する
2. DetailViewController.m ファイルの @implementation ブロックの上に次の行を追加します。
#import "SFRestAPI.h"
3. ファイルの最後にある @end マーカーのすぐ上に、updateWithObjectType:objectId:quantity:price:
署名をコピーし、その後に中括弧のペアを追加します。
- (void)updateWithObjectType:(NSString *)objectType
objectId:(NSString *)objectId
quantity:(NSString *)quantity
price:(NSString *)price {
}
4. 実装ブロックで、[Quantitiy (数量)] 項目と [Price (価格)] 項目を格納する新しい NSDictionary オブジェクト
を作成します。このオブジェクトを割り当てるには、目的の項目リストを含む
dictionaryWithObjectsAndKeys: ... NSDictionary クラスメソッドを使用します。
- (void)updateWithObjectType:(NSString *)objectType
objectId:(NSString *)objectId
quantity:(NSString *)quantity
price:(NSString *)price {
NSDictionary *fields = [NSDictionary dictionaryWithObjectsAndKeys:
quantity, @"Quantity__c",
price, @"Price__c",
nil];
}
5. SFRestRequest オブジェクトを作成します。このオブジェクトを割り当てるには、SFRestAPI 共有イン
スタンスで requestForUpdateWithObjectType:objectId:fields: インスタンスメソッドを使用しま
す。
- (void)updateWithObjectType:(NSString *)objectType
objectId:(NSString *)objectId
quantity:(NSString *)quantity
price:(NSString *)price {
NSDictionary *fields = [NSDictionary dictionaryWithObjectsAndKeys:
quantity, @"Quantity__c",
price, @"Price__c",
nil];
SFRestRequest *request =
[[SFRestAPI sharedInstance]
requestForUpdateWithObjectType:objectType
objectId:objectId
fields:fields];
}
75
ネイティブ iOS の開発
詳細画面を作成する
6. 最後に、SFRestAPI 共有インスタンスで send:delegate: をコールして、新しい SFRestRequest オブ
ジェクトをサービスに送信します。この場合、DetailViewController が SFRestDelegate であるた
め、delegate 引数には self を指定してください。
- (void)updateWithObjectType:(NSString *)objectType
objectId:(NSString *)objectId
quantity:(NSString *)quantity
price:(NSString *)price {
NSDictionary *fields = [NSDictionary dictionaryWithObjectsAndKeys:
quantity, @"Quantity__c",
price, @"Price__c",
nil];
SFRestRequest *request =
[[SFRestAPI sharedInstance]
requestForUpdateWithObjectType:objectType
objectId:objectId
fields:fields];
[[SFRestAPI sharedInstance] send:request delegate:self];
}
7. ユーザが [更新] ボタンをタップしたときに updateWithObjectType:objectId:quantity:price: メ
ソッドをコールするように updateTouchUpInside: アクションメソッドを編集します。
- (IBAction)updateTouchUpInside:(id)sender {
// For Update button
[self updateWithObjectType:@"Merchandise__c"
objectId:self.idData
quantity:[_quantityField text]
price:[_priceField text]];}
メモ:
• 追加課題: ユーザが実際に数量の値を変更したときにだけ更新が実行されるようにアプリケーショ
ンを効率化しましょう。
SFRestDelegate を DetailViewController に追加する
もう少しで作業は終了します。REST 要求を発行しましたが、まだ応答を処理するコードを入力する必要があり
ます。
1. DetailViewController.h ファイルを開き、<SFRestDelegate> が含まれるように
DetailViewController インターフェース宣言を変更します。
@interface DetailViewController : UIViewController <SFRestDelegate>
2. WarehouseViewController.m ファイルを開きます。
3. SFRestAPIDelegate セクションをマークする pragma を探します。
#pragma mark - SFRestAPIDelegate
76
ネイティブ iOS の開発
詳細画面を作成する
4. この pragma の下にある 4 つのメソッドを DetailViewController.m ファイルにコピーします。
- (void)request:(SFRestRequest *)request didLoadResponse:(id)jsonResponse {
NSArray *records = [jsonResponse objectForKey:@"records"];
NSLog(@"request:didLoadResponse: #records: %d", records.count);
self.dataRows = records;
[self.tableView reloadData];
}
- (void)request:(SFRestRequest*)request didFailLoadWithError:(NSError*)error {
NSLog(@"request:didFailLoadWithError: %@", error);
//add your failed error handling here
}
- (void)requestDidCancelLoad:(SFRestRequest *)request {
NSLog(@"requestDidCancelLoad: %@", request);
//add your failed error handling here
}
- (void)requestDidTimeout:(SFRestRequest *)request {
NSLog(@"requestDidTimeout: %@", request);
//add your failed error handling here
}
SFRestAPI インターフェースを実装するのに必要なのは、これらのメソッドだけです。このチュートリア
ルでは、エラー、キャンセル、およびタイムアウト条件の単純な処理を保持できます。ただし、
request:didLoadResponse: メソッドは詳細ビューの目的に合わせて変更する必要があります。
UINavigationController スタックを使用して、更新実行後にリストビューに戻りましょう。
5. DetailViewController.m ファイルで、request:didLoadResponse: 代理メソッドの既存のコードを
削除します。その場所に、成功メッセージを記録してすぐにルートビューコントローラに戻るコードを追
加します。修正したメソッドは次のようになります。
- (void)request:(SFRestRequest *)request didLoadResponse:(id)jsonResponse {
NSLog(@"1 record updated");
[self.navigationController popViewControllerAnimated:YES];
}
6. アプリケーションを構築して実行します。Warehouse ビューで、いずれかの項目をクリックします。これ
で、詳細ビューにアクセスしてその数量を編集できますが、キーボードを非表示にしたいときに非表示に
ならないという問題があります。アプリケーションが完全に機能するには、もう少し工夫が必要です。
キーボードを非表示にする
画面のテキスト入力コントロールがタッチイベントに応答している限り、iOS キーボードは表示されたままに
なります。これには、Interface Builder の「First Responder (ファーストレスポンダ)」設定が関与しています。この
簡単なアプリケーションではデフォルトの UIKit の動作のみを使用しているため、ファーストレスポンダを設
定していません。その結果、iOS はビューの入力コントロールをファーストレスポンダとしてみなす可能性が
あります。どのコントロールも、キーボードを非表示にするように iOS に明示的に指示していない場合、キー
ボードは有効化されたままになります。
77
ネイティブ iOS の開発
詳細画面を作成する
この問題は、タッチ対応編集コントロールにファーストレスポンダを放棄させることで解決できます。
1. DetailViewController.h の中括弧ブロックの下に、引数を取らず void を返す hideKeyboard という
名前の新しいインスタンスメソッドを追加します。
- (void)hideKeyboard;
2. 実装ファイルで、このメソッドを実装して resignFirstResponder メッセージをビューの各タッチ対応
編集コントロールに送信します。
- (void)hideKeyboard {
[_quantityField resignFirstResponder];
[_priceField resignFirstResponder];
}
残りの問題は、hideKeyboard メソッドをどこでコールするかだけです。ユーザがテキスト入力コント
ロールの外側をタップしたらキーボードが非表示になるようにします。色々なイベントを試すことができ
ると思いますが、どのような環境でもバックグラウンドのタッチを確実にキャッチできるのは [UIResponder
touchesEnded:withEvent:] だけです。
3. このイベントは、DetailViewController が継承するクラスですでに宣言されているため、
DetailViewController.h ファイルで再度宣言する必要はありません。代わりに、
DetailViewController.m ファイルで、メソッド本文の外側の新しい行に次の不完全なコードを入力し
ます。
- (void)t
DetailViewController クラス階層の一致するインスタンスメソッドのリストがポップアップメニュー
で表示されます。
メモ: ポップアップメニューが表示されない場合、次に説明するコードを入力します。
4. ポップアップメニューで、touchesEnded:withEvent: メソッドを強調表示して Enter キーを押します。
エディタによって、完全なメソッド署名がファイルに入力されます。開き括弧を入力して Enter キーを押
すだけで、エディタによってスタブメソッドが完成します。このスタブ内で、hideKeyboard メッセージ
を self に送信します。
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self hideKeyboard];
}
通常、イベントハンドラでは、独自のコードを追加する前にスーパークラスバージョンをコールすること
が想定されています。ただし、「iOS Developer Library」に説明されているように、この場合、スーパーコー
ルを除外するのが一般的な使用パターンです。唯一「わかっていること」は、次のコードを含む他のタッ
チイベントハンドラを実装する必要もあるということです。
– touchesBegan:withEvent:
– touchesMoved:withEvent:
– touchesCancelled:withEvent:
これは空のスタブ実装を追加するだけで済みます。
78
ネイティブ iOS の開発
詳細画面を作成する
5. Xcode エディタを使用して、touchesEnded: スタブを追加したときと同じ方法でこれらのスタブを追加し
ます。最終的なコードが次のようになっていることを確認します。
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{
[self hideKeyboard];
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event{
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{
}
viewWillAppear を使用したクエリの更新
viewDidLoad メソッドでは、最初に読み込まれたときのビューを設定できます。WarehouseViewController
実装では、リストビューと詳細ビューの両方を入力する REST API クエリがこのメソッドにあります。ただし、
WarehouseViewController はルートビューを表しているため、viewDidLoad 通知はビューの初期化時に 1
回しかコールされません。これはどういう意味でしょうか? ユーザが詳細ビューで数量を更新してリストビュー
に戻っても、クエリは更新されません。そのため、詳細ビューの同じレコードに戻っても、ユーザが期待する
更新された値は表示されません。
クエリを処理するには、別のメソッドが必要です。viewWillAppear メソッドは、そのビューが表示される
たびにコールされます。このメソッドを WarehouseViewController に追加して、SOQL クエリをそこに移動
しましょう。
1. WarehouseViewController.m ファイルの viewDidLoad 実装の後に次のコードを追加します。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
}
2. viewDidLoad メソッドから次の行をカットして、viewWillAppear: メソッドの super へのコールの後
に貼り付けます。
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForQuery:@"SELECT Name,
ID,
Price__c, Quantity__c FROM Merchandise__c LIMIT 10"];
[[SFRestAPI sharedInstance] send:request delegate:self];
最終的な viewDidLoad および viewWillAppear: メソッドは次のようになります。
- (void)viewDidLoad{
[super viewDidLoad];
self.title = @"Warehouse App";
}
79
ネイティブ iOS の開発
iOS ネイティブサンプルアプリケーション
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
//Here we use a query that should work on either Force.com or Database.com
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForQuery:@"SELECT Name,
ID,
Price__c, Quantity__c FROM Merchandise__c LIMIT 10"];
[[SFRestAPI sharedInstance] send:request delegate:self];
}
viewWillAppear: メソッドは、ユーザがリストビューに戻るたびにクエリを更新します。後でユーザが詳細
ビューに再度アクセスすると、リストビューコントローラは、更新されたデータで詳細ビューを更新します。
ステップ 5: アプリケーションを試す
1. アプリケーションを構築し、iPhone エミュレータで実行します。すべて適切に行った場合、Warehouse 画面
の Merchandise レコードをクリックしたときに詳細ページが表示されます。
2. レコードの数量と価格を更新します。値を編集した後で詳細ビューの [更新] ボタンをクリックしてくださ
い。詳細ビューに戻ると、更新された値が表示されます。
3. DE 組織にログインして、ブラウザ UI でレコードを表示し、更新された値を確認します。
iOS ネイティブサンプルアプリケーション
Xcode プロジェクトのテンプレートアプリケーションを実行するで作成したアプリケーション自体はサンプル
アプリケーションですが、その実行内容は SOQL クエリを発行し、結果を返すのみです。ネイティブの iOS サン
プルアプリケーションには、独自のアプリケーションで確認および操作できる多くの機能が含まれています。
• RestAPIExplorer では、ネイティブのすべての REST API ラッパーが実行されます。これは、
native/SampleApps/RestAPIExplorer の Mobile SDK for iOS にあります。
• NativeSqlAggregator には、SQL の集約例と、ネイティブ SmartStore の実装が表示されます。このサンプルア
プリケーションは、native/SampleApps/NativeSqlAggregator の SDK for iOS にあります。
• FileExplorer には、Files API と、その基盤となる MKNetwork ネットワーク機能強化が示されます このサンプル
アプリケーションは、native/SampleApps/FileExplorer の SDK for iOS にあります。
• SmartSyncExplorerには、iOS 上でのネイティブ SmartSync ライブラリの機能が示されます。このサンプルアプ
リケーションは、native/SampleApps/SmartSyncExplorer の Mobile SDK for iOS にあります。
80
第4章
トピック:
ネイティブ Android の開発
Salesforce Mobile SDK には、Android でネイティブモバイルアプリケーションを開発する
ためのライブラリおよびサンプルプロジェクトが用意されています。
•
Android ネイティブ
クイックスタート
Android のネイティブ SDK では、次の 2 つの主要な機能が提供されます。
•
ネイティブ Android
の要件
• OAuth2 ログインプロセスの自動化。これにより、プロセスをアプリケーションに
統合しやすくなります。
•
Android プロジェク
トの作成
• Salesforce REST API へのアクセス。アクセスを簡略化するユーティリティクラスが
使用されます。
•
Eclipse でのサンプ
ルプロジェクトの
設定
Android Salesforce Mobile SDK には、ネイティブアプリケーションのサンプルがいくつか
含まれています。また、新しいアプリケーションをすばやく作成する ant ターゲッ
トも提供されます。
•
ネイティブ Android
アプリケーション
の開発
•
チュートリアル: ネ
イティブ Android
Warehouse アプリ
ケーションの作成
•
Android ネイティブ
サンプルアプリ
ケーション
81
ネイティブ Android の開発
Android ネイティブクイックスタート
Android ネイティブクイックスタート
すばやく開始する手順は、次のとおりです。
1. ネイティブ Android 要件をすべて満たしていることを確認します。
2. Mobile SDK for Android をインストールします。
3. コマンドラインで、新しい Android プロジェクトを作成する forcedroid アプリケーションを実行し、Eclipse ま
たはコマンドラインからそのアプリケーションを実行します。
4. Eclipse でサンプルプロジェクトを設定します。
ネイティブ Android の要件
Mobile SDK 3.0 Android の開発には、次のソフトウェアが必要です。
• Java JDK 6 以降 — http://www.oracle.com/downloads。
メモ: Android Lollipop には Java JDK 7 以降が必要です。
• Apache Ant 1.8 以降 — http://ant.apache.org。
• Android SDK 4.2.2 (API レベル 17) 以降 — Mobile SDK ハイブリッドアプリケーションのデフォルトの Android SDK
バージョンは 4.4 (API レベル 19) です。
• Android SDK Tools バージョン 21 以降 —http://developer.android.com/sdk/installing.html。
メモ: 最良の結果を得るには、対象バージョンだけでなく、Android SDK の以前のすべてのバージョン
もインストールします。
• Eclipse — https://www.eclipse.org。サポートされている Eclipse の最小バージョンについては、Android
開発ツールに関する Web サイトを参照してください。
• Eclipse バージョン 21 以降用の Android ADT (Android 開発ツール) プラグイン —
http://developer.android.com/sdk。
• アプリケーションをエミュレータで実行するには、Platform 4.2 以降を対象とする Android 仮想デバイス (AVD)
を少なくとも 1 つ設定する必要があります。Eclipse での AVD の設定方法については、
http://developer.android.com/guide/developing/devices/managing-avds.htmlの手順を参照
してください。
Salesforce 側には、以下も必要です。
• Salesforce Mobile SDK 3.0 for Android。「iOS のインストール」を参照してください。
• 接続アプリケーションが存在する Salesforce Developer Edition 組織。
SalesforceSDK プロジェクトは、Android 4.2 (Jellybean) ライブラリを使用して作成されます。
Android プロジェクトの作成
新しいアプリケーションを作成するには、コマンドラインで forcedroid をもう一度使用します。アプリケーショ
ンを設定する方法は 2 つあります。
82
ネイティブ Android の開発
Android プロジェクトの作成
• forcedroid アプリケーションのプロンプトで対話形式でアプリケーションオプションを設定する。
• 直接コマンドラインでアプリケーションオプションを指定する。
ビデオチュートリアルについては、次の各ページを参照してください。
• 「Installing Salesforce Mobile SDK For Android On Windows」(Windows への Salesforce Mobile SDK For Android のインストー
ル) (http://www.salesforce.com/_app/video/developer/help/MobileSDK_part1.jsp)
• 「Creating Native Android Apps With Salesforce Mobile SDK」(Salesforce Mobile SDK を使用したネイティブ Android アプ
リケーションの作成) (http://www.salesforce.com/_app/video/developer/help/MobileSDK_part2.jsp)
対話形式でのアプリケーションオプションの指定
対話形式でアプリケーションオプションを入力するには、次のいずれかを実行します。
• Mobile SDK をグローバルにインストールした場合は、「forcedroid create」と入力する。
• Mobile SDK をローカルにインストールした場合は、「<forcedroid_path>/node_modules/.bin/forcedroid
create」と入力する。
forcedroid ユーティリティにより、各設定オプションが表示されます。
アプリケーションオプションの直接指定
必要に応じて、コマンドラインから直接 forceios パラメータを指定できます。使用方法に関する情報を表示す
るには、引数を指定せずに「forcedroid」と入力します。次のように使用可能なオプションのリストが表示
されます。
$ node_modules/.bin/forcedroid
Usage:
forcedroid create
--apptype=<Application Type> (native, hybrid_remote, hybrid_local)
--appname=<Application Name>
--targetdir=<Target App Folder>
--packagename=<App Package Identifier> (com.my_company.my_app)
--targetandroidapi=<Target API> (e.g. 21 for Lollipop = Only required/used for ‘native’)
--startpage=<Path to the remote start page> (/apex/MyPage — Only required/used for
'hybrid_remote')
[--usesmartstore=<Whether or not to use SmartStore/SmartSync> ('yes' or 'no', ‘no’ by
default -- Only required/used for ‘native’)]
この情報を使用して、「forcedroid create」と入力してからオプションおよび値を入力します。次に例を
示します。
$ node_modules/.bin/forcedroid create --apptype="native" --appname="packagetest"
--targetdir="PackageTest" --packagename="com.test.my_new_app"
Eclipse でのアプリケーションのインポートおよび作成
Eclipse エディタで新しいアプリケーションを作成して実行する手順は、次のとおりです。
1. Eclipse を起動し、ワークスペースディレクトリとしてターゲットディレクトリを選択します。
83
ネイティブ Android の開発
Android プロジェクトの作成
2. [Eclipse] > [Preferences (個人設定)] を選択し、[Android] セクションを選択して、Android SDK の場所がまだ設定
されていなければ入力します。
3. [OK] をクリックします。
4. [File (ファイル)] > [Import (インポート)] を選択し、[General (一般)] > [Existing Projects into Workspace (既存のプ
ロジェクトをワークスペースへ)] を選択します。
5. [Next (次へ)] をクリックします。
6. ルートディレクトリとして forcedroid/native ディレクトリを指定します。表示されるリストの横にあ
る [Deselect All (すべて選択解除)] をクリックし、リストを参照して SalesforceSDK プロジェクトおよび Cordova
プロジェクトを選択します。
7. –use_smartstore=yes を設定する場合、SmartStore プロジェクトも選択します。
8. [Import (インポート)] をクリックします。
9. ステップ 4 ~ 8 を繰り返します。ステップ 6 で、ターゲットディレクトリをルートとして選択し、新しいプ
ロジェクトのみを選択します。
プロジェクトのインポートが完了したら、Eclipse によって自動的にワークスペースが作成されます。このプロ
セスには数分かかる場合があります。ステータスバーにエラーが表示されていなければ、プロジェクトを実行
できます。
1. Eclipse ワークスペースで、Ctrl キーを押しながらプロジェクトをクリックするか、プロジェクトを右クリッ
クします。
2. ポップアップメニューから、[Run As (別のユーザとして実行)] > [Android Application (Android アプリケーショ
ン)] を選択します。
Eclipse によってエミュレータまたは接続されている Android デバイスでアプリケーションが起動します。
コマンドラインからのアプリケーションの作成および実行
コマンドラインからコマンドプロンプトに戻ると、プロジェクトを設定およびクリーンアップするための
Android ユーティリティの実行手順が forcedroid スクリプトにより出力されます。コマンドラインからアプリケー
ションを作成および実行する場合にのみこれらの手順を実行します。
1. 新しいアプリケーションを作成する前に、コマンドプロンプトで次のコマンドを実行して SalesforceSDK プロ
ジェクトを構築します。
cd $SALESFORCE_SDK_DIR/libs/SalesforceSDK
$ANDROID_SDK_DIR/tools/android update project -p . -t <id>
ant clean debug
ここで、SALESFORCE_SDK_DIR は SDK インストールディレクトリを、ANDROID_SDK_DIR は Android SDK
ディレクトリを指し示しています。
メモ: -t <id> パラメータは、対象の Android バージョンの API レベルを指定します。システムにイン
ストールされている API バージョンの ID を確認するには、android.bat list targets を使用しま
す。サポートされている API レベルは、「ネイティブ Android の要件」を参照してください。
84
ネイティブ Android の開発
Eclipse でのサンプルプロジェクトの設定
2. コマンドプロンプトで次のコマンドを実行して SmartStore プロジェクトを構築します。
cd $SALESFORCE_SDK_DIR/libs/SmartStore
$ANDROID_SDK_DIR/tools/android update project -p . -t <id>
ant clean debug
ここで、SALESFORCE_SDK_DIR は SDK インストールディレクトリを、ANDROID_SDK_DIR は Android SDK
ディレクトリを指し示しています。
3. 新しいアプリケーションを構築するには、コマンドプロンプトで次のコマンドを実行します。
cd <your_project_directory>
$ANDROID_SDK_DIR/tools/android update project -p . -t <id>
ant clean debug
ここで、ANDROID_SDK_DIR は Android SDK ディレクトリを指し示しています。
4. エミュレータが実行されていない場合は、Android AVD マネージャを使用して起動します。デバイスを使用
している場合は、接続します。
5. コマンドプロンプトで次のコマンドを入力します。
ant installd
メモ: 次の警告は無視しても問題ありません。
It seems that there are sub-projects. If you want to update them please use the
--subprojects parameter.
作成した Android プロジェクトには、作成および実行が可能な簡単なアプリケーションが含まれます。
関連トピック:
forcedroid パラメータ
Eclipse でのサンプルプロジェクトの設定
コピーしたリポジトリには、実行可能な他のサンプルアプリケーションがあります。これらを Eclipse にイン
ポートする手順は、次のとおりです。
1. Eclipse を起動し、ワークスペースディレクトリとしてターゲットディレクトリを選択します。
2. [Window (ウィンドウ)] > [Preferences (個人設定)] を選択し、[Android] セクションを選択して、Android SDK の
場所を入力します (まだ実行していない場合)。[OK] をクリックします。
3. [File (ファイル)] > [Import (インポート)] を選択し、[General (一般)] > [Existing Projects into Workspace (既存のプ
ロジェクトをワークスペースへ)] を選択します。
4. [Next (次へ)] をクリックします。
5. ルートディレクトリとして forcedroid/native を選択し、Android プロジェクトファイルに示すプロジェ
クトをインポートします。
85
ネイティブ Android の開発
Android プロジェクトファイル
Android プロジェクトファイル
forcedroid ディレクトリには、2 つの重要なライブラリプロジェクトがあります。
• libs/SalesforceSDK — Salesforce Mobile SDK プロジェクト。OAuth2 および REST API コールのサポートを提供
します。
• external/cordova — Cordova ライブラリ。このライブラリは、ネイティブアプリケーションとハイブリッ
ドアプリケーションの作成に必要です。
ネイティブ Android アプリケーションの開発
Salesforce Mobile SDK のネイティブ Android バージョンでは、ホストデバイスの Android オペレーティングシステム
を直接使用するリッチモバイルアプリケーションを作成できます。このようなアプリケーションを作成するに
は、Java および Android 開発を十分に理解し、Mobile SDK ネイティブクラスを使用するコードを記述できる必要
があります。
Android アプリケーションの構造
通常、Mobile SDK を使用するネイティブ Android アプリケーションには、次のクラスとアクティビティが必要に
なります。
• android.app.Application を拡張するアプリケーションエントリポイントクラス
• android.app.Activity を拡張する 1 つ以上のアクティビティ
Mobile SDK では、次の作業を実行します。
• android.app.Application を拡張するスタブクラスを作成する。
• onCreate() を Application スタブクラスに実装して SalesforceSDKManager.initNative() をコー
ルする。
• SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity を拡張す
る。この拡張は省略可能ですが、実行することをお勧めします。
最上位レベルの SalesforceSDKManager クラスは、パスコードを使用するアプリケーションにはパスコード
機能を実装し、パスコードを使用しないアプリケーションには空白を入力します。また、ログインのフェーズ
を設定したり、ログアウト後にクリーンアップしたり、システムレベルアカウントが削除されたときにアプリ
ケーションに情報を通知する特殊なイベントウォッチャを提供したりします。OAuth プロトコルは、内部クラ
スで自動的に処理されます。
SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity クラスは、
アプリケーションの一時停止および再開イベントや関連するパスコード管理を自由に処理できます。アプリ
ケーションのメインアクティビティだけでなくすべてのアクティビティで、これらのいずれかのクラスを拡張
することをお勧めします。アクティビティで別の基本クラスを使用する場合、SalesforceActivity にある
一時停止および再開プロトコルを自分で置き換える必要があります。
アクティビティ内で、Salesforce REST API をコールして Salesforce オブジェクトを操作します。Mobile SDK には、REST
要求および応答フローを簡略化する com.salesforce.androidsdk.rest パッケージが用意されています。
ユーザインターフェースレイアウト、画像サイズ、文字列、および XML ファイルのその他のリソースを定義し
てカスタマイズします。SDK は、内部的に R クラスインスタンスを使用して、リソースを取得および操作しま
86
ネイティブ Android の開発
Android アプリケーションの構造
す。ただし、クライアントアプリケーションは Mobile SDK のリソースに直接アクセスできるため、これらの機
能を管理するためにコードを記述する必要はありません。
87
ネイティブ Android の開発
ネイティブ API パッケージ
ネイティブ API パッケージ
Salesforce Mobile SDK では、ネイティブ Android API が Java パッケージにグループ化されています。これらのパッ
ケージの概要と要点については、「Android パッケージおよびクラス」 (ページ 361)を参照してください。
ネイティブクラスの概要
この Mobile SDK ネイティブクラスの概要では、各クラスの関連する詳細や必要なクラスがどこにあるのかにつ
いて説明します。
SalesforceSDKManager クラス
SalesforceSDKManager クラスは、Salesforce Mobile SDK を使用するすべてのネイティブ Android アプリケーショ
ンのエントリポイントです。このクラスは次のメカニズムを提供します。
• ログインおよびログアウト
• パスコード
• ユーザデータの暗号化および復号化
• 文字列変換
• ユーザエージェントアクセス
• アプリケーションの終了
• アプリケーションのクリーンアップ
initNative() メソッド
起動時に、静的 initNative() メソッドをコールして、シングルトン SalesforceSDKManager オブジェク
トを初期化します。このメソッドには次の 4 つの引数があります。
パラメータ名
説明
applicationContext
アプリケーションのコンテキストを説明する Context
のインスタンス。Application 拡張クラスでは、
コールを getApplicationContext() に渡してこの
パラメータを満たすことができます。
keyImplementation
KeyInterface Mobile SDK インターフェースの実装の
インスタンス。このインターフェースを実装する必要
があります。
mainActivity
メインアクティビティを表示するクラスの記述子。メ
インアクティビティは、ログイン後に最初に表示され
るアクティビティです。
loginActivity
(省略可能) カスタム LoginActivity クラスのクラス
記述子。
88
ネイティブ Android の開発
ネイティブクラスの概要
次に、TemplateApp の例を示します。
SalesforceSDKManager.initNative(getApplicationContext(), new KeyImpl(), MainActivity.class);
この例では、KeyImpl は、KeyInterface のアプリケーションの実装です。MainActivity は、
SalesforceActivity をサブクラス化し、ここではログイン後に最初にコールされるアクティビティとして
指定されています。
logout() メソッド
SalesforceSDKManager.logout() メソッドは、ユーザデータをクリアします。たとえば、ユーザ固有の独
自リソースを取り入れたが、次のユーザセッションには保持したくないとします。SmartStore は、ログアウト
時にユーザデータおよびアカウント情報を自動的に破棄します。
クリーンアップ後 (推奨) に、メソッド上書きのどこかでスーパークラスメソッドを常にコールします。次に、
擬似コード例を示します。
@Override
public void logout(Activity frontActivity) {
// Clean up all persistent and non-persistent app artifacts
// Call superclass after doing your own cleanup
super.logout(frontActivity);
}
getLoginActivityClass() メソッド
このメソッドは、ログインアクティビティの記述子を返します。ログインアクティビティは、Salesforce サーバ
がログインダイアログを提供するために使用する WebView を定義します。
getUserAgent() メソッド
Mobile SDK は、実行時にアプリケーションのバージョン設定情報を公開するためのユーザエージェント文字列
を作成します。このユーザエージェントの形式は次のようになります。
SalesforceMobileSDK/<salesforceSDK version> android/<android OS version> appName/appVersion
<Native|Hybrid>
次に、実際の例を示します。
SalesforceMobileSDK/2.0 android mobile/4.2 RestExplorer/1.0 Native
実行時にユーザエージェントを取得するには、SalesforceSDKManager.getUserAgent() メソッドをコー
ルします。
isHybrid() メソッド
Mobile SDK アプリケーションで、ネイティブクライアントとハイブリッドクライアントの両方を提供するよう
に設計されたライブラリを作成するとします。コールするアプリケーションのタイプに応じてライブラリコー
ドが内部的に切り替わりますが、実行時に何らかの方法でアプリケーションタイプを判断する必要がありま
す。コードでコール元アプリケーションタイプを判断するには、boolean 型の
89
ネイティブ Android の開発
ネイティブクラスの概要
SalesforceSDKManager.isHybrid() メソッドをコールします。true はハイブリッド、false はネイティブを
意味します。
KeyInterface インターフェース
KeyInterface は、実装して SalesforceSDKManager.initNative() メソッドに渡す必須のインターフェース
です。
getKey() メソッド
Base64 でエンコードされた暗号化キーを getKey() 抽象メソッドから返す必要があります。Encryptor.hash()
および Encryptor.isBase64Encoded() ヘルパーメソッドを使用して、適切なキーを生成します。Mobile SDK
は、キーを使用してアプリケーションデータおよびアカウント情報を暗号化します。
PasscodeManager クラス
PasscodeManager クラスは、パスコードの暗号化を管理し、必要に応じてパスコードページを表示します。
また、モバイルポリシーを読み込み、ローカルにキャッシュします。このクラスはすべてのパスコード関連の
アクティビティを処理するために内部的に使用されます。これにより、ユーザのコーディングは最小限に抑え
られます。一般的に、アプリケーションは次の 3 つの PasscodeManager メソッドのみをコールします。
• public void onPause(Activity ctx)
• public boolean onResume(Activity ctx)
• public void recordUserInteraction()
これらのメソッドは、次の要件を満たすネイティブアクティビティクラスでコールされる必要があります。
• パスコードを必要とするアプリケーション内に存在している。
• SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity を拡張し
ない。
SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity を拡張する
任意のアクティビティでこの実装を自由に取得できます。
onPause() および onResume()
これらのメソッドは、ユーザがアプリケーションを一時停止および再開したときのパスコードのダイアログ
ボックスを処理します。アクティビティクラスの一致するメソッドでこれらの各メソッドをコールします。た
とえば、SalesforceActivity.onPause() は、スーパークラスをコールする前にクラス記述子を引数とし
て渡し、PasscodeManager.onPause() をコールします。
@Override
public void onPause() {
passcodeManager.onPause(this);
super.onPause();
}
90
ネイティブ Android の開発
ネイティブクラスの概要
PasscodeManager.onResume() メソッドの boolean 型の戻り値を他のアクションを再開するための条件とし
て使用します。アプリケーションの onResume() の実装では、PasscodeManager バージョンをコールする
前にスーパークラスメソッドをコールします。次に例を示します。
@Override
public void onResume() {
super.onResume();
// Bring up passcode screen if needed
passcodeManager.onResume(this);
}
recordUserInteraction()
このメソッドは、最近のユーザ操作の大部分のタイムスタンプを保存します。アクティビティの
onUserInteraction() メソッドで PasscodeManager.recordUserInteraction() をコールします。次
に例を示します。
@Override
public void onUserInteraction() {
passcodeManager.recordUserInteraction();
}
Encryptor クラス
Encryptor ヘルパークラスは、SDK で必要なハッシュを使用して文字列の暗号化および復号化を行う静的ヘ
ルパーメソッドを提供します。Mobile SDK で使用されるすべてのキーは Base64 でエンコードされている必要が
あるとうことを、ネイティブアプリケーションが認識していることが重要です。他の暗号化パターンは使用で
きません。ハッシュを作成して、正しいエンコードを使用していることを確認する場合は、Encryptor クラ
スを使用します。
大部分の Encryptor メソッドは内部で使用されますが、このユーティリティは必要に応じてアプリケーショ
ンで自由に使用できます。たとえば、アプリケーションで独自のデータベースを実装する場合、制限のない暗
号化および復号化ツールとして Encryptor を使用できます。
SalesforceActivity クラス、SalesforceListActivity クラス、および
SalesforceExpandableListActivity クラス
SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity は、ネイティ
ブ SDK アクティビティの骨組みとなる基本クラスです。これらは、それぞれ android.app.Activity、
android.app.ListActivity、android.app.ExpandableListActivity を拡張します。
これらの各クラスでは、PasscodeManager コールを自由に実装できます。アプリケーションでパスコードを
現在使用していない場合でも、可能であればすべてのアプリケーションのアクティビティでこれらのいずれか
のクラスを拡張することをお勧めします。
パスコードで保護されているアプリケーションの場合:いずれかのアクティビティで SalesforceActivity、
SalesforceListActivity、SalesforceExpandableListActivity を拡張していない場合、これらの各
アクティビティにパスコードプロトコルを少し追加する必要があります。「パスコードの使用」を参照してく
ださい。
91
ネイティブ Android の開発
ネイティブクラスの概要
これらの各アクティビティクラスには、次の 1 つの抽象メソッドが含まれています。
public abstract void onResume(RestClient client);
このメソッドは、クラスによって実装される Activity.onResume() メソッドをオーバーロードします。ク
ラスメソッドは、RestClient インスタンスをインスタンス化した後でオーバーロードをコールします。この
メソッドを使用して、渡されるクライアントをキャッシュし、そのクライアントを使用して REST 要求を実行
します。
UI クラス
com.salesforce.androidsdk.ui パッケージのアクティビティは、すべての Mobile SDK アプリケーションに
共通する UI リソースを表しています。XML を介して、これらのリソースのスタイル、スキン、テーマを設定し
たり、カスタマイズしたりできます。SalesforceActivity、SalesforceListActivity、
SalesforceExpandableListActivity を除き、実行時にリソースを置き換えることを目的として、これら
のアクティビティクラスを上書きしないでください。
ClientManager クラス
ClientManager は、Android AccountManager クラスと連動して、ユーザアカウントを管理します。アプリ
ケーションにとって特に重要なことは、ClientManager クラスが次の 2 つのメソッドを介して RestClient イン
スタンスへのアクセスを提供するという点です。
• getRestClient()
• peekRestClient()
getRestClient() メソッドは、Salesforce データをクエリするための RestClient インスタンスを非同期で作
成します。この場合、非同期とは、このメソッドが UI スレッドでの使用を目的としていることを意味します。
peekRestClient() メソッドは、UI 以外のコンテキストで使用する RestClient インスタンスを同期して作
成します。
RestClient インスタンスを取得したら、このインスタンスを使用して、REST API コールを Salesforce に送信で
きます。
RestClient クラス
名前が示すように、RestClient クラスは、Android アプリケーションと Salesforce REST API の連絡役になります。
RestClient クラスの新しいインスタンスは明示的に作成しません。代わりに、ClientManager ファクトリ
クラスを使用して、RestClient インスタンスを取得します。RestClient インスタンスを取得したら、この
インスタンスを使用して、REST API コールを Salesforce に送信できます。コールするメソッドは、UI コンテキス
トからコールするかどうかによって異なります。「ClientManager クラス」を参照してください。
次の RestClient メソッドを使用して、REST 要求を送信します。
• sendAsync() — ClientManager.getRestClient() をコールして RestClient インスタンスを取得し
た場合、このメソッドをコールします。
• sendSync() — ClientManager.peekRestClient() をコールして RestClient インスタンスを取得し
た場合、このメソッドをコールします。
92
ネイティブ Android の開発
ネイティブクラスの概要
sendSync() メソッド
要求に対してどの程度の情報を提供できるかに応じて、RestClient.sendSync() の 3 つのオーバーロード
から選択できます。
sendAsync() メソッド
RestClient.sendAsync() メソッドは、WrappedRestRequest の新しいインスタンスの RestRequest オ
ブジェクトをラップします。次に、WrappedRestRequest オブジェクトを要求キューに追加して、そのオブ
ジェクトを返します。待機中に要求をキャンセルする場合、WrappedRestRequest オブジェクトで cancel()
をコールします。
getRequestQueue() メソッド
基盤となる RequestQueue オブジェクトにアクセスするには、RestClient インスタンスで
restClient.getRequestQueue() をコールします。RequestQueue オブジェクトを使用すると、待機中の
要求を直接キャンセルまたは操作できます。たとえば、restClient.getRequestQueue().cancelAll()
をコールして待機中の要求キュー全体をキャンセルできます。「要求キューの管理」のコード例を参照してく
ださい。
RestRequest クラス
RestRequest クラスは、アプリケーションから提供されるデータに基づいて REST API 要求を作成および書式
設定します。これは、Mobile SDK によって実装され、自身のインスタンスのファクトリとして機能します。
RestRequest のインスタンスを直接作成しないでください。代わりに、適切な RestRequest の静的ファク
トリメソッド (RestRequest.getRequestForCreate() など) をコールします。要求を送信するには、返され
た RestRequest オブジェクトを RestClient.sendAsync() または RestClient.sendSync() に渡しま
す。「REST API の使用」を参照してください。
RestRequest クラスは、Salesforce REST API および SOAP API によって提供される標準の Salesforce データ操作をネ
イティブに処理します。サポートされる操作は次のとおりです。
操作
パラメータ
説明
Versions
なし
Salesforceバージョンのメタデータを
返します。
Resources
API バージョン
リソース名および URI を含む、指定
された API バージョンで使用可能な
リソースを返します。
Metadata
API バージョン、オブジェクト種別 オブジェクトの完全なメタデータ
コレクションを返します。
DescribeGlobal
API バージョン
組織で使用できるすべてのオブジェ
クトとそのメタデータのリストを
返します。
93
ネイティブ Android の開発
ネイティブクラスの概要
操作
パラメータ
説明
Describe
API バージョン、オブジェクト種別 1 つのオブジェクト種別の説明を返
します。
Create
API バージョン、オブジェクト種
別、値オブジェクトに対する項目
名の対応付け
Retrieve
API バージョン、オブジェクト種
オブジェクト ID でレコードを取得
別、オブジェクト ID、項目のリスト します。
Search
API バージョン、SOQL クエリ文字列 指定された SOQL 検索を実行しま
す。
SearchResultLayout
API バージョン、オブジェクトのリ 指定されたオブジェクトの検索結
スト
果レイアウト情報を返します。
SearchScopeAndOrder
API バージョン
Update
API バージョン、オブジェクト種
指定された対応付けでオブジェク
別、オブジェクト ID、値オブジェク トを更新します。
トに対する項目名の対応付け
Upsert
API バージョン、オブジェクト種
別、外部 ID 項目、外部 ID、値オブ
ジェクトに対する項目名の対応付
け
外部 ID が外部 ID 項目に現在存在し
ているかどうかに基づいて、外部
データからオブジェクトを更新ま
たは挿入します。
Delete
API バージョン、オブジェクト種
別、オブジェクト ID
指定された ID を持つ特定のタイプ
のオブジェクトを削除します。
指定したオブジェクトに新しいレ
コードを作成します。
ログインユーザのデフォルトのグ
ローバル検索範囲内にあるオブジェ
クトの順序付きリストを返します。
適切な RestRequest インスタンスを取得するには、実行する操作に一致する RestRequest 静的メソッドを
コールします。次に、RestRequest 静的メソッドを示します。
• getRequestForCreate()
• getRequestForDelete()
• getRequestForDescribe()
• getRequestForDescribeGlobal()
• getRequestForMetadata()
• getRequestForQuery()
• getRequestForResources()
• getRequestForRetrieve()
• getRequestForSearch()
• getRequestForSearchResultLayout()
94
ネイティブ Android の開発
ネイティブクラスの概要
• getRequestForSearchScopeAndOrder()
• getRequestForUpdate()
• getRequestForUpsert()
• getRequestForVersions()
これらのメソッドは、RestClient のインスタンスに渡す RestRequest オブジェクトを返します。RestClient
クラスは、要求を送信する同期メソッド (sendSync()) および非同期メソッド (sendAsync()) を提供します。
UI スレッドから要求を送信する場合は、sendAsync() を使用します。 sendSync() は、非 UI スレッド (アク
ティビティによって実行されるサービスまたはワーカースレッドなど) の場合にのみ使用します。
FileRequests クラス
FileRequests クラスは、ファイル操作要求を構築するメソッドを提供します。各メソッドは、新しい
RestRequest オブジェクトを返します。アプリケーションは、このオブジェクトを Salesforce サービスに送信
して要求を処理します。たとえば、次のコードスニペットは ownedFilesList() メソッドをコールして
RestRequest オブジェクトを取得します。次に、RestClient.sendAsync() を使用して RestRequest オ
ブジェクトをサーバに送信します。
RestRequest ownedFilesRequest = FileRequests.ownedFilesList(null, null);
RestClient client = this.client;
client.sendAsync(ownedFilesRequest, new AsyncRequestCallback() {
// Do something with the response
});
メモ: この例では、null を最初のパラメータ (userId) に渡します。この値で、コンテキスト (ログインし
ている) ユーザの ID を使用するように ownedFilesList() メソッドに指示します。pageNum パラメータ
の 2 番目の null で、結果の最初のページを取得するようにメソッドに指示します。
FileRequests メソッドについての詳細は、「ファイルとネットワーキング」を参照してください。
メソッド
FileRequests メソッドについての詳細は、「FileRequests メソッド (Android)」を参照してください。REST リク
エストボディおよびレスポンスボディについての詳細は、[Chatter REST API Resources (Chatter REST API リソー
ス)] > [Files Resources (ファイルリソース)] (http://www.salesforce.com/us/developer/docs/chatterapi) を参照してくださ
い。
メソッド名
説明
ownedFilesList
指定されたユーザが所有するファイルのリストからペー
ジを取得する要求を構築します。
filesInUsersGroups
ユーザのグループが所有するファイルのリストからペー
ジを取得する要求を構築します。
filesSharedWithUser
ユーザと共有しているファイルのリストからページを取
得する要求を構築します。
95
ネイティブ Android の開発
ネイティブクラスの概要
メソッド名
説明
fileDetails
特定のバージョンのファイルの詳細を取得する要求を構
築します。
batchFileDetails
1 つの要求で 1 つ以上のファイルの最新の詳細を取得す
る要求を構築します。
fileRendition
ファイル (およびバージョン) の特定のページのプレ
ビュー/変換を取得する要求を構築します。
fileContents
この特定のファイルの実際のバイナリコンテンツを取得
する要求を構築します。
fileShares
このファイルの共有先のエンティティのリストからペー
ジを取得する要求を構築します。
addFileShare
指定されたファイル ID のファイル共有を指定されたエン
ティティ ID に追加する要求を構築します。
deleteFileShare
指定されたファイル共有を削除する要求を構築します。
uploadFile
新しいファイルをサーバにアップロードする要求を構築
します。新しいファイルを作成します。
WrappedRestRequest クラス
WrappedRestRequest クラスは、Volley Request クラスをサブクラス化します。WrappedRestRequest オブ
ジェクトは作成しません。RestClient.sendAsync() メソッドは、このクラスを使用して、渡された
RestRequest オブジェクトをラップし、コール元に返します。返されたこのオブジェクトで cancel() メ
ソッドをコールして、「待機中」の要求をキャンセルできます。
LoginActivity クラス
LoginActivity は、ログイン画面を定義します。ログインワークフローについては、説明する価値がありま
す。それは、ログインワークフローでアクティビティパッケージの他の 2 つのクラスが説明されているからで
す。ログインアクティビティで、[Menu (メニュー)] ボタンを押すと、[Clear Cookies (クッキーを解除)]、[Reload
(再読み込み)]、[Pick Server (サーバを選択)] の 3 つのオプションが表示されます。[Pick Server (サーバを選択)] は、
[Production (本番)]、[Sandbox]、[Custom Server (カスタムサーバ)] オプションを表示する ServerPickerActivity
クラスのインスタンスを起動します。[Custom Server (カスタムサーバ)]を選択すると、ServerPickerActivity
は CustomServerURLEditor クラスのインスタンスを起動します。このクラスは、カスタムサーバの名前を
入力できるポップオーバーダイアログを表示します。
その他の UI クラス
ui パッケージにあるその他のいくつかのクラスは、ネイティブ API 開発作業には影響しませんが、重要なため
ここで説明します。
96
ネイティブ Android の開発
ネイティブクラスの概要
PasscodeActivity クラスは、パスコード画面の UI を提供します。これは、Create、CreateConfirm、Check の 3
つのモードのいずれかで実行されます。ユーザが最初にログインしようとしたときは Create モードになりま
す。ここで、ユーザはパスコードを作成するように要求されます。ユーザがパスコードを送信すると、画面が
CreateConfirm モードで返され、ユーザは新しいパスコードを確認するように要求されます。以降は、ユーザに
パスコードの入力を要求する Check モードの画面が表示されるようになります。
SalesforceR は、非推奨クラスです。Mobile SDK が JAR 形式で提供されていたときは、開発者がバイナリファ
イルのリソースを編集するためにこのクラスが必要でした。Mobile SDK は、ライブラリプロジェクトとして使
用できるようになったため、SalesforceR は必要なくなりました。代わりに、SDK のリソースを自分のリソー
スで上書きできます。
SalesforceDroidGapActivity および SalesforceGapViewClient は、ハイブリッドアプリケーションで
のみ使用します。
UpgradeManager クラス
UpgradeManager は、デバイスにインストールされている SDK バージョンをサイレントアップグレードする
メカニズムを提供します。このクラスは、デバイスの共有設定ファイルに SDK バージョン情報を保存します。
アップグレードを実行するために、UpgradeManager は、現在の SalesforceSDKManager インスタンスを
クエリしてその SDK バージョンを取得し、デバイスのバージョン情報と比較します。アップグレードが必要な
場合 (データベーススキーマや暗号化パターンに変更がある場合など)、UpgradeManager は、デバイスの SDK
コンポーネントをアップグレードするために必要な手順を実行できます。このクラスは、将来使用される予定
です。Mobile SDK 2.0 の実装では、単にバージョン文字列を保存して比較するだけです。
ユーティリティクラス
util パッケージの大部分のクラスは内部で使用されますが、いくつかのクラスはサードパーティ開発者にも
利点があります。
クラス
説明
EventsObservable
Mobile SDK for Android が伝搬するすべてのイベントのリ
ストは、ソースコードを参照してください。
EventsObserver
イベントを傍受するにはこのインターフェースを実装
します。この機能は、特定のタイプのイベント発生時
に特殊な操作を実行する場合に便利です。
UriFragmentParser
この静的ヘルパークラスは直接コールできます。この
クラスは、特定の URI を解析して、そのパラメータを
一連のキー/値ペアに分離し、対応付けで返します。
ForcePlugin クラス
com.salesforce.androidsdk.phonegap パッケージのすべてのクラスは、ハイブリッドアプリケーション
のサポートを目的としています。これらのクラスの大部分には、ネイティブコードにアクセスする Javascript プ
ラグインが実装されています。これらの Mobile SDK プラグインの基本クラスは ForcePlugin です。Mobile SDK
97
ネイティブ Android の開発
パスコードの使用
アプリケーションに独自の Javascript プラグインを実装する場合、ForcePlugin を拡張して、抽象 execute()
関数を実装します。
ForcePlugin は、Javascript フレームワークと連動する CordovaPlugin を拡張します。これにより、ネイティ
ブ関数をコールできる Javascript モジュールを作成できるようになります。PhoneGap は両方のブリッジになりま
す。CordovaPlugin でネイティブプラグインを作成し、それを複製する Javascript ファイルを作成します。
Cordova は、いずれかのプラグインの Javascript 関数をスクリプトでコールすると、プラグインの execute() 関
数をコールします。
パスコードの使用
Mobile SDKアプリケーションのユーザデータは暗号化で保護されます。Salesforce 組織のシステム管理者は、ユー
ザに接続アプリケーションのパスコードを入力するように要求できます。この場合、アプリケーションは暗号
化ハッシュキーとしてそのパスコードを使用します。Salesforce システム管理者がパスコードを要求しない場
合、独自のキーを自分で入力する必要があります。
Salesforce Mobile SDK は、パスコードワークフローのすべての実装作業を行うわけではありません。パスコード
マネージャをコールしてユーザ入力を取得し、パスコードとプレフィックス/サフィックスを組み合わせて、
ユーザデータを暗号化するためのハッシュを作成します。また、パスコードが変更されたときのデータの復号
化と再暗号化を処理します。組織がパスコード要件を変更した場合、Mobile SDK は次のログインで変更を検出
し、その変更に応じて対応します。パスコードを使用する場合、SalesforceSDKManager.getKey() メソッ
ドを実装するだけで済みます。この場合、実装で行うべきことは、暗号化キーとして使用できる Base64 エン
コード文字列を返すことだけです。
パスコードは内部的に Base64 エンコード文字列として保存されます。SDK は、Encryptor クラスを使用して、
パスコードからハッシュを作成します。また、パスコードの代わりにキーを入力する場合も、このクラスを使
用してハッシュを生成する必要があります。パスコードとキーは、SmartStore データ、oAuth トークン、ユーザ
ID 文字列、関連するセキュリティ情報を暗号化および復号化する場合に使用されます。パスコードで暗号化さ
れるセキュリティデータを詳しく確認するには、ClientManager.changePasscode() メソッドを参照しま
す。
モバイルポリシーは、特定のパスコード属性 (パスコードの長さやパスコードダイアログ表示のタイミングな
ど) を定義します。接続アプリケーションのモバイルポリシーファイルは、Salesforce サーバにあります。ユー
ザが正しくないパスコードを 10 回連続で入力すると、そのユーザはログアウトされます。Mobile SDK は、ユー
ザが正しくないパスコードを入力した場合にフィードバックを提供し、試行できる残りの回数をユーザに通知
します。PasscodeManager クラスは、画面がロックされる前にフロントアクティビティへの参照を保存し、
画面のロックが解除されたときに同じアクティビティを再開できるようにします。
パスコードで保護されたアプリケーションで SalesforceActivity、SalesforceListActivity、
SalesforceExpandableListActivity を拡張しないアクティビティを定義する場合、これらの各アクティ
ビティクラスから次の 3 つの PasscodeManager メソッドをコールしてください。
• PasscodeManager.onPause()
• PasscodeManager.onResume(Activity)
• PasscodeManager.recordUserInteraction()
同じ名前のアクティビティのメソッドから onPause() および onResume() をコールします。アクティビティ
の onUserInteraction() メソッドから recordUserInteraction() をコールします。アクティビティク
98
ネイティブ Android の開発
リソースの処理
ラス記述子を onResume() に渡します。これらのコールにより、このようなイベント時にアプリケーション
でパスコードセキュリティが適用されます。「PasscodeManager クラス」を参照してください。
メモ: SalesforceActivity、SalesforceListActivity、SalesforceExpandableListActivity
クラスには、これらの必須メソッドを無償で実装できます。可能な場合は、これらのいずれかのクラス
に基づいてアクティビティクラスを作成してください。
リソースの処理
Salesforce Mobile SDK リソースは、libs/SalesforceSDK/res フォルダにある XML ファイルで設定されていま
す。これらのリソースの多くは、このフォルダで変更することでカスタマイズできます。
/res フォルダのリソースは、次のようなカテゴリに分類されます。
• Drawables — 背景、影付き、画像リソース (PNG ファイルなど)
• Layouts — 可視コンポーネント (パスコード画面など) の画面設定
• Values — SDK で使用される文字列、色、サイズ
その他の 2 つのリソース種別は、ほとんど内部で使用されます。
• Menu
• XML
drawable、layout、および value リソースは、さまざまなフォーム要素に対応するフォルダにさらに分類されま
す。これらのカテゴリは、各種デバイス種別および画面解像度に対応します。各カテゴリはそのフォルダ名で
定義されるため、すべてのバージョンで同じリソースファイル名を使用できます。たとえば、開発者が
icon1.png という名前のアイコンをさまざまなサイズで提供する場合、スマートフォン、ローエンドフォン、
タブレットに対応する各フォルダにアイコンを配置します。各フォルダで、このファイル名は icon1.png に
なります。フォルダ名の語幹は同じですが、サフィックスが異なります。
次の表に、フォルダ名とサフィックスを示します。
フォルダ名
使用方法
drawable
描画可能リソースの汎用バージョン
drawable-hdpi
高解像度 (スマートフォン向け)
drawable-ldpi
低解像度 (ローエンド機能端末向け)
drawable-mdpi
中解像度 (ローエンド機能スマートフォン)
drawable-xhdpi
超高密度画面 (~ 320 dpi) のリソース
drawable-xlarge
タブレット画面 (横方向)
drawable-xlarge-port
タブレット画面 (縦方向)
drawable-xxhdpi-port
超超高密度画面 (~ 480 dpi) のリソース
layout
レイアウトの汎用バージョン
menus
[接続を追加]ダイアログおよび電話のログインメニュー
99
ネイティブ Android の開発
リソースの処理
フォルダ名
使用方法
values
汎用スタイルおよび値
xml
一般的なアプリケーション設定
コンパイラは、ターゲットデバイス設定に一致する名前のフォルダでリソースを検索します。要求されたリ
ソースが想定されるフォルダにない場合 (ターゲットデバイスはタブレットであるが、要求されたアイコンが
drawables-xlarge または drawables-xlarge-port フォルダにない場合など)、コンパイラは汎用 drawable
フォルダでアイコンファイルを検索します。
Layouts
Mobile SDK の Layouts は、すべてのアプリケーションが使用する画面リソースを指定します。たとえば、Layouts
は、ログインおよびパスコードを処理するダイアログボックスを設定します。
layout の XML ノードの名前は、レイアウトが指定するコントロールのタイプを示します。たとえば、
res/layout/sf__passcode.xml にある次の EditText ノードは、テキスト編集コントロールを指定しま
す。
<EditText android:id="@+id/sf__passcode_text"
style="@style/SalesforceSDK.Passcode.Text.Entry"
android:inputType="textPassword" />
この場合、EditText コントロールは android:inputType 属性を使用します。その値が「textPassword」と
なっているため、オペレーティングシステムで入力値が隠されます。
style 属性は、リソースの他の場所で定義されたグローバルスタイルを参照します。所定の場所で style 属性を指
定する代わりに、中央ファイルでスタイルを定義し、必要な場所でその属性を参照します。値
@style/SalesforceSDK.Passcode.Text.Entry は、res/values/sf__styles.xml で定義された SDK 所
有のスタイルを参照します。次に、スタイルの定義を示します。
<style name="SalesforceSDK.Passcode.Text.Entry">
<item name="android:layout_width">wrap_content</item>
<item name="android:lines">1</item>
<item name="android:maxLength">10</item>
<item name="android:minWidth">@dimen/sf__passcode_text_min_width</item>
<item name="android:imeOptions">actionGo</item>
</style>
いずれかの独自のスタイルへの参照で style 属性を上書きできます。sf__styles.xml を変更する代わりに、
xyzcorp__styles.xml などの別ファイルでスタイルを定義します。res/values フォルダ (汎用デバイスス
タイル) または res/values-xlarge フォルダ (タブレットデバイス) にファイルを配置します。
Values
res/values および res/values-xlarge フォルダには、サイズ、色、文字列のリソースやカスタムスタイルなどのスタ
イルコンポーネントの定義が含まれています。このフォルダのファイル名は、リソースまたはスタイルコン
ポーネントのタイプを示します。独自の値を提供するには、会社やプロジェクトを反映するファイル名プレ
100
ネイティブ Android の開発
REST API の使用
フィックスを使用して、同じフォルダに新しいファイルを作成します。たとえば、開発者のプレフィックスが
XYZ の場合、XYZ__styles.xml という名前の新しいファイルで sf__styles.xml を上書きできます。
ファイル名
次の文字列を含む
sf__colors.xml
Mobile SDK スタイルで参照される色
sf__dimens.xml
Mobile SDK スタイルで参照されるサイズ
sf__strings.xml
Mobile SDKスタイルで参照される文字列。エラーメッセージを上
書きできます。
sf__styles.xml
Mobile SDK で使用されるビジュアルスタイル
strings.xml
アプリケーション定義の文字列
strings.xml の値を上書きできます。ただし、create_native スクリプトを使用してアプリケーションを
作成した場合、strings.xml の文字列はすでに適切な値を反映しています。
その他のリソース
その他の 2 つのフォルダには、Mobile SDK リソースが含まれています。
• res/menu は、内部的に使用されるメニューを定義します。アプリケーションで新しいメニューを定義す
る場合、新しいファイルのこの場所にリソースとして追加します。
• res/xml には、編集する必要のあるファイル servers.xml が含まれています。このファイルでは、デ
フォルトの本番サーバおよび Sandbox サーバを組織のログインサーバに変更する必要があります。このフォ
ルダにあるその他のファイルは内部で使用されます。authenticator.xml ファイルはアカウント認証リ
ソースを設定し、config.xml ファイルはハイブリッドアプリケーションの PhoneGap プラグインを定義し
ます。
関連トピック:
Android リソース
REST API の使用
Salesforce 組織からデータをクエリ、説明、作成、更新するために、ネイティブアプリケーションは Salesforce
REST API をコールします。Salesforce REST API は、SOQL 文字列を優先しますが、JSON または XML 形式のデータを受
け入れて返すこともできます。REST API についての詳細は、『REST API 開発者ガイド』を参照してください。関
連するSalesforce開発ドキュメントへのリンクは、Force.com 開発者向けドキュメントの Web サイトにあります。
Android ネイティブアプリケーションにより、最小限のコーディングで REST コールを介して Salesforce データに
アクセスできます。com.salesforce.androidsdk.rest パッケージのクラスは、通信チャネルを初期化し
て、低レベルの HTTP プラミングをカプセル化します。これらのクラスには、以下が含まれます。
• ClientManager — RestClient インスタンスのファクトリとして機能します。また、アカウントログインや
Salesforce サーバとのハンドシェイクも処理します。Mobile SDK によって実装されます。
101
ネイティブ Android の開発
REST API の使用
• RestClient — REST API 要求を Salesforce サーバに送信するためのプロトコルを処理します。RestClient の
インスタンスを直接作成しないでください。代わりに、ClientManager.getRestClient() メソッドを
コールします。Mobile SDK によって実装されます。
• RestRequest — アプリケーションから提供されるデータに基づいて REST API 要求を書式設定します。ま
た、自身のインスタンスのファクトリとしても機能します。RestRequest のインスタンスを直接作成しな
いでください。代わりに、適切な RestRequest の静的 getter 関数 (RestRequest.getRequestForCreate()
など) をコールします。SDK によって実装されます。
• RestResponse — 要求された書式で応答コンテンツを書式設定して、書式設定した応答をアプリケーショ
ンに返し、コンテンツストリームを終了します。RestRequest クラスは、RestResponse のインスタン
スを作成し、RestClient.AsyncRequestCallback インターフェースの実装を介してアプリケーション
に返します。SDK によって実装されます。
次に、UI スレッドで REST クラスを使用する場合の基本手順を示します。
1. ClientManager のインスタンスを作成します。
a. SalesforceSDKManager.getInstance().getAccountType() メソッドを使用して、ClientManager
コンストラクタの第 2 引数として渡す値を取得します。
b. ClientManager コンストラクタの LoginOptions パラメータの場合、
SalesforceSDKManager.GetInstance().getLoginOptions() をコールします。
2. ClientManager.RestClientCallback インターフェースを実装します。
3. ClientManager.getRestClient() をコールして RestClient インスタンスを取得し、
RestClientCallback 実装のインスタンスに渡します。native/SampleApps/RestExplorer サンプル
アプリケーションの次のコードは、RestClientCallback をインラインで実装およびインスタンス化して
います。
String accountType = SalesforceSDKManager.getInstance().getAccountType();
LoginOptions loginOptions = SalesforceSDKManager.getInstance().getLoginOptions();
// Get a rest client
new ClientManager(this, accountType, loginOptions,
SalesforceSDKManager.getInstance().shouldLogoutWhenTokenRevoked()).getRestClient(this,
new RestClientCallback() {
@Override
public void authenticatedRestClient(RestClient client) {
if (client == null) {
SalesforceSDKManager.getInstance().logout(ExplorerActivity.this);
return;
}
// Cache the returned client
ExplorerActivity.this.client = client;
}
});
4. 静的 RestRequest() getter メソッドをコールして、ニーズに合った RestRequest オブジェクトを取得し
ます。たとえば、Salesforce オブジェクトの説明を取得する場合は次のようになります。
request = RestRequest.getRequestForDescribe(apiVersion, objectType);
102
ネイティブ Android の開発
Android テンプレートアプリケーション: 詳細
5. 前のステップで取得した RestRequest オブジェクトを RestClient.sendAsync() または
RestClient.sendSync() に渡します。UI スレッドの場合、sendAsync() をコールします。
a. ClientManager.AsyncRequestCallback インターフェースを実装します。
b. 実装のインスタンスを sendAsync() メソッドに渡します。
c. ASyncRequestCallback.onSuccess() メソッドを介して、書式設定された応答を取得します。
次のコードは、AsyncRequestCallback をインラインで実装およびインスタンス化しています。
private void sendFromUIThread(RestRequest restRequest) {
client.sendAsync(restRequest, new AsyncRequestCallback() {
private long start = System.nanoTime();
@Override
public void onSuccess(RestRequest request, RestResponse result) {
try
{
// Do something with the result
}
catch (Exception e) {
printException(e);
}
EventsObservable.get().notifyEvent(EventType.RenditionComplete);
}
@Override
public void onError(Exception exception)
{
printException(exception);
EventsObservable.get().notifyEvent(EventType.RenditionComplete);
}
});
サービスから sendSync() メソッドをコールする場合、次の点を変更して同じ手順を実行します。
1. RestClient インスタンスを取得するには、ClientManager.getRestClient() ではなく
ClientManager.peekRestClient() をコールします。
2. sendSync() メソッドの戻り値から、書式設定された REST 応答を取得します。
Android テンプレートアプリケーション: 詳細
TemplateApp サンプルプロジェクトは、基本的な Android アプリケーションの作成に必要なすべてを実装します。
これは「ベアボーン」サンプルであるため、Mobile SDK の create_native ant スクリプトで新しいネイティブ Android
プロジェクトを設定するために使用するテンプレートとしても機能します。このプロジェクトを学習すれば、
ネイティブ Android SDK を迅速に理解できます。
TemplateApp プロジェクトでは、TemplateApp と MainActivity の 2 つのクラスが定義されています。
TemplateApp クラスは、Application を拡張し、その onCreate() 上書きで
SalesforceSDKManager.initNative() をコールします。MainActivity クラスは、SalesforceActivity
クラスをサブクラス化します。これらの 2 つのクラスがあれば、ログイン画面とホーム画面を表示するモバイ
ルアプリケーションを作成できます。
103
ネイティブ Android の開発
Android テンプレートアプリケーション: 詳細
約 200 行のコードしか含まれていませんが、TemplateApp は単なる「Hello World」の例ではありません。このメ
インアクティビティでは、REST 要求を介して Salesforce データを取得し、その結果をモバイルページに表示しま
す。Android オペレーティングシステム、デバイス、セキュリティの制限で許可されている範囲でアクティビ
ティの追加や他のコンポーネントのコールなどを行って TemplateApp を拡張できます。
TemplateApp クラス
すべてのネイティブ Android アプリケーションで android.app.Application のインスタンスが必要です。
次に、クラス全体を示します。
package com.salesforce.samples.templateapp;
import android.app.Application;
import com.salesforce.androidsdk.app.SalesforceSDKManager;
/**
* Application class for our application.
*/
public class TemplateApp extends Application {
@Override
public void onCreate() {
super.onCreate();
SalesforceSDKManager.initNative(getApplicationContext(), new KeyImpl(),
MainActivity.class);
}
}
TemplateApp クラスは、次の 2 つの主要なタスクを実行します。
• initNative() をコールしてアプリケーションを初期化する
• KeyInterface のアプリケーションの実装を渡す
大部分のネイティブ Android アプリケーションは同じようなコードを使用できます。このわずかな作業で、ア
プリケーションはパスコードおよびログイン/ログアウトメカニズムを自由に実装でき、その他のいくつかの
利点も得られます。「SalesforceActivity クラス、SalesforceListActivity クラス、および SalesforceExpandableListActivity ク
ラス」を参照してください。
MainActivity クラス
Mobile SDK アプリケーションでは、メインアクティビティはユーザのログイン直後に始まります。メインアク
ティビティが実行されると、他のアクティビティを起動できるようになり、次にサブアクティビティを起動で
きるようになります。メインアクティビティを終了することで、アプリケーションが終了します。他のすべて
のアクティビティは、メインアクティビティ内で連鎖的に終了します。
テンプレートアプリケーションの MainActivity クラスは、
com.salesforce.androidsdk.ui.sfnative.SalesforceActivity を拡張します。このスーパークラス
は、Mobile SDK の基本抽象アクティビティクラス SalesforceActivity で、必須のパスコードおよびログイ
ンプロトコルを自由に実装できます。代わりに別の基本アクティビティクラスを使用する場合、これらのプロ
トコルを自分で実装する必要があります。MainActivity は、アプリケーションの UI を初期化してその UI ボ
104
ネイティブ Android の開発
Android テンプレートアプリケーション: 詳細
タンを実装します。UI には、ユーザの Salesforce 取引先責任者または取引先を表示できるリストビューも含まれ
ます。ユーザがこれらのいずれかのボタンをクリックすると、MainActivity オブジェクトが数個の基本ク
エリを実行して、ビューを作成します。たとえば、Salesforce からユーザの取引先責任者を取得する場合、
onFetchContactsClick() メッセージハンドラが次のような単純な SOQL クエリを送信します。
public void onFetchContactsClick(View v) throws UnsupportedEncodingException {
sendRequest("SELECT Name FROM Contact");
}
内部的には、private sendRequest() メソッドが RestRequest クラスと指定の SOQL 文字列を使用して次のよ
うにサーバ要求を生成します。
private void sendRequest(String soql) throws UnsupportedEncodingException
{
RestRequest restRequest = RestRequest.getRequestForQuery(getString(R.string.api_version),
soql);
client.sendAsync(restRequest, new AsyncRequestCallback()
{
@Override
public void onSuccess(RestRequest request,
RestResponse result) {
try {
listAdapter.clear();
JSONArray records = result.asJSONObject().getJSONArray("records");
for (int i = 0; i < records.length(); i++) {
listAdapter.add(records.getJSONObject(i).getString("Name"));
}
} catch (Exception e) {
onError(e);
}
}
@Override
public void onError(Exception exception)
{
Toast.makeText(MainActivity.this,
MainActivity.this.getString(
SalesforceSDKManager.getInstance().getSalesforceR().stringGenericError(),
exception.toString()),
Toast.LENGTH_LONG).show();
}
});
}
このメソッドは、com.salesforce.androidsdk.rest.RestClient クラスのインスタンス client を使用
して SOQL クエリを処理します。RestClient クラスは、RestRequest と RestResponse の 2 つのヘルパー
クラスを使用して、クエリの送信とその結果の処理を行います。sendRequest() メソッドは、
RestClient.sendAsync() をコールして SOQL クエリを非同期に処理します。
sendRequest() メソッドは、sendAsync() コールに対応するために API バージョンと SOQL クエリ文字列を渡
して com.salesforce.androidsdk.rest.RestRequest のインスタンスを作成します。生成されたオブジェ
クトは、sendAsync() の第 1 引数になります。第 2 引数は、コールバックオブジェクトです。sendAsync()
はクエリの実行の完了時に、このコールバックオブジェクトに結果を送信します。 クエリに成功した場合、
105
ネイティブ Android の開発
チュートリアル: ネイティブ Android Warehouse アプリ
ケーションの作成
コールバックオブジェクトはクエリ結果を使用して UI リストのコントロールを設定します。クエリに失敗し
た場合、コールバックオブジェクトはトーストポップアップでエラーメッセージを表示します。
Java に関する注意事項:
RestClient.sendAsync() をコールするコードで、新しい AsyncRequestCallback オブジェクトをその第
2 引数としてインスタンス化します。ただし、AsyncRequestCallbackconstructor の後に、いくつかのメ
ソッド (onSuccess() や onError()) より優先されるコードブロックが続きます。このコードに不自然な点が
ある場合、よく状況を確認してください。ASyncRequestCallback は、インターフェースとして定義される
ため、実装はありません。これをインスタンス化するために、コードで 2 つの ASyncRequestCallback メ
ソッドをインラインで実装して、匿名クラスオブジェクトを作成します。この手法により、別のオブジェクト
からコールされない独自の sendAsync() 実装を TemplateApp に提供でき、一連の特殊なクラス名で API が
見づらくなることもありません。
TemplateApp マニフェスト
TemplateApp プロジェクトの AndroidManifest.xml ファイルを見ると、Mobile SDK ネイティブ Android アプリ
ケーションに必要なコンポーネントがわかります。次のコンポーネントのみ必要になります。
名前
タイプ
説明
MainActivity
アクティ
ビティ
ログイン後にコールさ
れる最初のアクティビ
ティ。名前とクラスは
プロジェクトで定義さ
れます。
create_native スクリプトで作成されたアプリケーションは、TemplateApp プロジェクトに基づいているた
め、MainActivity コンポーネントはすでにそのマニフェストに含まれています。他の Android アプリケーショ
ンと同様に、Eclipse の Android マニフェストエディタを使用して、他のコンポーネント (カスタムアクティビティ
またはサービスなど) を追加できます。
チュートリアル: ネイティブ Android Warehouse アプリケーショ
ンの作成
モバイル在庫管理アプリケーションを構築することで、ネイティブ Android SDK の知識を応用します。このチュー
トリアルでは、2 つのアクティビティを定義する簡単な主従関係アーキテクチャについて説明します。また、
Mobile SDK アプリケーションの設定、REST API ラッパークラスの使用、および Android SDK のインテグレーション
についても説明します。
前提条件
このチュートリアルでは、次のツールおよびパッケージが必要になります。
106
ネイティブ Android の開発
前提条件
• このチュートリアルでは、基本的な在庫データベースを含む Warehouse アプリケーションを使用します。こ
のアプリケーションを DE 組織にインストールする必要があります。既存の DE 組織にインストールする場
合、作成した既存の Warehouse コンポーネントをすべて削除してからインストールしてください。
1. インストール URL リンク http://bit.ly/package100 をクリックします。
2. すでにログインしている場合は、DE 組織のユーザ名とパスワードを入力します。
3. [パッケージインストールの詳細] ページで、[次へ] をクリックします。
4. [次へ] をクリックし、[セキュリティレベル] ページで [Next (次へ)] をクリックします。
5. [インストール] をクリックします。
6. [Deploy Now (今すぐデプロイ)] をクリックしてから、[Deploy (デプロイ)] をクリックします。
7. インストールが完了したら、右上のアプリケーションピッカーから [Warehouse (倉庫)] アプリケーショ
ンを選択できます。
8. データを作成するには、[Data (データ)] タブをクリックします。
9. [Create Data (データを作成)] ボタンをクリックします。
• 次の最新バージョンをインストールします。
– Java JDK 6 以降 — http://www.oracle.com/downloads。
メモ: Android Lollipop には Java JDK 7 以降が必要です。
– Apache Ant 1.8 以降 — http://ant.apache.org。
– Android SDK 4.2.2 (API レベル 17) 以降 — Mobile SDK ハイブリッドアプリケーションのデフォルトの Android
SDK バージョンは 4.4 (API レベル 19) です。
– Android SDK Tools バージョン 21 以降 —http://developer.android.com/sdk/installing.html。
メモ: 最良の結果を得るには、対象バージョンだけでなく、Android SDK の以前のすべてのバージョ
ンもインストールします。
– Eclipse — https://www.eclipse.org。サポートされている Eclipse の最小バージョンについては、Android
開発ツールに関する Web サイトを参照してください。
– Eclipse バージョン 21 以降用の Android ADT (Android 開発ツール) プラグイン —
http://developer.android.com/sdk。
– アプリケーションをエミュレータで実行するには、Platform 4.2 以降を対象とする Android 仮想デバイス
(AVD) を少なくとも 1 つ設定する必要があります。Eclipse での AVD の設定方法については、
107
ネイティブ Android の開発
ネイティブ Android アプリケーションを作成する
http://developer.android.com/guide/developing/devices/managing-avds.htmlの手順を参
照してください。
• npm を使用して Salesforce Mobile SDK をインストールします。
1. Node.js および npm がすでに正常にインストールされている場合は、ステップ 4 に進みます。
2. Node.js をシステムにインストールします。Node.js インストーラにより、npm が自動的にインストールさ
れます。
i. www.nodejs.org/download から Node.js をダウンロードします。
ii. ダウンロードしたインストーラを実行して Node.js および npm をインストールします。インストール
の許可を求めるプロンプトをすべて承諾します。
3. ターミナルウィンドウで、「npm」と入力して Return キーを押し、インストールが成功していること
を確認します。使用状況情報のページが表示されない場合、ステップ 2 に戻り、何が欠落しているのか
を調べます。
4. ターミナルウィンドウで、「sudo npm install forcedroid -g」と入力します。
このコマンドは、forcedroid パッケージを使用して Mobile SDK をグローバルにインストールします。-g オ
プションでは、npm install を任意のディレクトリから実行できます。npm ユーティリティによりパッ
ケージが /usr/local/lib/node_modules にインストールされ、/usr/local/bin のバイナリモ
ジュールにリンクされます。大部分のユーザは /usr/local の「参照・更新」権限がないため、sudo
オプションが必要になります。
ネイティブ Android アプリケーションを作成する
このチュートリアルでは、Salesforce Mobile SDK の使用を開始する方法 (SDK のインストール方法や DE 組織を使用
したネイティブプロジェクトテンプレートのツアーを含む) を学習します。後続のチュートリアルでは、テン
プレートアプリケーションを変更して、Warehouse スキーマと連携させる方法について説明します。
ステップ 1: 接続アプリケーションを作成する
このステップでは、Force.com で接続アプリケーションを設定する方法を学習します。これを行うことで構築す
るモバイルアプリケーションが認証され、ユーザの代わりに業界標準の OAuth 2.0 プロトコルを介して Force.com
と安全に通信し、Force.com API にアクセスできるようになります。
1. DE 組織で、あなたの名前 > [設定] をクリックし、[作成] > [アプリケーション] をクリックします。
2. [接続アプリケーション] で、[新規] をクリックして、[新規接続アプリケーション] ページを表示します。
3. [基本情報] で、フォームに次のように入力します。
• 接続アプリケーション名: My Native Android App (私のネイティブ Android アプリケーション)
• API 参照名: 推奨値を受け入れます。
• 取引先責任者 メール: メールアドレスを入力します。
4. OAuth 設定で、[OAuth 設定の有効化] チェックボックスをオンにします。
5. [コールバック URL] を mysampleapp://auth/success に設定します。
108
ネイティブ Android の開発
ネイティブ Android アプリケーションを作成する
6. [利用可能な OAuth 範囲] で、[データへのアクセスと管理] (api) および [ユーザに代わっていつでも要求を実
行] (refresh_token) をオンにして、[追加] をクリックします。
7. [保存] をクリックします。
設定を保存すると、作成した接続アプリケーションの詳細が表示されます。
• コールバック URL およびコンシューマ鍵を記録します。これらは、次のステップでネイティブアプリケー
ションを設定するときに使用します。
• モバイルアプリケーションではコンシューマの秘密は使用しないため、この値は無視できます。
ステップ 2: ネイティブ Android プロジェクトを作成する
新しい Mobile SDK プロジェクトを作成するには、ターミナルウィンドウで forcedroid ユーティリティをもう一度
使用します。
1. プロジェクトを作成するディレクトリに変更します。
2. Android プロジェクトを作成するには、「forcedroid create」と入力します。
設定値ごとに、forcedroid ユーティリティによってプロンプトが表示されます。
3. アプリケーション種別に、「native」と入力します。
4. アプリケーション名に、Warehouse と入力します。
5. ターゲットディレクトリに、「tutorial/AndroidNative」と入力します。
6. パッケージ名に、「com.samples.warehouse」と入力します。
7. SmartStore を使用するかどうか確認を求められたら、[Return] キーを押して、デフォルトを受け入れます。
ステップ 3: 新しい Android アプリケーションを実行する
これで、新しい Android アプリケーションが正常に作成されたので、Eclipse でそれを構築して実行し、環境が適
切に設定されていることを確認します。
メモ: 問題が発生したら、まず Android SDK マネージャをチェックして、最新の Android SDK、ビルドツー
ル、および開発ツールを取得していることを確認します。Android SDK マネージャは、Eclipse の [Window
109
ネイティブ Android の開発
ネイティブ Android アプリケーションを作成する
(ウィンドウ)] > [Android SDK Manager] にあります。欠落しているもののすべてをインストールしたら、
Android SDK マネージャを終了して再起動し、確実に最新の状態にします。
Eclipse でのアプリケーションのインポートおよび作成
forcedroid スクリプトにより、Eclipse エディタで新しいアプリケーションを実行する手順が出力されます。
1. Eclipse を起動し、ワークスペースディレクトリとして tutorial/AndroidNative を選択します。
2. [Eclipse] > [Preferences (個人設定)] を選択し、[Android] セクションを選択して、Android SDK の場所を入力しま
す。
3. [OK] をクリックします。
4. [File (ファイル)] > [Import (インポート)] を選択し、[General (一般)] > [Existing Projects into Workspace (既存のプ
ロジェクトをワークスペースへ)] を選択します。
5. [Next (次へ)] をクリックします。
6. ルートディレクトリとして forcedroid/native ディレクトリを指定します。表示されるリストの横にあ
る [すべて選択解除] をクリックし、リストを参照して SalesforceSDK プロジェクトにチェックを入れます。
7. [完了] をクリックします。
8. ステップ 4 ~ 8 を繰り返します。ステップ 6 で、tutorial/AndroidNative をルートとして選択し、新し
い Warehouse プロジェクトのみを選択します。
プロジェクトのインポートが完了したら、Eclipse によって自動的にワークスペースが作成されます。このプロ
セスには数分かかる場合があります。ステータスバーにエラーが表示されていなければ、プロジェクトを実行
できます。
1. Eclipse ワークスペースで、Ctrl キーを押しながらプロジェクトをクリックするか、プロジェクトを右クリッ
クします。
2. ポップアップメニューから、[Run As (別のユーザとして実行)] > [Android Application (Android アプリケーショ
ン)] を選択します。
メモ: [別のユーザとして実行]メニューに[Android アプリケーション]が表示されていない場合、Android
エミュレータまたはデバイスを設定する必要があります。
Eclipse によってエミュレータまたは接続されている Android デバイスでアプリケーションが起動します。
ステップ 4: Android アプリケーションの仕組みを探索する
ネイティブ Android アプリケーションは、簡単な Model View Controller (MVC) アーキテクチャを使用します。
• モデルは、Warehouse データベーススキーマです。
• ビューは、プロジェクトで定義されたアクティビティから取得します。
• コントローラの機能は、Android SDK クラス、Salesforce Mobile SDK、およびアプリケーションを相互に連携さ
せることです。
ビュー内で、完成したチュートリアルアプリケーションは主従関係にある 2 つの Android アクティビティを定
義します。MainActivity は、Merchandise カスタムオブジェクトのレコードを一覧表示します。MainActivity の項目
をクリックしてアクセスする DetailActivity では、選択したレコードの項目を表示および編集できます。
110
ネイティブ Android の開発
リスト画面をカスタマイズする
MainActivity クラス
アプリケーションが起動すると、WarehouseApp クラスが初めに実行フローを制御します。ログインプロセ
スが完了したら、WarehouseApp インスタンスは、SalesforceSDKManager シングルトンを介して制御をメ
インアクティビティクラスに渡します。
新しいアプリケーションの基盤として機能するテンプレートアプリケーションや、完成したチュートリアルで
は、メインアクティビティクラスに MainActivity という名前が付けられています。このクラスは、すべて
のアクティビティの Mobile SDK 基本クラスである SalesforceActivity をサブクラス化します。
ただし、カスタマイズするまでは、アプリケーションに他のアクティビティやタッチイベントハンドラは含ま
れていません。Salesforce にログインし、Salesforce Mobile SDK REST API を使用して要求を発行し、メインアクティ
ビティで応答を表示するだけです。このチュートリアルでは、テンプレートアプリケーションのコントロール
を置き換えて、SOQL REST 要求の目的を再設定し、Warehouse スキーマの Merchandise カスタムオブジェクトと連
携するようにします。
DetailActivity クラス
また、DetailActivity クラスも SalesforceActivity をサブクラス化しますが、さらに興味深いカスタ
マイズを示します。DetailActivity は、標準の Android SDK クラスおよび XML テンプレートを使用して、テ
キスト編集を実装します。また、Mobile SDK の RestClient および RestRequest クラスを使用して、Salesforce
のデータベースオブジェクトを更新する方法も示します。
RestClient クラスと RestRequest クラス
Mobile SDK アプリケーションは、REST API を介して Salesforce データを操作します。ただし、独自の REST 要求を作
成したり、HTTP レベルで直接作業したりする必要はありません。RestRequest クラスの便利な静的メソッド
を使用することで、最小限のコーディングで SOQL クエリの処理、SOSL 検索、および CRUD 操作を行うことがで
きます。便利な各 RestRequest メソッドは、書式設定された REST 要求をラップする RestRequest オブジェ
クトを返します。
要求をサーバに送信するには、RestClient インスタンスの sendAsync() または sendSync() メソッドに
RestRequest オブジェクトを渡します。RestClient オブジェクトは作成しません。アクティビティで
SaleforceActivity などの Mobile SDK アクティビティクラスを継承すると、Mobile SDK は RestClient のイ
ンスタンスを onResume() メソッドに渡します。または、ClientManager.getRestClient() をコールす
ることもできます。アプリケーションは、RestClient オブジェクトが代理で REST 要求を送信できるように
bootconfig.xml ファイルの接続アプリケーション情報を使用します。
リスト画面をカスタマイズする
このチュートリアルでは、メインアクティビティとそのレイアウトを修正し、Warehouse スキーマ固有のアプ
リケーションを作成します。また、Merchandise カスタムオブジェクトから必要なすべての情報を取得できるよ
うに、既存の SOQL クエリを適合させます。
ステップ 1: 既存のコントロールを削除する
テンプレートコードで提供されるメインアクティビティ画面は、目的に合っていません。コード用の領域を確
保しましょう。
111
ネイティブ Android の開発
リスト画面をカスタマイズする
1. Eclipse の Package Explorer から、res/layout/main.xml ファイルを開きます。ビューをテキスト形式モード
に設定してください。この XML ファイルには <LinearLayout> ルートノードがあり、このルートノードに
は、<include> ノード、ネストされた <LinearLayout> ノード、および <ListView> ノードの 3 つの子
ノードが含まれています。
2. 3 つの <Button> ノードがある、ネストされた <LinearLayout> ノードを削除します。編集したファイル
は次のようになります。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent" android:background="#454545"
android:id="@+id/root">
<include layout="@layout/header" />
<ListView android:id="@+id/contacts_list" android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
3. ファイルを保存し、src/com.samples.warehouse/MainActivity.java ファイルを開きます。
4. onClearClick()、onFetchAccountsClick()、および onFetchContactsClick() メソッドを削除し
ます。sendRequest() メソッドがローカルで使用されていないことがコンパイラで警告されても問題あ
りません。そのメソッドへのコールをすべて削除しましたが、次のステップで修正します。
ステップ 2: SOQL クエリを更新する
sendRequest() メソッドには、SOQL クエリを REST 要求として送信するためのコードがあります。このコー
ドの一部は再利用できますが、残りの部分は新しいアプリケーションに合わせてカスタマイズします。
1. sendRequest() を fetchDataForList() に名前変更します。置換
private void sendRequest(String soql) throws UnsupportedEncodingException
置換後
private void fetchDataForList()
throw 宣言が削除されています。引き続きローカルで例外処理を行うために、メソッド本文内でこの宣言
を復帰させます。fetchDataForList() コール元に例外をスローするのではなく、
RestRequest.getRequestForQuery() へのコールを囲むように try...catch ブロックを追加します。
2. Merchandise__c カスタムオブジェクトから最大 10 個のレコードを返すハードコード化された SOQL クエ
リを追加します。
private void fetchDataForList() {
String soql = "SELECT Name, Id, Price__c, Quantity__c
FROM Merchandise__c LIMIT 10";
112
ネイティブ Android の開発
リスト画面をカスタマイズする
3. RestRequest.getRequestForQuery() へのコールを try...catch ブロックで囲みます。置換前のス
テートメントは、次のとおりです。
RestRequest restRequest = RestRequest.getRequestForQuery(getString(R.string.api_version),
soql);
置換後
RestRequest restRequest = null;
try {
restRequest =
RestRequest.getRequestForQuery(getString(R.string.api_version), soql);
} catch (UnsupportedEncodingException e) {
showError(MainActivity.this, e);
return;
}
次に、完成バージョン (元は sendRequest() メソッド) を示します。
private void fetchDataForList() {
String soql = "SELECT Name, Id, Price__c, Quantity__c FROM
Merchandise__c LIMIT 10";
RestRequest restRequest = null;
try {
restRequest =
RestRequest.getRequestForQuery(
getString(R.string.api_version), soql);
} catch (UnsupportedEncodingException e){
showError(MainActivity.this, e);
return;
}
client.sendAsync(restRequest, new AsyncRequestCallback() {
@Override
public void onSuccess(RestRequest request,
RestResponse result) {
try {
listAdapter.clear();
JSONArray records =
result.asJSONObject().getJSONArray("records");
for (int i = 0; i < records.length(); i++) {
listAdapter.add(records.
getJSONObject(i).getString("Name"));
}
} catch (Exception e) {
onError(e);
}
}
@Override
public void onError(Exception exception) {
Toast.makeText(MainActivity.this,
MainActivity.this.getString(
SalesforceSDKManager.getInstance().
getSalesforceR().stringGenericError(),
113
ネイティブ Android の開発
リスト画面をカスタマイズする
exception.toString()),
Toast.LENGTH_LONG).show();
}
});
}
画面が読み込まれて認証が完了したら、fetchDataForList() をコールします。
4. onResume(RestClient client) メソッドで、メソッド本文の最後に次の行を追加します。
@Override
public void onResume(RestClient client) {
// Keeping reference to rest client
this.client = client;
// Show everything
findViewById(R.id.root).setVisibility(View.VISIBLE);
// Fetch data for list
fetchDataForList();
}
5. 最後に、特定のアクティビティコンテキストでエラーをレポートする showError() メソッドを実装しま
す。ファイルの上部で、インポートのリストの最後に次の行を追加します。
import android.content.Context;
6. MainActivity クラス定義の最後に、次のコードを追加します。
public static void showError(Context context, Exception e) {
Toast toast = Toast.makeText(context,
context.getString(
SalesforceSDKManager.getInstance().
getSalesforceR().stringGenericError(),
e.toString()),
Toast.LENGTH_LONG);
toast.show();
}
7. MainActivity.java ファイルを保存します。
ステップ 3: アプリケーションを試す
アプリケーションをテストするには、Package Explorer で Ctrl キーを押しながらアプリケーションをクリックし、
[Run As (別のユーザとして実行)] > [Android Application (Android アプリケーション)] を選択します。Android エミュ
レータが表示されたら、読み込みが完了するまで数分待機します。画面のロックを解除して、Salesforce ログイ
ン画面が表示されるまでもうしばらく待機します。Salesforce に正常にログインできたら、[許可] をクリックし
て必要な権限をアプリケーションに付与します。
この時点で Merchandise レコードをクリックしても何も起きません。次のチュートリアルでこれを修正します。
114
ネイティブ Android の開発
詳細画面を作成する
詳細画面を作成する
前のステップで、メインアクティビティで最大 10 個の Merchandise レコードのリストを表示するようにテンプ
レートアプリケーションを変更しました。このステップでは、詳細アクティビティおよびレイアウトを作成し
て作業を終了します。次に、メインアクティビティと詳細アクティビティをリンクします。
ステップ 1: 詳細画面を作成する
まず、res/layout/detail.xml という名前の XML ファイルを作成して詳細アクティビティのレイアウトを
設計します。
1. Package Explorer で、res/layout を展開します。
2. Ctrl キーを押しながら layout フォルダをクリックし、[New (新規)] > [Android XML File (Android XML ファイル)]
を選択します。
3. [File (ファイル)] 項目で、detail.xml と入力します。
4. [Root Element (ルート要素)] で、[LinearLayout] を選択します。
5. [Finish (完了)] をクリックします。
新しいファイルで、詳細画面で使用されるレイアウトおよびリソースを定義します。まず、名前、価格、
数量の項目および表示ラベルを追加します。
6. 新しいファイルのコンテンツを次の XML コードで置き換えます。
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#454545"
android:orientation="vertical" >
<include layout="@layout/header" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/name_label"
android:width="100dp" />
<EditText
android:id="@+id/name_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="text" />
</LinearLayout>
115
ネイティブ Android の開発
詳細画面を作成する
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/price_label"
android:width="100dp" />
<EditText
android:id="@+id/price_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="numberDecimal" />
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/quantity_label"
android:width="100dp" />
<EditText
android:id="@+id/quantity_field"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:inputType="number" />
</LinearLayout>
</LinearLayout>
7. ファイルを保存します。
8. レイアウトを終了するには、TextView 要素で参照される 3 つの表示ラベル (name_label、price_label、
および quantity_label) の表示名を定義します。
res/values/strings.xml にある <resources> ノードの終了直前に次のコードを追加します。
<!-- Detail screen -->
<string name="name_label">Name</string>
<string name="price_label">Price</string>
<string name="quantity_label">Quantity</string>
9. ファイルを保存し、テキストビューで AndroidManifest.xml ファイルを開きます。テキストビューを取
得できない場合、エディタ画面の下部にある [AndroidManifest.xml] タブをクリックします。
116
ネイティブ Android の開発
詳細画面を作成する
10. <application> セクションに次のコードを追加して、AndroidManifest.xml で新しいアクティビティ
を宣言します。
<!-- Merchandise detail screen -->
<activity android:name="com.samples.warehouse.DetailActivity"
android:theme="@android:style/Theme.NoTitleBar.Fullscreen">
</activity>
後で追加するボタンを除き、詳細画面のレイアウトおよび文字列リソースの設計は完了しました。画面の動作
を実装するには、新しいアクティビティを定義します。
ステップ 2: DetailActivity クラスを作成する
このモジュールでは、com.samples.warehouse パッケージで DetailActivity.java という名前の新しい
クラスファイルを作成します。
1. Package Explorer で、[WarehouseApp] > [src] > [com.samples.warehouse] ノードを展開します。
2. Ctrl キーを押しながら com.samples.warehouse フォルダをクリックし、[New (新規)] > [Class (クラス)] を
選択します。
3. [Name (名前)] 項目で、[「DetailActivity」] と入力します。
4. [Superclass (スーパークラス)]項目で、com.salesforce.androidsdk.ui.sfnative.SalesforceActivity
を入力または参照します。
5. [Finish (完了)] をクリックします。
コンパイラは、必要な onResume() メソッドのスタブ実装を提供します。Mobile SDK は、RestClient の
インスタンスをこのメソッドに渡します。REST API 要求を作成するには、このインスタンスが必要であるた
め、インスタンスへの参照をキャッシュすることをお勧めします。
6. 新しいクラスの上部にあるメンバー変数のリストに次の宣言を追加します。
private RestClient client;
7. onResume() メソッド本文で、次のコードを追加します。
@Override
public void onResume(RestClient client) {
// Keeping reference to rest client
this.client = client;
}
ステップ 3: DetailActivity クラスをカスタマイズする
アクティビティの設定を完了するには、Merchandise 項目値の編集を処理するように DetailActivity クラス
をカスタマイズします。
1. DetailActivity.java の上部にあるインポートリストに次のインポートを追加します。
import android.widget.EditText;
import android.os.Bundle;
117
ネイティブ Android の開発
詳細画面を作成する
2. クラス本文の上部で、3 つの入力項目に対応する非公開 EditText メンバーを追加します。
private EditText nameField;
private EditText priceField;
private EditText quantityField;
3. Merchandise カスタムオブジェクトのレコード ID を格納する変数を追加します。後でメインアクティビティ
と詳細アクティビティをリンクするときに、この変数を入力するコードを追加します。
private String merchandiseId;
4. 作成した detail.xml レイアウトを使用するようにビューを設定する onCreate() メソッドを追加しま
す。このメソッドをクラス定義の最後の直前に配置します。
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup view
setContentView(R.layout.detail);
nameField = (EditText) findViewById(R.id.name_field);
priceField = (EditText) findViewById(R.id.price_field);
quantityField = (EditText)
findViewById(R.id.quantity_field);
}
ステップ 4: 2 つのアクティビティをリンクする - 第 1 部: データクラスを作成
する
次に、MainActivity クラスと DetailActivity クラスを接続し、選択した Merchandise レコードの項目を共
有できるようにする必要があります。ユーザが在庫リストの項目をクリックしたら、MainActivity は、レ
コードの項目を表示するために必要なデータと共に DetailActivity を起動する必要があります。
現時点では、MainActivity.java のリストアダプタには Merchandise 項目の名前のみがあります。標準項目
(id と name) およびカスタム項目 (quantity と price) の値をローカルに保存して、これらを詳細画面に送信
できるようにしましょう。
まず、Merchandise レコードを表す静的データクラスを定義します。
1. Package Explorer で、[src] > [com.samples.warehouse] > [MainActivity.java] を開きます。
2. MainActivity 定義の最後に、次のクラス定義を追加します。
/**
* Simple class to represent a Merchandise record
*/
static class Merchandise {
public final String name;
public final String id;
public final int quantity;
public final double price;
public Merchandise(String name, String id, int quantity, double price) {
118
ネイティブ Android の開発
詳細画面を作成する
this.name = name;
this.id = id;
this.quantity = quantity;
this.price = price;
}
public String toString() {
return name;
}
}
3. このクラスを機能させるには、文字列ではなく Merchandise オブジェクトのリストを取得するようにメイン
アクティビティのリストアダプタを変更します。listAdapter 変数の宣言で、テンプレートの種類を
String から Merchandise に変更します。
private ArrayAdapter<Merchandise> listAdapter;
4. 新しい種類に合わせて、onResume() メソッドで listAdapter のインスタンス化を変更します。
listAdapter = new ArrayAdapter<Merchandise>(this, android.R.layout.simple_list_item_1,
new ArrayList<Merchandise>());
次に、SOQL コールの応答を受信したときに listAdapter オブジェクトを入力するコードを変更します。
5. ファイルの上部にある既存のリストに次のインポートを追加します。
import org.json.JSONObject;
6. 新しい Merchandise オブジェクトを使用するように fetchDataForList() の onSuccess() メソッド
を変更します。
public void onSuccess(RestRequest request, RestResponse result) {
try {
listAdapter.clear();
JSONArray records = result.asJSONObject().getJSONArray("records");
for (int i = 0; i < records.length(); i++) {
JSONObject record = records.getJSONObject(i);
Merchandise merchandise = new Merchandise(record.getString("Name"),
record.getString("Id"), record.getInt("Quantity__c"),
record.getDouble("Price__c"));
listAdapter.add(merchandise);
}
} catch (Exception e) {
onError(e);
}
}
119
ネイティブ Android の開発
詳細画面を作成する
ステップ 5: 2 つのアクティビティをリンクする - 第 2 部: リスト項目クリック
ハンドラを実装する
次に、クリックイベントをキャッチして、これらのイベントの発生時に詳細画面を起動する必要があります。
MainActivity をリストビュー項目のクリックのリスナーにします。
1. エディタで MainActivity.java ファイルを開きます。
2. 次のインポートを追加します。
import android.widget.AdapterView.OnItemClickListener;
3. クラス宣言を変更して、OnItemClickListener インターフェースを実装します。
public class MainActivity extends SalesforceActivity implements OnItemClickListener {
4. このリストビューの非公開メンバーを追加します。
private ListView listView;
5. super.onResume() コールの直前の onResume() メソッドに次の太字のコードを追加します。
public void onResume() {
// Hide everything until we are logged in
findViewById(R.id.root).setVisibility(View.INVISIBLE);
// Create list adapter
listAdapter = new ArrayAdapter<Merchandise>(
this, android.R.layout.simple_list_item_1, new ArrayList<Merchandise>());
((ListView) findViewById(R.id.contacts_list)).setAdapter(listAdapter);
// Get a handle for the list view
listView = (ListView) findViewById(R.id.contacts_list);
listView.setOnItemClickListener(this);
super.onResume();
}
リスト項目クリック用のリスナーを指定したので、リスト項目クリックハンドラを追加できます。
6. 次のインポートを追加します。
import android.widget.AdapterView;
import android.content.Intent;
7. Merchandise クラス定義の直前に、onItemClick() メソッドを追加します。
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
}
8. Merchandise オブジェクトの形式でリストアダプタから選択された項目を取得します。
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Merchandise merchandise = listAdapter.getItem(position);
120
ネイティブ Android の開発
詳細画面を作成する
}
9. 商品の詳細を渡して、詳細アクティビティを開始する Android のインテントを作成します。
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
Merchandise merchandise = listAdapter.getItem(position);
Intent intent = new Intent(this, DetailActivity.class);
intent.putExtra("id", merchandise.id);
intent.putExtra("name", merchandise.name);
intent.putExtra("quantity", merchandise.quantity);
intent.putExtra("price", merchandise.price);
startActivity(intent);
}
インテントから商品の詳細を抽出できるように DetailActivity クラスを更新して、終了しましょう。
10. Package Explorer で、[src] > [com.samples.warehouse] > [DetailActivity.java] を開きます。
11. onCreate() メソッドで、リスト画面の選択値を詳細アクティビティの対応するデータメンバーに割り当
てます。
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Setup view
setContentView(R.layout.detail);
nameField = (EditText) findViewById(R.id.name_field);
priceField = (EditText) findViewById(R.id.price_field);
quantityField = (EditText)
findViewById(R.id.quantity_field);
// Populate fields with data from intent
Bundle extras = getIntent().getExtras();
merchandiseId = extras.getString("id");
nameField.setText(extras.getString("name"));
priceField.setText(extras.getDouble("price") + "");
quantityField.setText(extras.getInt("quantity") + "");
}
ステップ 6: [更新] ボタンを実装する
もう少しで作業は終了します。不足している UI は、ユーザの編集内容をサーバに書き込むためのボタンのみ
です。次の操作を行う必要があります。
• ボタンをレイアウトに追加する
• ボタンの表示ラベルを定義する
• クリックハンドラを実装する
• 編集内容をサーバに保存する機能を実装する
121
ネイティブ Android の開発
詳細画面を作成する
1. detail.xml を再度開き、次の <Button> ノードを最も外側のレイアウトの最後のノードとして追加しま
す。
<Button
android:id="@+id/update_button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onUpdateClick"
android:text="@string/update_button" />
2. detail.xml ファイルを保存し、strings.xml を開きます。
3. 次のボタンの表示ラベル文字列を文字列リストの最後に追加します。
<string name="update_button">Update</string>
4. strings.xml ファイルを保存し、DetailActivity.java を開きます。
DetailActivity クラスで、[更新] ボタンの onClick イベントのハンドラを追加します。ハンドラの名前
は、detail.xml に追加した <Button> ノードの android:onClick 値と一致している必要があります。
この場合、名前は onUpdateClick です。このメソッドは単に、Merchandise__c 項目名をそれに対応す
る詳細画面の値と照合する対応付けを作成します。値が設定されると、saveData() メソッドをコールし
て、変更内容をサーバに書き込みます。
5. ハンドラをサポートするには、ファイルの上部にある既存のリストに次のインポートを追加します。
import java.util.HashMap;
import java.util.Map;
import android.view.View;
6. 次のメソッドを DetailActivity クラス定義に追加します。
public void onUpdateClick(View v) {
Map<String, Object> fields = new HashMap<String, Object>();
fields.put("Name", nameField.getText().toString());
fields.put("Quantity__c", quantityField.getText().toString());
fields.put("Price__c", priceField.getText().toString());
saveData(merchandiseId, fields);
}
saveData() が定義されていないことがコンパイラから通知されます。これを修正しましょう。saveData()
メソッドは、ユーザの値を使用して Merchandise__c オブジェクトを更新する REST API 更新要求を作成し
ます。次に、RestClient.sendAsync() メソッドを使用して、非同期に要求をサーバに送信します。サー
バ応答 (またはサーバエラー) を受信するコールバックメソッドは、sendAsync() コールでインラインで定
義されます。
7. ファイルの上部にある既存のリストに次のインポートを追加します。
import com.salesforce.androidsdk.rest.RestRequest;
import com.salesforce.androidsdk.rest.RestResponse;
122
ネイティブ Android の開発
Android ネイティブサンプルアプリケーション
8. saveData() メソッドを DetailActivity クラス定義に実装します。
private void saveData(String id, Map<String, Object> fields) {
RestRequest restRequest;
try {
restRequest = RestRequest.getRequestForUpdate(getString(R.string.api_version),
"Merchandise__c", id, fields);
} catch (Exception e) {
// You might want to log the error or show it to the user
return;
}
client.sendAsync(restRequest, new RestClient.AsyncRequestCallback() {
@Override
public void onSuccess(RestRequest request, RestResponse result) {
try {
DetailActivity.this.finish();
} catch (Exception e) {
// You might want to log the error or show it to the user
}
}
@Override
public void onError(Exception e) {
// You might want to log the error or show it to the user
}
});
}
これで完成です。アプリケーションを実行してテストする準備ができました。
ステップ 7: アプリケーションを試す
1. アプリケーションを構築し、Android エミュレータで実行します。すべて適切に行った場合、Warehouse 画面
の Merchandise レコードをクリックしたときに詳細ページが表示されます。
2. レコードの数量と価格を更新します。値を編集した後で詳細ビューの [更新] ボタンをクリックしてくださ
い。詳細ビューに戻ると、更新された値が表示されます。
3. DE 組織にログインして、ブラウザ UI でレコードを表示し、更新された値を確認します。
Android ネイティブサンプルアプリケーション
Salesforce Mobile SDK には、次のネイティブ Android サンプルアプリケーションがあります。
• RestExplorer: SalesforceSDK の OAuth および REST API 機能を示します。また、REST API アクションをタブレットか
ら調べる場合にも便利です。
• NativeSqlAggregator: SQL と SmartSQL の統合を示します。また、そのようなアプリケーションとして SmartStore
のネイティブ実装の方法も示します。
• FileExplorer: Files API および基盤となる Google Volley のネットワーキングの機能強化を示します。
123
ネイティブ Android の開発
Android ネイティブサンプルアプリケーション
• SmartSyncExplorer: Android 上でのネイティブ SmartSync ライブラリの機能を示します。このサンプルアプリ
ケーションは、native/SampleApps/SmartSyncExplorer の Mobile SDK for Android にあります。
124
第5章
トピック:
•
はじめに
•
HTML5 開発ツール
•
Visualforce を使用し
た HTML5 コンテン
ツの配信
•
Salesforce データへ
のアクセス: コント
ローラと API
•
ハイブリッドアプ
リケーションのク
イックスタート
•
ハイブリッドアプ
リケーション
•
iOS 7 ハイブリッド
アプリケーション
でのステータス
バーの制御
•
ハイブリッドアプ
リケーションの
JavaScript ファイル
•
バージョン設定お
よび JavaScript ライ
ブラリの互換性
•
ハイブリッドアプ
リケーションでの
セッション管理
•
Android ハイブリッ
ドアプリケーショ
ンからの SmartStore
と SmartSync の削除
•
例: 適切な JavaScript
ライブラリの提供
HTML5 およびハイブリッド開発
HTML5 により、ターゲットデバイスにソフトウェアをインストールせずに、軽量モ
バイルインターフェースを作成できます。どのモバイルデバイス、タッチデバイス、
デスクトップデバイスからでも、このモバイルインターフェースにアクセスできま
す。HTML5 でカメラや GPS など高度なモバイル機能がサポートされるようになり、
これらの一般的なデバイス機能を Salesforce モバイルアプリケーションで簡単に使用
できるようになりました。
次の方法で、Force.com プラットフォームを使用する HTML5 アプリケーションを作成
できます。
• Visualforce を使用して、HTML コンテンツを配信する。
• JavaScript Remoting を使用して、Force.com からレコードを取得するための Apex コン
トローラを呼び出す。
また、スタンドアロンの Mobile SDK ハイブリッドアプリケーションで HTML5 コードを
再設定し、App Store から配布することもできます。ハイブリッドに変換するには、
サードパーティの Cordova コマンドラインを使用して Mobile SDK コンテナプロジェク
トを作成してから、HTML5、JavaScript、および CSS ファイルをこのプロジェクトにイ
ンポートします。
125
HTML5 およびハイブリッド開発
はじめに
はじめに
Web 開発者には、Salesforce にアクセスする HTML5 アプリケーションを作成する準備が整えられています。HTML5
アプリケーションはブラウザで実行可能で、Salesforce Mobile SDK は必要ありません。開発者の作業は、Salesforce
API をコールして戻り値を取得し、それをロジックと UI につなげるだけです。モバイルブラウザで他のアプリ
ケーションを実行する場合と同じ利点と課題がありますが、Salesforce とそのパートナーがモバイル Web 設計お
よびコーディングの合理化に役立つツールを提供しています。
HTML5 アプリケーションをハイブリッドコンテナでスタンドアロンとして開発し、Apple® AppStore® または Android
マーケットプレイスで配布する場合は、Mobile SDK を使用してハイブリッドアプリケーションを作成する必要
があります。
HTML5 および JavaScript の使用
HTML5 コードおよび JavaScript コードを記述するために、Xcode や Microsoft® Visual Studio® などの専門的な開発環境
は必要ありません。最新のブラウザには、HTML や JavaScript デバッガなどの高度な開発機能が含まれています。
実際、アプリケーションをテキストエディタで作成し、ブラウザでテストすることができます。ただし、コー
ディング作業を最小限に抑える上で役立つ、業界の主要なライブラリに関しての十分な知識は必要です。
モバイル開発の近年の成長により、新しい Web 技術ツールキットが急増しました。これらの JavaScript ライブ
ラリの多くはオープンソースで、ライセンスは必要ありません。HTML5 開発用に Salesforce で提供されるほとん
どのツールは、このようなサードパーティ技術で構築されています。
HTML5 の開発要件
ブラウザベースの HTML5 Salesforce アプリケーションの作成を計画している場合は、Salesforce Mobile SDK は必要あ
りません。
• Force.com 組織が必要です。
• Apex および Visualforce に関する多少の知識が必要です。
メモ: このタイプの開発では、Visualforce を使用します。Database.com は使用できません。
マルチデバイス戦略
モバイルデバイスは世界的に普及しているため、HTML5 モバイルアプリケーションはさまざまなプラットフォー
ムやフォーム要素、デバイス機能に対応する必要があります。Visualforce でデバイスに依存しないモバイルア
プリケーションを作成する開発者は、次の重要な設計上の検討事項に直面します。
• アプリケーションでどのデバイスやフォーム要素をサポートするか?
• アプリケーションでデバイスの種類をどのように検出するか?
• 数種のデバイスを適切にサポートする Force.com アプリケーションをどのように設計するか?
126
HTML5 およびハイブリッド開発
マルチデバイス戦略
どのデバイスやフォーム要素をサポートするか?
この検討事項に対する答えは、特定の用途やエンドユーザの要望によって異なります。ただし、具体的にどの
デバイス、プラットフォーム、フォーム要素をサポートする必要があるかを時間をかけて検討することは重要
です。「あらゆるプラットフォーム、デバイス、フォーム要素をサポート」から、たとえば「デスクトップと
iPhone のみサポート」までの広いサポート範囲でどの程度サポートするかによって、上記の残りの 2 つの検討
事項への回答が大きく左右されます。
お分かりのように、この決定を下す際には重要なトレードオフを考慮する必要があります。多くのフォーム要
素をサポートすれば、当然アプリケーションの利用者層が増加します。しかし、アプリケーションの初期開発
と長期的な管理の両面においては複雑性が増大するという犠牲を伴います。
真のクロスデバイスアプリケーションの開発とは、どのフォーム要素やデバイス (デスクトップ、スマートフォ
ン、タブレット) でも Web ページの表示 (およびパフォーマンス) を最適にするという単純な問題ではありませ
ん。特定のデバイスやフォーム要素ごとにユーザ操作性を再考してカスタマイズする必要に迫られます。ス
マートフォンやタブレット向けのアプリケーションでは、デスクトップ向けに最適化された既存の Web ペー
ジでサポートされる付加的な機能 (ファイルのアップロードや、多数の異なるクリック操作を要する使用事例
のサポートなど) が必要なことはほとんどありません。
反対に、スマートフォンやタブレット向けのアプリケーションでは、地理位置情報や写真撮影といった、デス
クトップ環境では不可能な機能をサポートできます。LinkedIn や Flipboard のような優れた設計のアプリケーショ
ンでは、スマートフォン向けとタブレット向けでも機能が大きく異なります (たとえば、タブレット向けは水
平ナビゲーションで、スマートフォン向けは片手操作の垂直スクロール)。アプリケーションでどのデバイス
およびフォーム要素をサポートするかを決定するときは、これらのすべての事項に加え、サポートに関連して
必要な時間とコストも考慮します。
どのデバイスをサポートするかを決定したら、特定のユーザがどのデバイスから Web アプリケーションにア
クセスしているかを検出する必要があります。
クライアント側での検出
クライアント側の検出アプローチでは、クライアントブラウザ上で実行されている JavaScript (または CSS メディ
アクエリ) を使用してデバイスの種類を判別します。具体的には、次の 2 つの方法でデバイスの種類を検出で
きます。
• ユーザエージェントヘッダーによるクライアント側のデバイス検出 — このアプローチでは、JavaScript を使
用してユーザエージェント HTTP ヘッダーを解析し、この情報に基づいてデバイスの種類を判別します。も
ちろん、この判別を行う独自の JavaScript を記述することも可能ですが、既存の JavaScript を再利用すること
をお勧めします。インターネットをざっと検索しただけでも、ユーザエージェントヘッダーに基づいてデ
バイスの種類を検出できる再利用可能な JavaScript スニペットが多数見つかります。ただし、こうした検索
では、このアプローチを使用した場合の危険性も知ることになります。使用される可能性のある全ユーザ
エージェントのリストは膨大なうえ現在も増え続けていることから、この方法は概して信頼性が低いもの
と考えられています。
• 画面サイズやデバイス機能によるクライアント側のデバイス検出 — JavaScript のユーザエージェント文字列
を探るよりも適切な代替法は、デバイスの画面サイズや機能 (タッチ対応など) に基づいてデイバスの種類
を判別することです。オープンソースの Contact Viewer HTML5 モバイルアプリケーションはこのアプローチ
の一例で、すべて Visualforce で構築されています。具体的には、MobileAppTemplate.page のページ上部に、デ
バイスの画面サイズに基づいてスマートフォンとタブレットを判別するシンプルな JavaScript スニペットが
127
HTML5 およびハイブリッド開発
マルチデバイス戦略
記述されています。もう 1 つのオプションは、Device.js や Modernizr などのライブラリを使用してデイバスの
種類を検出する方法です。これらのライブラリは、CSS メディアクエリと機能検出 (タッチ対応など) の一定
の組み合わせを使用するため、デバイスの種類を検出する信頼性の高い方法になります。Modernizr ライブ
ラリを使用してデバイスの種類を検出する簡単な例については、
http://www.html5rocks.com/static/demos/cross-device/feature/index.html を参照してくだ
さい。Device.js ライブラリを使用して Visualforce と統合する包括的な例については、GitHub リポジトリ
(https://github.com/sbhanot-sfdc/Visualforce-Device.js) を参照してください。このリポジト
リの DesktopVersion.page から抜粋したスニペットを次に示します。
<apex:page docType="html-5.0" sidebar="false" showHeader="false" standardStylesheets="false"
cache="false" >
<head>
<!-- Every version of your webapp should include a list of all
versions. -->
<link rel="alternate" href="/apex/DesktopVersion" id="desktop" media="only screen and
(touch-enabled: 0)"/>
<link rel="alternate" href="/apex/PhoneVersion" id="phone" media="only screen and
(max-device-width: 640px)"/>
<link rel="alternate" href="/apex/TabletVersion" id="tablet" media="only screen and
(min-device-width: 641px)"/>
<meta name="viewport" content="width=device-width, user-scalable=no"/>
<script src="{!URLFOR($Resource.Device_js)}"/>
</head>
<body>
<ul>
<li><a href="?device=phone">Phone Version</a></li>
<li><a href="?device=tablet">Tablet Version</a></li>
</ul>
<h1> This is the Desktop Version</h1>
</body>
</apex:page>
上記のスニペットは、アプリケーションでサポートするデバイスの種類ごとに <link> タグを簡単に追加でき
ることを示しています。Device.js ライブラリが、検出されたデバイスの種類に基づいて自動的にユーザを
適切なVisualforceページにリダイレクトします。また、上記の「?device=xxx」という形式を使用して、デフォル
トの Device.js リダイレクトを上書きする方法もあります。
サーバ側でのデバイス検出
もう 1 つのオプションは、サーバ上 (Apex コントローラや拡張クラスなど) でデバイスの種類を検出する方法で
す。サーバ側でのデバイス検出は、ユーザエージェント HTTP ヘッダーの解析に基づきます。次に、Visualforce
ページが iPhone クライアントから参照されているかどうかを検出できる方法を示す簡単なコードスニペットを
示します。
<apex:page docType="html-5.0" sidebar="false" showHeader="false" cache="false"
standardStylesheets="false" controller="ServerSideDeviceDetection"
action="{!detectDevice}">
128
HTML5 およびハイブリッド開発
マルチデバイス戦略
<h1> This is the Desktop Version</h1>
</apex:page>
public with sharing class ServerSideDeviceDetection {
public boolean isIPhone {get;set;}
public ServerSideDeviceDetection() {
String userAgent =
System.currentPageReference().getHeaders().get('User-Agent');
isIPhone = userAgent.contains('iPhone');
}
public PageReference detectDevice(){
if (isIPhone)
return Page.PhoneVersion.setRedirect(true);
else
return null;
}
}
上記のコードスニペットのユーザエージェント解析は、包括的ではないため、正規表現マッチングに基づいて
サポートする必要があるすべてのデバイスを検出するより堅牢な機能を実装する必要があります。手始めに、
detectmobilebrowsers.com のコードスニペットに含まれる正規表現を確認することをお勧めします。
数種のデバイスを適切にサポートする Force.com アプリケーションをどのよう
に設計するか?
サポートする必要のあるデバイスと、そのデバイスの判別方法が決まったら、デバイスやフォーム要素ごとに
カスタマイズされたユーザ操作性を提供する最適なアプリケーション設計を考えます。ここでもいくつかのオ
プションを検討します。
同一の Visualforce ページを各種のフォーム要素で適切に表示させるだけでよいシンプルなアプリケーションの
場合は、応答性の高い設計アプローチが効果的なオプションです。簡単に言うと、応答性の高い設計では、
CCS3 メディアクエリを使用し、クライアントブラウザのフォーム要素に合わせてページの書式を動的に再設定
します。Twitter Bootstrap のような応答性の高い設計フレームワークもこの用途に使用できます。
もう 1 つのオプションは、複数の Visualforce ページを設計し、特定のフォーム要素ごとに各ページを最適化し
てから、前のセクションで説明したいずれかの手法を使用してユーザを適切なページにリダイレクトする方法
です。個別の Visualforce ページを用意するからといって、コードや機能が重複するわけではなく、また重複す
べきでもありません。適切に設計されたソリューションでは、クライアント側 (コンポーネントやテンプレー
トなど Visualforce の戦略を使用する) とサーバ側 (たとえば、共通のビジネスロジックを Apex クラスにカプセル
化して複数のページコントローラからコールできるようにする) の両方でコードを最大限に再利用できます。
こうした設計の優れた例は、前述のオープンソースの Contact Viewer アプリケーションで確認できます。このア
プリケーションはスマートフォン向け (ContactsAppMobile.page) とタブレット向け (ContactsApp.page)
に異なるページを用意していますが、両方が共通のテンプレート (MobileAppTemplate.page) を共有してい
るため、コードやアイテムが最大限に再利用されています。下の図は、Contact Viewer アプリケーションの設計
上の概念を示しています。
129
HTML5 およびハイブリッド開発
サポートされるブラウザ
また、1 つのVisualforceページを複数のフォーム要素に対応させることも可能です。この場合は、サーバ側でデ
バイスの検出を行い、ほとんどの Visualforce コンポーネント (具体的には、<div> タグの CSS「display:none/block」
プロパティ) で使用可能な「rendered」属性を利用して、ページ要素を選択的に表示または非表示にします。 た
だし、このアプローチはコードが膨大になり、管理が困難になる可能性があるため、慎重に使用する必要があ
ります。
サポートされるブラウザ
Salesforce フルサイトでサポートされるブラウザについて説明します。
重要: Summer '15 以降、Microsoft® Internet Explorer® バージョン 7 および 8 のサポートは停止されます。これら
のバージョンでは、このリリース日以降一部の機能が動作しなくなる可能性があります。このリリース
日以降、Salesforce カスタマーサポートでは Internet Explorer 7 および 8 に関する問題の調査は行いません。
Salesforce1 アプリケーションでサポートされるモバイルブラウザについては、「Salesforce1 アプリケーショ
ンの使用の要件」を参照してください。
130
HTML5 およびハイブリッド開発
サポートされるブラウザ
ブラウザ
コメント
Microsoft® Internet Explorer® バージョン 7、
8、9、10、11
Internet Explorer を使用する場合は、Salesforce でサポートされている
最新バージョンを使用することをお勧めします。すべての Microsoft
ソフトウェア更新を適用してください。次の制限があります。
• Salesforceフルサイトは、Windows 向けタッチ対応デバイスの Internet
Explorer ではサポートされていません。代わりに Salesforce1 モバ
イルブラウザアプリケーションを使用してください。
• [Salesforce1 の設定] ページと Salesforce1 ウィザードを使用するには
Internet Explorer 9 以降が必要です。
• Internet Explorer 11 の HTML ソリューションエディタは、Salesforce
ナレッジではサポートされていません。
• Internet Explorer の互換表示機能はサポートされていません。
• Internet Explorer 10 の Metro バージョンはサポートされません。
• Internet Explorer 6 および 7 は、複数アカウントのログインヒント
ではサポートされていません。
• Internet Explorer 7 および 8 は、データインポートウィザードでは
サポートされていません。
• Internet Explorer 7、8、および 11 は、開発者コンソールではサポー
トされていません。
• Internet Explorer 7 は、Open CTI ではサポートされていません。
• Internet Explorer 7 および 11 は、CTI Toolkit バージョン 4.0 以降を使用
して作成された Salesforce CRM Call Center ではサポートされていま
せん。
• Internet Explorer 7 は、Force.com Canvas ではサポートされていませ
ん。
• Internet Explorer 7 は、高度なブラウザパフォーマンスや最近の Web
テクノロジを必要とする Salesforce コンソール機能ではサポート
されていません。Internet Explorer 7 で使用できないコンソール機
能は次のとおりです。
– [最新のタブ] コンポーネント
– サイドバーの複数のカスタムコンソールコンポーネント
– サイドバーに積み上げられているコンソールコンポーネント
の垂直方向の自動サイズ調整
– コンソールコンポーネントの [ボタン CSS] のフォントと
フォントの色
– マルチモニターコンポーネント
– サイズ変更可能な強調表示パネル
– フィードベースのページレイアウトの全体の幅のフィードオ
プション
131
HTML5 およびハイブリッド開発
ブラウザ
サポートされるブラウザ
コメント
• Internet Explorer 7 および 8 は、セルフサービスのコミュニティテ
ンプレートではサポートされていません。
• Internet Explorer 7 および 8 では、商談分割の複数行の編集が使用
されると、パフォーマンス上の問題が生じます。
• セルフサービスのコミュニティテンプレートでは、Internet Explorer
9 以降でデスクトップユーザが、Internet Explorer 11 以降でモバイ
ルユーザがサポートされています。
• Internet Explorer 7、8、および 9 は、Salesforce Analytics Cloud ではサ
ポートされません。
設定の推奨事項については、「Internet Explorer の設定」を参照して
ください。
Mozilla® Firefox® の最新の安定バージョン
Salesforce は Firefox の最新バージョンのテストおよびサポートに努め
ています。
• Mozilla Firefox は、セルフサービスのコミュニティテンプレートの
デスクトップユーザに対してのみサポートされています。
設定の推奨事項については、「Firefox の設定」を参照してくださ
い。
Google Chrome™ の最新の安定バージョン Google Chrome は自動的に更新を適用するため、Salesforce は最新バー
ジョンのテストおよびサポートに努めています。Chrome の設定に
関する推奨事項はありません。Chrome は、[Google ドキュメントを
Salesforce に追加] ブラウザボタンまたは [コンソール] タブではサ
ポートされていません (Salesforce コンソールはサポートされていま
す)。
Mac OS X での Apple® Safari® バージョン 5.x
および 6.x
Safari の設定に関する推奨事項はありません。iOS の Apple Safari は、
Salesforce フルサイトではサポートされていません。
• Safari は、Salesforce コンソールではサポートされていません。
• Safari は、バージョン 4.0 より前の CTI Toolkit を使用して作成され
た Salesforce CRM Call Center ではサポートされていません。
• Safari は、Salesforce Analytics Cloud ではサポートされていません。
すべてのブラウザに関する推奨事項と要件
• すべてのブラウザに対して、JavaScript、Cookie、TLS 1.0 を有効にする必要があります。
• Salesforce では、ユーザの操作性を最大限に高めるために、少なくとも 1024x768 の画面解像度を使用するこ
とをお勧めします。画面解像度が 1024 x 768 未満である場合、レポートビルダーやページレイアウトエディ
タなどの Salesforce 機能が表示されない可能性があります。
• Apple Safari または Google Chrome を使用している Mac OS ユーザは、システム設定の [スクロールバーを表示]
が [常に] に設定されていることを確認してください。
132
HTML5 およびハイブリッド開発
サポートされるブラウザ
• 一部のサードパーティ Web ブラウザプラグインと拡張は、Chatter の機能に干渉する可能性があります。
Chatter が正常に機能しなかったり、整合性のない動作をする場合は、すべての Web ブラウザのプラグイン
と拡張を無効にしてから、もう一度試してみてください。
Salesforceの特定の機能には、一部のデスクトップクライアント、ツールキット、およびアダプタと同様に、独
自のブラウザ要件があります。次に例を示します。
• Internet Explorer は、次の機能を唯一サポートしているブラウザです。
– 標準差し込み印刷
– Windows Mobile デバイスへの Salesforce Classic のインストール
– Connect Offline
• 高度なページレイアウトエディタには、Firefox をお勧めします。
• Salesforce コンソールには、8 GB の RAM が搭載されたマシンで Chrome を使用することをお勧めします。
• Chatter で複数のファイルをアップロードする場合には、ブラウザ要件も適用されます。
停止されたサポートまたは制限付きのブラウザサポート
Summer '12 の時点で、Salesforce は Microsoftョ Internet Explorerョ 6 に対するサポートを停止しました。このブラウザ
で以前に機能していた既存の機能は、2014 年まで継続して動作する予定です。次のサポート制限があります。
• Internet Explorer 6 は、以下ではサポートされていません。
– アンサー
– Chatter
– Chatter アンサー
– Cloud Scheduler
– 拡張されたダッシュボードグラフオプション
– 拡張プロファイルユーザインターフェース
– 売上予測
– グローバル検索
– 結合レポート
– Live Agent
– 見積テンプレートエディタ
– Salesforce コンソール
– Salesforce ナレッジ
– スキーマビルダー
– Site.com
– エンタープライズテリトリー管理
– 新しいユーザインターフェースのテーマ
Internet Explorer 7 は、Site.com および Chatter Messenger ではサポートされていません。
133
HTML5 およびハイブリッド開発
HTML5 開発ツール
HTML5 開発ツール
今日の Web 開発者にとって、HTML5 開発をすばやく行うにはオープンソースツールが不可欠です。これらの
ツールを使用すると、HTML5 開発を大幅に簡略化できます。ツールの中には、一般的なオープンソース JavaScript
フレームワークで構築されているものもあれば、自社開発されたソリューションもあります。たとえば、Google
の Polymer フレームワークを Force.com JavaScript ライブラリと組み合わせると、Salesforce 対応のモバイルアプリ
ケーションを非常にすばやく作成できます。Salesforceでは、これと同様に機能するベータのオープンソースラ
イブラリ (モバイル UI 要素) を GitHub で提供しています。
モバイル UI 要素 (ベータ)
モバイルアプリケーションには、軽量で楽しく魅力があることが要求されます。モバイルアプリケーション開
発者は、一連の API に拘束される別のリストビューや詳細ページを再作成するのではなく、革新的な機能の作
成に時間をかける必要があります。HTML 開発者および JavaScript 開発者は、オープンソースのモバイル UI 要素
を使用して、既知の技術 (柔軟で使いやすい開発済みの一連のコンポーネント) を使用して画期的なアプリケー
ションを作成できます。
モバイル UI 要素アプリケーションは、次の方法でリリースできます。
• Visualforce ページでリリースする
• www.heroku.com または別のサードパーティサービスのリモートホストされるページでリリースする
• Salesforce Mobile SDK で提供されるハイブリッドコンテナを使用するスタンドアロンアプリケーションとして
リリースする
モバイル UI 要素は、Google の Polymer フレームワークに基づいた、オープンソースのサポート対象外ライブラ
リです。複雑なモバイルアプリケーションを作成するために組み合わせ可能な、基本的なビルディングブロッ
クを提供します。HTML 開発者はこのコンポーネントライブラリを使用して、複雑なモバイルフレームワーク
や設計パターンの詳しい知識を習得せずに、モバイルアプリケーションをすばやく簡単に作成できます。
モバイル UI 要素のソースコードは、https://github.com/ForceDotComLabs/mobile-ui-elements の Github にあります。
サードパーティのコード
モバイル UI 要素ライブラリでは、次のサードパーティのコンポーネントを使用しています。
• Polymer: 新しい拡張機能および機能を最新の HTML5 ブラウザに追加するために使用される JavaScript ライブラ
リ。Web コンポーネントで構築され、最新ブラウザ上で進化している Web プラットフォームを活用するよ
う設計されています。
• jQuery: JavaScript の作成を簡単にする JavaScript ライブラリ。
• Backbone.js: モデル–ビュー–プレゼンター (MVP) アプリケーション設計パラダイムを提供する JavaScript ライブ
ラリ。
• Underscore.js: JavaScript 用の「ユーティリティ関連」ライブラリ。
• Ratchet: 単純な HTML、CSS、JavaScript コンポーネントを使用するプロトタイプ iPhone アプリケーション。
次の参照セクションでは、現在使用可能な要素について説明します。
134
HTML5 およびハイブリッド開発
モバイル UI 要素 (ベータ)
force_selector_list
force-selector-list 要素は core-selector 要素の拡張で、force-sobject-collection 要素を囲む
ラッパーを提供します。force-selector-list は、セレクタ機能を必要とするリスト UI 要素のベースとし
て機能します。ユーザが行をタップすると、選択された属性が自動的に更新されます。
例
<force-selector-list sobject="Account" querytype="mru"></force-selector-list>
force-sobject
force-sobject 要素は、Polymer 要素の SmartSync Force.SObject をラップします。force-sobject 要素の
機能は、次のとおりです。
• キャッシュ用のオフラインストアの自動管理を提供する
• SmartSync SObject モデルとやりとりするための DOM ベースの単純なインターフェースを提供する
• 他の Polymer 要素が SmartSync を簡単に使用できるようにする
例
<force-sobject sobject="Account" recordid="001000000000AAA"></force-sobject>
force-sobject-collection
force-sobject-collection 要素は、SmartSync Force.SObjectCollection オブジェクトの Polymer 下位
ラッパーです。この要素の機能は、次のとおりです。
• キャッシュ用のオフラインデータストアを自動的に管理する (コンテナ内で実行されている場合)
• SmartSync とやりとりするための DOM ベースの単純なインターフェースを提供する
• 他の Polymer 要素が SmartSync データを簡単に使用できるようにする
例
<force-sobject-collection sobject="Account" querytype="mru"></force-sobject-collection>
force-sobject-layout
force-sobject-layout 要素は、特定の sObject レコードのレイアウト情報を提供します。この要素は
describeLayout API コールをラップします。レイアウト情報は既存のセッションのメモリにキャッシュさ
れ、オフラインで使用できるように SmartStore に保存されます。force-sobject-layout 要素はまた、
force-ui-detail や force-sobject-related など、ページレイアウトに依存する要素の基本定義を提供
します。
135
HTML5 およびハイブリッド開発
モバイル UI 要素 (ベータ)
例
<force-sobject-layout sobject="Account"></force-sobject-layout>
force-selector-relatedlist
force-selector-relatedlist 要素は、core-selector 要素を拡張したものであり、
force-sobject-collection 要素を使用して関連 sObject のレコードを取得します。
force-selector-relatedlist は、レコードの関連リストを表示しセレクタ機能も必要とする UI 要素の基
本要素です。
例
<force-selector-relatedlist related="{{related}}"></force-selector-relatedlist>
force-sobject-relatedlists
force-sobject-relatedlists 要素により、sObject レコードの関連リストが表示できます。関連リスト設定
をページレイアウト設定から取得するために、force-sobject-layout 要素を埋め込みます。特定の sObject
種別の関連リスト設定を解析します。recordid 属性が指定されている場合は、関連レコード項目を取得する
ために SOQL/キャッシュクエリも生成します。
例
<force-sobject-relatedlists sobject="Account"
recordid="001000000000AAA"></force-sobject-relatedlists>
force-sobject-store
force-sobject-store 要素は、Polymer 要素の SmartSync Force.StoreCache をラップします。この要素の
機能は、次のとおりです。
• sObject の種別ごとに SmartStore スープのライフサイクルを自動管理する
• sObject での参照関係に基づいてインデックス指定を自動作成する
• SmartSync SObject モデルとやりとりするための DOM ベースの単純なインターフェースを提供する
• 他の Polymer 要素が SmartStore データを簡単に使用できるようにする
例
<force-sobject-store sobject="Account"></force-sobject-store>
force-ui-app
force-ui-app 要素は、アプリケーションの基本のスタイルと構造を提供する最上位の UI 要素です。この要
素は、Polymer レイアウト機能を使用してページ上で柔軟なセクションを作成できるようにします。この機能
136
HTML5 およびハイブリッド開発
Visualforce を使用した HTML5 コンテンツの配信
は、分割ビューパネルを含む単一ページビューで便利です。メインセクションのすべての子セクションでは、
「コンテンツ」クラスを指定して正しいスタイルを適用する必要があります。
例
Visualforce コンテキストで使用する場合
<force-ui-app multipage="true"></force-ui-app>
force-ui-detail
force-ui-detail 要素により、Salesforce レコードの全画面表示が可能になります。この要素は、
force-sobject-layout 要素を使用してレコードのページレイアウトを取得します。また、sObject ですべて
の CRUD 操作を許可するために、force-sobject 要素の埋め込みも行います。デフォルトのスタイルを継承
するには、この要素が常に force-ui-app の子である必要があります。
例
<force-ui-detail sobject="Account" recordid="001000000000AAA"></force-ui-detail>
force-ui-list
force-ui-list 要素により、任意の sObject レコードのリストが表示できます。属性を使用して、特定のレ
コードセットを表示するようにこの要素を設定できます。適切なスタイルを継承するには、この要素が常に
force-ui-app の子である必要があります。
例
<force-ui-list sobject="Account" querytype="mru"></force-ui-list>
force-ui-relatedlist
force-ui-relatedlist 要素により force-selector-relatedlistelement が拡張され、sobject レコー
ドの関連レコードリストが表示されます。デフォルトのスタイルを継承するには、この要素が常に
force-ui-app の子である必要があります。
例
<force-ui-relatedlist related="{{related}}"></force-ui-relatedlist>
Visualforce を使用した HTML5 コンテンツの配信
デスクトップ環境用にカスタム Web サイトを作成するには、従来より Visualforce を使用しています。ただし、
HTML5 と組み合わせると、Visualforce がモバイル Web アプリケーションで実行できる配信メカニズムになりま
137
HTML5 およびハイブリッド開発
Salesforce データへのアクセス: コントローラと API
す。これらのアプリケーションでは、Sencha のようなサードパーティの UI ウィジェットライブラリや、AngularJS
および Backbone.js などのテンプレートフレームワークを活用して、Salesforce 内のデータにバインドできます。
HTML5 Apexページを設定するには、docType 属性を「html-5.0」に変更し、次のような他の設定を使用します。
<apex:page docType="html-5.0" sidebar="false" showHeader="false" standardStylesheets="false"
cache="true" >
</apex:page>
このコードは、HTML5 コンテンツを含めることができるApexページを設定しますが、作成されるのは空のペー
ジです。静的リソースとサードパーティのライブラリを使用することで、HTML と JavaScript のコードを追加し
て、完全に対話形式のモバイルアプリケーションを構築できます。
Salesforce データへのアクセス: コントローラと API
HTML5 アプリケーションでは、2 通りの方法で Salesforce データにアクセスできます。
• JavaScript Remoting を使用して、Apex コントローラを呼び出す。
• forcetk.mobilesdk.js を使用して Salesforce API にアクセスする。
JavaScript Remoting を使用した Apex コントローラの呼び出し
apex:actionFunction と同様に、JavaScript Remoting では、Visualforce ページでホストされる JavaScript コードを
使用して、Apex コントローラでメソッドを呼び出すことができます。
JavaScript Remoting には、いくつかの利点があります。
• apex:actionFunction に比べて柔軟性に富み、パフォーマンスが高い。
• Apex コントローラメソッドでパラメータと戻り値の型がサポートされ、Apex と JavaScript 間でデータ型の対
応付けが自動的に行われる。
• コールバックで非同期処理モデルを使用する。
• apex:actionFunction と異なり、AJAX 要求に Visualforce ページのビューステートが含まれない。この結
果、往復速度が速くなります。
ただし、apex:actionFunction に比べて、JavaScript Remoting ではより多くのコードを作成する必要がありま
す。
次の例では、Visualforce ページの <script> タグに JavaScript コードを挿入しています。このコードは、Visualforce
Remoting マネージャオブジェクトで invokeAction() メソッドをコールします。Apex コントローラオブジェ
クト objName で getItemId() という名前の関数をコールするのに必要なメタデータを invokeAction()
に渡します。invokeAction() は非同期で実行されるため、getItemId() から返される値を処理するコール
バック関数もコードで定義します。Apex コントローラでは、@RemoteAction アノテーションにより、外部の
JavaScript コードに getItemId() 関数が公開されます。
//Visualforce page code
<script type="text/javascript">
Visualforce.remoting.Manager.invokeAction(
'{!$RemoteAction.MyController.getItemId}',
objName,
138
HTML5 およびハイブリッド開発
Salesforce データへのアクセス: コントローラと API
function(result, event){
//process response here
},
{escape: true}
);
<script>
//Apex Controller code
@RemoteAction
global static String getItemId(String objectName) { ... }
@RemoteAction アノテーションについての詳細は、
http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_annotation_RemoteAction.htm を参照してくだ
さい。
ForceTK および jQuery を使用した Salesforce API へのアクセス
次のコードサンプルでは、ユーザインターフェースに jQuery Mobile ライブラリを使用しています。このコード
を実行するには、Visualforce ページに jQuery および ForceTK ライブラリが含まれている必要があります。これら
のリソースを追加する手順は、次のとおりです。
1. app.js、forcetk.mobilesdk.js、jquery.js、およびプロジェクトに必要な他の静的リソースを含む、
ZIP ファイルなどのアーカイブファイルを作成します。
2. Salesforce で、[あなたの名前] > [アプリケーションの設定] > [開発] > [静的リソース] からアーカイブファイル
をアップロードします。
jQuery Mobile ライブラリのインスタンスを取得すると、サンプルコードで ForceTK クライアントオブジェクトが
作成され、セッション ID を使用して初期化されます。次に非同期の ForceTK query() メソッドをコールして、
SOQL クエリが処理されます。クエリのコールバック関数では、jQuery Mobile を使用して、クエリから返された
最初の Name 項目が、「accountname」という ID のオブジェクトに HTML として表示されます。Apex ページの最
後では、HTML5 コンテンツにより accountname 要素が単純な <span> タグとして定義されます。
<apex:page>
<apex:includeScript value="{!URLFOR($Resource.static, 'jquery.js')}" />
<apex:includeScript value="{!URLFOR($Resource.static, 'forcetk.mobilesdk.js')}"
<script type="text/javascript">
// Get a reference to jQuery that we can work with
$j = jQuery.noConflict();
// Get an instance of the REST API client and set the session ID
var client = new forcetk.Client();
client.setSessionToken('{!$Api.Session_ID}');
client.query("SELECT Name FROM Account LIMIT 1", function(response){
$j('#accountname').html(response.records[0].Name);
});
</script>
<p>The first account I see is <span id="accountname"></span>.</p>
</apex:page>
139
/>
HTML5 およびハイブリッド開発
ハイブリッドアプリケーションのクイックスタート
メモ:
• Visualforce ページからであっても REST API を使用すると、API コールが使用されます。
• Mobile SDK コンテナまたは Cordova Web ビューから行う SalesforceAPI コールには、プロキシサービスは必
要ありません。Cordova Web ビューでは同じ発生元のポリシーが無効になるため、API コールを直接行
うことができます。この免除は、すべての Mobile SDK ハイブリッドアプリケーションとネイティブア
プリケーションに適用されます。
追加オプション
HTML5 アプリケーションでは、SmartSync Data Framework を使用できます。必要な JavaScript ライブラリを静的リ
ソースとして含めるだけで十分です。モデルおよび転送機能を利用してください。この場合、オフラインアク
セスは無効になります。「SmartSync を使用した Salesforce オブジェクトへのアクセス」を参照してください。
Salesforce Developer Marketing には、開発者向けに HTML5 アプリケーションのクイックスタートに役立つモバイル
パックが用意されています。
オフラインの制限事項
Force.com で HTML5 をオフラインで使用する場合のヒントについては、次の記事を参照してください。
• https://developer.salesforce.com/blogs/developer-relations/2011/06/using-html5-offline-with-forcecom.html
• http://developer.salesforce.com/blogs/developer-relations/2013/03/using-javascript-with-force-com.html
ハイブリッドアプリケーションのクイックスタート
ハイブリッドアプリケーションは、Salesforce Mobile SDK を活用しながら、容易に操作できる JavaScript および
HTML5 を使用して開発できます。
ハイブリッドアプリケーション開発の概念を理解している場合は、次の手順を使用してすばやく開発を開始で
きます。
1. Android のアプリケーション開発には、次の前提条件があります。
• Java JDK 6 以降 — http://www.oracle.com/downloads。
メモ: Android Lollipop には Java JDK 7 以降が必要です。
• Apache Ant 1.8 以降 — http://ant.apache.org。
• Android SDK 4.2.2 (API レベル 17) 以降 — Mobile SDK ハイブリッドアプリケーションのデフォルトの Android
SDK バージョンは 4.4 (API レベル 19) です。
• Android SDK Tools バージョン 21 以降 —http://developer.android.com/sdk/installing.html。
メモ: 最良の結果を得るには、対象バージョンだけでなく、Android SDK の以前のすべてのバージョ
ンもインストールします。
• Eclipse — https://www.eclipse.org。サポートされている Eclipse の最小バージョンについては、Android
開発ツールに関する Web サイトを参照してください。
140
HTML5 およびハイブリッド開発
ハイブリッドアプリケーション
• Eclipse バージョン 21 以降用の Android ADT (Android 開発ツール) プラグイン —
http://developer.android.com/sdk。
• アプリケーションをエミュレータで実行するには、Platform 4.2 以降を対象とする Android 仮想デバイス
(AVD) を少なくとも 1 つ設定する必要があります。Eclipse での AVD の設定方法については、
http://developer.android.com/guide/developing/devices/managing-avds.htmlの手順を参
照してください。
2. iOS のアプリケーション開発には、次の前提条件があります。
• Xcode — バージョン 6.0 以降 (最新バージョンを推奨)。
• iOS 7.0 以降。
• 接続アプリケーションが存在する Salesforce Developer Edition 組織。
3. Mobile SDK をインストールします。
• Android のインストール
• iOS のインストール
4. まだ接続アプリケーションがない場合は、接続アプリケーションを作成 (ページ 15)します。OAuth 範囲と
して api と refresh_token を選択します。
メモ: コールバック URL を指定する場合、実際のアドレスを使用する必要はありません。
myapp:///mobilesdk/oauth/done など、URL に似た任意の値を使用してください。
5. ハイブリッドアプリケーションを作成します。
• 「ハイブリッドアプリケーションを作成する (ページ142)」の手順に従います。アプリケーション種別と
して hybrid_local を使用します。
6. 新しいアプリケーションを実行します。
• Android でハイブリッドアプリケーションを実行する (ページ 144)
• iOS でハイブリッドアプリケーションを実行する (ページ 145)
ハイブリッドアプリケーション
ハイブリッドアプリケーションは、HTML5 Web アプリケーションの開発の容易さと、ネイティブプラットフォー
ムの機能とを統合したものです。これらは、Salesforce Mobile コンテナ (アプリケーションをデバイス固有のコー
ドに変換するネイティブレイヤ) 内で実行されます。
ハイブリッドアプリケーションの機能は、HTML5 と JavaScript ファイルで定義します。これらのアプリケーショ
ンは、次の 2 つのカテゴリのいずれかになります。
• ハイブリッドローカル — forcetk.mobilesdk.js ライブラリを使用して開発されたハイブリッドアプリ
ケーションが Mobile コンテナ内に Web アプリケーションをラップします。これらのアプリケーションは、
その HTML、JavaScript、および CSS ファイルをデバイス上に保存します。
• ハイブリッドリモート — Visualforceテクノロジを使用して開発されたハイブリッドアプリケーションが Mobile
コンテナを介して Apex ページを配信します。これらのアプリケーションは、その HTML、JavaScript、および
CSS ファイルの一部または全部を Salesforce サーバまたはデバイス上 (の http://localhost) に保存します。
141
HTML5 およびハイブリッド開発
ハイブリッド開発について
HTML および JavaScript コードを提供するだけでなく、対象プラットフォームで最小限のコンテナアプリケーショ
ンを保守することも必要です。これらのアプリケーションは、必要に応じて設定するネイティブテンプレート
と似ています。
他の開発者が使用するためにライブラリまたはサンプルアプリケーションを作成している場合は、GitHub など
のバージョン管理されるオンラインリポジトリに公開モジュールを投稿することをお勧めします
(https://github.com)。スニペットなどの小規模なサンプル用に、GitHub にはオーバーヘッドの低い共有フォーラ
ムである gist が用意されています (https://gist.github.com)。
ハイブリッド開発について
ハイブリッドアプリケーションを Mobile SDK コンテナで開発する場合、変更後にリコンパイルとリビルドが必
要になります。ブラウザで JavaScript 開発を行う方が容易です。コードを変更した後、ブラウザを更新するだけ
で変更内容を確認できます。この理由により、ハイブリッドアプリケーションはブラウザで直接開発し、テス
トの最終段階でのみコンテナでコードを実行することをお勧めします。
開発者ツールが組み込まれている Google Chrome などのブラウザで開発することをお勧めします。これらのツー
ルでは、実行時に Web アプリケーションのシンボルおよびコードにアクセスできます。
Cordova を使用したハイブリッドアプリケーションの開発
Salesforce Mobile SDK 3.1 では、ハイブリッドコンテナがアップグレードされ、 Apache Cordova 3.6.x (iOS の場合は
3.6.3、Android の場合は 3.6.4) を使用するようになりました。アーキテクチャ上、Mobile SDK ハイブリッドアプリ
ケーションは、Cordova プラグインとして Salesforce Mobile SDK を使用する Cordova アプリケーションになりまし
た。Cordova 3 の機能強化を活用するこのアーキテクチャにより、新バージョンの Cordova にプロジェクトをアッ
プグレードする処理が簡略化されます。Cordova には、アプリケーションを更新するための単純なコマンドラ
インツールも用意されています。Cordova 3 の利点についての詳細は、このブログ投稿を参照してください。
ハイブリッドアプリケーションを作成する
ハイブリッドアプリケーションを開発するには、次の前提条件を満たす必要があります。
• HTML5 および JavaScript 開発に習熟している。
• ハイブリッドコンテナアプリケーションの作成と保守用に目的のプラットフォームの開発環境がインストー
ルされている。Android の場合は、ネイティブ Android の要件を参照してください。iOS の場合は、ネイティ
ブ iOS の要件を参照してください。
• ハイブリッドリモートアプリケーションの場合、HTML5 およびハイブリッド開発の要件を満たしている。
• ハイブリッドリモートアプリケーションの場合、アプリケーションを作成するときに指し示す Apex ラン
ディングページが存在する。
Mobile SDK ハイブリッドアプリケーションを作成するには、forceios または forcedroid ユーティリティと Cordova コ
マンドラインを使用します。
1. コマンドプロンプトまたはターミナルウィンドウを開きます。
2. Cordova コマンドラインをインストールします。
npm -g install cordova
142
HTML5 およびハイブリッド開発
Cordova を使用したハイブリッドアプリケーションの開
発
3. 対象プラットフォームの手順に従います。
Android の場合:
iOS の場合:
a. forcedroid npm パッケージをインストールします。 a. forceios npm パッケージをインストールします。
すでに forcedroid の旧バージョンがインストール
すでに forceios の旧バージョンがインストールさ
されている場合、再インストールする必要があ
れている場合、再インストールする必要があり
ります。
ます。
b. Mobile SDK for Android をインストールしたら、
b. Mobile SDK for iOS をインストールしたら、「iOS プ
「Android プロジェクトの作成」 で説明されてい
ロジェクトの作成」 で説明されているように新
るように新しいハイブリッドアプリケーション
しいハイブリッドアプリケーションを作成しま
を作成します。アプリケーション種別の入力を
す。アプリケーション種別の入力を要求された
要求されたら、次のように指定します。
ら、次のように指定します。
• hybrid_local (ローカルプロジェクトにコー
ドを保存するハイブリッドアプリケーション
の場合)。
• hybrid_local (ローカルプロジェクトにコー
ドを保存するハイブリッドアプリケーション
の場合)。
• hybrid_remote (サーバの Visualforce アプリ
ケーションのコードを含むハイブリッドアプ
リケーションの場合)。forcedroid から開始ペー
ジの入力を要求されたら、Apex ランディング
ページの相対 URL を指定します。
• hybrid_remote (サーバの Visualforce アプリ
ケーションのコードを含むハイブリッドアプ
リケーションの場合)。forceios から開始ページ
の入力を要求されたら、Apex ランディング
ページの相対 URL を指定します。
4. HTML、JavaScript、および CSS ファイルと bootconfig.json ファイルをプロジェクトディレクトリの
${target.dir}/www/ ディレクトリに置きます。
重要: cordova.js、cordova.force.js、Cordova プラグインを含めないでください。
5. cd コマンドを使用してプロジェクトディレクトリに移動します。
6. 必要な Cordova プラグインごとに、次のように入力します。
cordova plugin add <plugin repo or plugin name>
メモ: https://plugins.cordova.io に移動して使用可能なプラグインを検索します。
7. (省略可能) iOS サポートを新しい Android ハイブリッドアプリケーションに追加するには、次のように入力し
ます。
cordova platform add ios
このステップでは、アプリケーションディレクトリに platforms/ios ディレクトリを作成してから、ios
ディレクトリに Xcode プロジェクトを作成します。Xcode プロジェクトには、アプリケーションに追加した
プラグインが含まれます。
143
HTML5 およびハイブリッド開発
Cordova を使用したハイブリッドアプリケーションの開
発
8. (省略可能) Android サポートを新しい iOS ハイブリッドアプリケーションに追加するには、次のように入力し
ます。
cordova platform add android
このステップでは、アプリケーションディレクトリに platforms/android ディレクトリを作成してか
ら、android ディレクトリに Eclipse プロジェクトを作成します。Eclipse プロジェクトには、アプリケーショ
ンに追加したプラグインが含まれます。
9. 次のように入力します。
cordova prepare
Web アセットを、www/ ディレクトリの下にあるそれぞれのプラットフォーム固有ディレクトリにリリース
します。
重要: リリース時、www/ ディレクトリの内容を変更した後は必ず cordova prepare を実行して、変
更をプラットフォーム固有のプロジェクトフォルダにリリースします。
Cordova コマンドラインについての詳細は、Cordova 3.5 のドキュメントで「Command-Line Interface」を参照してく
ださい。
Android でハイブリッドアプリケーションを実行する
cordova prepare をハイブリッドアプリケーションで実行したら、Eclipse でプロジェクトを開きアプリケー
ションをエミュレータで実行するようにワークスペースを設定するか、Cordova コマンドラインを引き続き使
用できます。いずれの場合も、Android SDK がインストール済みで、いくつかのデバイスエミュレータが AVD で
設定済みであることを確認してください。エミュレータをコマンドラインから実行するには、次のように入力
します。
cordova emulate android
アプリケーションを Eclipse で実行する手順は、次のとおりです。
1. Eclipse を起動します。
2. 新しいアプリケーションディレクトリをワークスペースのルートとして選択します。
3. [File (ファイル)] > [Import (インポート)] を選択します。
4. Android ディレクトリを展開し、[Existing Android Code into Workspace (既存の Android コードをワークスペー
スへ)] を選択します。
5. [Next (次へ)] をクリックします。
6. 新しいアプリケーションディレクトリをルートディレクトリとして選択します。
7. [Deselect All (すべて選択解除)] をクリックして、次のプロジェクトを選択します。
• platforms/android
• platforms/android/CordovaLib
• plugins/com.salesforce/android/libs/SalesforceSDK
• plugins/com.salesforce/android/libs/SmartStore (SmartStore を使用する予定の場合)
144
HTML5 およびハイブリッド開発
ハイブリッドリモートアプリケーションの開発
8. すべてが作成されたら、新しいアプリケーションプロジェクトを右クリックし、[Run (実行)] > [As Android
Application (Android アプリケーションとして)] を選択します。
iOS でハイブリッドアプリケーションを実行する
cordova prepare を iOS ハイブリッドアプリケーションで実行したら、Xcode でプロジェクトを開き iOS シ
ミュレータでアプリケーションを実行するか、Cordova コマンドラインを引き続き使用できます。いずれの場
合も、Xcode がインストール済みであることを確認してください。iOS シミュレータをコマンドラインから実行
するには、次のように入力します。
cordova emulate ios
アプリケーションを Eclipse で実行する手順は、次のとおりです。
1. Xcode で、[File (ファイル)] > [Open (開く)] をクリックし、<app directory>/platforms/ios/<app
name>.xcodeproj を選択します。
2. [Run (実行)] をクリックします。
ハイブリッドリモートアプリケーションの開発
ハイブリッドリモートアプリケーションのためにサーバで cordova.js やプラグインをホストする必要がな
くなります。代わりに、HTML ソースに cordova.js を https://localhost/cordova.js として追加でき
ます。次に例を示します。
<script src="https://localhost/cordova.js"></script>
すべての CSS および JavaScript リソースに https://localhost を使用することで、それらのファイルを、サー
バから配信するのではなくアプリケーションと一緒にバンドルすることもできます。この方法により、ハイブ
リッドリモートアプリケーションを Visualforce と Apex で開発できるうえに、パフォーマンスも大幅に向上しま
す。
メモ:
• Mobile SDK 2.3 以降では、ハイブリッドリモートアプリケーションの https://localhost が自動的に
ホワイトリストに登録されます。以前のバージョンの Mobile SDK で開発されたアプリケーションの場
合、手動で https://localhost を config.xml ファイルにホワイトリスト登録できます。
• https://localhost を使用してソースファイルを追加する Visualforce ページは、Salesforce Mobile SDK
コンテナアプリケーションでのみ機能します。ページを Web ブラウザでも動作させるには、Apex を使
用してユーザエージェントを調べ、クライアントが Mobile SDK コンテナかどうかを検出します。検出
結果に基づいて、適切な script include タグを使用します。
例: ハイブリッドローカルアプリケーションの FileExplorer SDK サンプルは、簡単にハイブリッドリモート
アプリケーションに変換できます。アプリケーションを変換するには、メイン HTML ページをサーバから
配信される Apex ページとして再定義します。次に、CSS および JavaScript リソースをアプリケーションと一
緒にバンドルして、デバイスに保存されるようにします。
145
HTML5 およびハイブリッド開発
ハイブリッドリモートアプリケーションの開発
1. bootconfig.json ファイルを更新してアプリケーションをハイブリッドリモートとして再定義しま
す。次の行を変更します。
"isLocal": true,
"startPage": "FileExplorer.html",
変更後
"isLocal": false,
"startPage": "apex/FileExplorer",
2. Visualforce 対応の Salesforce 組織の場合、FileExplorer.html ファイルを複製する新しい Apex ページを
「FileExplorer」という名前で作成します。
<apex:page showHeader="false" sidebar="false">
<!-- Paste content of FileExplorer.html here -->
</apex:page>
3. CSS ファイルへのすべての参照を、https://localhost から読み込まれるように更新します。置換
前:
<link rel="stylesheet" href="css/styles.css"/>
<link rel="stylesheet" href="css/ratchet.css"/>
置換後:
<link rel="stylesheet" href="https://localhost/css/styles.css"/>
<link rel="stylesheet" href="https://localhost/css/ratchet.css"/>
4. すべてのスクリプト参照についてステップ 3 を繰り返します。置換前:
<!-- Container -->
<script src="js/jquery.min.js"></script>
<script src="js/underscore-min.js"></script>
<script src="js/backbone-min.js"></script>
<script src="cordova.js"></script>
<script src="js/forcetk.mobilesdk.js"></script>
<script src="js/smartsync.js"></script>
<script src="js/fastclick.js"></script>
<script src="js/stackrouter.js"></script>
<script src="js/auth.js"></script>
<!-- End Container -->
置換後:
<!-- Container -->
<script src="https://localhost/js/jquery.min.js"></script>
<script src="https://localhost/js/underscore-min.js"></script>
<script src="https://localhost/js/backbone-min.js"></script>
<script src="https://localhost/cordova.js"></script>
<script src="https://localhost/js/forcetk.mobilesdk.js"></script>
<script src="https://localhost/js/smartsync.js"></script>
<script src="https://localhost/js/fastclick.js"></script>
<script src="https://localhost/js/stackrouter.js"></script>
146
HTML5 およびハイブリッド開発
ハイブリッドサンプルアプリケーション
<script src="https://localhost/js/auth.js"></script>
<!-- End Container -->
このサンプルをテストするときは、必ず Apex ページを作成した組織にログインしてください。
ハイブリッドサンプルアプリケーション
Salesforce Mobile SDK 2.3 では、Cordova がハイブリッドプロジェクトジェネレータとして導入されたため、ハイブ
リッドサンプルアプリケーションのアクセスおよび作成手段も同様に変換されています。変更の概要を次に示
します。
• forcedroid および forceios ユーティリティの samples ターゲットは廃止されました。
• iOS サンプルには、SalesforceMobileSDK-iOS GitHub リポジトリのルートディレクトリにある Mobile SDK ワークス
ペース (SalesforceMobileSDK.xcodeproj) からアクセスできます。また、Android サンプルには、コピー
された SalesforceMobileSDK-Android リポジトリの hybrid/SampleApps ディレクトリからアクセスできます。
• 必要に応じて、SalesforceMobileSDK-Shared GitHub リポジトリからハイブリッドサンプルのソースコードのみを
ダウンロードし、Cordova コマンドラインを使用してサンプルを作成できます。
Salesforce Mobile SDK には、次のハイブリッドサンプルアプリケーションが用意されています。
• AccountEditor: SmartSync Data Framework を使用して Salesforce データにアクセスする方法について説明します。
• ContactExplorer: ContactExplorer サンプルアプリケーションでは、PhoneGap (Cordova とも呼ばれる) を使
用して、ローカルデバイスの取引先責任者を取得します。また、forcetk.mobilesdk.js ツールキット
を使用して、Salesforce REST API で REST トランザクションを実装します。アプリケーションでは、Salesforce SDK
の OAuth2 サポートを使用して OAuth ログイン情報を取得し、JavasScript イベントを送信することによって、
そのログイン情報を forcetk.mobilesdk.js に伝搬します。
• HybridFileExplorer: Files API を示します。
• SmartStoreExplorer: SmartStore API を探索できます。
• SimpleSync:: SmartSync プラグインの使用方法を示します。
• VFConnector: ネイティブコンテナ内の Visualforce ページのラップ方法を示す VFConnector サンプルアプリケー
ションです。この例では、BasicVFTest というVisualforceページが組織に存在することを想定しています。
アプリケーションではまず、Salesforce SDK OAuth2 サポートを使用して OAuth のログイン情報を取得し、その
ログイン情報を使用して、Visualforce ページにアクセスするための適切な Web ビュー Cookie を設定します。
ハイブリッドサンプルアプリケーションを作成する
forcedroid または forceios ツールを使用して、ハイブリッドサンプルアプリケーションを作成できます。Web ア
セット (HTML、JavaScript、および CSS ファイル) と、サンプルハイブリッドアプリケーション用の
bootconfig.json ファイルは、SalesforceMobileSDK-Shared GitHub リポジトリから入手できます。
メモ: ContactExplorer サンプルには org.apache.cordova.contacts および
org.apache.cordova.statusbar プラグインが必要です。
他のハイブリッドサンプルアプリケーションには、特殊な Cordova プラグインは必要ありません。
サンプルアプリケーションを作成する手順は、次のとおりです。
147
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
1. コマンドプロンプトまたはターミナルウィンドウを開きます。
2. 共有リポジトリをコピーします。
git clone https://github.com/forcedotcom/SalesforceMobileSDK-Shared
3. forcedroid または forceios を使用して、新しいアプリケーションを作成します。type に、「hybrid_local」と入
力します。
4. 新しいアプリケーションのディレクトリに変更します。
cd <app_target_directory>
5. ContactExplorer サンプルアプリケーションを作成している場合は、必須の Cordova プラグインを追加します。
cordova plugin add org.apache.cordova.contacts
cordova plugin add org.apache.cordova.statusbar
6. Android サポートを forceios プロジェクトに追加するには、次のように入力します。
cordova platform add android
7. (Mac のみ) iOS サポートを forcedroid プロジェクトに追加するには、次のように入力します。
cordova platform add ios
8. サンプルソースファイルを新しいプロジェクトディレクトリの www フォルダにコピーします。
Mac の場合:
cp -RL <local path to SalesforceMobileSDK-Shared>/SampleApps/<template>/* www/
Windows の場合:
copy <local path to SalesforceMobileSDK-Shared>\SampleApps\<template>\*.* www
既存のファイルを上書きするかどうかたずねられたら、上書きに同意します。
9. Cordova の最終準備を実行します。
cordova prepare
ContactExplorer ハイブリッドサンプルの実行
ハイブリッドローカルサンプルアプリケーションの 1 つである ContactExplorer を見てみましょう。
メモ: 次の Cordova スクリプトを実行する前に、Apache Ant がインストール済みでシステムパスに追加され
ていることを確認します。
このサンプルアプリケーションのソースコードは GitHub にあるため、まず共有リポジトリをコピーします。
1. コマンドプロンプトまたはターミナルウィンドウを開きます。
2. 共有リポジトリ git clone https://github.com/forcedotcom/SalesforceMobileSDK-Shared を
コピーします。
148
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
3. コピーが終了したら、Mac OS X の $appname 環境変数または Windows の %appname% を定義します。
「contactsApp」など任意の名前を使用します。
export appname=contactsApp
Windows の場合は次のようになります。
set appname=contactsApp
4. 次のスクリプトを実行します。このスクリプトは Mac 互換ですが Windows でも容易に実行できます。その
ためには、$appname を %appname% に置換し、cp -RL ではなく Windows の copy コマンドを使用します。
さらに、Windows 互換ではない cordova platform add ios コマンドを削除します。
cordova create $appname com.salesforce.contactexplorer $appname
cd $appname
cordova plugin add https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin
cordova plugin add org.apache.cordova.contacts
cordova plugin add org.apache.cordova.statusbar
cordova platform add android
cordova platform add ios
cp -RL <local path to SalesforceMobileSDK-Shared>/samples/$template/* www/
cordova prepare
このスクリプトでは iOS プロジェクトと Android プロジェクトを作成します。これらはどちらも ContactsExplorer
サンプルアプリケーションをラップします。これで、いずれかのプラットフォームでアプリケーションを実行
する準備ができました。iOS デバイスを使用する場合、developer.apple.com/library にある『Xcode User Guide』(Xcode
ユーザガイド) の説明に従ってプロファイルを設定する必要があります。同様に、Android デバイスは
developer.android.com/tools の説明に従って設定する必要があります。アプリケーションを実行するためにさらに
サポートが必要な場合は、「Android でハイブリッドアプリケーションを実行する (ページ 144)」または「iOS で
ハイブリッドアプリケーションを実行する (ページ 145)」を参照してください。
アプリケーションを実行すると、初期スプラッシュ画面が表示された後でSalesforceログイン画面が表示されま
す。
149
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
DE のユーザ名とパスワードを使用してログインします。アプリケーションに Salesforce 内のデータへのアクセ
スを許可するように要求されたら、[許可] をタップします。これで DE アカウントから取引先責任者と取引先
のリストを取得できるようになりました。
150
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
タップして DE アカウントから Contact および Account レコードを取得します。スクロールダウンしてリストを
表示します。
151
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
このアプリケーションでは、デバイスからも取引先責任者を取得できます。これは同等の Web アプリケーショ
ンではできない操作です。アプリケーションで実際にこの操作をどのように行うのかを詳しく見てみましょ
う。
サンプルアプリケーションの仕組み
ログインプロセスの完了後、サンプルアプリケーションに index.html (www フォルダ内) が表示されます。
ページの読み込みが完了してモバイルフレームワークの準備ができたら、onDeviceReady() 関数によって
regLinkClickHandlers() (inline.js 内) がコールされます。regLinkClickHandlers() によって、サ
ンプルアプリケーション内のさまざまな関数用に 5 つのクリックハンドラが設定されます。
$j('#link_fetch_device_contacts').click(function() {
logToConsole("link_fetch_device_contacts clicked");
var contactOptionsType =
cordova.require("org.apache.cordova.contacts.ContactFindOptions");
var options = new contactOptionsType();
options.filter = ""; // empty search string returns all contacts
options.multiple = true;
var fields = ["name"];
var contactsObj = cordova.require("org.apache.cordova.contacts.contacts");
contactsObj.find(fields, onSuccessDevice, onErrorDevice, options);
});
});
152
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
このハンドラで org.apache.cordova.contacts.contacts オブジェクトに対して find() をコールし、
デバイスから取引先責任者リストを取得します。onSuccessDevice() 関数 (ここには示されていません) に
よって、取引先責任者リストが index.html ページに表示されます。
$j('#link_fetch_sfdc_contacts').click(function() {
logToConsole("link_fetch_sfdc_contacts clicked");
forcetkClient.query("SELECT Name FROM Contact",
onSuccessSfdcContacts, onErrorSfdc);
});
#link_fetch_sfdc_contacts ハンドラで、 forcetkClient オブジェクトを使用してクエリを実行しま
す。このオブジェクトは、OAuth 2.0 との初期のやりとりの中で設定され、認証されたユーザのコンテキストで
Force.com REST API へのアクセス権が付与されます。ここで DE アカウントの全取引先責任者の名前を取得し、
onSuccessSfdcContacts() によってそれらが index.html ページ上にリストとして表示されます。
$j('#link_fetch_sfdc_accounts').click(function() {
logToConsole("link_fetch_sfdc_accounts clicked");
forcetkClient.query("SELECT Name FROM Account",
onSuccessSfdcAccounts, onErrorSfdc);
});
#link_fetch_sfdc_accounts ハンドラは前のハンドラとよく似ており、Force.com REST API を介して Account
レコードを取得します。残りのハンドラ #link_reset と #link_logout によって、表示されたリストのク
リアとユーザのログアウトがそれぞれ実行されます。
情報をリストするモバイルページを作成する
ContactExplorer サンプルハイブリッドアプリケーションはさまざまな点で役に立ち、ハイブリッドモバイルアプ
リケーション開発を学習するときの出発点としても適しています。ここでは、Warehouse というカスタムSalesforce
スキーマから Merchandise レコードを表示するようにこのアプリケーションを変更します。
入門用オンラインコンテンツ (http://wiki.developerforce.com/page/Developing_Cloud_Apps_—_Coding_Optional) を使用
すると、すばやく Warehouse スキーマを作成できます。Salesforce パッケージに習熟している場合は、Developer
Edition 組織 (http://goo.gl/1FYg90) にパッケージとしてインストールできます。
メモ:
• Xcode で Cordova iOS プロジェクトを変更する場合、変更のテストのために Staging/www/ プロジェク
トフォルダへのコードのコピーが必要になることがあります。Xcode ではなく Cordova コマンドライン
のみを使用して Cordova iOS アプリケーションを作成する場合、<projectname>/www/ フォルダのみを
変更する必要があります。
アプリケーションの初期化ブロックを変更する (index.html)
このセクションでは、アプリケーションを Warehouse スキーマ固有にし、Merchandise カスタムオブジェクトの
すべてのレコードを表示するように、ビューファイル (index.html) とコントローラ (inline.js) を変更しま
す。
アプリケーションでは、モバイルアプリケーションのデフォルトのホームページに Merchandise レコードのリス
トが表示されるようにします。そのため、最初に行うのは、アプリケーションが onDeviceReady 関数をコー
ルしたときの自動処理の変更です。regLinkClickHanders() への 2 つのコール (onDeviceReady() 関数内
153
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
と salesforceSessionRefreshed() 関数内) をコメントアウトします。続いて、次のコードを index.html
の salesforceSessionRefreshed() 関数の最後に追加します。
// log message
logToConsole("Calling out for records");
// register click event handlers -- see inline.js
// regLinkClickHandlers();
// retrieve Merchandise records, including the Id for links
forcetkClient.query("SELECT Id, Name, Price__c, Quantity__c
FROM Merchandise__c", onSuccessSfdcMerchandise, onErrorSfdc);
この JavaScript コードは ForceTK ライブラリを利用して、基本的な SOQL ステートメントで Force.com データベース
をクエリし、Merchandise カスタムオブジェクトからレコードを取得します。成功すると、この関数は JavaScript
関数の onSuccessSfdcMerchandise (この後で作成) をコールします。
アプリケーションの mainpage ビューを作成する (index.html)
標準的なモバイルのタッチ指向ユーザインターフェースに Merchandise レコードを表示するには、index.html
をスクロールダウンして、<body> タグの内容全体を次の HTML で置き換えます。
<!-- Main page, to display list of Merchandise once app starts -->
<div data-role="page" data-theme="b" id="mainpage">
<!-- page header -->
<div data-role="header">
<!-- button for logging out -->
<a href='#' id="link_logout" data-role="button"
data-icon='delete'>
Log Out
</a>
<!-- page title -->
<h2>List</h2>
</div>
<!-- page content -->
<div id="#content" data-role="content">
<!-- page title -->
<h2>Mobile Inventory</h2>
<!-- list of merchandise, links to detail pages -->
<div id="div_merchandise_list">
<!-- built dynamically by function onSuccessSfdcMerchandise -->
</div>
</div>
</div>
全体的に見ると、更新されたビューでは、標準 HTML タグと jQuery Mobile マークアップ (data-role、data-theme、
data-icon など) を使用してアプリケーションに効果的なタッチインターフェース形式が設定されています。
HTML、CSS、JavaScript、jQuery など、基本的な標準 Web 開発技術を習得していれば、ハイブリッドベースのモバ
イルアプリケーションを開発するのは簡単です。
154
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
アプリケーションのコントローラを変更する (inline.js)
前のセクションでは、コントローラの onSuccessSfdcMerchandise 関数に応じて、ビューの初期化ブロッ
クが div_merchandise_list div タグの範囲内で Merchandise リスト項目を表示する HTML を動的に生成しまし
た。このステップでは、onSuccessSfdcMerchandise 関数を作成します。
inline.js ファイルを開き、サンプル関数に似た次のコントローラアクションを追加します。
重要: このコードやバイナリファイルのコードを切り取って貼り付ける場合は注意が必要です。コードを
プレーンテキストエディタに貼り付け、そこからコピーすることにより、まず純粋なテキストにするこ
とをお勧めします。また、コードステートメントの途中にある改行はすべて削除します。
// handle successful retrieval of Merchandise records
function onSuccessSfdcMerchandise(response) {
// avoid jQuery conflicts
var $j = jQuery.noConflict();
var logToConsole =
cordova.require("com.salesforce.util.logger".logToConsole;
// debug info to console
logToConsole("onSuccessSfdcMerchandise: received " +
response.totalSize + " merchandise records");
// clear div_merchandise_list HTML
$j("#div_merchandise_list").html("");
// set the ul string var to a new UL
var ul = $j('<ul data-role="listview" data-inset="true"
data-theme="a" data-dividertheme="a"></ul>');
// update div_merchandise_list with the UL
$j("#div_merchandise_list").append(ul);
// set the first li to display the number of records found
// formatted using list-divider
ul.append($j('<li data-role="list-divider">Merchandise records: '
+ response.totalSize + '</li>'));
// add an li for the merchandise being passed into the function
// create array to store record information for click listener
inventory = new Array();
// loop through each record, using vars i and merchandise
$j.each(response.records, function(i, merchandise) {
// create an array element for each merchandise record
inventory[merchandise.Id] = merchandise;
// create a new li with the record's Name
var newLi = $j("<li class='detailLink' data-id='" + merchandise.Id
+ "'><a href='#'>" + merchandise.Name + "</a></li>");
ul.append(newLi);
});
// render (create) the list of Merchandise records
$j("#div_merchandise_list").trigger( "create" );
// send the rendered HTML to the log for debugging
logToConsole($j("#div_merchandise_list").html());
155
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
// set up listeners for detailLink clicks
$j(".detailLink").click(function() {
// get the unique data-id of the record just clicked
var id = $j(this).attr('data-id');
// using the id, get the record from the array created above
var record = inventory[id];
// use this info to set up various detail page information
$j("#name").html(record.Name);
$j("#quantity").val(record.Quantity__c);
$j("#price").val(record.Price__c);
$j("#detailpage").attr("data-id",record.Id);
// change the view to the detailpage
$j.mobile.changePage('#detailpage', {changeHash: true});
});
}
コードのコメントで各行について説明されています。この JavaScript に記述された logToConsole(); へのコー
ルにより、コンソールログに HTML が表示されたため、コードの作成結果を確認できます。次にサンプル出力
の抜粋を示します。
<ul data-role="listview" data-inset="true" data-theme="a"
data-dividertheme="a" class="ui-listview ui-listview-inset
ui-corner-all ui-shadow">
<li data-role="list-divider" role="heading"
class="ui-li ui-li-divider ui-btn ui-bar-a ui-corner-top">Merchandise records: 6
</li>
<li class="detailLink ui-btn ui-btn-up-a ui-btn-icon-right ui-li"
data-id="a00E0000003BzSfIAK" data-theme="a">
<div class="ui-btn-inner ui-li">
<div class="ui-btn-text">
<a href="#" class="ui-link-inherit">Tablet</a>
</div>
</div>
</li>
<li class="detailLink ui-btn ui-btn-up-a ui-btn-icon-right ui-li"
data-id="a00E0000003BuUpIAK" data-theme="a">
<div class="ui-btn-inner ui-li">
<div class="ui-btn-text">
<a href="#" class="ui-link-inherit">Laptop</a>
</div>
</div>
</li>
...
</ul>
特に、コードの次の動作に注意します。
• アプリケーションの主ページに表示する Merchandise レコードのリストを作成する
156
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
• Merchandise レコードの名前を表示するための各リスト項目を作成する
• 対象の詳細ページに表示される内容を決定する固有のリンク情報を含む各リスト項目を作成する
新規アプリケーションをテストする
モバイルアプリケーションのシミュレータを再起動します。起動後、初期ページには次のような画面が表示さ
れます。
特定の Merchandise レコードをクリックしても、現時点では何も起こりません。リスト機能は便利ですが、詳細
ビューと組み合わせることで利便性が向上します。次のセクションでは、ユーザが特定の Merchandise レコード
をクリックすると表示される detailpage の作成方法について学習します。
詳細情報のモバイルページを作成する
前のトピックでは、起動後にすべての Merchandise レコードを一覧表示し、詳細ページへのリンクを提供するよ
うにサンプルハイブリッドアプリケーションを変更しました。このトピックでは、detailpageビューを作成し、
アプリケーションのコントローラを更新して作業を終了します。
157
HTML5 およびハイブリッド開発
ContactExplorer ハイブリッドサンプルの実行
アプリケーションの detailpage ビューを作成する (index.html)
ユーザがアプリケーションのmainpageビューで Merchandise レコードをクリックすると、クリックリスナーがレ
コード固有の情報を生成して、その情報を表示する detailpage というビューを読み込みます。detailpage ビューを
作成するには、次の div タグを mainpage div タグの後に追加します。
<!-- Detail page, to display details when user clicks specific Merchandise record -->
<div data-role="page" data-theme="b" id="detailpage">
<!-- page header -->
<div data-role="header">
<!-- button for going back to mainpage -->
<a href='#mainpage' id="backInventory"
class='ui-btn-left' data-icon='home'>
Home
</a>
<!-- page title -->
<h1>Edit</h1>
</div>
<!-- page content -->
<div id="#content" data-role="content">
<h2 id="name"></h2>
<label for="price" class="ui-hidden-accessible">
Price ($):</label>
<input type="text" id="price" readonly="readonly"></input>
<br/>
<label for="quantity" class="ui-hidden-accessible">
Quantity:</label>
<!-- note that number is not universally supported -->
<input type="number" id="quantity"></input>
<br/>
<a href="#" data-role="button" id="updateButton"
data-theme="b">Update</a>
</div>
</div>
コメントで、HTML の各部分について説明されています。基本的にこのビューはフォームであり、ユーザはこ
のビューを使用して Merchandise レコードの [Price (価格)] 項目と [Quantity (数量)] 項目を表示し、必要に応じてレ
コードの数量を更新できます。
onSuccessSfdcMerchandise 関数 (inline.js 内) の最後の部分で jQuery がコールされ、詳細ページ要素を対
象の Merchandise レコードの値で更新します。必要に応じてそのコードを確認します。
アプリケーションのコントローラを変更する (inline.js)
ユーザが新しい detailpage ビューで [Update (更新)] ボタンをクリックするとどうなるでしょうか。現時点では何
も起きません。そのボタンのクリックを処理するには、アプリケーションのコントローラ (inline.js) を変更
する必要があります。
inline.js で、次の JavaScript を onSuccessSfdcMerchandise 関数の最後に追加します。
// handle clicks to Update on detailpage
$j("#updateButton").click(function() {
// update local information in the inventory array
158
HTML5 およびハイブリッド開発
iOS 7 ハイブリッドアプリケーションでのステータスバー
の制御
inventory[$j("#detailpage").attr("data-id")].Quantity__c = $j("#quantity").val();
currentRecord = inventory[$j("#detailpage").attr("data-id")];
// strip out ID before updating the database
var data = new Object();
data.Quantity__c = $j("#quantity").val();
// update the database
forcetkClient.update("Merchandise__c", currentRecord.Id,
data,updateSuccess,onErrorSfdc);
});
コードのコメントで各行について説明されています。成功すると、新しいハンドラが updateSuccess 関数
(現時点は有効ではない) をコールします。次の簡単な関数を inline.js に追加します。
function updateSuccess(message) {
alert("Item Updated");
}
アプリケーションをテストする
モバイルアプリケーションのシミュレータを再起動します。再起動後、特定の Merchandise レコードをクリック
すると、次の画面のような詳細ページが表示されます。
自由にレコードの数量を更新してから、DE 組織にログインし、Force.com アプリケーション UI を使用してレコー
ドを表示したときに同じ数量が表示されることを確認します (上記を参照)。
iOS 7 ハイブリッドアプリケーションでのステータスバーの制御
iOS 7 では、ステータスバーを表示するか非表示にするかと、ステータスバーを Web ビューにオーバーレイ表
示するかどうかを選択できます。Cordova ステータスバープラグインを使用してこれらの設定を指定できます。
Salesforce Mobile SDK 2.3 以降では、デフォルトでステータスバーは表示され、Web ビューにオーバーレイ表示さ
れます。
159
HTML5 およびハイブリッド開発
ハイブリッドアプリケーションの JavaScript ファイル
ステータスバーを非表示にするには、次のキーをアプリケーションの plist に追加します。
<key>UIStatusBarHidden</key>
<true/>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
非表示のステータスバーの例については、AccountEditor サンプルアプリケーションを参照してください。
ステータスバーの外観 (オーバーレイ、背景色、透過性など) を制御するには、次のように org.apache.cordova.statusbar
をアプリケーションに追加します。
cordova plugin add org.apache.cordova.statusbar
外観の制御は、config.xml ファイルまたは JavaScript から行います。完全な手順は、
https://github.com/apache/cordova-plugin-statusbar を参照してください。Web ビューにオーバーレイ表示しないステー
タスバーの例については、ContactExplorer サンプルアプリケーションを参照してください。
関連トピック:
ハイブリッドサンプルアプリケーション
ハイブリッドアプリケーションの JavaScript ファイル
外部連動関係
Mobile SDK では、ハイブリッドアプリケーションのさまざまな機能に次の外部連動関係を使用します。
外部 JavaScript ファイル
説明
jquery.js
一般的な HTML ユーティリティライブラリ
underscore.js
SmartSync サポート
backbone.js
SmartSync サポート
含める JavaScript ファイル
Mobile SDK 2.3 以降では、Cordova ユーティリティがアプリケーションに必要な Cordova プラグインファイルをプ
ロジェクトのプラットフォームディレクトリにコピーします。ユーザがこれらのファイルを www/ フォルダに
コピーする必要はありません。
HTML コードに (<script> タグを使用して) 含めるファイルはハイブリッドプロジェクトの種別によって異なりま
す。次に示す各種別について、リストのファイルをすべて含めます。
基本的なハイブリッドアプリケーションの場合:
• cordova.js
基本的なハイブリッドアプリケーションから REST API コールを行う場合:
• cordova.js
160
HTML5 およびハイブリッド開発
バージョン設定および JavaScript ライブラリの互換性
• forcetk.mobilesdk.js
ハイブリッドアプリケーションで SmartSync を使用する場合:
• jquery.js
• underscore.js
• backbone.js
• cordova.js
• forcetk.mobilesdk.js
• smartsync.js
バージョン設定および JavaScript ライブラリの互換性
ハイブリッドアプリケーションでは、クライアント JavaScript コードは、Cordova (旧 PhoneGap) および SalesforceSDK
プラグインを介してネイティブコードとやり取りします。JavaScript コードをモバイルアプリケーションとパッ
ケージ化する場合は、テストによってコードがネイティブコードと動作することを確認します。ただし、アプ
リケーションが VisualForce で記述されている場合など、JavaScript コードがサーバから取得される場合は、有害
な競合が発生する可能性があります。このような場合は、使用している Mobile SDK とバージョンが適合する
Cordova の JavaScript ライブラリを使用するように十分注意する必要があります。
たとえば、PhoneGap 1.2 を使用する Mobile SDK 1.2 を含むアプリケーションを配信し、後から Mobile SDK 1.3 を使用
する更新を配信するとします。バージョン 1.3 の Mobile SDK では、PhoneGap 1.2 ではなく Cordova 1.8.1 が使用され
ます。そのため、更新されたアプリケーションの JavaScript コードは、ネイティブコンポーネントへのアクセス
に、Cordova 1.8.1 および Mobile SDK 1.3 バージョンの JavaScript ライブラリのみを使用する必要があります。バー
ジョンが適合しない JavaScript ライブラリを使用すると、アプリケーションがクラッシュする可能性がありま
す。
クライアントのアップグレードを顧客に強制することはできないため、どのようにしてクラッシュを回避でき
るでしょうか。まず、クライアントのバージョンを識別します。次に、クライアントが古い場合にはアプリ
ケーションへのアクセスを拒否する (「最新バージョンに更新してください」警告を表示するなど) か、互換性
のある JavaScript ライブラリを提供することをお勧めします。
次の表に、Cordova および PhoneGap のバージョンと Mobile SDK バージョンの相関付けを示します。
Mobile SDK のバージョン
Cordova または PhoneGap のバージョン
1.2
PhoneGap 1.2
1.3
Cordova 1.8.1
1.4
Cordova 2.2
1.5
Cordova 2.3
2.0
Cordova 2.3
2.1
Cordova 2.3
2.2
Cordova 2.3
2.3
Cordova 3.5
161
HTML5 およびハイブリッド開発
バージョン設定および JavaScript ライブラリの互換性
Mobile SDK のバージョン
Cordova または PhoneGap のバージョン
3.0
Cordova 3.6
ユーザエージェントを使用した Mobile SDK のバージョンの検出
Mobile SDKのバージョンを検出するには、ユーザエージェント文字列を活用できます。ユーザエージェントは、
SalesforceMobileSDK/<version> で開始します。ユーザエージェントを取得したら、返された文字列を解
析して Mobile SDK のバージョンを検出できます。
ユーザエージェントは、サーバで次の Apex コードを使用して取得できます。
userAgent = ApexPages.currentPage().getHeaders().get('User-Agent');
同様に、クライアントでは navigator オブジェクトを使用して JavaScript で取得できます。
userAgent = navigator.userAgent;
sdkinfo プラグインを使用した Mobile SDK のバージョンの検出
JavaScript では、sdkinfo プラグインを使用して、Mobile SDK のバージョンとその他の情報を取得することもで
きます。cordova.force.js ファイルで定義されるこのプラグインには、次のメソッドが備えられています。
getInfo(callback)
このメソッドは、次の情報を提供する連想配列を返します。
メンバー名
説明
sdkVersion
コンテナの作成に使用されるSalesforce Mobile SDKのバー
ジョン (「1.4」など)。
appName
ハイブリッドアプリケーションの名前。
appVersion
ハイブリッドアプリケーションのバージョン。
forcePluginsAvailable
コンテナにインストールされたSalesforceプラグインの
名前を含む配列 (「com.salesforce.oauth」、
「com.salesforce.smartstore」など)。
次のコードは、sdkinfo プラグインに保存された情報を取得して、アラートボックスに表示します。
var sdkinfo = cordova.require("com.salesforce.plugin.sdkinfo");
sdkinfo.getInfo(new function(info) {
alert("sdkVersion->" + info.sdkVersion);
alert("appName->" + info.appName);
alert("appVersion->" + info.appVersion);
162
HTML5 およびハイブリッド開発
ハイブリッドアプリケーションでのセッション管理
alert("forcePluginsAvailable->" + JSON.stringify(info.forcePluginsAvailable));
});
関連トピック:
例: 適切な JavaScript ライブラリの提供
ハイブリッドアプリケーションでのセッション管理
モバイルアプリケーションに影響を与える可能性がある一般的な問題を解決するために、Mobile SDK ではハイ
ブリッドアプリケーションにネイティブコンテナを使用しています。これらのコンテナは、Web セッション管
理の複雑さを取り除くことによって、シームレスな認証とセッション管理を提供します。ただし、よく使用さ
れるモバイルアプリケーションアーキテクチャの進化に伴い、「One Size Fits All (1 つのサイズですべてに対応)」
というアプローチは制限が厳しすぎることがわかっています。たとえば、モバイルアプリケーションでJavaScript
Remoting in Visualforce を使用していると、セッションが期限切れになった場合に Salesforce Cookie が失われること
があります。この Cookie は、ユーザが手動で再度ログインした場合にのみ取得されます。
Mobile SDK では、リアクティブなセッション管理を使用します。ハイブリッドコンテナでセッションを自動的
に管理するのではなく、セッションイベントに応答することによって開発者が管理に関与できるようになりま
した。この戦略により、開発者は、Salesforce Touch プラットフォームでセッション管理をさらに細かく制御で
きます。
Mobile SDK 1.3 以前で開発されたアプリケーションを更新する場合、セッション管理コードをアップグレードす
る必要があります。リアクティブ管理に切り替えるには、アプリケーションのアーキテクチャに応じてセッ
ション管理の設定を調整します。次の表には、一般的なアーキテクチャの動作と推奨されるアプローチがまと
められています。
アプリケーションアーキ
テクチャ
SDK 1.3 以前のプロアク
ティブな動作
SDK 1.4 以降のリアクティ コードのアップグレード
ブな動作
手順
REST API
バックグラウンドセッショ JavaScript からの更新
ンの更新
JavaScript Remoting in
Visualforce
アプリケーションの再起
動
JavaScript からのセッション タイムアウトをキャッチ
と CSRF トークンの更新
し、ページの再読み込み
または新しい iFrame の読み
込みを行います。
jQuery Mobile
アプリケーションの再起
動
ページの再読み込み
次のセクションでは、各アーキテクチャの詳しいコーディング手順を示します。
163
forcetk.mobilesdk.js は変更さ
れません。他のフレーム
ワークについては、更新
コードを追加します。
タイムアウトをキャッチ
し、ページの再読み込み
を行います。
HTML5 およびハイブリッド開発
ハイブリッドアプリケーションでのセッション管理
REST API (Apex2REST を含む)
REST API を活用するハイブリッドアプリケーションを作成またはアップグレードする場合、REST コールが行わ
れた時点で期限切れのセッションを検出し、新しいアクセストークンを要求します。アプリケーションの作成
者は、このフレームワークに基づき、forcetk.mobilesdk.js などの API ラップ用ライブラリを活用してセッションの
保有期間を管理してください。
ContactExplorer サンプルアプリケーションにある index.html の次のコードは、推奨される技法を示していま
す。アプリケーションを初めて読み込む場合、更新関数のハンドル (この場合は salesforceSessionRefreshed)
を渡して Salesforce OAuth プラグインで getAuthCredentials() をコールします。OAuth プラグイン関数は、
更新関数をコールし、セッションおよび更新トークンを渡します。返された値を使用して、forcetk.mobilesdk を
初期化します。
• onDeviceReady() 関数から:
cordova.require("com.salesforce.plugin.oauth").getAuthCredentials(salesforceSessionRefreshed,
getAuthCredentialsError);
• salesforceSessionRefreshed() 関数:
function salesforceSessionRefreshed(credsData) {
forcetkClient = new forcetk.Client(credsData.clientId, credsData.loginUrl);
forcetkClient.setSessionToken(credsData.accessToken, apiVersion,
credsData.instanceUrl);
forcetkClient.setRefreshToken(credsData.refreshToken);
forcetkClient.setUserAgentString(credsData.userAgent);
}
完全なコードについては、ContactExplorer サンプルアプリケーション
(SalesforceMobileSDK-Android/hybrid/SampleApps/ContactExplorer または
SalesforceMobileSDK-iOS/hybrid/SampleApps/ContactExplorer) を参照してください。
JavaScript Remoting in Visualforce
JavaScript Remoting を使用して Visualforce ページにアクセスするモバイルアプリケーションでは、セッションの更
新コードをメソッドのパラメータリストに組み込みます。JavaScript で、Visualforceリモートコールを使用して、
セッション状態を調べ、適宜調整します。
<Controller>.<Method>(
<params>,
function(result, event) {
if (hasSessionExpired(event)) {
// Reload will try to redirect to login page, container will intercept
// the redirect and refresh the session before reloading the origin page
window.location.reload();
} else {
// Everything is OK. You can go ahead and use the result.
},
{escape: true}
);
164
HTML5 およびハイブリッド開発
ハイブリッドアプリケーションでのセッション管理
この例では、hasSessionExpired() を次のように定義します。
function hasSessionExpired(event) {
return (event.type == "exception" && event.message.indexOf("Logged in?") != -1);
}
高度な使用事例: ページ全体を再読み込みしても、最適なユーザ操作性が提供されない場合があります。ペー
ジ全体の再読み込みを回避するには、次の操作が必要です。
1. アクセストークンを更新します。
2. Visualforce ドメインの Cookie を更新します。
3. 最後に、CSRF トークンを更新します。
次のようなページの完全な再読み込みは行いません。
window.location.reload();
代わりに、次のようにします。
// Refresh oauth token
cordova.require("com.salesforce.plugin.oauth").authenticate(
function(creds) {
// Reload hidden iframe that points to a blank page to
// to refresh Visualforce domain cookies
var iframe = document.getElementById("blankIframeId");
iframe.src = src;
// Refresh CSRF cookie
// Get the provider array
var providers = Visualforce.remoting.Manager.providers;
// Get the last provider in the arrays (usually only one)
var provider = Visualforce.remoting.last;
provider.refresh(function() {
//Retry call for a seamless user experience
});
},
function(error) {
console.log("Refresh failed");
}
);
jQuery Mobile
JQueryMobile では、Ajax コールを行って、ページを表示するためのデータを転送します。セッションが期限切れ
になると、フレームワークにより 302 エラーがマスクされます。エラーを回復するには、次のコードを組み込
んで、ページを強制的に更新します。
$(document).on('pageloadfailed', function(e, data) {
console.log('page load failed');
if (data.xhr.status == 0) {
// reloading the VF page to initiate authentication
window.location.reload();
165
HTML5 およびハイブリッド開発
Android ハイブリッドアプリケーションからの SmartStore
と SmartSync の削除
}
});
Android ハイブリッドアプリケーションからの SmartStore と
SmartSync の削除
forcedroid 3.0 以降を使用してハイブリッド Android アプリケーションを作成すると、SmartStore および SmartSync モ
ジュールが自動的に含まれます。アプリケーションでこれらのモジュールを使用しない場合は、簡単に削除で
きます。
1. XML エディタでプロジェクトの AndroidManifest.xml を開き、<application> ノードを見つけます。
2. android:name 属性を次のように変更します。
android:name="com.salesforce.androidsdk.app.HybridApp"
3. project.properties ファイルを編集します。Eclipse の Package Explorer でプロジェクト名を右クリックし、
[Properties (プロパティ)] を選択します。
4. 左パネルで [Android] を選択します。
5. [Library (ライブラリ)] セクションで SmartSync のエントリを強調表示し、[Remove (削除)] をクリックします。
6. [Add... (追加)] をクリックし、「SalesforceSDK」を選択して [OK] をクリックします。
メモ: project.properties ファイルを直接編集する場合は、次のパスを置換します。
..\\..\\plugins\\com.salesforce\\src\\android\\libs\\SmartSync
置換後のパスは、次のとおりです。
..\\..\\plugins\\com.salesforce\\src\\android\\libs\\SalesforceSDK
7. (省略可能) プロジェクトエクスプローラで SmartStore および SmartSync ライブラリを選択し、右クリックして
[Delete (削除)] をクリックします。
以上の手順で、SmartStore および SmartSync ライブラリの参照が削除され、アプリケーションの基本アプリケー
ションクラスが HybridAppWithSmartSync Mobile SDK クラスから汎用 HybridApp クラスに変更されます。
例: 適切な JavaScript ライブラリの提供
正しいバージョンの JavaScript ライブラリを提供するには、使用する Salesforce Mobile SDK のバージョンごとに別
個のバンドルを作成します。次に、必要なバージョンをダウンロードするサーバに Apex コードを提供します。
1. アプリケーションでサポートする Salesforce Mobile SDK のバージョンごとに、次の操作を実行します。
a. 目的の SDK バージョンの JavaScript ライブラリを含む ZIP ファイルを作成します。
b. ZIP ファイルを静的リソースとして組織にアップロードします。
たとえば、Salesforce Mobile SDK バージョン 1.3 を使用するクライアントを配信する場合は、次のファイルを
zip ファイルに追加します。
166
HTML5 およびハイブリッド開発
例: 適切な JavaScript ライブラリの提供
• cordova.force.js
• SalesforceOAuthPlugin.js
• bootconfig.js
• cordova-1.8.1.js (名前を cordova.js に変更する必要があります)
メモ: バンドルでは、Cordova JavaScript ライブラリの名前を cordova.js (PhoneGap-x.x.js ライブラ
リを使用するバージョンをパッケージ化する場合は PhoneGap.js) に変更できます。
2. 使用するバンドルを判別する Apex コントローラを作成します。コントローラコードで、ユーザエージェン
ト文字列を解析して、クライアントで使用しているバージョンを見つけます。
a. 組織の [設定] から、[開発] > [Apex クラス] をクリックします。
b. 次の定義を使用して、SDKLibController という名前の新しい Apex コントローラを作成します。
public class SDKLibController {
public String getSDKLib() {
String userAgent = ApexPages.currentPage().getHeaders().get('User-Agent');
if (userAgent.contains('SalesforceMobileSDK/1.3')) {
return 'sdklib13';
}
// Add additional if statements for other SalesforceSDK versions
// for which you provide library bundles.
}
}
3. バンドル内のライブラリごとに Visualforce ページを作成し、そのページを使用してクライアントを目的のラ
イブラリにリダイレクトします。
たとえば、SalesforceOAuthPlugin ライブラリの場合は、次のようになります。
a. 組織の [設定] から、[開発] > [ページ] をクリックします。
b. 次の定義を使用して、「SalesforceOAuthPlugin」という名前の新しいページを作成します。
<apex:page controller="SDKLibController" action="{!URLFor($Resource[SDKLib],
'SalesforceOAuthPlugin.js')}">
</apex:page>
c. HTML コードの <script> タグで VisualForce ページを参照します。必ずステップ 3b で作成したページを
指し示すようにしてください。次に例を示します。
<script type="text/javascript" src="/apex/SalesforceOAuthPlugin" />
メモ: バンドル内のライブラリごとに別個の <script> タグを指定します。
167
第6章
トピック:
•
•
SmartStore を使用し
たオフラインデー
タの安全な保存
SmartSync を使用し
た Salesforce オブ
ジェクトへのアク
セス
オフライン管理
Salesforce Mobile SDK には、データをオフラインで使用するために保存および同期でき
る、次の 2 つのモジュールがあります。
• SmartStore
• SmartSync Data Framework
SmartStore では、デバイス上の暗号化されたデータベース、またはスープにアプリ
ケーションデータを保存できます。デバイスが再度オンラインになったときに、
SmartStore API を使用してデータの変更を Salesforce サーバと同期できます。
SmartSync には、Salesforce データを簡単に取得して JavaScript オブジェクトとしてモデ
ル化し、オフラインで使用するためにキャッシュするメカニズムがあります。オフ
ラインでの変更を Salesforce サーバにアップロードするときに、SmartSync を使用して
同期プロセスを詳細に制御できます。SmartSync は一般的な Backbone.js オープン
ソースライブラリで構築されており、デフォルトのキャッシュとして SmartStore を使
用します。
168
オフライン管理
SmartStore を使用したオフラインデータの安全な保存
SmartStore を使用したオフラインデータの安全な保存
モバイルデバイスの接続はいつでも失われる可能性があり、病院や飛行機などの環境では接続が禁止されるこ
とがよくあります。このような状況に対処するには、モバイルアプリケーションがオフラインになっても引き
続き動作するようにすることが重要です。
Mobile SDK は、モバイルデバイス向けの安全なマルチスレッドオフラインストレージソリューションである
SmartStore を備えています。SmartStore により、ユーザはデバイスの接続が失われても安全な環境で作業を続行
できます。
SmartStore について
SmartStoreは、単純な 1 つのテーブルのデータベースにデータを JSON ドキュメントとして保存します。このデー
タベースのインデックスを定義したり、標準クエリを実装する SmartStore ヘルパーメソッドか、SmartStore のス
マート SQL 言語を使用するカスタムクエリのいずれかを使用してデータをクエリしたりできます。
SmartStore は、StoreCache (Mobile SDK のキャッシュメカニズム) を使用して、オフライン同期および競合の解決
サービスを提供します。StoreCache を使用して、Salesforce データの操作を管理することをお勧めします。
メモ: 純粋な HTML5 アプリケーションは、オフライン情報をブラウザのキャッシュに保存します。ブラウ
ザのキャッシュは Mobile SDK の一部ではないため、ここでは説明していません。SmartStore は、ストレージ
機能をデバイスで使用します。この方法には、ネイティブ開発またはハイブリッド開発が必要です。
サンプルコードについて
この章のコードスニペットでは、すべての Salesforce 組織で事前定義されている 2 つのオブジェクト (取引先と
商談) を使用しています。取引先と商談は主従関係にあり、取引先には複数の商談を含めることができます。
関連トピック:
オフラインキャッシュのための StoreCache の使用
競合検出
スマート SQL クエリ
SmartStore のスープ
SmartStoreは、のオフラインデータを 1 つ以上のスープに保存します。スープとは、概念的にはオフラインで保
存またはクエリするデータレコードの論理的なコレクション (JSON オブジェクトで表される) です。Force.comで
は通常、スープはオフラインで保存する標準オブジェクトまたはカスタムオブジェクトに対応付けられます。
データ自体の保存に加え、データ内の項目に対応付けるインデックスを指定して、データのクエリをさらに簡
単にカスタマイズできます。
スープはアプリケーションにいくつでも保存できますが、本来は自己完結型データセットです。スープ間に直
接的な相関関係はありません。
警告: SmartStore データは、本質的に揮発性です。有効期限は、認証済みユーザおよび OAuth トークンの状
態に関係しています。ユーザがアプリケーションからログアウトすると、そのユーザに関連付けられて
169
オフライン管理
ハイブリッドアプリケーションでの SmartStore の有効化
いるスープデータは SmartStore によりすべて削除されます。同様に、OAuth 更新トークンが取り消される
か期限切れになると、ユーザのアプリケーション状態がリセットされ、SmartStore のすべてのデータが消
去されます。アプリケーションの設計時には、SmartStore データの揮発性を十分に考慮してください。こ
の警告は、組織で更新トークンに短期の有効期限を設定している場合に特に重要です。
SmartStore のデータ型
SmartStore では、次のデータ型がサポートされます。
型
説明
integer
4 バイト (SDK 2.1 以前) または 8 バイト (SDK 2.2 以降) で
保存される符号付き整数
floating
8 バイトの IEEE 浮動小数点数として保存される浮動小
数点値
string
データベースエンコード (UTF-8) で保存されるテキスト
文字列
このセクションの内容:
日付表現
日付表現
SmartStore は、日時の型を指定しません。これらの値の表記には次の表の SmartStore のデータ型を使用すること
をお勧めします。
型
形式
説明
string
ISO 8601 文字列
「YYYY-MM-DD HH:MM:SS.SSS」
floating
ユリウス日数
グリニッジの紀元前 4714 年 11 月 24
日の正午からの予期的グレゴリオ
暦に応じた日数。この値には、小
数で表される部分的な日数を含め
ることができます。
integer
Unix 時間
1970-01-01 00:00:00 UTC からの秒数
ハイブリッドアプリケーションでの SmartStore の有効化
ハイブリッドアプリケーションでは、JavaScript から SmartStore にアクセスします。ハイブリッドモバイルアプ
リケーションでオフラインアクセスを有効にするには、Visualforce または HTML ページに cordova.js ライブラ
リファイルを含める必要があります。
170
オフライン管理
既存の Android アプリケーションへの SmartStore の追加
Android アプリケーションでは、SmartStore は省略可能なコンポーネントです。Mobile SDK npm スクリプトを使用
して Android SmartStore アプリケーションを作成する場合は、次のようになります。
• プロンプトが表示される forcedroid create を使用して Android プロジェクトを作成する場合、SmartStore
を使用するかどうか確認を求められたら、「yes」を指定します。
• コマンドラインパラメータが含まれる forcedroid create を使用する場合、省略可能な
––usesmartstore=yes パラメータを指定します。
iOS アプリケーションでは、SmartStore は常に含まれます。forceios create を使用して iOS プロジェクトを
作成する場合は、SmartStore ライブラリが暗黙的に含まれるため、SmartStore を使用するオプションが表示され
ません。
関連トピック:
Android プロジェクトの作成
iOS プロジェクトの作成
既存の Android アプリケーションへの SmartStore の追加
既存の Android プロジェクト (ハイブリッドまたはネイティブ) に SmartStore を追加する手順は、次のとおりで
す。
1. SmartStore ライブラリプロジェクトをプロジェクトに追加します。Eclipse で、[プロジェクト] メニューから
[プロパティ] を選択します。左パネルで Android を選択し、右側の [追加] をクリックします。
libs/SmartStore プロジェクトを選択します。
2. <projectname>App.java ファイルで、SalesforceSDKManager の代わりに
SalesforceSDKManagerWithSmartStore クラスをインポートします。次のステートメントを置換しま
す。
import com.salesforce.androidsdk.app.SalesforceSDKManager
置換後のステートメントは、次のとおりです。
import com.salesforce.androidsdk.smartstore.app.SalesforceSDKManagerWithSmartStore
3. <projectname>App.java ファイルで、SalesforceSDKManager ではなく
SalesforceSDKManagerWithSmartStore クラスを拡張するようにアプリケーションクラスを変更しま
す。
スープの登録
スープにアクセスするには、まずスープを登録する必要があります。
スープを登録するには、スープ名および 1 つ以上のインデックス指定のリストを指定します。次のハイブリッ
ド、Android、および iOS の各例では、名前、ID、および所有者 (または親) ID 項目で構成されるインデックス指
定配列を作成します。
スープには、そのエントリで検出された 1 つ以上の項目にインデックス付けされます。スープエントリでの挿
入、更新、削除操作は、スープインデックスで追跡されます。スープを登録する場合、少なくとも 1 つのイン
171
オフライン管理
スープの登録
デックス項目を常に指定します。たとえば、単純なキー/値の保存としてスープを使用している場合は、文字
列型の 1 つのインデックス指定を使用します。
ハイブリッドアプリケーション
スープを登録する JavaScript 関数には、正常およびエラー条件用のコールバック関数が必要です。
navigator.smartstore.registerSoup(soupName, indexSpecs, successCallback, errorCallback)
スープがまだ存在していない場合は、この関数で作成されます。スープがすでに存在する場合は、登録するこ
とで既存のスープにアクセスできます。
indexSpecs
indexSpecs 配列を使用して、事前定義されたインデックス付けでスープを作成します。 indexSpecs 配
列のエントリは、スープのインデックス付け方法を指定します。各エントリは、path:type ペアで構成さ
れます。path はインデックス項目の名前、type は「string」、「integer」、または「floating」のいずれか
です。インデックスパスでは大文字と小文字が区別され、Owner.Name などの複合パスを含めることができ
ます。
"indexSpecs":[
{
"path":"Name",
"type":"string"
}
{
"path":"Id",
"type":"string"
}
{
"path":"ParentId",
"type":"string"
}
]
メモ:
• 特定の indexSpecs 配列で記述された項目にインデックスエントリが存在しないと、そのインデッ
クスで追跡されなくなります。
• インデックスのタイプは、インデックスにのみ適用されます。インデックス付き項目 (「select
{soup:path} from {soup}」など) をクエリすると、インデックス指定で指定したタイプのデー
タが返されます。
• インデックス列には null 項目を含めることができます。
successCallback
正常なコールバック関数は、1 つの引数 (スープ名) を取ります。
function(soupName) { alert("Soup " + soupName + " was successfully created"); };
スープが正常に作成されると、スープが準備完了であることを示す successCallback が返されます。ト
ランザクションが完了するまで待機し、他の操作を開始する前にコールバックを受け取ります。渡された
名前でスープを登録すると、正常なコールバック関数からスープが返されます。
172
オフライン管理
スープの登録
errorCallback
エラーコールバック関数は、1 つの引数 (エラーの説明文字列) を取ります。
function(err) { alert ("registerSoup failed with error:" + err); }
スープの作成時にエラーが発生する理由には、次のようなものがあります。
• スープ名が無効または不正である
• インデックスがない (少なくとも 1 つのインデックス指定が必要)
• データベースエラーなど、他の予期しないエラーが発生した
スープがすでに存在するかどうかを確認するには、次の関数を使用します。
navigator.smartstore.soupExists(soupName, successCallback, errorCallback);
Android ネイティブアプリケーション
Android の場合、com.salesforce.androidsdk.smartstore.store.IndexSpec タイプの配列でインデッ
クス指定を定義します。
SalesforceSDKManagerWithSmartStore sdkManager =
SalesforceSDKManagerWithSmartStore.getInstance();
SmartStore smartStore = sdkManager.getSmartStore();
IndexSpec[] ACCOUNTS_INDEX_SPEC = {
new IndexSpec("Name", Type.string),
new IndexSpec("Id", Type.string),
new IndexSpec("OwnerId", Type.string)
};
smartStore.registerSoup("Account", ACCOUNTS_INDEX_SPEC);
iOS ネイティブアプリケーション
iOS の場合、SFSoupIndex オブジェクトの配列でインデックス指定を定義します。
NSString* const kAccountSoupName = @"Account";
...
- (SFSmartStore *)store
{
return [SFSmartStore sharedStoreWithName:kDefaultSmartStoreName];
}
...
- (void)createAccountsSoup {
if (![self.store soupExists:kAccountSoupName]) {
NSArray *keys = @[@"path", @"type"];
173
オフライン管理
スープからのデータの取得
NSArray *nameValues = @[@"Name", kSoupIndexTypeString];
NSDictionary *nameDictionary = [NSDictionary
dictionaryWithObjects:nameValues forKeys:keys];
NSArray *idValues = @[@"Id", kSoupIndexTypeString];
NSDictionary *idDictionary =
[NSDictionary dictionaryWithObjects:idValues forKeys:keys];
NSArray *ownerIdValues = @[@"OwnerId", kSoupIndexTypeString];
NSDictionary *ownerIdDictionary =
[NSDictionary dictionaryWithObjects:ownerIdValues
forKeys:keys];
NSArray *accountIndexSpecs =
[SFSoupIndex asArraySoupIndexes:@[nameDictionary,
idDictionary, ownerIdDictionary]];
[self.store registerSoup:kAccountSoupName
withIndexSpecs:accountIndexSpecs];
}
}
関連トピック:
SmartStore のデータ型
スープからのデータの取得
SmartStore には、クエリ文字列を作成する一連のヘルパーメソッドが備えられています。特定のレコードセッ
トをクエリするには、クエリ指定に適した build* メソッドをコールします。必要に応じて、次の表に示すイ
ンデックス項目、並び替え順、および絞り込みに使用する他のメタデータも定義できます。
パラメータ
説明
indexPath
名前、取引先番号、日付などの検索対象。
beginKey
省略可能。クエリ範囲の開始を定義するために使用されます。
endKey
省略可能。クエリ範囲の終了を定義するために使用されます。
order
省略可能。「昇順」または「降順」のいずれかです。
pageSize
省略可能。指定されていない場合、結果の Cursor.pageSize に収まるページ
サイズがネイティブプラグインから返されます。
メモ: すべてのクエリは 1 つの述語の検索です。結合をサポートするのはスマート SQL クエリのみです。
174
オフライン管理
スープからのデータの取得
すべてのクエリ
buildAllQuerySpec(indexPath, order, [pageSize]) は、スープ内のすべてのエントリを返します。
特定の順序では並び替えられません。スープ内のすべてのエントリをスキャンする場合に、このクエリを使用
します。
order と pageSize は省略可能で、デフォルトはそれぞれ昇順と 10 です。次のように指定できます。
• buildAllQuerySpec(indexPath)
• buildAllQuerySpec(indexPath, order)
• buildAllQuerySpec(indexPath, order, [pageSize])
ただし、buildAllQuerySpec(indexPath,[pageSize]) は指定できません。
ページサイズについての詳細は、「カーソルの使用」を参照してください。
メモ: 基本的には、画面に表示するエントリ数に合わせて pageSize を設定します。円滑なスクロール表
示を行うには、実際に表示するエントリ数の 2 倍または 3 倍に値を増やします。
スマート SQL SELECT ステートメントを含むクエリ
buildSmartQuerySpec(smartSql, [pageSize]) は、smartSql で指定されたクエリを実行します。この
関数では独自のスマート SQL SELECT ステートメントを指定するため、他のクエリファクトリ関数に比べて柔軟
性が高まります。「スマート SQL クエリ」を参照してください。
pageSize は省略可能であり、デフォルトは 10 です。
次に、さまざまな開発環境で SQL COUNT 関数をコールするスマート SQL クエリのサンプルコードを示します。
Javascript:
var querySpec = navigator.smartstore.buildSmartQuerySpec("select count(*) from {employees}",
1);
navigator.smartstore.runSmartQuery(querySpec, function(cursor) {
// result should be [[ n ]] if there are n employees
});
iOS ネイティブ:
SFQuerySpec* querySpec = [SFQuerySpec newSmartQuerySpec:@"select count(*) from {employees}"
withPageSize:1];
NSArray* result = [_store queryWithQuerySpec:querySpec pageIndex:0];
// result should be [[ n ]] if there are n employees
Android ネイティブ:
SmartStore store = SalesforceSDKManagerWithSmartStore.getInstance().getSmartStore();
JSONArray result = store.query(QuerySpec.buildSmartQuerySpec("select count(*) from
{employees}", 1), 0);
// result should be [[ n ]] if there are n employees
175
オフライン管理
スープからのデータの取得
Exact によるクエリ
buildExactQuerySpec(indexPath, matchKey, [pageSize]) は、indexPath 値の特定の matchKey と
完全に一致するエントリを見つけます。特定の ID の子エントリを検索する場合に、このクエリを使用します。
たとえば、状況別の商談を検索できます。ただし、結果の順序は指定できません。
ID によって子を取得するサンプルコードは、次のとおりです。
var querySpec = navigator.smartstore.buildExactQuerySpec(
“sfdcId”,
“some-sfdc-id”);
navigator.smartstore.querySoup(“Catalogs”,
querySpec, function(cursor) {
// we expect the catalog to be in:
// cursor.currentPageOrderedEntries[0]
});
親 ID によって子を取得するサンプルコードは、次のとおりです。
var querySpec = navigator.smartstore.buildExactQuerySpec(“parentSfdcId”, “some-sfdc-id);
navigator.smartstore.querySoup(“Catalogs”, querySpec, function(cursor) {});
Range によるクエリ
buildRangeQuerySpec(indexPath, beginKey, endKey, [order, pageSize]) は、indexPath の値が
beginKey と endKey で定義された範囲内にあるエントリを見つけます。整数として保存された日付範囲な
ど、数値範囲で検索する場合に、この関数を使用します。
order と pageSize は省略可能で、デフォルトはそれぞれ昇順と 10 です。次のように指定できます。
• buildRangeQuerySpec(indexPath, beginKey, endKey)
• buildRangeQuerySpec(indexPath, beginKey, endKey, order)
• buildRangeQuerySpec(indexPath, beginKey, endKey, order, pageSize)
ただし、buildRangeQuerySpec(indexPath, beginKey, endKey, pageSize) は指定できません。
beginKey と endKey に null 値を渡すと、範囲無期限の検索を実行できます。
• endKey に null を渡すと、indexPath が beginKey 以下の項目のすべてのレコードが検出されます。
• beginKey に null を渡すと、indexPath が endKey 以下の項目のすべてのレコードが検出されます。
• beginKey と endKey の両方に null を渡すと、すべてのエントリに対するクエリと同じ結果になります。
Like によるクエリ
buildLikeQuerySpec(indexPath, likeKey, [order, pageSize]) は、indexPath の値が指定の likeKey
に似ているエントリを見つけます。キーワードで開始する用語を検索するには「foo%」、キーワードで終了す
る用語を検索するには「%foo」、indexPath 値のどこかにあるキーワードを検索するには「%foo%」をそれぞ
れ使用できます。一般検索および名前の部分一致を行う場合に、この関数を使用します。order と pageSize
は省略可能で、デフォルトはそれぞれ昇順と 10 です。
メモ: Like によるクエリは、クエリメソッドの中で最も低速です。
176
オフライン管理
スマート SQL クエリ
クエリの実行
クエリは非同期に実行され、JavaScript コールバックにカーソルが返されます。正常なコールバックの形式は、
function(cursor) です。クエリ指定を querySoup メソッドに渡すには、querySpec パラメータを使用し
ます。
navigator.smartstore.querySoup(soupName,querySpec,successCallback,errorCallback);
主キーによる個々のスープエントリの取得
すべてのスープエントリには、一意の内部 ID (スープ内のすべてのエントリを保持する内部テーブルにおける
主キー) が自動的に与えられます。この ID 項目は、スープエントリで _soupEntryId 項目として使用できま
す。スープエントリは、retrieveSoupEntries メソッドを使用して _soupEntryId で検索できます。返さ
れる順序は保証されず、エントリが削除されている場合は、結果の配列に含まれません。このメソッドでは、
スープエントリを最も速く取得できますが、使用できるのは _soupEntryId がわかっている場合のみです。
navigator.smartStore.retrieveSoupEntries(soupName, indexSpecs, successCallback,
errorCallback)
スマート SQL クエリ
Salesforce Mobile SDK バージョン 2.0 以降では、自由形式の SELECT ステートメント用に SmartStore でスマート SQL ク
エリ言語がサポートされます。スマート SQLクエリでは、スープおよびスープ項目の参照用に、標準 SQL SELECT
の文法が他の記述子と組み合わされます。これにより、結合の使用を含め、制御および柔軟性が最大限に高ま
ります。スマート SQL では、標準 SQL SELECT 構造がすべてサポートされます。
スマート SQL の制限
スマート SQL でサポートされるのは、SELECT ステートメントおよびインデックス付きパスのみです。
構文
構文は標準 SQL SELECT の仕様と同じですが、次の点で違いがあります。
使用方法
構文
列を指定する
{<soupName>:<path>}
テーブルを指定する
{<soupName>}
スープエントリの JSON 文字列全体
を参照する
{<soupName>:_soup}
内部スープエントリ ID を参照する
{<soupName>:_soupEntryId}
最終更新日を参照する
{<soupName>:_soupLastModifiedDate}
177
オフライン管理
スマート SQL クエリ
サンプルクエリ
Employees および Departments という名前の 2 つのスープについて考えます。Employees スープには、次の標準項
目が含まれています。
• 名 (firstName)
• 姓 (lastName)
• 部署コード (deptCode)
• 従業員 ID (employeeId)
• マネージャ ID (managerId)
Departments スープには、次の項目が含まれています。
• 名 (name)
• 部署コード (deptCode)
次に、これらのスープを使用した基本的なスマート SQL クエリをいくつか示します。
select {employees:firstName}, {employees:lastName}
from {employees} order by {employees:lastName}
select {departments:name}
from {departments}
order by {departments:deptCode}
結合
スマート SQL では、ユーザが結合を使用することもできます。次に例を示します。
select {departments:name}, {employees:firstName} || ' ' || {employees:lastName}
from {employees}, {departments}
where {departments:deptCode} = {employees:deptCode}
order by {departments:name}, {employees:lastName}
さらに、自己結合を行うこともできます。
select mgr.{employees:lastName}, e.{employees:lastName}
from {employees} as mgr, {employees} as e
where mgr.{employees:employeeId} = e.{employees:managerId}
集計関数
スマート SQL では、次のような集計関数の使用をサポートしています。
• COUNT
• SUM
• AVG
次に例を示します。
select {account:name},
count({opportunity:name}),
178
オフライン管理
カーソルの使用
sum({opportunity:amount}),
avg({opportunity:amount}),
{account:id},
{opportunity:accountid}
from {account},
{opportunity}
where {account:id} = {opportunity:accountid}
group by {account:name}
NativeSqlAggregator サンプルアプリケーションには、集計関数や結合用のスマート SQLサポートを含め、SmartStore
のネイティブ実装が完全に装備されています。
関連トピック:
NativeSqlAggregator サンプルアプリケーション: ネイティブアプリケーションでの SmartStore の使用
カーソルの使用
クエリから返される結果が大きすぎて、読み込めない場合があります。代わりに、クエリ結果の小さなサブ
セット (単一ページ) のみがネイティブ領域から JavaScript 領域にいつでもコピーされます。クエリを実行する
と、クエリ結果のリストでページ移動する方法を提供するカーソルオブジェクトがネイティブ領域から返され
ます。JavaScript コードで前後のページに移動して、目的のページを JavaScript 領域にコピーできます。
メモ: 上級ユーザ向け: カーソルはデータのスナップショットではなく、動的です。スープに変更を加え
てからカーソルのページ移動を開始すると、その変更が表示されます。カーソルで保持されるデータは、
元のクエリと結果セットでの現在の位置のみです。カーソルを移動すると、クエリが再度実行されます。
このため、新しく作成されたスープエントリを返すことができます (元のクエリの結果が返されている場
合)。
次のカーソル関数を使用して、クエリ結果を移動します。
• navigator.smartstore.moveCursorToPageIndex(cursor, newPageIndex, successCallback,
errorCallback) — カーソルを特定のページインデックスに移動します。0 は最初のページ、totalPages
- 1 は最後のページです。
• navigator.smartstore.moveCursorToNextPage(cursor, successCallback, errorCallback) —
次のエントリページに移動します (存在する場合)。
• navigator.smartstore.moveCursorToPreviousPage(cursor, successCallback, errorCallback)
— 前のエントリページに移動します (存在する場合)。
• navigator.smartstore.closeCursor(cursor, successCallback, errorCallback) — 終了した
ら、カーソルを閉じます。
メモ: 上記の関数の successCallback には、1 つの引数 (更新後のカーソル) を指定します。
データの操作
挿入、更新、および削除するスープエントリを追跡するために、SmartStore では次の項目が各エントリに追加
されます。
• _soupEntryId — この項目は、特定のスープのテーブルに含まれるスープエントリの主キーです。
179
オフライン管理
データの操作
• _soupLastModifiedDate — 1/1/1970 からのミリ秒数です。
– JavaScript 日付に変換するには、new Date(entry._soupLastModifiedDate) を使用します。
– 日付を 1/1/1970 を起点とした対応するミリ秒数に変換するには、date.getTime() を使用します。
スープエントリを挿入または更新すると、これらの項目が SmartStore で自動的に設定されます。特定のエント
リを削除または取得すると、そのエントリを _soupEntryId で参照できます。
スープエントリの挿入または更新
指定されたスープエントリに _soupEntryId スロットが設定済みの場合、そのスロットで識別されるエント
リはスープ内で更新されます。エントリに _soupEntryId スロットが存在しないか、スロットの値が既存の
スープエントリと一致しない場合は、スープがエントリに追加 (挿入) され、_soupEntryId スロットが上書き
されます。
メモ: _soupEntryId または _soupLastModifiedDate の値は、自分自身で操作しないでください。
エントリの挿入または更新には、upsertSoupEntries メソッドを使用します。
navigator.smartStore.upsertSoupEntries(soupName, entries[], successCallback, errorCallback)
soupName は対象スープの名前であり、entries はスープのデータ構造と一致する 1 つ以上のエントリの配列
です。successCallback パラメータと errorCallback パラメータは、registerSoup のパラメータのよう
に動作します。ただし、upsertSoupEntries の正常なコールバックは、新しいレコードが挿入されたか、既
存のレコードが更新されたことを示します。
外部 ID を使用した更新/挿入
スープエントリが外部システムのデータを反映している場合、外部システムの ID (主キー) を使用してそのエン
ティティを参照する必要がある場合があります。そのため、外部 ID を使用した更新/挿入がサポートされてい
ます。更新/挿入を実行する場合、任意のインデックス項目を外部 ID 項目として指定できます。SmartStore で
は、指定された項目と同じ値を持つ既存のスープエントリが検索され、次の結果が得られます。
• 同じ値を持つ項目が存在しないと、新しいスープエントリが作成されます。
• 外部 ID が見つかると、更新されます。
• 外部 ID と一致する項目が複数存在すると、エラーが返されます。
新しいエントリをローカルで作成する場合は、通常の更新/挿入を使用します。新しいエントリを後からサー
バにアップロードするときにクエリできる値に、外部 ID 項目を設定します。
サーバから取得したデータでエントリを更新する場合は、外部 ID を使用して更新/挿入します。これにより、
同じリモートレコードに対してスープエントリが重複しないことが保証されます。
次のサンプルコードでは、レコードがサーバにまだ存在しないため、id 項目の値に new を選択しています。
オンラインになったら、ローカルにのみ存在するレコードをクエリ (id == "new" であるレコードを検索) し
て、それをサーバにアップロードできます。レコードの実際の ID がサーバから返されると、その id 項目を
ローカルで更新できます。サーバでまだ作成されていないカタログに属する製品を作成する場合、
parentSoupEntryId 項目を使用して、カタログとの関係を取得できます。カタログがサーバで作成された
ら、ローカルレコードの parentExternalId 項目を更新します。
180
オフライン管理
データの操作
次のコードには、サンプルシナリオが含まれています。まず、upsertSoupEntries をコールして、新しい
スープエントリを作成します。コールバックに成功したら、新しく割り当てられたスープエントリ ID を持つ
新しいレコードを取得します。次に、説明を変更し forcetk.mobilesdk メソッドをコールして、サーバで
新しいアカウントを作成し、更新します。最後のコールは、外部 ID を使用した更新/挿入を示します。コード
を見やすくするため、エラーコールバックは指定していません。また、SmartStore コールはすべて非同期であ
るため、実際のアプリケーションでは、前のステップのコールバックで各ステップを実行する必要がありま
す。
// Specify data for the account to be created
var acc = {id: "new", Name: "Cloud Inc", Description: "Getting started"};
// Create account in SmartStore
// This upsert does a "create" because the acc has no _soupEntryId field
navigator.smartstore.upsertSoupEntries("accounts", [ acc ],
function(accounts) {
acc = accounts[0];
// acc should now have a _soupEntryId field
// (and a _lastModifiedDate as well)
});
// Update account's description in memory
acc["Description"] = "Just shipped our first app ";
// Update account in SmartStore
// This does an "update" because acc has a _soupEntryId field
navigator.smartstore.upsertSoupEntries("accounts", [ acc ], function(accounts) {
acc = accounts[0];
});
// Create account on server (sync client -> server for entities created locally)
forcetkClient.create("account", {"Name": acc["Name"], "Description": acc["Description"]},
function(result) {
acc["id"] = result["id"];
// Update account in SmartStore
navigator.smartstore.upsertSoupEntries("accounts", [ acc ]);
});
// Update account's description in memory
acc["Description"] = "Now shipping for iOS and Android";
// Update account's description on server
// Sync client -> server for entities existing on server
forcetkClient.update("account", acc["id"], {"Description": acc["Description"]});
// Later, there is an account (with id: someSfdcId) that you want
// to get locally
// There might be an older version of that account in the
// SmartStore already
// Update account on client
// sync server -> client for entities that might or might not
// exist on client
181
オフライン管理
スープの管理
forcetkClient.retrieve("account", someSfdcId, "id,Name,Description", function(result) {
// Create or update account in SmartStore (looking for an account
// with the same sfdcId)
navigator.smartstore.upsertSoupEntriesWithExternalId("accounts", [ result ], "id");
});
スープの管理
SmartStore には、スープメタデータを取得して、スープレベルの他の操作を実行できるユーティリティ機能が
用意されています。この機能は、ハイブリッド、Android ネイティブ、および iOS ネイティブアプリケーション
で使用できます。
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、JavaScript の各スープ管理関数が 2 つのコールバック関数を取ります。1
つは要求されたデータを返す成功コールバックで、もう 1 つはエラーコールバックです。成功コールバック
は、そのコールバックを使用するスープ管理関数によって異なります (後続のセクションで説明)。エラーコー
ルバックはすべて、エラーの説明文字列を示す 1 つの引数を取ります。たとえば、エラーコールバック関数は
次のように定義できます。
function(e) { alert(“ERROR: “ + e);}
JavaScript でスープ管理関数をコールするには、最初に Cordova プラグインを呼び出して SmartStore オブジェクト
を初期化してから、関数をコールします。次の例では、名前付きのコールバック関数を個別に定義しています
が、匿名のコールバック関数をインラインで定義することもできます。
var sfSmartstore = function() {return cordova.require("com.salesforce.plugin.smartstore");};
function onSuccessRemoveSoup(param) {
logToConsole()("onSuccessRemoveSoup: " + param);
$("#div_soup_status_line").html("Soup removed: " + SAMPLE_SOUP_NAME);
}
function onErrorRemoveSoup(param) {
logToConsole()("onErrorRemoveSoup: " + param);
$("#div_soup_status_line").html("removeSoup ERROR");
}
sfSmartstore().removeSoup(SAMPLE_SOUP_NAME,
onSuccessRemoveSoup,
onErrorRemoveSoup);
Android ネイティブアプリケーション
SmartStore 対応の Android ネイティブアプリケーションでスープ管理 API を使用するには、SmartStore 共有インス
タンスで次のメソッドをコールします。
private SalesforceSDKManagerWithSmartStore sdkManager;
private SmartStore smartStore;
sdkManager = SalesforceSDKManagerWithSmartStore.getInstance();
smartStore = sdkManager.getSmartStore();
smartStore.clearSoup("user1Soup");
182
オフライン管理
スープの管理
iOS ネイティブアプリケーション
iOS ネイティブアプリケーションでスープ管理 API を使用するには、SFSmartStore.h をインポートします。
SFSmartStore 共有インスタンスでスープ管理メソッドをコールします。次のいずれかの SFSmartStore ク
ラスメソッドを使用して、共有インスタンスを取得します。
現在のユーザの SmartStore インスタンスを使用する場合
+ (id)sharedStoreWithName:(NSString*)storeName;
指定したユーザの SmartStore インスタンスを使用する場合
+ (id)sharedStoreWithName:(NSString*)storeName user:(SFUserAccount *)user;
次に例を示します。
self.store = [SFSmartStore sharedStoreWithName:kDefaultSmartStoreName];
if ([self.store soupExists:@"Accounts"]) {
[self.store removeSoup:@"Accounts"];
}
このセクションの内容:
データベースサイズの取得
データベースによるハードディスクの消費容量をクエリするには、適切なデータベースサイズメソッドを
コールします。
スープのクリア
スープのすべてのエントリを削除するには、適切なスープクリアメソッドをコールします。
スープのインデックス指定の取得
スープのインデックス指定を検証または表示する場合は、適切なインデックス指定取得メソッドをコール
します。
スープの既存のインデックス指定の変更
既存のインデックス指定を変更するには、適切なスープ変更メソッドをコールします。
スープへの再インデックス付け
以前にスープを変更しデータへの再インデックス付けを行わなかったが、その後スープの全要素に適切な
インデックスを付けることにした場合は、再インデックス付けを行います。
スープの削除
スープを削除すると消去されます。ユーザがサインアウトすると、すべてのスープが自動的に削除されま
す。サインアウト以外でスープを削除する場合は、適切なスープ削除メソッドをコールします。
関連トピック:
既存の Android アプリケーションへの SmartStore の追加
データベースサイズの取得
データベースによるハードディスクの消費容量をクエリするには、適切なデータベースサイズメソッドをコー
ルします。
183
オフライン管理
スープの管理
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
navigator.smartstore.getDatabaseSize(successCallback, errorCallback)
成功コールバックは、データベースサイズ (バイト単位) を含む 1 つのパラメータをサポートします。次に例を
示します。
function(dbSize) { alert("db file size is:" + dbSize + " bytes"); }
Android ネイティブアプリケーション
Android アプリケーションでは、次のメソッドをコールします。
public int getDatabaseSize ()
iOS ネイティブアプリケーション
Android アプリケーションでは、次のメソッドをコールします。
- (long)getDatabaseSize
スープのクリア
スープのすべてのエントリを削除するには、適切なスープクリアメソッドをコールします。
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
navigator.smartstore.clearSoup(soupName, successCallback, errorCallback)
成功コールバックは、スープ名を含む 1 つのパラメータをサポートします。次に例を示します。
function(soupName) { alert("Soup " + soupName + " was successfully emptied"); }
Android アプリケーション
Android アプリケーションでは、次のメソッドをコールします。
public void clearSoup ( String soupName )
iOS アプリケーション
iOS アプリケーションでは、次のメソッドをコールします。
- (void)clearSoup:(NSString*)soupName;
184
オフライン管理
スープの管理
スープのインデックス指定の取得
スープのインデックス指定を検証または表示する場合は、適切なインデックス指定取得メソッドをコールしま
す。
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
getSoupIndexSpecs()
この関数は、成功およびエラーコールバック関数のほかに、1 つの引数 soupName を取ります。この引数は
スープの名前です。次に例を示します。
navigator.smartstore.getSoupIndexSpecs(soupName, successCallback, errorCallback)
成功コールバックは、インデックス指定の配列を含む 1 つのパラメータをサポートします。次に例を示しま
す。
function(indexSpecs) { alert("Soup " + soupName + " has the following indexes:" +
JSON.stringify(indexSpecs); }
Android アプリケーション
Android アプリケーションでは、次のメソッドをコールします。
public IndexSpec [] getSoupIndexSpecs ( String soupName )
iOS アプリケーション
iOS アプリケーションでは、次のメソッドをコールします。
- (NSArray*)indicesForSoup:(NSString*)soupName
スープの既存のインデックス指定の変更
既存のインデックス指定を変更するには、適切なスープ変更メソッドをコールします。
データに再インデックス付けする場合は、次の点に留意してください。
• 再インデックス付けはコストがかかる可能性があるため、reIndexData 引数は省略可能です。reIndexData
を false に設定すると、スループットが大幅に加速するものと予想されます。
• すでにデータが含まれているスープを変更すると、アプリケーションのパフォーマンスが低下することが
あります。reIndexData を true に設定すると、パフォーマンスヒットが悪化します。
• パフォーマンスの指針として、reIndexData が true に設定されている場合の alterSoup() 操作の所要時
間は 1000 レコードあたり 1 秒です。個別のパフォーマンスは、デバイスの性能、要素のサイズ、およびイ
ンデックスの数によって異なります。
• スープの変更が完了するまで SmartStore の他の操作は実行できません。
• ユーザがアプリケーションを終了するなどして操作が中断された場合は、アプリケーションで SmartStore
データベースが再度開かれたときにその操作が自動的に再開されます。
185
オフライン管理
スープの管理
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
navigator.smartstore.alterSoup(soupName, indexSpecs, reIndexData, successCallback,
errorCallback)
この関数は、成功およびエラーコールバック関数のほかに、次の引数を取ります。
パラメータ名
引数の説明
soupName
文字列型。スープの名前を渡します。
indexSpecs
配列型。インデックス指定のインデックスエントリの
セットを渡します。
reIndexData
ブール型。インデックス指定を置換後に関数でスープ
に再インデックス付けするかどうかを示します。
成功コールバックは、スープ名を含む 1 つのパラメータをサポートします。次に例を示します。
function(soupName) { alert("Soup " + soupName + " was successfully altered"); }
次の例では、スープの単純な変更を行います。最初に、開発者が name 項目および address 項目にインデッ
クス付けされる項目を定義し、エージェントレコードを更新/挿入します。
navigator.smartstore.registerSoup("myAgents", [{path:'name',type:'string'}, {path:'address',
type:'string'}]);
navigator.smartstore.upsertSoupEntries("myAgents", [{name:'James Bond', address:'1 market
st', agentNumber:"007"}]);
過去の経験から、ユーザがエージェントの address ではなく「agentNumber」を使用したクエリを望んでいる
ことが判明している場合は、address へのインデックスを削除して、agentNumber へのインデックスを追加
します。
navigator.smartstore.alterSoup("myAgents", [{path:'name',type:'string'}, {path:'agentNumber',
type:'string'}], true);
メモ: 開発者が reIndexData パラメータを false に設定した場合は、agentNumber に対するクエリで、
挿入済みのエントリ (「James Bond」) が検索されません。ただし、name でレコードをクエリすることは可
能です。agentNumber によるクエリをサポートするには、最初に
navigator.smartstore.reIndexSoup("myAgents", ["agentNumber"]) をコールする必要があり
ます。
Android ネイティブアプリケーション
Android ネイティブアプリケーションでは、次のメソッドをコールします。
public void alterSoup(String soupName, IndexSpec [] indexSpecs, boolean reIndexData) throws
JSONException
186
オフライン管理
スープの管理
iOS ネイティブアプリケーション
iOS ネイティブアプリケーションでは、次のメソッドをコールします。
- (BOOL) alterSoup:(NSString*)soupName withIndexSpecs:(NSArray*)indexSpecs
reIndexData:(BOOL)reIndexData;
スープへの再インデックス付け
以前にスープを変更しデータへの再インデックス付けを行わなかったが、その後スープの全要素に適切なイン
デックスを付けることにした場合は、再インデックス付けを行います。
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
navigator.smartstore.reIndexSoup(soupName, listOfPaths, successCallback, errorCallback)
この関数は、成功およびエラーコールバック関数のほかに、次の引数を取ります。
パラメータ名
引数の説明
soupName
文字列型。スープの名前を渡します。
listOfPaths
配列型。再インデックス付けするインデックスパスの
リスト。
成功コールバックは、スープ名を含む 1 つのパラメータをサポートします。次に例を示します。
function(soupName) { alert("Soup " + soupName + " was successfully re-indexed."); }
Android アプリケーション
Android アプリケーションでは、次のメソッドをコールします。
public void reIndexSoup(String soupName, String[] indexPaths, boolean handleTx)
iOS アプリケーション
iOS アプリケーションでは、次のメソッドをコールします。
- (BOOL) reIndexSoup:(NSString*)soupName withIndexPaths:(NSArray*)indexPaths
スープの削除
スープを削除すると消去されます。ユーザがサインアウトすると、すべてのスープが自動的に削除されます。
サインアウト以外でスープを削除する場合は、適切なスープ削除メソッドをコールします。
187
オフライン管理
SmartStore インスペクタを使用したテスト
ハイブリッドアプリケーション
ハイブリッドアプリケーションでは、次の関数をコールします。
navigator.smartstore.removeSoup(soupName,successCallback,errorCallback);
Android アプリケーション
Android アプリケーションでは、次のメソッドをコールします。
public void dropSoup ( String soupName )
iOS アプリケーション
iOS アプリケーションでは、次のメソッドをコールします。
- (void)removeSoup:(NSString*)soupName
SmartStore インスペクタを使用したテスト
テスト中、SmartStore データがコードで意図したとおりに処理されているかどうかを確認できると便利です。
SmartStore インスペクタには、こうしたテストを行うためのモバイル UI が用意されています。SmartStore インス
ペクタでは、次のことができます。
• スープメタデータ (スープの名前やインデックス指定など) を検証する。
• スープのコンテンツをクリアする。
• スマート SQL クエリを実行する。
メモ: SmartStoreインスペクタは、テストとデバッグのみのためにあります。アプリケーションの最終バー
ジョンを作成する前に、SmartStore インスペクタへの参照をすべて削除してください。
ハイブリッドアプリケーション
ハイブリッドアプリケーションの SmartStore プラグインオブジェクトで showInspector() をコールして、
SmartStore インスペクタを起動します。HTML の場合
<!-- include Cordova -->
<script src="cordova.js"></script>
<script> ブロックまたは参照先の JavaScript ライブラリの場合
var sfSmartstore = function() {return cordova.require("com.salesforce.plugin.smartstore");};
sfSmartstore().showInspector();
188
オフライン管理
擬似 SmartStore の使用
Android ネイティブアプリケーション
Android ネイティブアプリケーションでは、SmartStoreInspectorActivity クラスを使用して、SmartStore
インスペクタを起動します。
final Intent i = new Intent(activity, SmartStoreInspectorActivity.class);
activity.startActivity(i);
iOS ネイティブアプリケーション
iOS ネイティブアプリケーションでは、クラスレベルの SFSmartStoreInspectorViewController:present
メッセージを送信して、SmartStore インスペクタを起動します。
#import <SalesforceSDKCore/SFSmartStoreInspectorViewController.h>
...
[SFSmartStoreInspectorViewController present];
SFSmartStoreInspectorViewController:present クラスはそれ自体のライフサイクルを管理しますが、
何らかの例外的な理由で SFSmartStoreInspectorViewController:present を破棄する必要がある場合
は、クラスレベルの SFSmartStoreInspectorViewController:dismiss メッセージを送信します。
[SFSmartStoreInspectorViewController dismiss];
擬似 SmartStore の使用
コンテナ外で実行しながら SmartStore を使用するコードの開発とテストを容易にするため、エミュレートされ
た SmartStore を使用できます。
MockSmartStore は、データをローカルストレージ (または必要に応じてメモリのみ) に保存する SmartStore の
JavaScript 実装です。
external/shared/test ディレクトリには、次のファイルがあります。
• MockCordova.js — コンテナ外でプラグインのテストのみを目的とする、Cordova 関数の最小限の実装。
Cordova プラグインコールを受信します。
• MockSmartStore.js — コンテナ外での開発およびテストのみを目的とする、SmartStore の JavaScript 実装。
また、SmartStore Cordova プラグインコールを受信し、MockSmartStore を使用して処理します。
SmartStore を使用してアプリケーションを開発する場合、次の変更を加え、コンテナ外でアプリケーションを
テストします。
• cordova.js ではなく MockCordova.js を含める。
• MockSmartStore.js を含める。
MockSmartStore の例を確認するには、external/shared/test/test.html をチェックアウトします。
同じ発生元のポリシー
同じ発生元のポリシーでは、同じサイトのページでスクリプトを実行し、相互のメソッドおよびプロパティに
制限なしでアクセスできます。また、異なるサイトのすべてのページで、ほとんどのメソッドおよびプロパ
ティへのアクセスがブロックされます。コンテナでは同じ発生元のポリシーが Web ビューで無効になるため、
189
オフライン管理
NativeSqlAggregator サンプルアプリケーション: ネイティ
ブアプリケーションでの SmartStore の使用
同じ発生元のポリシーに関する制限は、コンテナ内でコードを実行する場合には問題になりません。ただし、
リモート API をコールする場合は、同じ発生元のポリシーに関する制限を考慮する必要があります。
ブラウザには同じ発生元のポリシーを無効にする方法が備えられており、特定のブラウザを使用した場合の方
法を調査できます。ローカルファイルシステムから読み込まれた JavaScript ファイルから Force.com に対して XHR
コールを行う場合は、同じ発生元のポリシーを無効にしてブラウザを起動する必要があります。次の記事は、
一般的ないくつかのブラウザで同じ発生元のポリシーを無効にする方法を説明しています: 「Getting Around
Same-Origin Policy in Web Browsers (Web ブラウザでの同じ発生元のポリシーの回避)」。
認証
MockSmartStore を使用する認証では、アクセストークンと更新トークンを実際のセッションから取得し、その
コードを JavaScript アプリケーションで手動で作成する必要があります。また、forcetk.mobilesdk JavaScript
Toolkit の初期化にもこれらのトークンが必要です。
メモ:
• MockSmartStore は、データを暗号化せず、本番アプリケーションでの使用を目的としていません。
• 現在、MockSmartStore では、次の形式のスマート SQL クエリがサポートされています。
– SELECT...WHERE...。次に例を示します。
SELECT {soupName:selectField} FROM {soupName} WHERE {soupName:whereField} IN
(values)
– SELECT...WHERE...ORDER BY...。次に例を示します。
SELECT {soupName:_soup} FROM {soupName} WHERE {soupName:whereField} LIKE 'value'
ORDER BY LOWER({soupName:orderByField})
– SELECT count(*) FROM {soupName}
MockSmartStore では、build*QuerySpec() 関数で処理される、より単純なタイプのスマート SQL ス
テートメントは直接サポートされていません。代わりに、目的に合ったクエリ指定の関数が使用され
ます。
関連トピック:
スープからのデータの取得
NativeSqlAggregator サンプルアプリケーション: ネイティブアプリ
ケーションでの SmartStore の使用
NativeSqlAggregator アプリケーションは、ネイティブアプリケーションで SmartStore を使用する方法を示します。
また、SUM や COUNT などの集計関数を含め SQL に似た複雑なクエリを行ったり、SmartStore 内の異なるスープを
結合したりする機能も示します。
190
オフライン管理
NativeSqlAggregator サンプルアプリケーション: ネイティ
ブアプリケーションでの SmartStore の使用
スープの作成
Salesforce オブジェクトを SmartStore に保存するための最初のステップは、オブジェクトにスープを作成するこ
とです。スープを登録する関数コールは、2 つの引数 (スープの名前とインデックス指定) を受け付けます。イ
ンデックス付けでは、3 つのデータ型 (string、integer、および floating decimal) をサポートしています。次の例で
は、Name、Id、および OwnerId の各項目でインデックス付けして Account オブジェクトのスープを初期化する方
法を示しています。
Android:
SalesforceSDKManagerWithSmartStore sdkManager =
SalesforceSDKManagerWithSmartStore.getInstance();
SmartStore smartStore = sdkManager.getSmartStore();
IndexSpec[] ACCOUNTS_INDEX_SPEC = {
new IndexSpec("Name", Type.string),
new IndexSpec("Id", Type.string),
new IndexSpec("OwnerId", Type.string)
};
smartStore.registerSoup("Account", ACCOUNTS_INDEX_SPEC);
iOS:
NSString* const kAccountSoupName = @"Account";
...
- (void)createAccountsSoup {
if (![self.store soupExists:kAccountSoupName]) {
NSArray *keys = @[@"path", @"type"];
NSArray *nameValues = @[@"Name", kSoupIndexTypeString];
NSDictionary *nameDictionary = [NSDictionary
dictionaryWithObjects:nameValues forKeys:keys];
NSArray *idValues = @[@"Id", kSoupIndexTypeString];
NSDictionary *idDictionary =
[NSDictionary dictionaryWithObjects:idValues forKeys:keys];
NSArray *ownerIdValues = @[@"OwnerId", kSoupIndexTypeString];
NSDictionary *ownerIdDictionary =
[NSDictionary dictionaryWithObjects:ownerIdValues
forKeys:keys];
NSArray *accountIndexSpecs =
[SFSoupIndex asArraySoupIndexes:@[nameDictionary,
idDictionary, ownerIdDictionary]];
[self.store registerSoup:kAccountSoupName
withIndexSpecs:accountIndexSpecs];
}
}
191
オフライン管理
NativeSqlAggregator サンプルアプリケーション: ネイティ
ブアプリケーションでの SmartStore の使用
スープへのデータの保存
スープを作成したら、次にデータをスープに保存します。次の例の account は、Account オブジェクトの単一
レコードを表します。Android では、account の種別は JSONObject になります。iOS では、種別が
NSDictionary になります。
Android:
SmartStore smartStore = sdkManager.getSmartStore();
smartStore.upsert("Account", account);
iOS:
SFSmartStore *store = [SFSmartStore sharedStoreWithName:kDefaultSmartStoreName];
[store upsertEntries:[NSArray arrayWithObject:account] toSoup:@"Account"];
SmartStore に対するクエリの実行
Mobile SDK 2.0 以降では、SQL に似た高度なクエリを、複数のスープにまたがる SmartStore に対して実行できま
す。SmartStore クエリの構文は標準 SQL の構文に似ていますが、細かい点で多少の違いがあります。スープ名と
インデックス項目間の区切り文字として、コロン (「:」) が使用されます。<soup-name>:<field-name> ペア
はそれぞれ 1 組の中括弧で囲まれます。「スマート SQL クエリ」を参照してください。
次に、SmartStore に対して実行する集計クエリの例を示します。
SELECT {Account:Name},
COUNT({Opportunity:Name}),
SUM({Opportunity:Amount}),
AVG({Opportunity:Amount}), {Account:Id}, {Opportunity:AccountId}
FROM {Account}, {Opportunity}
WHERE {Account:Id} = {Opportunity:AccountId}
GROUP BY {Account:Name}
このクエリは、2 つのスープ (Account と Opportunity) 間の暗黙的な結合を表します。返される内容は次のとおり
です。
• Account の名前
• Account に関連付けられた Opportunity 数
• その Account の各 Opportunity に関連付けられたすべての金額の合計
• その Account の 1 つの Opportunity に関連付けられた金額の平均
• Account 名によるグルーピング
次のコードスニペットは、ネイティブアプリケーション内からこのようなクエリを実行する方法を示していま
す。この例では、smartSql がクエリ、pageSize が要求されたページサイズです。pageIndex 引数は、ど
の結果ページを返すかを指定します。
Android:
QuerySpec querySpec = QuerySpec.buildSmartQuerySpec(smartSql, pageSize);
JSONArray result = smartStore.query(querySpec, pageIndex);
192
オフライン管理
SmartSync を使用した Salesforce オブジェクトへのアク
セス
iOS:
SFSmartStore *store = [SFSmartStore sharedStoreWithName:kDefaultSmartStoreName];
SFQuerySpec *querySpec = [SFQuerySpec newSmartQuerySpec:queryString
withPageSize:pageSize];
NSArray *result = [store queryWithQuerySpec:querySpec pageIndex:pageIndex];
SmartSync を使用した Salesforce オブジェクトへのアクセス
SmartSync ライブラリは、開発者が Salesforce データベースとモバイルアプリケーション間で容易にデータを同
期できるようにする API のコレクションです。データの取得およびサーバエンドポイントへの投稿、デバイス
でのデータのキャッシュ、およびキャッシュされたデータの読み込みの手段を提供します。SmartSyncでは、同
期操作用にキャッシュポリシーを事前定義して、オフラインおよびオンラインシナリオでキャッシュされた
データとサーバデータ間のやりとりを微調整します。SmartSyncの一連の便利なメソッドを使用すると、sObject
メタデータの取得、最近使用されたオブジェクトのリストの取得、SOQL および SOSL クエリの作成など、よく
行うネットワーク作業を自動化できます。
ネイティブ
ネイティブアプリケーションでの SmartSync の使用
SmartSync ネイティブライブラリには、オフライン対応アプリケーションの開発を簡略化するネイティブの iOS
API および Android API が用意されています。このネイティブ機能のサブセットは、Cordova プラグインを介して
ハイブリッドアプリケーションでも使用できます。
SmartSync ライブラリには、Android と iOS で同様のアーキテクチャおよび機能が用意され、各プラットフォーム
のネイティブ言語で示されます。両方に共通の分かりやすい機能的な概念が採用されています。
• Salesforce REST API を使用して、Salesforce オブジェクトメタデータをクエリする。
• 取得したオブジェクトデータをオフラインで使用できるようにローカルに安全に保存する。
• デバイスがオフラインからオンライン状態になったときにデータの変更を同期する。
SmartSync ネイティブライブラリでは、次の操作を実行できます。
• サーバエンドポイントとやりとりして、データを取得および投稿する。SmartSyncヘルパー API は、使用頻度
が最も高いエンドポイントを対象にします。これらの API は、sObject メタデータの取得、MRU (最近使用し
た) オブジェクトのリストの取得、SOQL および SOSL クエリの作成に役立ちます。
• Salesforce レコードおよびメタデータを取得し、事前定義されたキャッシュポリシーの 1 つを使用してデバ
イスにキャッシュする。
• レコードをオフラインで編集し、SmartStore にオフラインで保存する。
• ローカルで変更されたデータを Salesforce クラウドに転送して、レコードのバッチを同期する。
SmartSync コンポーネント
SmartSync アーキテクチャの基盤となるコンポーネントは次のとおりです。
193
オフライン管理
ネイティブ
同期マネージャ
• Android クラス: com.salesforce.androidsdk.smartsync.manager.SyncManager
• iOS クラス: SFSmartSyncSyncManager
sObject のサイズの大きなバッチをサーバから SmartSync にダウンロードする API を提供します。このクラス
は、メタデータマネージャとは独立して機能し、最も簡単で最も一般的な同期操作の実行を目的とします。
同期マネージャは、sObject のセットをサーバから SmartStore にダウンロードする「下方同期」操作、および
ローカルで作成、更新、または削除された sObject をサーバにアップロードする「上方同期」操作の API を
提供します。
同期マネージャは、次のユーティリティクラスと連動します。
同期操作の状態を追跡します。この操作の状態は次
com.salesforce.androidsdk.smartsync.util.SyncState のとおりです。
• Android:
• 新規 — 同期操作が開始されましたが、サーバと
のトランザクションはまだ始まっていません。
• iOS: SFSyncState
• 実行中 — 同期操作が現在サーバと同期トランザ
クションのネゴシエーションを行っています。
• 完了 — 同期操作が正常に完了しました。
• 失敗 — 同期操作に失敗しました。
「下方同期」操作中にダウンロードする sObject を指
com.salesforce.androidsdk.smartsync.util.SyncTarget 定します。
• Android:
• iOS: SFSyncTarget
「上方同期」操作の設定オプションを指定します。
com.salesforce.androidsdk.smartsync.util.SyncOptions オプションには、同期する項目名のリストが示され
ます。
• iOS: SFSyncOptions
• Android:
メタデータマネージャ
• Android クラス: com.salesforce.androidsdk.smartsync.manager.MetadataManager
• iOS クラス: SFSmartSyncMetadataManager
データ読み込み機能を実行します。このクラスは、同期マネージャのプロトコルがサポートするものより
も高機能のクエリおよび設定を処理する場合に役立ちます。たとえば、メタデータマネージャの API には次
の機能があります。
• SmartScope オブジェクト型を読み込む。
• sObject の MRU リストを読み込む。結果はグローバルにすることも、特定の sObject に限定することもで
きます。
• describe API を使用して、sObject の完全オブジェクト定義を読み込む。
• 組織で使用可能なすべての sObject のリストを読み込む。
194
オフライン管理
ネイティブ
• sObject が検索可能かどうかを判断し、検索可能な場合は sObject 型の検索レイアウトを読み込む。
• sObject 型の色リソースを読み込む。
• sObject をサーバで表示済みとマークし、その sObject 型の MRU リストの一番上に sObject を移動する。
サーバとやりとりするために、MetadataManager は次の標準の Mobile SDK REST API クラスを使用します。
• Android: RestClient、RestRequest
• iOS: SFRestAPI、SFRestRequest
また、SmartSync キャッシュマネージャを使用して、キャッシュとの間でデータの書き込みと読み取りを行
います。
キャッシュマネージャ
• Android クラス: com.salesforce.androidsdk.smartsync.manager.CacheManager
• iOS クラス: SFSmartSyncCacheManager
デバイス上のキャッシュとの間で、オブジェクト、オブジェクト型、オブジェクトレイアウトの書き込み
と読み取りを行います。また、指定したキャッシュの種類およびキャッシュキーを削除するメソッドを提
供します。キャッシュマネージャは、キャッシュデータを、SQLCipher がサポートするSmartStoreデータベー
スに保存します。キャッシュマネージャはアプリケーションとやりとりできないわけではありませんが、
メタデータマネージャがその主要クライアントで、通常はメタデータマネージャがアプリケーションとの
すべてのやりとりを処理します。
SOQL ビルダー
• Android クラス: com.salesforce.androidsdk.smartsync.util.SOQLBuilder
• iOS クラス: SFSmartSyncSoqlBuilder
クエリの句を個々に指定して、SOQL クエリステートメントを簡単に作成できるようにするユーティリティ
クラスです。
SOSL ビルダー
• Android クラス: com.salesforce.androidsdk.smartsync.util.SOSLBuilder
• iOS クラス: SFSmartSyncSoslBuilder
クエリの句を個々に指定して、SOSL クエリステートメントを簡単に作成できるようにするユーティリティ
クラスです。
SmartSyncSDKManager (Android のみ)
Android の場合は、SmartSync アプリケーションが基本アプリケーションとは異なる SDK マネージャオブジェ
クトを使用します。App クラスにより、SalesforceSDKManager ではなく、SmartSyncSDKManager が
拡張されます。forcedroid バージョン 3.0 以降を使用して SmartStore アプリケーションを新規作成する場合は、
この置換が自動的に行われます。この変更は、Android のネイティブとハイブリッドの両方の SmartSync アプ
リケーションに適用されます。
メモ: マルチユーザの切り替えをサポートするために、SmartSync ではユーザアカウントごとにそのコン
ポーネントの固有のインスタンスを作成します。
195
オフライン管理
ネイティブ
キャッシュポリシー
アプリケーションデータを更新するときに、キャッシュポリシーを指定して、SmartSyncにキャッシュの処理方
法を指示できます。サーバデータと同期する、サーバの更新に失敗したときは代わりにキャッシュを使用す
る、キャッシュをクリアする、キャッシュを無視するなどを選択できます。Android の場合、キャッシュポリ
シーは com.salesforce.androidsdk.smartsync.manager.CacheManager.CachePolicy クラスで定義
されます。iOS の場合は、SFSmartSyncCacheManager.h で定義される SFDataCachePolicy 列挙の一部で
す。
データを読み込むメタデータマネージャのメソッドをコールするたびに、キャッシュポリシーを指定します。
Android MetadataManager データの読み込みメソッドの例を次に示します。
public List<SalesforceObjectType>
loadSmartScopeObjectTypes(CachePolicy cachePolicy,
long refreshCacheIfOlderThan);
public List<SalesforceObject> loadMRUObjects(String objectTypeName,
int limit, CachePolicy cachePolicy, long refreshCacheIfOlderThan,
String networkFieldName);
public List<SalesforceObjectType> loadAllObjectTypes(CachePolicy cachePolicy,
long refreshCacheIfOlderThan);
public SalesforceObjectType loadObjectType(String objectTypeName,
CachePolicy cachePolicy, long refreshCacheIfOlderThan);
public List<SalesforceObjectType> loadObjectTypes(List<String> objectTypeNames,
CachePolicy cachePolicy, long refreshCacheIfOlderThan);
また、キャッシュを再読み込みする時期かどうかをキャッシュマネージャが判断しやすくするキャッシュポリ
シーも指定できます。
Android:
public boolean needToReloadCache(boolean cacheExists,
CachePolicy cachePolicy, long lastCachedTime, long refreshIfOlderThan);
iOS:
- (BOOL)needToReloadCache:(BOOL)cacheExists
cachePolicy:(SFDataCachePolicy)cachePolicy
lastCachedTime:(NSDate *)cacheTime
refreshIfOlderThan:(NSTimeInterval)refreshIfOlderThan;
キャッシュポリシーのリストを次に示します。
表 5 : キャッシュポリシー
キャッシュポリシー (iOS)
キャッシュポリシー (Android)
説明
IgnoreCacheData
IGNORE_CACHE_DATA
キャッシュデータを無視し
ます。常にサーバから最新
のデータを取得します。
196
オフライン管理
キャッシュポリシー (iOS)
ネイティブ
キャッシュポリシー (Android)
説明
ReloadAndReturnCacheOnFailure RELOAD_AND_RETURN_CACHE_ON_FAILURE サーバからデータの読み込
みを試行しますが、サーバ
へのコールに失敗した場合
は代わりにキャッシュデー
タを使用します。
ReturnCacheDataDontReload
RETURN_CACHE_DATA_DONT_RELOAD
キャッシュのデータを返
し、サーバへのコールは試
行しません。
ReloadAndReturnCacheData
RELOAD_AND_RETURN_CACHE_DATA
サーバからデータを再読み
込みし、キャッシュを新し
いデータで更新します。
ReloadIfExpiredAndReturnCacheData RELOAD_IF_EXPIRED_AND_RETURN_CACHE_DATA キャッシュデータが古く
なっている場合 (指定した
タイムアウトを経過した場
合) はサーバからデータを
再読み込みします。それ以
外の場合は、キャッシュの
データを返します。
InvalidateCacheDontReload
INVALIDATE_CACHE_DONT_RELOAD
キャッシュをクリアし、
サーバからデータを再読み
込みしません。
InvalidateCacheAndReload
INVALIDATE_CACHE_AND_RELOAD
キャッシュをクリアし、
サーバからデータを再読み
込みします。
オブジェクト表現
メタデータマネージャを使用する場合、メタデータマネージャの読み込みメソッドをコールした結果として
SmartSyncモデル情報を取得できます。メタデータマネージャは現在のユーザの組織からデータを読み込み、そ
れを次の 3 つのクラスのいずれかで表現します。
• オブジェクト
• オブジェクト種別
• オブジェクト種別レイアウト
オブジェクト
• Android クラス: com.salesforce.androidsdk.smartsync.model.SalesforceObject
• iOS クラス: SFObject
197
オフライン管理
ネイティブ
これらのクラスは、Salesforceの sObject から取得したデータをカプセル化します。オブジェクトクラスは、クエ
リの結果が含まれる Android の JSONObject または iOS の NSDictionary オブジェクトからデータを読み込み
ます。その後で、オブジェクトの ID、種別、名前をプロパティとして保存します。JSONObject 自体も未加工
データとして保存します。
オブジェクト種別
• Android クラス: com.salesforce.androidsdk.smartsync.model.SalesforceObjectType
• iOS クラス: SFObjectType
オブジェクト種別クラスは、プレフィックス、名前、表示ラベル、複数形の表示ラベル、項目など、sObject の
詳細を保存します。
オブジェクト種別レイアウト
• Android クラス: com.salesforce.androidsdk.smartsync.model.SalesforceObjectTypeLayout
• iOS クラス: SFObjectTypeLayout
オブジェクト種別レイアウトクラスは、組織の sObject に対して定義されている列形式の検索レイアウトを取
得します (定義されている場合)。レイアウトがない場合、アプリケーションで表示する項目とそれらを表示す
る形式を自由に選択できます。
関連トピック:
キャッシュポリシー
SmartSync ネイティブアプリケーションの作成
forceios バージョン 3.0 以降では SmartSync ネイティブアプリケーションを作成するのに特別な努力は必要ありま
せん。作成する forceios ネイティブアプリケーションには自動的に SmartStore および SmartSync ライブラリが含ま
れます。
Android の場合、forcedroid バージョン 3.0 以降で必要なのは追加のパラメータを 1 つ指定することだけです。
forcedroid パラメータをハードコード化している場合は、--usesmartstore=yes を設定します。対話型で
forcedroid create を使用する場合、forcedroid から「アプリケーションで SmartStore または SmartSync を使用
しますか?」と尋ねられたら「はい」と答えます。forcedroid 3.0 以降の場合、SmartStore サポートに SmartSync ライ
ブラリが含まれます。
既存の Android アプリケーションへの SmartSync の追加
Mobile SDK 2.3 以降で作成された既存の Android プロジェクト (ハイブリッドまたはネイティブ) に SmartSync を追
加する手順を次に示します。
1. 現在アプリケーションが Mobile SDK 2.2 以前に構築されている場合は、「以前のリリースからの移行 (ページ
332)」の説明に従って、プロジェクトを SDK の最新バージョンにアップグレードします。
2. SmartSyncライブラリプロジェクトをプロジェクトに追加します。SmartSyncはSmartStoreを使用するため、プ
ロジェクトがSmartStoreを使用して構築されていない場合は、このライブラリも追加する必要があります。
a. Eclipse で、[Project (プロジェクト)] > [Properties (プロパティ)] を選択します。
198
オフライン管理
ネイティブ
b. 左パネルで [Android] を選択し、[Add (追加)] をクリックします。
c. libs/SmartSync プロジェクトを選択し、まだ参照されていない場合は libs/SmartStore プロジェ
クトを選択します。
3. プロジェクト全体で、SalesforceSDKManager オブジェクトを使用するすべてのコードを、代わりに
SmartSyncSDKManager を使用するように変更します。
メモ: プロジェクト全体の検索および置換を実行する場合は、KeyInterface インポートは変更せず、
そのままにします。
import com.salesforce.androidsdk.app.SalesforceSDKManager.KeyInterface;
既存の iOS アプリケーションへの SmartSync の追加
SmartSync は既存のネイティブ iOS アプリケーションに簡単に追加できます。forceios 3.0 バージョンで作成される
アプリケーションには、必要なライブラリが自動的に含まれます。アプリケーションがMobile SDKの旧バージョ
ンに基づいている場合は、最初に以前のリリースからの移行 (ページ 332)に記載のアップグレード手順に従い
ます。アプリケーションが Mobile SDK 3.0 に更新されたら、ネイティブ SmartSync クラスを使い始めることがで
きます。
データの同期
SmartSync ネイティブアプリケーションでは、同期マネージャを使用してデバイスと Salesforce サーバ間のデー
タを同期します。同期マネージャは、「上方」同期 (デバイスからサーバ) または「下方」同期 (サーバからデ
バイス) のメソッドを提供します。
SmartSync アプリケーションのデータ要求はすべて非同期です。非同期であるため、コールする同期メソッド
は、サーバの応答をコールバックメソッドまたは定義された更新ブロックで返します。
上方同期または下方同期メソッドは、それぞれ同期状態オブジェクトを返します。このオブジェクトには次の
情報が含まれます。
• 同期操作 ID。この ID を同期マネージャの getSyncStatus メソッドに渡すことで、いつでも操作の進行状
況を確認できます。
• 同期パラメータ (スープ名、下方同期操作のターゲット、上方同期操作のオプション)。
• 操作の種類 (上方または下方)。
• 進行率 (整数、0 ~ 100)。
• トランザクション内の総レコード数。
下方同期
サーバからローカルの SmartSync スープに sObject をダウンロードするには、「下方同期」メソッドを使用しま
す。
• Android SyncManager メソッド:
public SyncState syncDown(SyncTarget target, String soupName,
SyncUpdateCallback callback) throws JSONException;
199
オフライン管理
ネイティブ
public SyncState syncDown(SyncTarget target, SyncOptions options, String soupName,
SyncUpdateCallback callback) throws JSONException;
• iOS SFSmartSyncSyncManager メソッド:
- (SFSyncState*) syncDownWithTarget:(SFSyncTarget*)target
soupName:(NSString*)soupName
updateBlock:(SFSyncSyncManagerUpdateBlock)updateBlock;
- (SFSyncState*) syncDownWithTarget:(SFSyncTarget*)target
options:(SFSyncOptions*)options
soupName:(NSString*)soupName
updateBlock:(SFSyncSyncManagerUpdateBlock)updateBlock;
「下方同期」メソッドの場合、ダウンロードする sObject のリストを指定するターゲットを定義します。明示
的なリストを指定するには、Android では JSONObject、iOS では NSDictionary を使用します。ただし、クエ
リ文字列でターゲットを定義することもできます。同期ターゲットクラスでは、SOSL、SOQL、または MRU クエ
リからターゲットオブジェクトを作成するためのファクトリメソッドが提供されます。
ダウンロードされたデータを受信する SmartStore スープの名前も指定します。このスープには、__local__ と
いう名前のインデックス付けされた文字列項目が必要です。Mobile SDK は、コールバックメソッドか、指定さ
れた更新ブロックを使用して同期操作の進行状況をレポートします。
options パラメータを使用すると、ローカルで変更されたレコードの処理を制御できます。次のいずれかの
動作を選択できます。
1. 変更されたローカルレコードを上書きし、ローカルの変更をすべて消去する。options パラメータを次の
値に設定します。
• Android: SyncOptions.optionsForSyncDown(MergeMode.OVERWRITE)
• iOS: [SFSyncOptions newSyncOptionsForSyncDown:SFSyncStateMergeModeOverwrite]
2. すべてのローカルの変更とローカルで変更されたレコードを保持する。options パラメータを次の値に設
定します。
• Android: SyncOptions.optionsForSyncDown(MergeMode.LEAVE_IF_CHANGED)
• iOS: [SFSyncOptions newSyncOptionsForSyncDown:SFSyncStateMergeModeLeaveIfChanged])
重要: options パラメータを取らないバージョンの syncDown を使用する場合、キャッシュ内にある既
存の sObject が上書きされる可能性があります。ローカルの変更を保持するには、下方同期を実行する前
に必ず上方同期を実行してください。
上方同期
ローカルの変更をサーバに適用するには、次のいずれかの「上方同期」メソッドを使用します。
• Android SyncManager メソッド:
public SyncState syncUp(SyncOptions options, String soupName,
SyncUpdateCallback callback) throws JSONException
200
オフライン管理
ネイティブ
• iOS SFSmartSyncSyncManager メソッド:
- (SFSyncState*) syncUpWithOptions:(SFSyncOptions*)options
soupName:(NSString*)soupName
updateBlock:(SFSyncSyncManagerUpdateBlock)updateBlock;
これらのメソッドはサーバを特定の SmartStore スープのデータで更新します。スープ内にある作成、更新、ま
たは削除されたレコードが検索され、それらの変更がサーバ上で複製されます。options 引数には更新する
項目のリストを指定します。
ローカルに作成されたオブジェクトには、sObject の型を指定する「type」項目を含む「attributes」項目を含める
必要があります。たとえば、Acme という名前の取引先の場合、{Id:”local_x”, Name: Acme, attributes:
{type:”Account”}} を使用します。
例: Android:
SmartSyncExplorer ネイティブサンプルアプリケーションは、Contact レコードに SmartSync を使用する方法を
示します。Android の場合、このサンプルでは Salesforce Contact レコードを Java オブジェクトとして表す
ContactObject クラスを定義します。Contact データを SmartStore スープと下方同期するために、
syncDownContacts メソッドは ContactObject インスタンスの情報で作成された SOQL クエリから同期
ターゲットを作成します。
次のスニペットでは、SOQLBuilder を使用しています。SOQLBuilder は、実際の SOQL 文字列のように
解釈できる形式で SOQL クエリを動的に指定しやすくする、SmartSync ファクトリクラスです。各
SOQLBuilder プロパティ setter は、コール側オブジェクトから作成された新しい SOQLBuilder オブジェク
トを返します。これにより、1 つの論理ステートメント内でメソッドコールをチェーニングできます。
SOQL クエリのすべての部分を指定したら、 build() をコールして最終的な SOQL 文字列を作成します。
private void syncDownContacts() {
smartStore.registerSoup(ContactListLoader.CONTACT_SOUP, CONTACTS_INDEX_SPEC);
try {
final String soqlQuery =
SOQLBuilder.getInstanceWithFields(ContactObject.CONTACT_FIELDS)
.from(Constants.CONTACT).limit(ContactListLoader.LIMIT).build();
final SyncTarget target = SyncTarget.targetForSOQLSyncDown(soqlQuery);
syncMgr.syncDown(target, ContactListLoader.CONTACT_SOUP,
new SyncUpdateCallback() {
@Override
public void onUpdate(SyncState sync) {
handleSyncUpdate(sync);
}
});
} catch (JSONException e) {
Log.e(TAG, "JSONException occurred while parsing", e);
}
}
下方同期操作が成功した場合、つまり SyncState.isDone() が true の場合は、受信したデータが指定さ
れたスープに取り込まれます。そのため、handleSyncUpdate() メソッドで行われているように、コー
ルバックメソッドで必要なのは簡単な実装のみです。
private void handleSyncUpdate(SyncState sync) {
if (Looper.myLooper() == null) {
201
オフライン管理
ネイティブ
Looper.prepare();
}
if (sync.isDone()) {
switch(sync.getType()) {
case syncDown:
Toast.makeText(MainActivity.this,
Sync down successful!",
Toast.LENGTH_LONG).show();
break;
case syncUp:
Toast.makeText(MainActivity.this,
"Sync up successful!",
Toast.LENGTH_LONG).show();
syncDownContacts();
break;
default:
break;
}
}
}
サーバに上方同期する場合は、syncDown() と同じ引数 (項目のリスト、ソースSmartStoreスープの名前、
更新コールバック) を指定して syncUp() をコールします。コーディング上の違いは、影響を受ける項目
のリストを SyncTarget ではなく SyncOptions のインスタンスとして形式設定する点のみです。次に、
SmartSyncExplorer サンプルでのその処理方法を示します。
private void syncUpContacts() {
final SyncOptions options =
SyncOptions.optionsForSyncUp(Arrays.asList(ContactObject.CONTACT_FIELDS));
try {
syncMgr.syncUp(options, ContactListLoader.CONTACT_SOUP,
new SyncUpdateCallback() {
@Override
public void onUpdate(SyncState sync) {
handleSyncUpdate(sync);
}
});
} catch (JSONException e) {
Log.e(TAG, "JSONException occurred while parsing", e);
}
}
SmartSyncExplorer の例の場合、更新コールバックでは上方同期が完了すると syncDownContacts() をコー
ルするという追加のステップを実行します。このステップにより、SmartStore スープにサーバでの Contact
への最近の変更がすべて反映され、最新の状態であることが保証されます。
private void handleSyncUpdate(SyncState sync) {
if (Looper.myLooper() == null) {
Looper.prepare();
}
if (sync.isDone()) {
switch(sync.getType()) {
case syncDown:
Toast.makeText(MainActivity.this,
202
オフライン管理
ネイティブ
Sync down successful!",
Toast.LENGTH_LONG).show();
break;
case syncUp:
Toast.makeText(MainActivity.this,
"Sync up successful!",
Toast.LENGTH_LONG).show();
syncDownContacts();
break;
default:
break;
}
}
}
iOS:
SmartSyncExplorer ネイティブサンプルアプリケーションは、Contact レコードに SmartSync を使用する方法を
示します。iOS の場合、このサンプルでは Salesforce Contact レコードを Objective-C オブジェクトとして表す
ContactSObjectData クラスを定義します。サンプルではまた、ContactSObjectData クラスをサポー
トする次の複数のクラスも定義します。
• ContactSObjectDataSpec
• SObjectData
• SObjectDataSpec
• SObjectDataFieldSpec
• SObjectDataManager
Contact データを SmartStore スープと下方同期するために、SObjectDataManager の refreshRemoteData
メソッドは SOQL 文字列を使用して SFSyncTarget オブジェクトを作成します。このクエリ文字列は、
Contact オブジェクトの情報で作成されています。SFSmartSyncSyncManager の
syncDownWithTarget:soupName:updateBlock: メソッドは、このターゲットと、返されたデータを
受信するスープの名前を取ります。このメソッドには、同期操作が成功または失敗したときにコールさ
れる更新ブロックも必要です。
- (void)refreshRemoteData {
if (![self.store soupExists:self.dataSpec.soupName]) {
[self registerSoup];
}
NSString *soqlQuery = [NSString stringWithFormat:@"SELECT %@ FROM %@ LIMIT %d",
[self.dataSpec.fieldNames componentsJoinedByString:@","],
self.dataSpec.objectType,
kSyncLimit];
SFSyncTarget *syncTarget = [SFSyncTarget newSyncTargetForSOQLSyncDown:soqlQuery];
__weak SObjectDataManager *weakSelf = self;
[self.syncMgr syncDownWithTarget:syncTarget
soupName:self.dataSpec.soupName
updateBlock:^(SFSyncState* sync) {
if ([sync isDone] || [sync hasFailed]) {
[weakSelf refreshLocalData];
203
オフライン管理
ネイティブ
}
}
];
}
下方同期操作が成功した場合、つまり SFSyncState の isDone メソッドが YES を返した場合は、指定さ
れたスープがサーバデータを受信します。次に、更新ブロックは制御を refreshLocalData メソッドに
渡し、このメソッドがデータをスープから取得し、変更を反映して UI を更新します。
- (void)refreshLocalData {
if (![self.store soupExists:self.dataSpec.soupName]) {
[self registerSoup];
}
SFQuerySpec *sobjectsQuerySpec =
[SFQuerySpec newAllQuerySpec:self.dataSpec.soupName
withPath:self.dataSpec.orderByFieldName
withOrder:kSFSoupQuerySortOrderAscending withPageSize:kMaxQueryPageSize];
NSError *queryError = nil;
NSArray *queryResults =
[self.store queryWithQuerySpec:sobjectsQuerySpec
pageIndex:0
error:&queryError];
[self log:SFLogLevelDebug msg:@"Got local query results. Populating data rows."];
if (queryError) {
[self log:SFLogLevelError
format:@"Error retrieving '%@' data from SmartStore: %@",
self.dataSpec.objectType,
[queryError localizedDescription]];
return;
}
self.fullDataRowList = [self populateDataRows:queryResults];
[self log:SFLogLevelDebug
format:@"Finished generating data rows. Number of rows: %d.
Refreshing view.",
[self.fullDataRowList count]];
[self resetDataRows];
}
サーバに上方同期する場合は、下方同期に使用したものと同じ引数 (項目のリスト、ソースSmartStoreスー
プの名前、更新ブロック) を指定して syncUp:withOptions:soupName:updateBlock: メッセージを
SFSmartSyncSyncManager に送信します。コーディング上の違いは、影響を受ける項目のリストを
SFSyncTarget ではなく SFSyncOptions のインスタンスとして形式設定する点のみです。SmartSyncExplorer
サンプルが上方同期メッセージを送信する方法を次に示します。
- (void)updateRemoteData:(SFSyncSyncManagerUpdateBlock)completionBlock {
SFSyncOptions *syncOptions =
[SFSyncOptions newSyncOptionsForSyncUp:self.dataSpec.fieldNames];
[self.syncMgr syncUpWithOptions:syncOptions
soupName:self.dataSpec.soupName
204
オフライン管理
ネイティブ
updateBlock:^(SFSyncState* sync) {
if ([sync isDone] || [sync hasFailed]) {
completionBlock(sync);
}
}
];
}
ここに示す更新ブロックは、同期操作が完了したと判断すると、updateRemoteData に渡される完了ブ
ロックをコールします。ユーザは、ボタンをタップして同期操作を開始します。したがって、完了ブロッ
クの定義を確認するには、ContactListViewController.m の syncUpDown ボタンハンドラを調べま
す。このハンドラは次のブロックで updateRemoteData をコールします。
[self.dataMgr updateRemoteData:^(SFSyncState *syncProgressDetails) {
dispatch_async(dispatch_get_main_queue(), ^{
weakSelf.navigationItem.rightBarButtonItem.enabled = YES;
if ([syncProgressDetails isDone]) {
[weakSelf.dataMgr refreshLocalData];
[weakSelf showToast:@"Sync complete!"];
[weakSelf.dataMgr refreshRemoteData];
} else if ([syncProgressDetails hasFailed]) {
[weakSelf showToast:@"Sync failed."];
} else {
[weakSelf showToast:[NSString stringWithFormat:@"Unexpected status:
%@", [SFSyncState syncStatusToString:syncProgressDetails.status]]];
}
});
}];
上方同期操作が成功すると、このブロックは最初にデバイスの表示を更新して「Sync complete!」(同期完
了) という確認トーストを表示してから、SObjectDataManager メッセージを refreshRemoteData に
送信します。この最終ステップにより、SmartStore スープにサーバでの Contact への最近の変更がすべて反
映され、最新の状態であることが保証されます。
キャッシュデータの保存および取得
キャッシュマネージャは、SmartSync キャッシュとの間で sObject メタデータの書き込みおよび読み取りを行う
メソッドを提供します。どのメソッドも、キャッシュ内のデータを識別するキー文字列を指定する必要があり
ます。アプリケーションがキャッシュデータの位置を特定するために役立つ、任意の一意の文字列を使用でき
ます。
また、キャッシュデータのタイプも指定します。キャッシュマネージャのメソッドは、sObject データの 3 つの
カテゴリ (メタデータ、MRU (最近使用した) リスト、レイアウト) のいずれかの読み取りおよび書き込みを行い
ます。指定したタイプ識別子は各自のアプリケーションでしか使用されないため、これらのデータタイプを明
確に区別する一意の文字列を使用できます。
キャッシュマネージャのクラス
• Android: com.salesforce.androidsdk.smartsync.manager.CacheManager
• iOS: SFSmartSyncCacheManager
205
オフライン管理
ネイティブ
読み取りおよび書き込みメソッド
sObject メタデータ、MRU リスト、sObject レイアウトの読み取りおよび書き込みを行う CacheManager のメソッ
ドを次に示します。
• Android:
sObject メタデータ
public List<SalesforceObject> readObjects(String cacheType, String cacheKey);
public void writeObjects(List<SalesforceObject> objects, String cacheKey, String
cacheType);
MRU リスト
public List<SalesforceObjectType> readObjectTypes(String cacheType, String cacheKey);
public void writeObjectTypes(List<SalesforceObjectType> objects,
String cacheKey, String cacheType);
sObject レイアウト
public List<SalesforceObjectTypeLayout> readObjectLayouts(String cacheType, String
cacheKey);
public void writeObjectLayouts(List<SalesforceObjectTypeLayout> objects,
String cacheKey, String cacheType);
• iOS:
Read メソッド
- (NSArray *)readDataWithCacheType:(NSString *)cacheType
cacheKey:(NSString *)cacheKey
cachePolicy:(SFDataCachePolicy)cachePolicy
objectClass:(Class)objectClass
cachedTime:(out NSDate **)lastCachedTime;
Write メソッド
- (void)writeDataToCache:(id)data
cacheType:(NSString *)cacheType
cacheKey:(NSString *)cacheKey;
キャッシュのクリア
アプリケーションのキャッシュをクリアする準備ができたら、キャッシュマネージャの次のメソッドを使用し
ます。
• Android:
public void removeCache(String cacheType, String cacheKey);
• iOS:
- (void)removeCache:(NSString *)cacheType cacheKey:(NSString *)cacheKey;
これらのメソッドにより、キャッシュの選択した部分がクリアされます。キャッシュ全体をクリアするには、
保存している各キャッシュキーおよびデータ型に対するメソッドをコールします。
206
オフライン管理
ハイブリッド
ハイブリッド
ハイブリッドアプリケーションでの SmartSync の使用
ハイブリッドアプリケーション用の SmartSync Data Framework は、Salesforce オブジェクトを JavaScript オブジェク
トとして表す Mobile SDK ライブラリです。ハイブリッドアプリケーションで SmartSync を使用すると、Salesforce
オブジェクトのモデルを作成でき、そのモデルのデータを変更するだけで基盤となるレコードを操作できま
す。SOQL または SOSL クエリを実行すると、JSON 文字列としてではなくモデルコレクションで結果レコードが
取得されます。
Mobile SDK では、ハイブリッドアプリケーションで SmartSync を使用するために 2 つのオプションがあります。
• com.salesforce.plugin.smartsync: SmartSync プラグインは基本的な「上方同期」と「下方同期」機能
を提供します。このプラグインは、ネイティブ SmartSync ライブラリの一部を公開します。このプラグイン
は、Web ビューではなくネイティブスレッドで大量のレコードを迅速に同期するための単純な同期シナリ
オで使用します。
• smartsync.js: SmartSync JavaScript ライブラリは、より複雑な同期操作のための Force.SObject データフレーム
ワークを提供します。このライブラリは、拡張性の高いデータモデリングメカニズムを定義するオープン
ソースの JavaScript フレームワークである backbone.js をベースにしています。この技術を理解するには、
backbonejs.org にある例とドキュメントを参照してください。
SmartSync の使用方法を示す一連のサンプルハイブリッドアプリケーションが次の場所に用意されています。
hybrid/SampleApps/AccountEditor/assets/www フォルダのサンプルアプリケーションは、smartsync.js
での Force.SObject ライブラリの使用方法を示します。
• Account Editor (AccountEditor.html)
• User Search (UserSearch.html)
• User and Group Search (UserAndGroupSearch.html)
hybrid/SampleApps/SimpleSync フォルダのサンプルアプリケーションは、SmartSync プラグインの使用方
法を示します。
Backbone テクノロジについて
SmartSync ライブラリ smartsync.js は、オープンソースの Backbone JavaScript ライブラリの拡張機能を提供し
ます。Backbone ライブラリは、Web アプリケーションを構築する主要なビルディングブロックを定義します。
• 情報をモデル化する Models (キーと値のバインドイベントおよびカスタムイベントを含む)
• データセットを格納する Collections (豊富な enumerable 関数の API を含む)
• モデルの情報を表示する Views (宣言型イベント処理を含む)
• ビュー間の移動を制御するルータ
Salesforce SmartSync Data Framework は、Model および Collection コア Backbone オブジェクトを拡張し、Salesforce
REST API に接続します。SmartSync は、SmartStore (Mobile SDK の安全なストレージコンポーネント) を介してオフラ
インサポート (省略可能) も提供します。
Backbone についての詳細は、http://backbonejs.org/ および http://backbonetutorials.com/ を参照してください。また、
オンラインで「backbone javascript」を検索すれば、多数のチュートリアルやビデオを見つけることもできます。
207
オフライン管理
ハイブリッド
モデルとモデルコレクション
SmartSync Data Framework は、次の 2 つの種別のオブジェクトで構成されています。
• モデル
• モデルコレクション
これらのオブジェクトの定義は、backbone.js (一般的なサードパーティの JavaScript フレームワーク) で定義
されているクラスを拡張します。背景情報は、http://backbonetutorials.com を参照してください。
モデル
クライアントのモデルはサーバレコードを表します。SmartSyncでは、モデルオブジェクトは Force.SObject
(Backbone.Model クラスのサブクラス) のインスタンスです。SObject は、Salesforce API および SmartStore (必
要に応じて) と連動するように Model を拡張します。
SObject モデルオブジェクトで次の CRUD 操作を実行できます。
• Create
• Destroy
• Fetch
• Save
• Get/set attributes
また、モデルオブジェクトは監視可能です。ビューとコントローラはオブジェクトの変更時に通知を受信でき
ます。
プロパティ
Force.SObject は、次のプロパティを Backbone.Model に追加します。
sobjectType
必須。このモデルが表す Salesforce オブジェクトの名前。この値は、標準オブジェクトまたはカスタムオブ
ジェクトのいずれかを参照できます。
fieldlist
必須。取得、保存、破棄する項目の名前。
cacheMode
オフラインの動作。
mergeMode
競合処理の動作。
cache
更新可能なレコードのオフラインストレージの場合に使用します。SmartSync Data Framework には、
Force.StoreCache (SmartStore によってサポートされるキャッシュ実装) が組み込まれています。
cacheForOriginals
競合検出に対応できるように、サーバから取得したレコードの元のコピーを格納します。
208
オフライン管理
ハイブリッド
例
モデルプロパティの値は、次のような複数の方法で割り当てることができます。
• Force.SObject インスタンスのプロパティとして割り当てる。
• Force.SObject サブクラスのメソッドとして割り当てる。これらのメソッドでは、目的の CRUD アクショ
ン (「create」、「create」、「update」、「delete」) を指定するパラメータを使用します。
• fetch()、save()、destroy() 関数コールのパラメータで割り当てる。
たとえば、次のコードスニペットはどれも同じ内容になります。
// As properties on a Force.SObject instance
acc = new Force.SObject({Id:"<some_id>"});
acc.sobjectType = "account";
acc.fieldlist = ["Id", "Name"];
acc.fetch();
// As methods on a Force.SObject sub-class
Account = Force.SObject.extend({
sobjectType: "account",
fieldlist: function(method) { return ["Id", "Name"];}
});
Acc = new Account({Id:"<some_id>"});
acc.fetch();
// In the options parameter of fetch()
acc = new Force.SObject({Id:"<some_id>"});
acc.sobjectType = "account";
acc.fetch({fieldlist:["Id", "Name"]);
モデルコレクション
SmartSync Data Framework のモデルコレクションは、クエリ結果のコンテナです。モデルコレクションに保存さ
れるクエリ結果は、SOQL、SOSL、MRU クエリを介してサーバから取得できます。また、必要に応じて、SmartSQL
(キャッシュが SmartStore の場合) や別のクエリメカニズム (代替キャッシュを使用している場合) を介してキャッ
シュから取得することもできます。
モデルコレクションオブジェクトは、Force.SObjectCollection (Backbone.Collection クラスのサブク
ラス) のインスタンスです。SObjectCollection は、Salesforce API および SmartStore (必要に応じて) と連動する
ように Collection を拡張します。
プロパティ
Force.SObjectCollection は、次のプロパティを Backbone.Collection に追加します。
config
必須。コレクションで保持できるレコードを定義します (SOQL、SOSL、MRU、SmartSQL を使用)。
cache
更新可能なレコードのオフラインストレージの場合に使用します。SmartSync Data Framework には、
Force.StoreCache (SmartStore によってサポートされるキャッシュ実装) が組み込まれています。
209
オフライン管理
ハイブリッド
cacheForOriginals
競合検出に対応できるように、サーバから取得したレコードの元のコピーを格納します。
例
モデルコレクションプロパティの値は、次のような複数の方法で割り当てることができます。
• Force.SObject インスタンスのプロパティとして割り当てる
• Force.SObject サブクラスのメソッドとして割り当てる
• fetch()、save()、destroy() 関数コールのオプションパラメータで割り当てる
たとえば、次のコードスニペットはどれも同じ内容になります。
// As properties on a Force.SObject instance
list = new Force.SObjectCollection({config:<valid_config>});
list.fetch();
// As methods on a Force.SObject sub-class
MyCollection = Force.SObjectCollection.extend({
config: function() { return <valid_config>; }
});
list = new MyCollection();
list.fetch();
// In the options parameter of fetch()
list = new Force.SObjectCollection();
list.fetch({config:valid_config});
SmartSync プラグインの使用
SmartSync プラグインは、 SmartSync ネイティブライブラリの「上方同期」および「下方同期」機能への JavaScript
アクセスを提供します。そのため、パフォーマンス集約的な操作 (ネットワークネゴシエーション、解析、
SmartStore 管理など) はネイティブスレッド上で実行され、Web 表示操作に影響を与えません。
SmartSync プラグインは、Mobile SDK の npm スクリプトによってプロジェクトに追加されます。
• forceios バージョン 3.0 を使用してハイブリッドプロジェクトを作成する場合、プラグインは自動的に含まれ
ます。
• forcedroid バージョン 3.0 を使用してハイブリッドプロジェクトを作成する場合、SmartStore を使用するかど
うか尋ねられたときに「はい」と答えるとプラグインが自動的に含まれます。
SmartSync プラグインを既存のハイブリッドアプリケーションに追加する場合、forcedroid または forceios のバー
ジョン 3.0 を使用してアプリケーションを再作成し、Web アプリケーションファイルを新しいアプリケーショ
ンにコピーすることをお勧めします。
SmartSync プラグインのメソッド
SmartSync プラグインは、syncDown() と syncUp() の 2 つのメソッドを公開します。これらのメソッドを使
用する場合、いくつかの重要なガイドラインに従うと作業が簡素化されます。
210
オフライン管理
ハイブリッド
• プラグインを使用して同期するレコードをローカルで作成、更新、または削除するには、smartsync.js
の Force.SObject を使用します。SmartSync は、smartsync.js によって作成されるスープレコードにい
くつかの特殊な項目があるものと想定します。
• 同様に、同期操作で使用するスープを作成するには、smartsync.js の Force.StoreCache を使用しま
す。
• スープのオブジェクトを変更している場合は、syncDown() をコールする前に必ず syncUp() をコールし
ます。
syncDown() メソッド
target で指定した sObject を、soupName で指定した SmartStore スープにダウンロードします。スープの sObject
の ID がターゲットで指定したオブジェクトの ID と同じ場合は、SmartSync がスープの重複オブジェクトを上書
きします。
構文
cordova.require("com.salesforce.plugin.smartsync").syncDown(
target, soupName, options, callback);
パラメータ
target
スープにダウンロードする sObject を示します。次のいずれかの文字列にすることができます。
•
{type:"soql", query:"<soql query>"}
指定した SOQL クエリで返された sObject をダウンロードします。
•
{type:"sosl", query:"<sosl query>"}
指定した SOSL クエリで返された sObject をダウンロードします。
•
{type:"mru", sobjectType:"<sobject type>", fieldlist:"<fields to fetch>"}
指定した sObject 型の最近使用した sObject の指定した項目をダウンロードします。
soupName
ダウンロードされた sObject を受信するスープの名前。
options
次のいずれかの値を使用します。
• 変更されたローカルレコードを上書きする場合は、
{mergeMode:Force.MERGE_MODE_DOWNLOAD.OVERWRITE} を渡します。
• 変更されたローカルレコードを維持する場合は、
{mergeMode:Force.MERGE_MODE_DOWNLOAD.LEAVE_IF_CHANGED} を渡します。この値を使用する
と、ローカルで変更されたレコードが上書きされません。
callback
同期の開始後にコールされる関数。この関数は、同期操作中に複数回コールされます。
1. 同期操作の開始時
2. 内部 REST 要求の完了時
211
オフライン管理
ハイブリッド
3. 結果の各ページをダウンロード後 (結果を 100% 受信するまで)
同期操作の状況更新は、ブラウザイベントによって通知されます。これらの更新をリスンするには、次の
コードを使用します。
document.addEventListener("sync",
function(event) {
// event.detail contains the status of the sync operation
}
);
event.detail メンバーには、次の項目との対応付けが含まれます。
• syncId: この同期操作の ID
• type: 「syncDown」
• target: 指定したターゲット
• soupName: 指定したスープ名
• options: 「{}」
• status: 同期状況 (「新規」、「実行中」、「完了」、「失敗」のいずれか)
• progress: 現時点でダウンロード済みの合計レコードの割合 (整数、0 ~ 100%)
• totalSize: 現時点でダウンロード済みのレコード数
syncUp() メソッド
soupName で指定したSmartStoreスープで作成、削除、または更新されたレコードをアップロードして、Salesforce
サーバの対応するレコードを更新、作成、または削除します。更新はブラウザイベントによって通知されま
す。
構文
cordova.require("com.salesforce.plugin.smartsync").syncUp(soupName, options, callback);
パラメータ
soupName
アップロードする sObject があるスープの名前
options
次のキーとの対応付け:
• fieldlist: サーバに送信される項目のリスト
callback
同期の開始後にコールされる関数。この関数は、同期操作中に複数回コールされます。
1. 同期操作の開始時
2. 内部 REST 要求の完了時
3. 結果の各ページをアップロード後 (結果を 100% 受信するまで)
212
オフライン管理
ハイブリッド
同期操作の状況更新は、ブラウザイベントによって通知されます。これらの更新をリスンするには、次の
コードを使用します。
document.addEventListener("sync",
function(event) {
// event.detail contains the status of the sync operation
}
);
event.detail メンバーには、次の項目との対応付けが含まれます。
• syncId: この同期操作の ID
• type: 「syncUp」
• target: 「{}」
• soupName: 指定したスープ名
• options: アップロードする項目のリスト
• status: 同期状況 (「新規」、「実行中」、「完了」、「失敗」のいずれか)
• progress: 現時点でダウンロード済みの合計レコードの割合 (整数、0 ~ 100%)
• totalSize: 現時点でダウンロード済みのレコード数
JavaScript での SmartSync Data Framework の使用
ハイブリッドアプリケーションで SmartSync を使用するには、<script> タグを使用して次のファイルをインポー
トします。
• jquery-x.x.x.min.js (SalesforceMobileSDK-Shared リポジトリの dependencies/jquery/ ディレクトリ
内のバージョンを使用)
• underscore-x.x.x.min.js (SalesforceMobileSDK-Shared リポジトリの dependencies/underscore/ ディ
レクトリ内のバージョンを使用)
• backbone-x.x.x.min.js (SalesforceMobileSDK-Shared リポジトリの dependencies/backbone/ ディレクト
リ内のバージョンを使用)
• cordova.js
• forcetk.mobilesdk.js
• smartsync.js
モデルオブジェクトの実装
SmartSync オブジェクトの使用を開始するには、操作する各 SObject を表すモデルオブジェクトを定義しま
す。SObjects は、標準 Salesforce オブジェクトまたはカスタムオブジェクトになります。たとえば、次のコー
ドは、2 つの必須プロパティ (sobjectType および fieldlist) を設定する Account オブジェクトのモデルを作
成し、cacheMode() 関数を定義します。
app.models.Account = Force.SObject.extend({
sobjectType: "Account",
fieldlist: ["Id", "Name", "Industry", "Phone"],
cacheMode: function(method) {
213
オフライン管理
ハイブリッド
if (app.offlineTracker.get("offlineStatus") == "offline") {
return "cache-only";
}
else {
return (method == "read" ? "cache-first" : "server-first");
}
}
});
app.models.Account モデルオブジェクトは、smartsync.js で定義されている Force.SObject を拡張し
ます。また、cacheMode() 関数は、ローカル offlineTracker オブジェクトをクエリして、デバイスのオ
フライン状況を取得します。Cordova ライブラリを使用して、特定時点のオフライン状況を判断できます。
SmartSync は、モデルに対して取得操作または保存操作を実行できます。アプリケーションの cacheMode の値
を使用して、操作の実行対象 (サーバまたはキャッシュ) を決定します。cacheMode メンバーは、単純な string
型のプロパティか、文字列を返す関数のいずれかになります。
モデルコレクションの実装
このサンプルアプリケーションのモデルコレクションは、Force.SObjectCollection を拡張します。
// The AccountCollection Model
app.models.AccountCollection = Force.SObjectCollection.extend({
model: app.models.Account,
fieldlist: ["Id", "Name", "Industry", "Phone"],
setCriteria: function(key) {
this.key = key;
},
config: function() {
// Offline: do a cache query
if (app.offlineTracker.get("offlineStatus") == "offline") {
return {type:"cache", cacheQuery:{queryType:"like",
indexPath:"Name", likeKey: this.key+"%",
order:"ascending"}};
}
// Online
else {
// First time: do a MRU query
if (this.key == null) {
return {type:"mru", sobjectType:"Account",
fieldlist: this.fieldlist};
}
// Other times: do a SOQL query
else {
var soql = "SELECT " + this.fieldlist.join(",")
+ " FROM Account"
+ " WHERE Name like '" + this.key + "%'";
return {type:"soql", query:soql};
}
}
}
});
214
オフライン管理
ハイブリッド
このモデルコレクションは、コレクションから取得する取引先の名前であるキー (省略可能) を使用します。ま
た、取得される情報を決定する config() 関数も定義します。デバイスがオフラインの場合、config() 関数
はキャッシュクエリステートメントを作成します。デバイスがオンラインで、キーが指定されていない場合、
最後に使用したレコード ("mru") をクエリします。デバイスがオンラインで、キーが指定されている場合、キー
に一致する名前のレコードを取得する標準 SOQL クエリを作成します。Force.SObjectCollection プロトタ
イプの取得操作は、返された設定を透過的に使用して、モデルコレクションにクエリレコードを自動的に入力
します。
キャッシュクエリの書式設定についての詳細は、「querySpec」を参照してください。
メモ: これらのコード例は、Account Editor サンプルアプリケーションの一部です。サンプルの説明は、
「Account Editor のサンプル」を参照してください。
オフラインキャッシュ
オフラインサポートを提供するには、アプリケーションでそのモデルおよびコレクションをキャッシュできる
必要があります。SmartSync は、キャッシュの操作を完全に制御できるメカニズム (設定可能) を提供します。
デフォルトキャッシュおよびカスタムキャッシュの実装
デフォルトキャッシュの場合、SmartSync ライブラリは StoreCache (SmartStore を使用するキャッシュ実装) を定義
します。StoreCache と SmartStore はどちらも SmartSync アプリケーションのコンポーネント (省略可能) です。アプ
リケーションが Mobile SDK コンテナではなくブラウザで実行されている場合や、SmartStore を使用しない場合、
代替キャッシュ実装を提供する必要があります。SmartSyncでは、次の操作をサポートするためにキャッシュオ
ブジェクトが必要になります。
• retrieve
• save
• save all
• remove
• find
SmartSync のキャッシュワークフロー
SmartSync モデルは、アプリケーションの代わりにキャッシュおよび Salesforce サーバとのすべてのやり取りを
実行します。アプリケーションは、モデルオブジェクトの属性を取得および設定します。モデルは、保存操作
時にこれらの属性設定を使用して、変更をキャッシュまたはサーバに書き込むかどうかを判断したり、新しい
データと既存のデータのマージ方法を決定したりします。基本データまたはモデル自体に何らかの変更がある
と、モデルはイベント通知を送信します。同様に、取得を要求すると、モデルはモデルコレクションでデータ
を取得してアプリケーションに提供します。
215
オフライン管理
ハイブリッド
SmartSync は、CRUD 操作時にキャッシュのデータを透過的に更新します。フラグ (省略可能) を介して透過レベ
ルを制御できます。キャッシュされたオブジェクトは、ローカルで作成、更新、削除されたかどうかを示す
「dirty」属性を保持します。
キャッシュモデル
キャッシュを使用する場合、各 CRUD 操作のモデルを指定できます。サポートされるモードは次のとおりです。
モード
定数
説明
"cache-only"
Force.CACHE_MODE.CACHE_ONLY
キャッシュから読み取る
か、キャッシュに書き込
みます。サーバの操作は
実行しません。
"server-only"
Force.CACHE_MODE.SERVER_ONLY
サーバから読み取るか、
サーバに書き込みます。
キャッシュの操作は実行
しません。
"cache-first"
Force.CACHE_MODE.CACHE_FIRST
取得操作の場合のみ。
キャッシュからレコード
を取得します。キャッ
シュにレコードが含まれ
216
オフライン管理
モード
ハイブリッド
定数
説明
ていない場合、サーバか
ら取得してキャッシュを
更新します。
"server-first" (デ
フォルト)
Force.CACHE_MODE.SERVER_FIRST
サーバの操作を実行し、
キャッシュを更新しま
す。
直接キャッシュをクエリするには、キャッシュクエリを使用します。SmartStore は、クエリ API、独自のクエリ
言語、Smart SQL を提供します。「スープからのデータの取得」を参照してください。
オフラインキャッシュの実装
SmartSyncでオフラインキャッシュをサポートするには、次のようないくつかのタスクを実装する必要がありま
す。
• app.models.Account の例で示すようにオフライン状況を追跡して、CRUD 操作の適切なキャッシュコン
トロールフラグを指定する。
• ローカルで編集されたレコードを収集し、デバイスがオンラインに戻ったときにその変更をサーバに保存
する。次の例では、SmartStore キャッシュクエリを使用して、ローカルで変更されたレコードを取得し、
SyncPage 関数をコールして、HTML でその結果を表示しています。
sync: function() {
var that = this;
var localAccounts = new app.models.AccountCollection();
localAccounts.fetch({
config: {type:"cache", cacheQuery: {queryType:"exact",
indexPath:"__local__", matchKey:true}},
success: function(data) {
that.slidePage(new app.views.SyncPage({model: data}).render());
}
});
}
app.views.SyncPage = Backbone.View.extend({
template: _.template($("#sync-page").html()),
render: function(eventName) {
$(this.el).html(this.template(_.extend(
{countLocallyModified: this.model.length},
this.model.toJSON())));
this.listView = new app.views.AccountListView({el: $("ul",
this.el), model: this.model});
this.listView.render();
return this;
},
217
オフライン管理
ハイブリッド
...
});
オフラインキャッシュのための StoreCache の使用
smartsync.js ライブラリは、データを SmartStore に保存する StoreCache という名前のキャッシュを実装しま
す。SmartSync は StoreCache をデフォルトキャッシュとして使用しますが、StoreCache はスタンドアロンコンポー
ネントです。SmartSync を使用しない場合でも、SmartStore の操作に StoreCache を活用できます。
メモ: StoreCache は SmartSync と併用することを想定していますが、「オフラインキャッシュ」 で説明され
ているように、要件を満たす任意のキャッシュメカニズムを SmartSync と共に使用することもできます。
作成および初期化
StoreCache オブジェクトは、内部的に SmartStore スープと連動します。スープ soupName によってサポートされ
る StoreCache オブジェクトを作成するには、次のコンストラクタを使用します。
new Force.StoreCache(soupName [, additionalIndexSpecs, keyField])
soupName
必須。基盤となる SmartStore スープの名前。
additionalIndexSpecs
デフォルトのインデックス項目に加えてキャッシュインデックスに含める項目。書式設定の手順は、「スー
プの登録」を参照してください。
keyField
レコード ID を格納する項目の名前。指定しない場合、StoreCache は "Id" という名前の項目で ID を検索しま
す。
StoreCache オブジェクトのスープ項目には、オフライン編集を追跡する次の 4 つの追加の Boolean 項目が含まれ
ます。
• __locally_created__
• __locally_updated__
• __locally_deleted__
• __local__ (前の 3 つのいずれかが true の場合、true に設定)
これらの項目は内部で使用することを目的としていますが、アプリケーションでも使用できます。StoreCache
は、 __local__ 項目およびその ID 項目の各スープにインデックスを付けます。additionalIndexSpecs パ
ラメータを使用して、インデックスに含める追加項目を指定できます。
基盤となるスープを登録するには、StoreCache オブジェクトで init() をコールします。この関数は、スープ
の登録が完了したときに解決する jQuery promise を返します。
StoreCache メソッド
init()
基盤となる SmartStore スープを登録します。スープの登録が完了したときに解決さる jQuery promise を返しま
す。
218
オフライン管理
ハイブリッド
retrieve(key [, fieldlist])
SmartStore によって返される keyField のキーを持つレコードに解決する jQuery promise を返します。レコードが
検出されない場合や、検出されたレコードに fieldlist パラメータのすべての項目が含まれていない場合、
promise は null に解決されます。
key
取得されるレコードのキー値。
fieldlist
(省略可能) 必須項目の JavaScript 配列。次に例を示します。
["field1","field2","field3"]
save(record [, noMerge])
SmartStoreの更新/挿入が完了したときに、保存されたレコードに解決する jQuery promise を返します。noMerge
が指定されていない場合や、false の場合、渡されたレコードは、同じキーのサーバレコード (存在する場合)
とマージされます。
record
保存されるレコード。次のような形式になります。
{<field_name1>:"<field_value1>"[,<field_name2>:"<field_value2>",...]}
次に例を示します。
{Id:"007", Name:"JamesBond", Mission:"TopSecret"}
noMerge
(省略可能) 渡されたレコードが、一致するサーバレコードとマージされるかどうかを示す boolean 値。デ
フォルトは false です。
saveAll(records [, noMerge])
records が、保存されるレコードの配列である点を除き、save() と同じです。保存されるレコードに解
決する jQuery promise を返します。
records
レコードの配列。配列の各項目は、save() 関数に示されるように書式設定されます。
noMerge
(省略可能) 渡されたレコードが、一致するサーバレコードとマージされるかどうかを示す boolean 値。デ
フォルトは false です。
remove(key)
指定されたキーを持つレコードが SmartStore から削除されたときに解決する jQuery promise を返します。
key
削除されるレコードのキー値。
find(querySpec)
SmartStore に対してクエリが実行されたときに解決する jQuery promise を返します。解決される値は、次の項
目を持つオブジェクトです。
219
オフライン管理
ハイブリッド
項目
説明
records
取得されたすべてのレコード
hasMore
さらにレコードを取得できるかどうかをチェックす
る関数
getMore
さらにレコードを取得する関数
closeCursor
開いているカーソルを閉じて、今後の取得を無効に
する関数
querySpec
SmartStore クエリ関数コールに基づく仕様。次のような形式になります。
{queryType: "like" | "exact" | "range" | "smart"[, query_type_params]}
ここで、query_type_params は、関連する SmartStore クエリ関数コールの形式に一致します。「スー
プからのデータの取得」を参照してください。
次に、いくつか例を示します。
{queryType:"exact", indexPath:"<indexed_field_to_match_on>", matchKey:<value_to_match>,
order:"ascending"|"descending", pageSize:<entries_per_page>}
{queryType:"range", indexPath:"<indexed_field_to_match_on>", beginKey:<start_of_Range>,
endKey:<end_of_range>, order:"ascending"|"descending", pageSize:<entries_per_page>}
{queryType:"like", indexPath:"<indexed_field_to_match_on>", likeKey:"<value_to_match>",
order:"ascending"|"descending", pageSize:<entries_per_page>}
{queryType:"smart", smartSql:"<smart_sql_query>", order:"ascending"|"descending",
pageSize:<entries_per_page>}
例
次の例では、StoreCache オブジェクトの作成、初期化、使用方法を示します。
var cache = new Force.StoreCache("agents", [{path:"Mission", type:"string"} ]);
// initialization of the cache / underlying soup
cache.init()
.then(function() {
// saving a record to the cache
return cache.save({Id:"007", Name:"JamesBond", Mission:"TopSecret"});
})
.then(function(savedRecord) {
// retrieving a record from the cache
return cache.retrieve("007");
})
.then(function(retrievedRecord) {
// searching for records in the cache
return cache.find({queryType:"like", indexPath:"Mission", likeKey:"Top%",
220
オフライン管理
ハイブリッド
order:"ascending", pageSize:1});
})
.then(function(result) {
// removing a record from the cache
return cache.remove("007");
});
次の例では、saveAll() 関数の使用方法と find() 関数の結果を示します。
// initialization
var cache = new Force.StoreCache("agents", [ {path:"Name", type:"string"}, {path:"Mission",
type:"string"} ]);
cache.init()
.then(function() {
// saving some records
return cache.saveAll([{Id:"007", Name:"JamesBond"},{Id:"008", Name:"Agent008"},
{Id:"009", Name:"JamesOther"}]);
})
.then(function() {
// doing an exact query
return cache.find({queryType:"exact", indexPath:"Name", matchKey:"Agent008",
order:"ascending", pageSize:1});
})
.then(function(result) {
alert("Agent mission is:" + result.records[0]["Mission"];
});
競合検出
モデルオブジェクトは、オブジェクトをサーバに保存するときに不要なデータ損失を回避する競合検出 (省略
可能) をサポートしています。競合検出は、デバイスがオフライン状態から復帰しているかどうかに関係なく、
任意の保存操作と共に使用できます。
競合検出をサポートするには、サーバから取得した元の値を格納するセカンダリキャッシュを指定します。
SmartSyncは、後で参照できるようにこのキャッシュを保持します。保存または削除する場合、マージモードを
指定します。次の表に、サポートされるモードの概要を示します。モードの説明を理解するには、「theirs」を
現在のサーバレコード、「yours」を現在のローカルレコード、「base」をサーバから最初に取得したレコード
として考えます。
モード
定数
説明
overwrite
Force.MERGE_MODE.OVERWRITE
「theirs」または「base」
と比較することなく
「yours」をサーバに書
き込みます。これは、
競合検出を使用しない
場合と同じです。
merge-accept-yours
Force.MERGE_MODE.MERGE_ACCEPT_YOURS
「theirs」と「yours」を
マージします。同じ項
目がローカルとリモー
221
オフライン管理
モード
ハイブリッド
定数
説明
トの両方で変更された
場合、ローカルの値が
保持されます。
merge-fail-if-conflict
Force.MERGE_MODE.MERGE_FAIL_IF_CONFLICT
merge-fail-if-changed Force.MERGE_MODE.MERGE_FAIL_IF_CHANGED
「theirs」と「yours」を
マージします。同じ項
目がローカルとリモー
トの両方で変更された
場合、この操作は失敗
します。
「theirs」と「yours」を
マージします。何らか
の項目がリモートで変
更された場合、この操
作は失敗します。
保存または削除操作が失敗した場合、次の項目を含むレポートオブジェクトを取得します。
項目名
次の文字列を含む
base
最初に取得した属性
theirs
最新のサーバ属性
yours
ローカルで変更された属性
remoteChanges
base と theirs 間で変更された項目のリスト
localChanges
base と yours 間で変更された項目のリスト
conflictingChanges
異なる値を使用して theirs と yours の両方で変更された
項目のリスト
ダイアグラムは、マージモードの仕組みを明確にするのに役立ちます。
MERGE_MODE.OVERWRITE
MERGE_MODE.OVERWRITE ダイアグラムでは、クライアントは A と B を変更し、サーバは B と C を変更してい
ます。B への変更は競合していますが、A と C への変更は競合していません。ただし、保存操作では、すべて
のクライアントの値が無差別にサーバに書き込まれるため、サーバの変更が上書きされます。
222
オフライン管理
ハイブリッド
MERGE_ACCEPT_YOURS
MERGE_MODE.MERGE_ACCEPT_YOURS ダイアグラムでは、クライアントは A と B を変更し、サーバは B と C を
変更しています。競合があるかどうかに関係なく、クライアントの変更 (A と B) によってサーバの対応する項
目が上書きされます。ただし、クライアントが変更しなかった項目 (C) では、対応するサーバの値は上書きさ
れません。
MERGE_FAIL_IF_CONFLICT (失敗)
最初の MERGE_MODE.MERGE_FAIL_IF_CONFLICT ダイアグラムでは、クライアントとサーバの両方が B を変
更しています。これらの競合する変更が原因で保存操作が失敗します。
MERGE_FAIL_IF_CONFLICT (成功)
2 番目の MERGE_MODE.MERGE_FAIL_IF_CONFLICT ダイアグラムでは、クライアントは A を変更し、サーバは
B を変更しています。これらの変更は競合しないため、保存操作は成功します。
223
オフライン管理
ハイブリッド
ミニチュートリアル: 競合検出
次のミニチュートリアルでは、さまざまな状況下でマージモードが保存操作にどのような影響を与えるかにつ
いて説明します。HTML コンテキスト内のさまざまな例を挙げて説明します。
1. 必要なキャッシュを設定します。
var cache = new Force.StoreCache(soupName);
var cacheForOriginals = new Force.StoreCache(soupNameForOriginals);
var Account = Force.SObject.extend({sobjectType:"Account", fieldlist:["Id", "Name",
"Industry"], cache:cache, cacheForOriginals:cacheForOriginals});
2. 既存の取引先を取得します。
var account = new Account({Id:<some actual account id>});
account.fetch();
3. 取引先の名前が「Acme」で業種が「ソフトウェア」だとします。名前を「Acme2」に変更します。
Account.set("Name", "Acme2");
4. デフォルトの "overwrite" マージモードが使用されるように、マージモードを指定せずにサーバに保存しま
す。
account.save(null);
取引先の名前が「Acme2」でその業種が「ソフトウェア」になりました。サーバ上の業種が「電子機器」に
変更されるとします。
5. 取引先名を再度変更します。
Account.set("Name", "Acme3");
現在、キャッシュの変更 (名前) とサーバの変更 (業種) があります。
6. "merge-fail-if-changed" マージモードを使用して再度保存します。
account.save(null,
{mergeMode: "merge-fail-if-changed", error: function(err) {
// err will be a map of the form:
// {base:…, theirs:…, yours:…,
// remoteChanges:["Industry"], localChanges:["Name"],
// conflictingChanges:[]}
});
サーバレコードが変更されているため、エラーコールバックがコールされます。
224
オフライン管理
ハイブリッド
7. "merge-fail-if-conflict" マージモードを使用して再度保存します。サーバの変更とクライアントの変更間で競合
が存在しないため、このマージは成功します。
account.save(null, {mergeMode: "merge-fail-if-conflict"});
取引先の名前は「Acme3」(yours) で、その業種は「電子機器」(theirs) になりました。一方、サーバ上の名前
が「NewAcme」、業種が「サービス」に変更されるとします。
8. 取引先名を再度変更します。
Account.set("Name", "Acme4");
9. "merge-fail-if-changed" マージモードを使用して再度保存します。サーバレコードが変更されているため、エ
ラーコールバックがコールされます。
account.save(null, {mergeMode: "merge-fail-if-changed", error: function(err) {
// err will be a map of the form:
// {base:…, theirs:…, yours:…,
// remoteChanges:["Name", "Industry"], localChanges:["Name"],
// conflictingChanges:["Name"]}
});
10. "merge-fail-if-conflict" マージモードを使用して再度保存します。
account.save(null, {mergeMode: "merge-fail-if-changed", error: function(err) {
// err will be a map of the form:
// {base:…, theirs:…, yours:…,
// remoteChanges:["Name", "Industry"], localChanges:["Name"],
// conflictingChanges:["Name"]}
});
サーバとキャッシュの両方で名前項目が変更されて競合が発生しているため、エラーコールバックがコー
ルされます。
11. "merge-accept-yours" マージモードを使用して再度保存します。マージモードでは、どちらの名前の値を受け
入れるかが save() 関数に通知されているため、このマージは成功します。また、業種を変更していない
ため、この項目は競合しません。
account.save(null, {mergeMode: "merge-accept-yours"});
名前は「Acme4」(yours) で、業種は「サービス」(theirs) です。どちらもキャッシュとサーバにあります。
カスタム API エンドポイントへのアクセス
Mobile SDK 2.1 では、すべてのREST APIを操作できるようにSmartSyncの範囲が拡張されています。以前は、Force.com
API を使用して sObject に基本的な操作しか実行できませんでした。現在では、Apex REST オブジェクト、Chatter
Files、および他の Salesforce REST API と共に SmartSync を使用できるようになりました。 また、Salesforce 以外の REST
API もコールできます。
Force.RemoteObject クラス
任意の REST コールをサポートするために、SmartSync には Force.RemoteObject 抽象クラスが導入されてい
ます。Force.RemoteObject は、Force.SObject と Backbone.Model 間の抽象化レイヤとして機能しま
225
オフライン管理
ハイブリッド
す。Force.SObject は、Backbone.Model を直接サブクラス化するのではなく、Backbone.Model をサブ
クラス化する Force.RemoteObject をサブクラス化するようになりました。Force.RemoteObject は、サー
バとの通信を除き、Force.SObject が以前に行っていたすべてのことを実行します。
syncRemoteObjectWithServer() を使用したカスタムエンドポイントのコール
RemoteObject.syncRemoteObjectWithServer() プロトタイプメソッドは、サーバとのやりとりを処理し
ます。Force.SObject は、syncRemoteObjectWithServer() を実装して Force.com REST API を使用します。
他のサーバエンドポイントを使用する場合、Force.RemoteObject のサブクラスを作成し、
syncRemoteObjectWithServer() を実装します。このメソッドは、サブクラスのオブジェクトに対して
fetch() をコールしたときにコールされます (サーバから取得するようにオブジェクトが現在設定されている
場合)。
例: 例
HybridFileExplorer サンプルアプリケーションは、Force.RemoteObject の使用方法を示す SmartSync アプリ
ケーションです。HybridFileExplorer は、Chatter REST API をコールしてファイルを操作します。これは、
Force.RemoteObject を拡張する app.models.File オブジェクトを定義します。app.models.File
は、syncRemoteObjectWithServer() の実装で /chatter/files/fileId REST API をラップする
forcetk.fileDetails() をコールします。
app.models.File = Force.RemoteObject.extend({
syncRemoteObjectWithServer: function(method, id) {
if (method != "read")
throw "Method not supported " + method;
return Force.forcetkClient.fileDetails(id, null);
}
})
Force.RemoteObjectCollection クラス
取得されたオブジェクトのコレクションをサポートするために、SmartSync には
Force.RemoteObjectCollection 抽象クラスが導入されています。このクラスは、
Force.SObjectCollection と Backbone.Collection 間の抽象化レイヤとして機能します。Force.SObjectCollection
は、Backbone.Collection を直接サブクラス化するのではなく、Backbone.Collection をサブクラス化する
Force.RemoteObjectCollection をサブクラス化するようになりました。Force.RemoteObjectCollection は、サー
バとの通信を除き、Force.SObjectCollection が以前に行っていたすべてのことを実行します。
fetchRemoteObjectFromServer() を使用してカスタムエンドポイントを実装する
RemoteObject.fetchRemoteObjectFromServer() プロトタイプメソッドは、サーバとのやりとりを処理
します。このメソッドは Force.com REST API を使用して SOQL/SOSL および MRU クエリを実行します。任意のサー
バエンドポイントを使用する場合、Force.RemoteObjectCollection のサブクラスを作成し、
fetchRemoteObjectFromServer() を実装します。このメソッドは、サブクラスのオブジェクトに対して
fetch() をコールしたときにコールされます (サーバから取得するようにオブジェクトが現在設定されている
場合)。
226
オフライン管理
ハイブリッド
app.models.FileCollection.fetchRemoteObjectsFromServer() 関数が返されると、応答のメタデー
タを使用する有効な情報や、便利な関数を格納するオブジェクトが promise 化されます。このオブジェクトに
は、次が含まれます。
• totalSize: 返されたコレクションのファイル数
• records: 返されたファイルのコレクション
• hasMore: 結果の別のページを取得できるかどうかを示す boolean 値を返す関数
• getMore: 結果の次のページを取得する関数 (hasMore() で true が返された場合)
• closeCursor: コレクションの反復処理が終了したことを示す関数
これらの関数は、サーバ応答に含まれている情報 (Files.length や nextPageUrl など) を利用します。
例: 例
HybridFileExplorer サンプルアプリケーションでは、Force.RemoteObjectCollection の使用方法も示し
ます。この例では、Chatter REST APIをコールして、ファイルのリストを反復処理します。ownedFilesList、
filesInUsersGroups、および filesSharedWithUser の 3 つの REST 操作がサポートされています。
この例の hasMore() や getMore() などの関数を記述して、結果のページを移動できます。ただし、ア
プリケーションは直接 fetchRemoteObjectsFromServer() をコールしないため、コレクションオブ
ジェクトで fetch() をコールすると返される promise オブジェクトをキャプチャします。
app.models.FileCollection = Force.RemoteObjectCollection.extend({
model: app.models.File,
setCriteria: function(key) {
this.config = {type:key};
},
fetchRemoteObjectsFromServer: function(config) {
var fetchPromise;
switch(config.type) {
case "ownedFilesList": fetchPromise =
Force.forcetkClient.ownedFilesList("me", 0);
break;
case "filesInUsersGroups": fetchPromise =
Force.forcetkClient.filesInUsersGroups("me", 0);
break;
case "filesSharedWithUser": fetchPromise =
Force.forcetkClient.filesSharedWithUser("me", 0);
break;
};
return fetchPromise
.then(function(resp) {
var nextPageUrl = resp.nextPageUrl;
return {
totalSize: resp.files.length,
records: resp.files,
hasMore: function() {
return nextPageUrl != null; },
getMore: function() {
var that = this;
227
オフライン管理
ハイブリッド
if (!nextPageUrl)
return null;
return
forcetkClient.queryMore(nextPageUrl)
.then(function(resp) {
nextPageUrl = resp.nextPageUrl;
that.records.
pushObjects(resp.files);
return resp.files;
});
},
closeCursor: function() {
return $.when(function() {
nextPageUrl = null;
});
}
};
});
}
});
Apex REST リソースの使用
Apex REST リソースをサポートするために、Mobile SDK には、Force.ApexRestObject と
Force.ApexRestObjectCollection の 2 つのクラスが用意されています。これらのクラスは、それぞれ
Force.RemoteObject と Force.RemoteObjectCollection をサブクラス化し、Apex REST を使用して作成
した REST API と通信できます。
Force.ApexRestObject
Force.ApexRestObject は、Force.SObject と似ています。sobjectType の代わりに、
Force.ApexRestObject には services/apexrest を基準とする Apex REST リソースの相対パスが必要です。
たとえば、リソースのフルパスが services/apexrest/simpleAccount/* の場合、/simpleAccount/* の
みを指定します。また、Force.ApexRestObject では、ID 項目名が「Id」以外の場合、その名前を指定する
必要があります。
例: 例
accountId と accountName の 2 つの項目を含む取引先である「simple account」(簡単な取引先) という名
前の Apex REST リソースを作成したとします。
@RestResource(urlMapping='/simpleAccount/*')
global with sharing class SimpleAccountResource {
static String getIdFromURI() {
RestRequest req = RestContext.request;
return req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
}
@HttpGet global static Map&lt;String, String&gt; doGet() {
String id = getIdFromURI();
Account acc = [select Id, Name from Account
228
オフライン管理
ハイブリッド
where Id = :id];
return new Map&lt;String, String&gt;{
'accountId'=>acc.Id, 'accountName'=>acc.Name};
}
@HttpPost global static Map&lt;String, String&gt;
doPost(String accountName) {
Account acc = new Account(Name=accountName);
insert acc;
return new Map&lt;String, String&gt;{
'accountId'=>acc.Id, 'accountName'=>acc.Name};
}
@HttpPatch global static Map&lt;String, String&gt;
doPatch(String accountName) {
String id = getIdFromURI();
Account acc = [select Id from Account
where Id = :id];
acc.Name = accountName;
update acc;
return new Map&lt;String, String&gt;{
'accountId'=>acc.Id, 'accountName'=>acc.Name};
}
@HttpDelete global static void doDelete() {
String id = getIdFromURI();
Account acc = [select Id from Account where Id = :id];
delete acc;
RestContext.response.statusCode = 204;
}
}
SmartSync で、次を実行して「simple account」を作成します。
var SimpleAccount = Force.ApexRestObject.extend(
{apexRestPath:"/simpleAccount",
idAttribute:"accountId",
fieldlist:["accountId", "accountName"]});
var acc = new SimpleAccount({accountName:"MyFirstAccount"});
acc.save();
その「simple account」を更新できます。
acc.set("accountName", "MyFirstAccountUpdated");
acc.save(null, {fieldlist:["accountName"]);
// our apex patch endpoint only expects accountName
別の「simple account」を取得できます。
var acc2 = new SimpleAccount({accountId:"&lt;valid id&gt;"})
acc.fetch();
「simple account」を削除できます。
acc.destroy();
229
オフライン管理
ハイブリッド
メモ: 通常、SmartSync のコール (fetch()、save()、および destroy() など) では、正常なコール
バック関数およびエラーコールバック関数を定義するオプションパラメータを渡します。次に例を
示します。
acc.destroy({success:function(){alert("delete succeeded");}});
Force.ApexRestObjectCollection
Force.ApexRestObjectCollection は、Force.SObjectCollection と似ています。取得用に指定する設
定では、SOQL、SOSL、または MRU がサポートされていません。代わりに、services/apexrest を基準とする
Apex REST リソースの相対パスが必要です。たとえば、リソースのフルパスが
services/apexrest/simpleAccount/* の場合、/simpleAccount/* のみを指定します。
エンドポイントでクエリ文字列のパラメータがサポートされていれば、これらを渡すこともできます。Apex
REST エンドポイントは、次の形式で応答を返す必要があります。
{
totalSize: <number of records returned>
records: <all fetched records>
nextRecordsUrl: <url to get next records or null>
}
例: 例
「simple account」という名前の Apex REST リソースを作成したとします。これは、指定された名前と一致す
る「simple account」を返します。
@RestResource(urlMapping='/simpleAccounts/*')
global with sharing class SimpleAccountsResource {
@HttpGet global static SimpleAccountsList doGet() {
String namePattern =
RestContext.request.params.get('namePattern');
List<SimpleAccount> records = new List<SimpleAccount>();
for (SObject sobj : Database.query(
'select Id, Name from Account
where Name like \'' + namePattern + '\'')) {
Account acc = (Account) sobj;
records.add(new SimpleAccount(acc.Id, acc.Name));
}
return new SimpleAccountsList(records.size(), records);
}
global class SimpleAccountsList {
global Integer totalSize;
global List<SimpleAccount> records;
global SimpleAccountsList(Integer totalSize,
List<SimpleAccount> records) {
this.totalSize = totalSize;
this.records = records;
}
}
230
オフライン管理
ハイブリッド
global class SimpleAccount {
global String accountId;
global String accountName;
global SimpleAccount(String accountId, String accountName)
{
this.accountId = accountId;
this.accountName = accountName;
}
}
}
SmartSync で、次を実行して「simple account」レコードのリストを取得します。
var SimpleAccountCollection =
Force.ApexRestObjectCollection.extend(
{model: SimpleAccount,
config:{
apexRestPath:"/simpleAccounts",
params:{namePattern:"My%"}
}
}
);
var accs = new SimpleAccountCollection();
accs.fetch();
メモ: 通常、SmartSync のコール (fetch() など) では、正常なコールバック関数およびエラーコール
バック関数を定義するオプションパラメータを渡します。次に例を示します。
acc.fetch({success:function(){alert("fetched " +
accs.models.length + " simple accounts");}});
チュートリアル: SmartSync アプリケーションの作成
このチュートリアルでは、SmartSync Data Framework を使用するローカルハイブリッドアプリケーションの作成
方法について説明します。Mobile SDK 2.0 に付属するUser Search のサンプルアプリケーションを再作成します。
User Search では、Salesforce 組織のユーザレコードを検索し、ユーザレコードに関する基本情報の詳細を確認で
きます。
このサンプルでは、次の Web テクノロジを使用しています。
• Backbone.js
• Ratchet
• HTML5
• JavaScript
プロジェクトの設定
まず、NPM インストーラを使用して Salesforce Mobile SDK をインストールしていることを確認します。iOS の手順
は、「iOS のインストール」を参照してください。Android の手順は、「Android のインストール」を参照してく
ださい。
231
オフライン管理
ハイブリッド
また、http://goratchet.com/ から ratchet.css ファイルをダウンロードします。
1. Mobile SDKをインストールしたら、プラットフォームのローカルハイブリッドプロジェクトを作成します。
a. iOS の場合: コマンドターミナルで、次のコマンドを入力します。
forceios create --apptype=hybrid_local
--appname=UserSearch --companyid=com.acme.UserSearch
--organization=Acme --outputdir=.
forceios スクリプトによって、./UserSearch/UserSearch.xcode.proj にプロジェクトが作成されま
す。
b. Android の場合:コマンドターミナルまたは Windows コマンドプロンプトで、次のコマンドを入力します。
forcedroid create -—apptype="hybrid_local"
--appname="UserSearch" --targetdir=.
--packagename="com.acme.usersearch"
forcedroid スクリプトによって ./UserSearch にプロジェクトが作成されます。
2. 画面の指示に従って、Eclipse (Android の場合) または Xcode (iOS の場合) で新しいプロジェクトを開きます。
3. www/ フォルダを開きます。
4. ファイルを https://github.com/forcedotcom/SalesforceMobileSDK-Shared/ の samples/usersearch ディレクトリか
ら www/ フォルダにコピーします。
5. www フォルダで、コードエディタを使用して index.html を開き、そのすべてのコンテンツを削除しま
す。
アプリケーションの HTML ファイルの編集
アプリケーションの基本構造を作成するには、参照、リンク、コードインフラストラクチャを格納する空の
HTML ページを定義します。
1. Xcode で、index.html を編集して次の基本構造を追加します。
<!DOCTYPE html>
<html>
<head>
</head>
<body>
</body>
</html>
2. <head> 要素で、次の操作を行います。
a. Web ページではなくアプリケーションのようなページにするために拡大縮小を無効にします。
<meta name="viewport" content="width=device-width, initial-scale=1.0,
maximum-scale=1.0, user-scalable=no;" />
b. コンテンツタイプを設定します。
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
232
オフライン管理
ハイブリッド
c. モバイル用の外観になるようにリンクを ratchet.css ファイルに追加します。
<link rel="stylesheet" href="css/ratchet.css"/>
d. 必要な JavaScript ファイルを含めます。
<script
<script
<script
<script
<script
<script
src="jquery/jquery-2.0.0.min.js"></script>
src="backbone/underscore-1.4.4.min.js"></script>
src="backbone/backbone-1.0.0.min.js"></script>
src="cordova.js"></script>
src="forcetk.mobilesdk.js"></script>
src="smartsync.js"></script>
3. コンテンツを本文に追加します。<body> ブロックで、div タグを追加して、アプリケーション UI を格納
します。
<body>
<div id="content"></div>
名前空間でオブジェクトとクラスを保持することをお勧めします。このサンプルでは、app 名前空間を使
用して、モデルとビューを格納しています。
4. <script> タグで、アプリケーション名前空間を作成します。この名前空間を app と呼びます。
<script>
var app = {
models: {},
views: {}
}
この手順の残りの部分で、引き続きコードを <script> ブロックに追加していきます。
5. jQuery を待機するイベントリスナーおよびハンドラを追加し、Cordova をコールして認証フローを開始しま
す。また、コールバック関数 appStart を指定し、ユーザのログイン情報を処理します。
jQuery(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady,false);
});
function onDeviceReady() {
cordova.require("com.salesforce.plugin.oauth").
getAuthCredentials(appStart);
}
アプリケーションの初期化と認証が完了したら、Salesforce OAuth プラグインは appStart() をコールして
ユーザのログイン情報を渡します。appStart() 関数は、SmartSyncを初期化する Force.init() をコール
してログイン情報をSmartSyncに渡します。また、appStart() 関数は、アプリケーションの Backbone Router
オブジェクトを作成します。
6. <script> ブロックの最後に appStart() 関数定義を追加します。
function appStart(creds) {
Force.init(creds, null, null,
cordova.require("com.salesforce.plugin.oauth").forcetkRefresh);
233
オフライン管理
ハイブリッド
app.router = new app.Router();
Backbone.history.start();
}
例: 次に、この時点の完全なアプリケーションを示します。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0;
user-scalable=no" />
<meta http-equiv="Content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" href="css/ratchet.css"/>
<script src="jquery/jquery-2.0.0.min.js"></script>
<script src="backbone/underscore-1.4.4.min.js"></script>
<script src="backbone/backbone-1.0.0.min.js"></script>
<script src="cordova.js"></script>
<script src="forcetk.mobilesdk.js"></script>
<script src="smartsync.js"></script>
</head>
<body>
<div id="content"></div>
<script id="search-page" type="text/template">
<header class="bar-title">
<h1 class="title">Users</h1>
</header>
<div class="bar-standard bar-header-secondary">
<input type="search" class="search-key"
placeholder="Search"/>
</div>
<div class="content">
<ul class="list"></ul>
</div>
</script>
<script id="user-list-item" type="text/template">
<img src="<%= SmallPhotoUrl %>" class="small-img" />
<div class="details-short">
<b><%= FirstName %> <%= LastName %></b><br/>
Title<%= Title %>
</div>
</script>
<script>
var app = {
models: {},
views: {}
};
234
オフライン管理
ハイブリッド
jQuery(document).ready(function() {
document.addEventListener("deviceready", onDeviceReady,false);
});
function onDeviceReady() {
cordova.require("com.salesforce.plugin.oauth").
getAuthCredentials(appStart);
}
function appStart(creds) {
console.log(JSON.stringify(creds));
Force.init(creds, null, null,
cordova.require("com.salesforce.plugin.oauth").forcetkRefresh);
app.router = new app.Router();
Backbone.history.start();
}
</script>
</body>
</html>
SmartSync モデルおよびコレクションの作成
HTML インフラストラクチャを設定したので、次の 2 つの主オブジェクトを拡張して SmartSync を使用します。
• Force.SObject
• Force.SObjectCollection
これらのオブジェクトは、Backbone.Model.extend() 関数をサポートできるように Backbone.Model を拡
張します。この関数を使用してオブジェクトを拡張するには、カスタムプロパティおよびカスタム機能を含む
JavaScript オブジェクトに渡します。
1. <body> タグで、Salesforce User sObject のモデルオブジェクトを作成します。Force.SObject を拡張して、
対象とする sObject タイプおよび項目を指定します。
app.models.User = Force.SObject.extend({
sobjectType: "User",
fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl",
"Title", "Email", "MobilePhone","City"]
})
2. User オブジェクトの設定直後に、User Search 結果を保持するコレクションを作成します。
Force.SObjectCollection を拡張して、コレクションの項目のモデルとして新しいモデル
(app.models.User) を指定します。
app.models.UserCollection = Force.SObjectCollection.extend({
model: app.models.User
});
例: 次に、完全なモデルコードを示します。
// Models
app.models.User = Force.SObject.extend({
sobjectType: "User",
fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl",
235
オフライン管理
ハイブリッド
"Title", "Email", "MobilePhone","City"]
});
app.models.UserCollection = Force.SObjectCollection.extend({
model: app.models.User
});
テンプレートの作成
テンプレートを使用すると、別の HTML ページ内に HTML レイアウトを設定できます。タイプが "text/template" の
<script> タグを使用して、HTML ページにインラインテンプレートを定義できます。JavaScript コードでは、
実行時に新しい HTML ページをインスタンス化する場合、テンプレートをページの設計として使用できます。
検索ページテンプレートはシンプルです。このテンプレートには、ヘッダー、検索項目、および検索結果を保
持するリストが含まれます。
1. 新しいスクリプトブロックを追加します。<body> ブロック内の "content" <div> タグの直後にこのブロッ
クを配置します。
<script id="search-page" type="text/template">
</script>
2. 新しい <script> ブロックで、Ratchet スタイルを使用して検索ページの HTML テンプレートを定義します。
<script id="search-page" type="text/template">
<header class="bar-title">
<h1 class="title">Users</h1>
</header>
<div class="bar-standard bar-header-secondary">
<input type="search" class="search-key" placeholder="Search"/>
</div>
<div class="content">
<ul class="list"></ul>
</div>
</script>
検索ビューの追加
画面のビューを作成するには、Backbone.View を拡張します。検索ビューの拡張で、テンプレートの読み込
み、サブビューとイベントハンドラの定義、およびビューを表示して SOQL 検索クエリを実行する機能の実装
を行います。
1. <body> ブロックで、SearchPage という名前の Backbone.View 拡張を app.views 配列に作成します。
app.views.SearchPage = Backbone.View.extend({
});
この手順の残りの部分で、すべてのコードを extend({}) ブロックに追加します。
236
オフライン管理
ハイブリッド
2. _.template() 関数をコールして search-page テンプレートを読み込みます。これに search-page スクリ
プトタグの未加工の HTML コンテンツを渡します。
template: _.template($("#search-page").html()),
3. 検索結果のリストを格納する UserListView という名前のサブビューをインスタンス化します。後で、
app.views.UserListView ビューを定義します。
initialize: function() {
this.listView = new app.views.UserListView({model: this.model});
},
4. 検索ページビューの render() 関数を作成します。アプリケーションの HTML コンテンツとしてテンプレー
トを読み込むだけでビューを表示できます。検索項目に以前に入力した条件を復元し、<ul> 要素内のサブ
ビューを表示します。
render: function(eventName) {
$(this.el).html(this.template());
$(".search-key", this.el).val(this.model.criteria);
this.listView.setElement($("ul", this.el)).render();
return this;
},
5. ユーザが検索項目に文字を入力したときに検索を実行する keyup イベントハンドラを追加します。
events: {
"keyup .search-key": "search"
},
search: function(event) {
this.model.criteria = $(".search-key", this.el).val();
var soql = "SELECT Id, FirstName, LastName, "
+ "SmallPhotoUrl, Title FROM User WHERE "
+ "Name like '" + this.model.criteria + "%' "
+ "ORDER BY Name LIMIT 25 ";
this.model.fetch({config: {type:"soql", query:soql}});
}
この関数は、SOQL クエリを定義します。次に、バッキングモデルを使用してそのクエリをサーバに送信
し、結果を取得します。
例: 次に、完全な拡張を示します。
app.views.SearchPage = Backbone.View.extend({
template: _.template($("#search-page").html()),
initialize: function() {
this.listView = new app.views.UserListView(
{model: this.model}
);
},
237
オフライン管理
ハイブリッド
render: function(eventName) {
$(this.el).html(this.template());
$(".search-key", this.el).val(this.model.criteria);
this.listView.setElement($("ul", this.el)).render();
return this;
},
events: {
"keyup .search-key": "search"
},
search: function(event) {
this.model.criteria = $(".search-key", this.el).val();
var soql = "SELECT Id, FirstName, LastName, "
+ "SmallPhotoUrl, Title FROM User WHERE "
+ "Name like '" + this.model.criteria + "%' “
+ "ORDER BY Name LIMIT 25 ";
this.model.fetch({config: {type:"soql", query:soql}});
}
});
検索結果リストビューの追加
検索結果リストのビューでは、テンプレートは必要ありません。これは、単純にリスト項目ビューのコンテナ
です。listItemViews メンバーのこれらのビューを追跡します。基盤となるコレクションが変更されると、
それ自体を再表示します。
1. <body> ブロックで、Backbone.View を拡張して検索結果リストのビューを作成します。リスト項目ビュー
の配列と initialize() 関数を追加します。
app.views.UserListView = Backbone.View.extend({
listItemViews: [],
initialize: function() {
this.model.bind("reset", this.render, this);
},
この手順の残りの部分で、すべてのコードを extend({}) ブロックに追加します。
2. render() 関数を作成し、既存の各リスト項目ビューで close() をコールしてこれらをクリーンアップし
ます。
render: function(eventName) {
_.each(this.listItemViews,
function(itemView) { itemView.close(); });
238
オフライン管理
ハイブリッド
3. render() 関数で、基盤となるコレクションのレコードに対応する新しい一連のリスト項目ビューを作成
します。これらの各ビューは、リストのエントリにすぎません。後で app.views.UserListItemView を
定義します。
this.listItemViews = _.map(this.model.models, function(model) { return new
app.views.UserListItemView({model: model}); });
4. リスト項目ビューをルート DOM 要素に追加します。
$(this.el).append(_.map(this.listItemViews, function(itemView) {
return itemView.render().el;} ));
return this;
}
例: 次に、完全な拡張を示します。
app.views.UserListView = Backbone.View.extend({
listItemViews: [],
initialize: function() {
this.model.bind("reset", this.render, this);
},
render: function(eventName) {
_.each(this.listItemViews, function(itemView) {
itemView.close(); });
this.listItemViews = _.map(this.model.models,
function(model) {
return new app.views.UserListItemView(
{model: model}); });
$(this.el).append(_.map(this.listItemViews,
function(itemView) {
return itemView.render().el;
} ));
return this;
}
});
検索結果リスト項目ビューの追加
検索結果リスト項目ビューを定義するには、リストの 1 行のビューを設計して実装します。各リスト項目に
は、次のユーザ項目が表示されます。
• SmallPhotoUrl
• FirstName
• LastName
• 役職
1. <body> ブロックで、検索結果リスト項目のテンプレートを作成します。
<script id="user-list-item" type="text/template">
<img src="<%= SmallPhotoUrl %>" class="small-img" />
239
オフライン管理
ハイブリッド
<div class="details-short">
<b><%= FirstName %> <%= LastName %></b><br/>
Title<%= Title %>
</div>
</script>
2. テンプレートの直後に、検索結果リスト項目のビューを作成します。再度、Backbone.View をサブクラ
ス化し、tagName メンバーを定義して、ビュー全体をリストとして表示するように指定します。この手順
の残りの部分で、すべてのコードを extend({}) ブロックに追加します。
app.views.UserListItemView = Backbone.View.extend({
tagName: "li",
});
3. user-list-item スクリプトの未加工のコンテンツを使用して、_.template() をコールし、テンプレー
トを読み込みます。
template: _.template($("#user-list-item").html()),
4. render() 関数で、モデルのデータを使用してテンプレートを表示します。
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
5. リストビューからコールされる close() メソッドを追加し、必要なクリーンアップを行ってメモリリーク
を回避します。
close: function() {
this.remove();
this.off();
}
例: 次に、完全な拡張を示します。
app.views.UserListItemView = Backbone.View.extend({
tagName: "li",
template: _.template($("#user-list-item").html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
close: function() {
this.remove();
this.off();
}
});
240
オフライン管理
ハイブリッド
ルータ
Backbone ルータは、ビュー間の移動パスを定義します。ルータについての詳細は、「ルータとは?」を参照し
てください。
1. <body> ブロックの終了タグの直前で、Backbone.Router を拡張してアプリケーションルータを定義しま
す。
app.Router = Backbone.Router.extend({
});
この手順の残りの部分で、すべてのコードを extend({}) ブロックに追加します。
2. アプリケーションは 1 つの画面しかサポートしないので、1 つの「ルート」のみが必要になります。routes
オブジェクトを追加します。
routes: {
"": "list"
},
3. 検索結果のコレクションと検索ページビューを作成する initialize() 関数を定義します。
initialize: function() {
Backbone.Router.prototype.initialize.call(this);
// Collection behind search screen
app.searchResults = new app.models.UserCollection();
app.searchView = new app.views.SearchPage({model: app.searchResults});
},
4. このルートの項目のみを処理する list() 関数を定義します。リスト画面が表示されたときに、検索結果
を取得して検索ビューを表示します。
list: function() {
app.searchResults.fetch();
$('#content').html(app.searchView.render().el);
}
5. index.html をダブルクリックしてブラウザで開き、アプリケーションを実行します。
例: これで完了です。次に、アプリケーション全体を示します。
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width,
initial-scale=1.0, maximum-scale=1.0; user-scalable=no" />
<meta http-equiv="Content-type" content="text/html;
charset=utf-8">
<link rel="stylesheet" href="css/ratchet.css"/>
<script src="jquery/jquery-2.0.0.min.js"></script>
<script src="backbone/underscore-1.4.4.min.js"></script>
<script src="backbone/backbone-1.0.0.min.js"></script>
<script src="cordova.js"></script>
241
オフライン管理
ハイブリッド
<script src="forcetk.mobilesdk.js"></script>
<script src="smartsync.js"></script>
</head>
<body>
<div id="content"></div>
<script id="search-page" type="text/template">
<header class="bar-title">
<h1 class="title">Users</h1>
</header>
<div class="bar-standard bar-header-secondary">
<input type="search" class="search-key" placeholder=
"Search"/>
</div>
<div class="content">
<ul class="list"></ul>
</div>
</script>
<script id="user-list-item" type="text/template">
<img src="<%= SmallPhotoUrl %>" class="small-img" />
<div class="details-short">
<b><%= FirstName %> <%= LastName %></b><br/>
Title<%= Title %>
</div>
</script>
<script>
var app = {
models: {},
views: {}
};
jQuery(document).ready(function() {
document.addEventListener("deviceready",onDeviceReady,false);
});
function onDeviceReady() {
cordova.require("com.salesforce.plugin.oauth").
getAuthCredentials(appStart);
}
function appStart(creds) {
console.log(JSON.stringify(creds));
Force.init(creds, null, null,
cordova.require("com.salesforce.plugin.oauth").forcetkRefresh);
app.router = new app.Router();
Backbone.history.start();
}
// Models
242
オフライン管理
ハイブリッド
app.models.User = Force.SObject.extend({
sobjectType: "User",
fieldlist: ["Id","FirstName","LastName",
"SmallPhotoUrl","Title","Email","MobilePhone",
"City"]
});
app.models.UserCollection = Force.SObjectCollection.extend({
model: app.models.User
});
// Views
app.views.SearchPage = Backbone.View.extend({
template: _.template($("#search-page").html()),
initialize: function() {
this.listView =
new app.views.UserListView({model: this.model});
},
render: function(eventName) {
$(this.el).html(this.template());
$(".search-key", this.el).val(this.model.criteria);
this.listView.setElement($("ul", this.el)).render();
return this;
},
events: {
"keyup .search-key": "search"
},
search: function(event) {
this.model.criteria = $(".search-key", this.el).val();
var soql = "SELECT Id, FirstName, LastName,
SmallPhotoUrl, Title
FROM User WHERE Name like
'" + this.model.criteria + "%'
ORDER BY Name LIMIT 25 ";
this.model.fetch({config: {type:"soql", query:soql}});
}
});
app.views.UserListView = Backbone.View.extend({
listItemViews: [],
initialize: function() {
this.model.bind("reset", this.render, this);
},
render: function(eventName) {
_.each(this.listItemViews, function(itemView) {
itemView.close(); });
this.listItemViews = _.map(this.model.models,
243
オフライン管理
ハイブリッド
function(model) {
return new
app.views.UserListItemView(
{model: model}
);
}
);
$(this.el).append(_.map(this.listItemViews,
function(itemView) { return itemView.render().el;}
));
return this;
}
});
app.views.UserListItemView = Backbone.View.extend({
tagName: "li",
template: _.template($("#user-list-item").html()),
render: function(eventName) {
$(this.el).html(this.template(this.model.toJSON()));
return this;
},
close: function() {
this.remove();
this.off();
}
});
// Router
app.Router = Backbone.Router.extend({
routes: {
"": "list"
},
initialize: function() {
Backbone.Router.prototype.initialize.call(this);
// Collection behind search screen
app.searchResults = new app.models.UserCollection();
app.searchView =
new app.views.SearchPage({model: app.searchResults});
console.log("here");
},
list: function() {
app.searchResults.fetch();
$('#content').html(app.searchView.render().el);
}
});
</script>
</body>
</html>
244
オフライン管理
ハイブリッド
SmartSync サンプルアプリケーション
Salesforce Mobile SDK には、ハイブリッドアプリケーションでの SmartSync の使用方法を示すサンプルアプリケー
ションが備えられています。Account Editor には、これらのサンプルの全機能が装備されています。いずれかの
単純なサンプルに切り替えるには、bootconfig.json ファイルの startPage プロパティを変更します。
iOS でのサンプルの実行
Salesforce Mobile SDK for iOS インストールディレクトリで、SalesforceMobileSDK.xcworkspace をダブルク
リックして Xcode で開きます。Xcode プロジェクトナビゲータで、Hybrid SDK/AccountEditor プロジェク
トを選択し、[実行] をクリックします。
Android でのサンプルの実行
Eclipse ワークスペースでサンプルを実行するには、SalesforceMobileSDK-Android リポジトリのコピーから次のプロ
ジェクトをインポートします。
• libs/SalesforceSDK
• libs/SmartStore
• hybrid/SampleApps/AccountEditor
Eclipse で作成が完了したら、Package Explorer で [AccountEditor] を Ctrl キーを押しながらクリックするか右クリッ
クしてから、[Run As (別のユーザとして実行)] > [Android Application (Android アプリケーション)] をクリックし
ます。
User and Group Search のサンプル
User and Group Search は、最も単純な SmartSync サンプルアプリケーションです。ユーザおよびコラボレーション
グループの検索と、一致するレコードのリスト表示を 1 つの画面で行うことができます。
サンプルを作成して実行する場合は、ハイブリッドサンプルアプリケーションを作成する (ページ 147)の説明
を参照してください。
ログイン後、検索ボックスに 2 文字以上を入力して、一致結果を確認します。
内部で実行される処理の確認
任意のエディタで UserAndGroupSearch.html を開きます。ファイルの主要なセクションは、次のとおりで
す。
• スクリプトの内容
• テンプレート
• モデル
• ビュー
• ルータ
スクリプトの内容
このサンプルには、SmartSync アプリケーション用のライブラリの標準リストが含まれています。
245
オフライン管理
ハイブリッド
• jQuery — http://jquery.com/ を参照してください。
• Underscore — Backbone に必要な JavaScript 用のユーティリティ関連のライブラリです。http://underscorejs.org/を
参照してください。
• Backbone — Web アプリケーションに構造を提供します。SmartSync Data Framework で使用されます。
http://backbonejs.org/ を参照してください。
• cordova.js — SalesforceMobileSDK で使用するすべてのハイブリッドアプリケーションに必要です。
• fastclick.js — 物理タップしてからクリックイベントが発生するまでの 300 ミリ秒の遅延を回避するた
めに使用されるライブラリです。https://github.com/ftlabs/fastclick を参照してください。
• stackrouter.js および auth.js — 3 つのすべてのサンプルアプリケーションで使用されるヘルパー
JavaScript ライブラリです。
テンプレート
このアプリケーションのテンプレートは、次のとおりです。
• search-page — 検索ページ全体のテンプレート
• user-list-item — ユーザリスト項目のテンプレート
• group-list-item — コラボレーショングループリスト項目のテンプレート
モデル
このアプリケーションでは、SearchCollection モデルが定義されます。
SearchCollection は Force.SObjectCollection クラスをサブクラス化し、Force.SObjectCollection
は Backbone ライブラリの Collection クラスをサブクラス化します。その唯一のメソッドにより、fetch()
メソッドで使用される SOSL クエリが設定され、コレクションが入力されます。
app.models.SearchCollection = Force.SObjectCollection.extend({
setCriteria: function(key) {
this.config = {type:"sosl", query:"FIND {" + key + "*} "
+ "IN ALL FIELDS RETURNING "
+ "CollaborationGroup (Id, Name, SmallPhotoUrl,
MemberCount), "
+ "User (Id, FirstName, LastName, SmallPhotoUrl, Title "
+ "ORDER BY Name) "
+ "LIMIT 25"
};
}
});
ビュー
User and Group Search では、3 つのビューが定義されます。
246
オフライン管理
ハイブリッド
SearchPage
検索ページには、モデルとして SearchCollection が使用されます。検索入力項目に変更があるかどう
かを監視し、モデルを適宜更新します。
events: {
"keyup .search-key": "search"
},
search: function(event) {
var key = $(".search-key", this.el).val();
if (key.length >= 2) {
this.model.setCriteria(key);
this.model.fetch();
}
}
ListView
検索画面のリスト部分です。ListView でも、モデルとして Collection が指定され、Collection のレ
コードごとに ListItemView オブジェクトが作成されます。
ListItemView
データに基づいてユーザまたはグループのいずれかのテンプレートを選択して、1 つのリスト項目の詳細を
表示します。
ルータ
このアプリケーションでは 1 つの画面しか定義されないため、ルータにはあまり意味はありません。
User Search のサンプル
User Search は、User and Group Search より複雑なサンプルです。1 つの画面ではなく、2 つの画面が定義されます。
一致項目のリストが検索から返された場合、各項目をタップすると、基本情報の詳細画面が表示されます。複
数の画面が定義されるため、このサンプルではルータの使用についても示しています。
サンプルを作成して実行する場合は、ハイブリッドサンプルアプリケーションを作成する (ページ 147)の説明
を参照してください。
User and Group Search の場合と異なり、検索ボックスには 1 文字のみを入力して、検索結果の表示を開始します。
この理由は、サーバに対するクエリで SOSL ではなく SOQL がアプリケーションで使用されるからです。
検索結果リストのエントリをタップすると、基本情報の詳細画面が表示されます。
内部で実行される処理の確認
任意のエディタで UserSearch.html ファイルを開きます。ファイルの主要なセクションは、次のとおりです。
• スクリプトの内容
• テンプレート
• モデル
• ビュー
• ルータ
247
オフライン管理
ハイブリッド
スクリプトの内容
このサンプルには、SmartSync アプリケーション用のライブラリの標準リストが含まれています。
• jQuery — http://jquery.com/ を参照してください。
• Underscore — Backbone に必要な JavaScript 用のユーティリティ関連のライブラリです。http://underscorejs.org/ を
参照してください。
• Backbone — Web アプリケーションに構造を提供します。SmartSync Data Framework で使用されます。
http://backbonejs.org/ を参照してください。
• cordova.js — SalesforceMobileSDK で使用するすべてのハイブリッドアプリケーションに必要です。
• forcetk.mobilesdk.js — Rest API コールを行うための Force.com JavaScript ライブラリです。SmartSync に必
要です。
• smartsync.js — Mobile SDK SmartSync Data Framework です。
• fastclick.js — 物理タップしてからクリックイベントが発生するまでの 300 ミリ秒の遅延を回避するた
めに使用されるライブラリです。https://github.com/ftlabs/fastclick を参照してください。
• stackrouter.js および auth.js — 3 つのすべてのサンプルアプリケーションで使用されるヘルパー
JavaScript ライブラリです。
テンプレート
このアプリケーションのテンプレートは、次のとおりです。
• search-page — 検索ページ全体のテンプレート
• user-list-item — ユーザリスト項目のテンプレート
• user-page — ユーザ詳細ページのテンプレート
モデル
このアプリケーションでは、UserCollection および User という 2 つのモデルが定義されます。
UserCollection は Force.SObjectCollection クラスをサブクラス化し、Force.SObjectCollection
は Backbone ライブラリの Collection クラスをサブクラス化します。その唯一のメソッドにより、fetch()
メソッドで使用される SOQL クエリが設定され、コレクションが入力されます。
app.models.UserCollection = Force.SObjectCollection.extend({
model: app.models.User,
fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl", "Title"],
setCriteria: function(key) {
this.key = key;
this.config = {type:"soql", query:"SELECT "
+ this.fieldlist.join(",")
+ " FROM User"
+ " WHERE Name like '" + key + "%'"
+ " ORDER BY Name "
+ " LIMIT 25 "
};
}
});
248
オフライン管理
ハイブリッド
User は、SmartSync の Force.SObject クラスをサブクラス化します。User モデルでは、次の項目が定義さ
れます。
• モデルが表す sObject の種別を示す sobjectType 項目 (この場合は User)
• サーバから取得する項目リストを含む fieldlist 項目
次にコードを示します。
app.models.User = Force.SObject.extend({
sobjectType: "User",
fieldlist: ["Id", "FirstName", "LastName", "SmallPhotoUrl", "Title", "Email",
"MobilePhone","City"]
});
ビュー
このサンプルでは、4 つのビューが定義されます。
SearchPage
検索ページ全体のビュー。モデルとして UserCollection が指定されます。検索入力項目に変更があるか
どうかを監視し、search() 関数でモデルを適宜更新します。
events: {
"keyup .search-key": "search"
},
search: function(event) {
this.model.setCriteria($(".search-key", this.el).val());
this.model.fetch();
}
UserListView
検索画面のリスト部分のビュー。このビューでも、モデルとして UserCollection が指定され、
UserCollection オブジェクトのユーザごとに UserListItemView オブジェクトが作成されます。
UserListItemView
1 つのリスト項目のビュー。
UserPage
ユーザの詳細を表示するビュー。
ルータ
router クラスは、アプリケーションの 2 つの画面間の移動を処理します。このクラスでは、routes 項目を
使用して、ビューが router クラスメソッドに対応付けられます。
routes: {
"": "list",
"list": "list",
"users/:id": "viewUser"
},
249
オフライン管理
ハイブリッド
リストページから fetch() をコールして検索結果のコレクションを取得し、検索ページをビューに表示しま
す。
list: function() {
app.searchResults.fetch();
// Show page right away - list will redraw when data comes in
this.slidePage(app.searchPage);
},
ユーザ詳細ページから fetch() をコールしてユーザモデルを取得し、ユーザ詳細ページをビューに表示しま
す。
viewUser: function(id) {
var that = this;
var user = new app.models.User({Id: id});
user.fetch({
success: function() {
app.userPage.model = user;
that.slidePage(app.userPage);
}
});
}
Account Editor のサンプル
Account Editor は、Mobile SDK 2.0 の最も複雑な SmartSync ベースのサンプルアプリケーションです。取引先をオン
ラインまたはオフラインで作成/編集/削除したり、競合の検出を示したりすることができます。
サンプルを実行する手順は、次のとおりです。
1. external/shared/sampleApps/smartsync/bootconfig.json に変更を加えた場合は、元のコンテン
ツに戻します。
2. Account Editor を起動します。
このアプリケーションには、3 つの画面が含まれています。
• 取引先の検索
• 取引先の詳細
• 同期
アプリケーションを初めて起動すると、最後に使用した取引先をリストする取引先検索画面が表示されます。
この画面では、次の操作を実行できます。
• 検索文字列を入力して、指定した文字列が名前に含まれている取引先を検索する。
• 取引先をタップして、取引先詳細画面を起動する。
• [作成] をタップして、空の取引先詳細画面を起動する。
• [オンライン]をタップして、オフラインにする。すでにオフラインになっている場合は、[オフライン]ボタ
ンをタップして、オンラインに戻すことができます (デバイスを機内モードにして、オフラインにすること
もできます)。
取引先詳細画面を起動するには、取引先検索画面で取引先レコードをタップします。選択した取引先の項目
が、詳細画面に表示されます。この画面では、次の操作を実行できます。
250
オフライン管理
ハイブリッド
• 項目をタップして、値を変更する。
• [保存] をタップして、取引先を更新または作成する。入力規則エラーが発生すると、問題のある項目が強
調表示されます。
保存時にオンラインになっており、最後の取得以降にサーバのレコードが変更された場合は、リモートで
変更された項目について警告が表示されます。
[マージ] および [上書き] という他の 2 つのボタンを使用して、アプリケーションで変更をどのように保存す
るかを制御できます。[上書き] をタップすると、画面に現在表示されているすべての値がサーバに保存さ
れます。[マージ] をタップすると、ユーザが変更した項目のみがサーバに保存され、ユーザが変更しない
項目についてはサーバで変更が継続されます。
• [削除] をタップして、取引先を削除する。
• [オンライン] をタップしてオフラインにするか、[オフライン] をタップしてオンラインにする。
同期画面を表示するには、[オンライン]をタップしてオフラインにしてから、取引先を作成、更新、または削
除します。[オフライン]を再度タップしてオンラインに戻すと、デバイスで変更したすべての取引先が同期画
面に表示されます。
ローカルの変更をサーバに保存するには、[n 件のレコードを処理] をタップします。取引先の保存に失敗する
と、同期に失敗したことが表記されて取引先がリストに残ります。リスト内の任意の取引先をタップしてさら
に編集したり、ローカルで削除した取引先を復元したりできます。
内部で実行される処理の確認
このサンプルのソースコードを表示するには、HTML またはテキストエディタで AccountEditor.html を開
きます。
ファイルの主要なセクションは、次のとおりです。
• スクリプトの内容
• テンプレート
• モデル
• ビュー
• ルータ
スクリプトの内容
このサンプルには、SmartSync アプリケーション用のライブラリの標準リストが含まれています。
• jQuery — http://jquery.com/ を参照してください。
• Underscore — Backbone に必要な JavaScript 用のユーティリティ関連のライブラリです。http://underscorejs.org/ を
参照してください。
• Backbone — Web アプリケーションに構造を提供します。SmartSync Data Framework で使用されます。
http://backbonejs.org/ を参照してください。
• cordova.js — Salesforce Mobile SDK を使用するハイブリッドアプリケーションに必要です。
• forcetk.mobilesdk.js — REST API コールを行うための Force.com JavaScript ライブラリです。SmartSync に必
要です。
251
オフライン管理
ハイブリッド
• smartsync.js — Mobile SDK SmartSync Data Framework です。
• fastclick.js — 物理タップしてからクリックイベントが発生するまでの 300 ミリ秒の遅延を回避するた
めに使用されるライブラリです。https://github.com/ftlabs/fastclick を参照してください。
• stackrouter.js および auth.js — 3 つのすべてのサンプルアプリケーションで使用されるヘルパー
JavaScript ライブラリです。
テンプレート
このアプリケーションのテンプレートは、次のとおりです。
• search-page
• sync-page
• account-list-item
• edit-account-page (取引先詳細ページ用)
モデル
このアプリケーションでは、AccountCollection、Account および OfflineTracker という 3 つのモデル
が定義されます。
AccountCollection は SmartSync の Force.SObjectCollection クラスのサブクラスであり、
Force.SObjectCollection は Backbone フレームワークの Collection クラスのサブクラスです。
AccountCollection.config() メソッドは、コレクションに対する適切なクエリを返します。クエリモー
ドには、次のいずれかを指定できます。
• オンラインでありクエリ条件を指定していない場合は、最後に使用 (MRU)
• オンラインでありクエリ条件を指定した場合は SOQL
• オフラインの場合は SmartSQL
コレクションでアプリケーションから fetch() をコールすると、config() から返されたクエリが fetch()
関数で実行されます。このクエリ結果を使用して、オフラインキャッシュまたはサーバのいずれかの Account
オブジェクトで AccountCollection が入力されます。
AccountCollection では、AccountEditor アプリケーションで設定された 2 つのグローバルキャッシュを使用
します。app.cache はオフラインストレージ用で、app.cacheForOriginals は競合検出用です。コードで
は、AccountCollection モデルが次のように指定されていることがわかります。
• app.models.Account モデルのオブジェクトを含む (model 項目)
• クエリ対象の項目のリストを指定する (fieldlist 項目)
• サンプルアプリケーションのグローバルオフラインキャッシュを使用する (cache 項目)
• サンプルアプリケーションのグローバル競合検出キャッシュを使用する (cacheForOriginals 項目)
• オンラインクエリおよびオフラインクエリを処理する config() 関数を定義する
次にコードを示します (読みやすくするため簡略化しています)。
app.models.AccountCollection = Force.SObjectCollection.extend({
model: app.models.Account,
fieldlist: ["Id", "Name", "Industry", "Phone", "Owner.Name",
"LastModifiedBy.Name", "LastModifiedDate"],
252
オフライン管理
ハイブリッド
cache: function() { return app.cache},
cacheForOriginals: function() {
return app.cacheForOriginals;},
config: function() {
// Offline: do a cache query
if (!app.offlineTracker.get("isOnline")) {
...
}
// Online
else {
...
}
}
});
Account は SmartSync の Force.SObject クラスのサブクラスであり、Force.SObject は Backbone フレーム
ワークの Model クラスのサブクラスです。Account モデルのコードは、次のように指定していることを示し
ます。
• sobjectType 項目を使用して、モデルが表す sObject の種別を示す (この場合は Account)。
• サーバから取得する項目がサーバに送信する項目と同じではないため、fieldlist を項目としてではなく
メソッドとして定義する。
• サンプルアプリケーションのグローバルオフラインキャッシュを使用する (cache 項目)。
• サンプルアプリケーションのグローバル競合検出キャッシュを使用する (cacheForOriginals 項目)。
• 現在のオフライン状況に基づいたキャッシュ方法を示す値を返す cacheMode() メソッドをサポートする。
次にコードを示します。
app.models.Account = Force.SObject.extend({
sobjectType: "Account",
fieldlist: function(method) {
return method == "read"
? ["Id", "Name", "Industry", "Phone", "Owner.Name",
"LastModifiedBy.Name", "LastModifiedDate"]
: ["Id", "Name", "Industry", "Phone"];
},
cache: function() { return app.cache;},
cacheForOriginals: function() { return app.cacheForOriginals;},
cacheMode: function(method) {
if (!app.offlineTracker.get("isOnline")) {
return Force.CACHE_MODE.CACHE_ONLY;
}
// Online
else {
return (method == "read"
? Force.CACHE_MODE.CACHE_FIRST : Force.CACHE_MODE.SERVER_FIRST);
}
}
});
OfflineTracker は、Backbone の Model クラスのサブクラスです。このクラスは、ブラウザのオフライン状
況を監視することによって、アプリケーションのオフライン状況を追跡します。ブラウザがオフラインである
253
オフライン管理
ハイブリッド
ことが検出された場合は、アプリケーションが自動的にオフラインに切り替わります。ただし、オンラインに
なるのはユーザが要求した場合のみです。
次にコードを示します。
app.models.OfflineTracker = Backbone.Model.extend({
initialize: function() {
var that = this;
this.set("isOnline", navigator.onLine);
document.addEventListener("offline", function() {
console.log("Received OFFLINE event");
that.set("isOnline", false);
}, false);
document.addEventListener("online", function() {
console.log("Received ONLINE event");
// User decides when to go back online
}, false);
}
});
ビュー
このサンプルでは、5 つのビューが定義されます。
• SearchPage
• AccountListView
• AccountListItemView
• EditAccountView
• SyncPage
ビューには通常、デザインテンプレート、initialize() 関数、および render() 関数を指定するテンプレー
ト項目が含まれています。
各ビューでは、events 項目も定義できます。この項目には配列が含まれ、キー/値エントリがイベントタイプ
およびイベントハンドラ関数名をそれぞれ指定します。エントリには次の形式が使用されます。
"<event-type>[ <control>]": "<event-handler-function-name>"
次に例を示します。
events: {
"click .button-prev": "goBack",
"change": "change",
"click .save": "save",
"click .merge": "saveMerge",
"click .overwrite": "saveOverwrite",
"click .toggleDelete": "toggleDelete"
},
254
オフライン管理
ハイブリッド
SearchPage
検索画面全体のビュー。モデルとして AccountCollection が指定されます。検索入力項目に変更がある
かどうか (keyup イベント) を監視し、search() 関数でモデルを適宜更新します。
events: {
"keyup .search-key": "search"
},
search: function(event) {
this.model.setCriteria($(".search-key", this.el).val());
this.model.fetch();
}
AcountListView
検索画面のリスト部分のビュー。モデルとして AccountCollection が指定され、AccountCollection
オブジェクトの取引先ごとに AccountListItemView オブジェクトが作成されます。
AccountListItemView
リスト内の項目のビュー。
EditAccountPage
取引先詳細ページのビュー。このビューでは、いくつかのイベントを監視します。
イベントタイプ
ターゲットコントロール
ハンドラ関数名
クリック
button-prev
goBack
変更
set 以外 (任意の編集コントロール change
が有効)
クリック
save
save
クリック
merge
saveMerge
クリック
overwrite
saveOverwrite
クリック
toggleDelete
toggleDelete
2 つのイベントハンドラ関数は、特に注意が必要です。change() 関数は、ユーザ編集をモデルに戻すため
にビューでイベントターゲットがどのように使用されるかを表示します。
change: function(evt) {
// apply change to model
var target = event.target;
this.model.set(target.name, target.value);
$("#account" + target.name + "Error", this.el).hide();
}
toggleDelete() 関数は、ユーザが取引先を削除または復元できる切り替えを処理します。ユーザが復元
をクリックした場合は、内部の __locally_deleted__ flag が false に設定され、レコードがキャッシュ
255
オフライン管理
ハイブリッド
内に復元されていることを示します。それ以外の場合は、ローカルモデルを破棄することによって、サー
バでのレコードの削除が試みられます。
toggleDelete: function() {
if (this.model.get("__locally_deleted__")) {
this.model.set("__locally_deleted__", false);
this.model.save(null, this.getSaveOptions(
null, Force.CACHE_MODE.CACHE_ONLY));
}
else {
this.model.destroy({
success: function(data) {
app.router.navigate("#", {trigger:true});
},
error: function(data, err, options) {
var error = new Force.Error(err);
alert("Failed to delete account:
" + (error.type === "RestError" ?
error.details[0].message :
"Remote change detected - delete aborted"));
}
});
}
}
SyncPage
同期ページのビュー。このビューでは、いくつかのイベントを監視します。
イベントタイプ
コントロール
ハンドラ関数名
クリック
button-prev
goBack
クリック
sync
sync
画面がどのように表示されるかを確認するには、render メソッドを調べます。
render: function(eventName) {
$(this.el).html(this.template(_.extend(
{countLocallyModified: this.model.length},
this.model.toJSON())));
this.listView.setElement($("ul", this.el)).render();
return this;
},
ユーザが [実行] (同期コントロール) をタップしたときの動作を見てみましょう。
sync() 関数は、まずローカルで変更された取引先をビューのコレクションで確認し、それをサーバに保
存しようとします。保存に成功し、ローカルで変更された他のレコードがない場合は、アプリケーション
256
オフライン管理
ハイブリッド
が検索画面に戻ります。それ以外の場合は、取引先がローカルの保存に失敗したとマークされ、sync()
を再度コールします。
sync: function(event) {
var that = this;
if (this.model.length == 0 ||
this.model.at(0).get("__sync_failed__")) {
// We push sync failures back to the end of the list.
// If we encounter one, it means we are done.
return;
}
else {
var record = this.model.shift();
var options = {
mergeMode: Force.MERGE_MODE.MERGE_FAIL_IF_CHANGED,
success: function() {
if (that.model.length == 0) {
app.router.navigate("#", {trigger:true});
}
else {
that.sync();
}
},
error: function() {
record = record.set("__sync_failed__", true);
that.model.push(record);
that.sync();
}
};
return record.get("__locally_deleted__")
? record.destroy(options) :
record.save(null, options);
}
});
ルータ
ルータが初期化されると、サンプル全体で使用される 2 つグローバルキャッシュが設定されます。
setupCaches: function() {
// Cache for offline support
app.cache = new Force.StoreCache("accounts",
[ {path:"Name", type:"string"} ]);
// Cache for conflict detection
app.cacheForOriginals = new Force.StoreCache("original-accounts");
return $.when(app.cache.init(), app.cacheForOriginals.init());
},
257
オフライン管理
ハイブリッド
グローバルキャッシュが設定されると、2 つの AccountCollection オブジェクトも設定されます。1 つは検
索画面用、もう 1 つは同期画面用です。
// Collection behind search screen
app.searchResults = new app.models.AccountCollection();
// Collection behind sync screen
app.localAccounts = new app.models.AccountCollection();
app.localAccounts.config = {type:"cache", cacheQuery: {queryType:"exact",
indexPath:"__local__", matchKey:true, order:"ascending", pageSize:25}};
最後に、Search、Sync、および EditAccount の各画面用にビューオブジェクトが作成されます。
// We keep a single instance of SearchPage / SyncPage and EditAccountPage
app.searchPage = new app.views.SearchPage({model: app.searchResults});
app.syncPage = new app.views.SyncPage({model: app.localAccounts});
app.editPage = new app.views.EditAccountPage();
ルータには、アクションをルータクラスのメソッドに対応付ける routes 項目があります。
routes: {
"": "list",
"list": "list",
"add": "addAccount",
"edit/accounts/:id": "editAccount",
"sync":"sync"
},
list アクションは、fetch() をコールして検索結果のコレクションを取得し、検索ページをビューに表示し
ます。
list: function() {
app.searchResults.fetch();
// Show page right away - list will redraw when data comes in
this.slidePage(app.searchPage);
},
addAccount アクションは、空の取引先オブジェクトを作成し、その取引先の編集ページをビューに表示しま
す。
addAccount: function() {
app.editPage.model = new app.models.Account({Id: null});
this.slidePage(app.editPage);
},
editAccount アクションは、指定された Account オブジェクトを取得し、取引先詳細ページをビューに表示し
ます。
editAccount: function(id) {
var that = this;
var account = new app.models.Account({Id: id});
account.fetch({
success: function(data) {
app.editPage.model = account;
that.slidePage(app.editPage);
},
258
オフライン管理
ハイブリッド
error: function() {
alert("Failed to get record for edit");
}
});
}
sync アクションは、fetch をコールして localAccounts コレクションを計算し、同期ページをビューに表示し
ます。
sync: function() {
app.localAccounts.fetch();
// Show page right away - list will redraw when data comes in
this.slidePage(app.syncPage);
}
259
第7章
トピック:
•
アーキテクチャ
•
ファイルのダウン
ロードと共有の管
理
•
ファイルのアップ
ロード
•
暗号化とキャッ
シュ
•
Android アプリケー
ションでのファイ
ルの使用
•
iOS ネイティブアプ
リケーションでの
ファイルの使用
•
ハイブリッドアプ
リケーションでの
ファイルの使用
ファイルとネットワーキング
Mobile SDK 2.1 には、ファイルとネットワーキングのための API が導入されています。
この API には、2 つのレベルのテクノロジがあります。ファイル管理レベルでは、SDK
は Chatter REST API でファイル要求をラップする一連の便利なメソッドを提供します。
REST API ラッパーレベルでは、ネットワーキングレイヤは待機中の REST 要求をアプリ
ケーションで制御できるようにするオブジェクトを公開します。このような表裏一
体のテクノロジを合わせることで、堅牢な機能セットと高度なネットワーキングパ
フォーマンスを SDK で実現できます。
260
ファイルとネットワーキング
アーキテクチャ
アーキテクチャ
Mobile SDK 2.1 以降では、Android REST 要求システムは、基盤となるアーキテクチャとしてオープンソース外部ラ
イブラリの Google Volley を使用します。このアーキテクチャでは、Volley QueueManager オブジェクトにアク
セスして要求を管理できます。実行時には、QueueManager を使用して、非同期スレッドで待機中の要求を
キャンセルできます。Volley についての詳細は、https://developers.google.com/events/io/sessions/325304728 を参照し
てください。
iOS では、SalesforceNetworkSDK ライブラリを使用して、ファイル管理およびネットワーキングを行いま
す。ファイルや他の REST 要求の REST API コールは、すべてこのライブラリを経由します。
SalesforceNetworkSDK ライブラリ自体は、一般的なオープンソースライブラリである MKNetworkKit を実装
します。
メモ: 古いバージョンの Mobile SDK iOS アプリケーションで RestKit ライブラリに直接アクセスした場合、
MKNetworkKit ライブラリを使用するようにそのコードを更新する必要があります。
ハイブリッド JavaScript 関数では、デバイスのオペレーティングシステム (Android または iOS) に対応する Mobile
SDK のアーキテクチャを使用して、ファイル操作を実装します。これらの関数は、forcetk.mobilesdk.js
で定義されています。
ファイルのダウンロードと共有の管理
Salesforce Mobile SDK には、ファイルのダウンロード操作や共有操作のための特殊な REST 要求を構築する便利な
メソッドがあります。これらの要求を使用して、次のことを実行できます。
• ファイルのバイトストリームにアクセスする。
• ファイルのページをダウンロードする。
• ファイルのページをプレビューする。
• ファイルレコードの詳細を取得する。
• ファイル共有情報にアクセスする。
• ファイル共有を追加および削除する。
要求のページ
REST 要求の「ページ」という用語は、コンテキストに応じて結果セットの特定項目または項目グループを表し
ます。たとえば、特定のファイルのページをプレビューする場合、要求は表示されたページの中から指定され
たページを取得します。他の大部分の要求では、ページとは結果のリストのセクションを表します。1 ページ
のレコードまたはトピックの最大数は、デフォルトの 25 に設定されます。
応答には、NextPageUrl 項目が含まれます。この値が定義されている場合、結果には別のページがあります。
アプリケーションで結果のページをスクロールする場合、この項目を使用して不要な要求が送信されないよう
にできます。また、応答状況を確認するだけで、リストの最後であるかどうかを検出することもできます。何
も返されない場合やエラーが返される場合は、これ以上表示するものがないため、別の要求を発行する必要は
ありません。
261
ファイルとネットワーキング
ファイルのアップロード
ファイルのアップロード
ネイティブモバイルプラットフォームでは、ファイルをアップロードするためのメソッドがサポートされてい
ます。アップロードするローカルファイルへのパス、ファイルの名前またはタイトル、および説明を入力しま
す。MIME タイプがわかっている場合、そのタイプも指定できます。アップロードメソッドは、ファイルをサー
バにアップロードできるプラットフォーム固有の要求オブジェクトを返します。この要求をサーバに送信する
と、バージョンが 1 に設定されたファイルがサーバで作成されます。
次に、アプリケーション種別ごとに使用するメソッドを示します。
アプリケーション Upload メソッド
種別
Android ネイティ
ブ
iOS ネイティブ
ハイブリッド
(Android と iOS)
署名
FileRequests.uploadFile()
public static RestRequest
uploadFile(
File theFile,
String name,
String description,
String mimeType)
throws UnsupportedEncodingException
- requestForUploadFile:
name:description:mimeType:
- (SFRestRequest *)
requestForUploadFile:(NSData *)data
name:(NSString *)name
description:(NSString *)description
mimeType:(NSString *)mimeType
なし
なし
暗号化とキャッシュ
Mobile SDK は、ファイルの暗号化されていないバイトストリームへのアクセスを提供しますが、ファイルの
キャッシュまたは保存は実装しません。アプリケーションでファイルをデバイスに保存する必要がある場合、
独自の解決策を自由に考案できます。
Android アプリケーションでのファイルの使用
FileRequests クラスは、ファイル操作を実行する RestRequest オブジェクトを作成するための静的メソッ
ドを提供します。各メソッドは、新しい RestRequest オブジェクトを返します。次に、アプリケーションは
ownedFilesList() メソッドをコールして RestRequest オブジェクトを取得します。このオブジェクトは、
RestRequest オブジェクトを使用してサーバに要求を送信する関数にパラメータとして渡されます。
performRequest(FileRequests.ownedFilesList(null, null));
262
ファイルとネットワーキング
要求キューの管理
この例では、null を最初のパラメータ (userId) に渡します。この値で、コンテキスト (ログインしている) ユー
ザの ID を使用するように ownedFilesList() メソッドに指示しています。pageNum パラメータの 2 番目の
null で、結果の最初のページを取得するようにメソッドに指示します。
ネイティブ Android アプリケーションの場合、ファイル管理クラスおよびメソッドは
com.salesforce.androidsdk.rest.files パッケージにあります。
関連トピック:
FileRequests メソッド (Android)
要求キューの管理
RestClient クラスは、内部的に Volley RequestQueue クラスのインスタンスを使用して REST API 要求を管理
します。基盤となる RequestQueue オブジェクトにアクセスするには、RestClient インスタンスで
restClient.getRequestQueue() をコールします。RequestQueue オブジェクトを使用すると、待機中の
要求を直接キャンセルまたは操作できます。
例: 例: 待機中のすべての要求のキャンセル
次のコードでは、RestClient (client) のインスタンスで getRequestQueue() をコールします。次
に、RequestQueue.cancelAll() メソッドをコールして、キューにある待機中のすべての要求をキャ
ンセルします。cancelAll() メソッドは RequestFilter パラメータを受け入れるため、コードでは、
Volley RequestFilter インターフェースを実装するカスタムクラス CountingFilter のオブジェクトを
渡します。
CountingFilter countingFilter = new CountingFilter();
client.getRequestQueue().cancelAll(countingFilter);
int count = countingFilter.getCancelCount();
...
/**
* Request filter that cancels all requests and also counts the number of requests
canceled
*
*/
class CountingFilter implements RequestFilter {
private int count = 0;
public int getCancelCount() {
return count;
}
@Override
public boolean apply(Request<?> request) {
count++;
return true;
}
}
263
ファイルとネットワーキング
iOS ネイティブアプリケーションでのファイルの使用
RequestQueue.cancelAll() では、操作の続行を許可する前に RequestFilter ベースのオブジェク
トでキューの各項目を調べることができます。cancelAll() は、各反復でフィルタの apply() メソッ
ドを内部的にコールします。apply() で true が返されると、キャンセル操作は続行されます。false が返
されると、cancelAll() はその要求をキャンセルせずにキューの次の要求に進みます。
このコード例では、CountingFilter.apply() は、コールごとに単純に内部カウンタを増分します。こ
のサンプルコードでは、cancelAll() 操作の完了後に CountingFilter.getCancelCount() をコール
して、キャンセルしたオブジェクト数をレポートします。
iOS ネイティブアプリケーションでのファイルの使用
ネイティブ iOS アプリケーションでファイルを処理するには、SFRestAPI (Files) カテゴリで定義されてい
る便利なメソッドを使用します。これらのメソッドは、Android ネイティブアプリケーションとハイブリッド
アプリケーションの Files API と似ています。これらは、要求を REST API の同じリストに送信しますが、異なる基
盤を使用します。
iOS プロジェクトの設定
Mobile SDK 2.1 より前に構築された Salesforce Mobile SDK アプリケーションを更新する場合、すべてのターゲットに
SalesforceNetworkSDK ライブラリが含まれるようにプロジェクトの設定を調整する必要があります。
1. Mobile SDK 2.1 に付属する MKNetworking ライブラリをダウンロードします。
https://github.com/forcedotcom/SalesforceMobileSDK-iOS-Distribution の圧縮ファイルからバイナリライブラリとそれ
らのヘッダーを取得します。
2. プロジェクトで次のモジュールをリンクします。
• libMKNetworkKit-iOS.a
• libSalesforceNetworkSDK.a
• ImageIO.framework
Files API では、次のフレームワークも必要になります。通常、これらはデフォルトでリンクされています。
• CFNetwork.framework
• SystemConfiguration.framework
• Security.framework
REST 応答とマルチスレッド
ネットワーキングライブラリは常に、現在 SFRestDelegate が実行されているスレッドに REST 応答を送りま
す。この設計では、代理メソッドでどのようにサーバ応答を処理しても、目的の用途に対応できます。応答を
受信したら、返されたデータを使用して任意の操作を実行できます。たとえば、キャッシュしたり、データ
264
ファイルとネットワーキング
要求の管理
ベースに保存したり、すぐに UI コントロールに一括送信したりできます。ただし、応答を直接 UI に送信する
場合代理メソッドでそのメッセージをメインスレッドに送る必要があります。
関連トピック:
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
要求の管理
MKNetworkKit (iOS Mobile SDK の基盤となるネットワーキングアーキテクチャ) は、MKNetworkEngine と
MKNetworkOperation の 2 つのキーオブジェクトを使用します。次に、Salesforce Network SDK for iOS は、対応す
る MKNetworkKit オブジェクトをラップする SFNetworkEngine と SFNetworkOperation の 2 つの主オブジェ
クトを定義します。SFRestRequest は、内部的に SFNetworkOperation オブジェクトを使用して、各サー
バコールを実行します。
要求のために SFNetworkOperation オブジェクトにアクセスする方法は 2 つあります。
• 次のメソッドは SFNetworkOperation* を返します。
– [SFRestRequest send:]
– [SFRestAPI send:delegate:]
• SFRestRequest オブジェクトには、種別が SFNetworkOperation* の networkOperation オブジェク
トが含まれます。
待機中の REST 要求をキャンセルする方法も 2 つあります。
• SFRestRequest は、要求をキャンセルする新しいメソッドを提供します。
- (void) cancel;
• SFRestAPI には、現在実行されているすべての要求をキャンセルするメソッドがあります。
- (void)cancelAllRequests;
例: 要求をキャンセルする方法の例
すべての要求をキャンセルする
[[SFRestAPI sharedInstance] cancelAllRequests];
1 つの要求をキャンセルする
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForOwnedFilesList:nil
page:0];
[[SFRestAPI sharedInstance] send:request delegate:self];
...
// User taps Cancel Request button while waiting for the response
-(void) cancelRequest:(SFRestRequest *) request {
[request cancel];
}
265
ファイルとネットワーキング
ハイブリッドアプリケーションでのファイルの使用
ハイブリッドアプリケーションでのファイルの使用
アップロードを除き、ネイティブアプリケーションと同じファイル要求をハイブリッドアプリケーションで使
用できます。ハイブリッドファイル要求ラッパーは、forcetk.mobilesdk.js JavaScript ライブラリにありま
す。ハイブリッド関数を使用する場合、サーバ応答を受信して処理するコールバック関数を渡します。また、
エラーを処理する関数も渡します。
コードを簡素化するために、smartsync.js および forcetk.mobilesdk.js ライブラリを利用して、HTML
アプリケーションを構築できます。HybridFileExplorer サンプルアプリケーションは、この方法を示します。
メモ: Mobile SDK では、ハイブリッドアプリケーションでのファイルのアップロードをサポートしていま
せん。
関連トピック:
ハイブリッドアプリケーションの Files メソッド
266
第8章
トピック:
•
転送通知について
•
ハイブリッドアプ
リケーションでの
転送通知の使用
•
Android での転送通
知の使用
•
iOS での転送通知の
使用
転送通知と Mobile SDK
Salesforce からの転送通知は、モバイルユーザが組織内の重要な動向を常に把握して
おくのに役立ちます。Summer '14 で正式リリースされた Salesforce Mobile 転送通知サー
ビスでは、コードを実装する前にモバイル転送通知を設定およびテストできます。
本番環境でモバイル通知を受信するには、Mobile SDK アプリケーションでモバイル
OS プロバイダの登録プロトコルを実装して、受信通知を処理します。Mobile SDK で
は、大部分の登録タスクが内部的に実装されているため、コーディング作業を最小
限に抑えることができます。
267
転送通知と Mobile SDK
転送通知について
転送通知について
Salesforce Mobile 転送通知サービスを使用すると、ネイティブおよびハイブリッドモバイルアプリケーションで
転送通知を開発してテストできます。Salesforce Mobile SDK には、転送通知サービスへのデバイス登録を実装で
きる API が用意されています。ただし、通知の受信と処理は、引き続き開発者が行う必要があります。
転送通知の設定は、さまざまなレベルで行われます。
• デバイステクノロジプロバイダからの転送サービスの設定 (Apple for iOS、Google for Android)
• 転送通知を有効にするための Salesforce 接続アプリケーション定義の設定
• Apex トリガの実装
または
Chatter REST API の転送通知リソースのコール
• Mobile SDK アプリケーションでのコードの変更
• 実行時のモバイルデバイスの登録
Apple または Google のサービス設定、接続アプリケーションの設定、Apex または Chatter REST API のコーディン
グ、および Mobile SDK アプリケーションへの軽微な変更は、お客様自身で行います。Salesforce Mobile SDK は、ラ
ンタイム登録を透過的に処理します。
組織のモバイル転送通知の設定方法についての詳細は、『Salesforce Mobile 転送通知実装ガイド』を参照してく
ださい。
ハイブリッドアプリケーションでの転送通知の使用
ハイブリッドアプリケーションで転送通知を使用するには、まず次のことを行います。
• OS プロバイダの転送通知に登録する。
• ターゲットデバイスプラットフォームの転送通知をサポートするように接続アプリケーションを設定する。
Salesforce Mobile SDK では、ハイブリッドアプリケーション自体で通知を受信するように登録できます。登録し
たら、受信通知を処理する動作を定義します。
関連トピック:
Android での転送通知の使用
iOS での転送通知の使用
コードの変更 (ハイブリッド)
1. cordova.require("com.salesforce.plugin.oauth").getAuthCredentials() のコールバックに、
次のコードを追加します。
cordova.require("com.salesforce.util.push").registerPushNotificationHandler(
function(message) {
// add code to handle notifications
},
268
転送通知と Mobile SDK
Android での転送通知の使用
function(error) {
// add code to handle errors
}
);
例: このコードは、メッセージの処理方法の一例を示しています。サーバは、message["payload"] の
ペイロードを配信します。
function(message) {
var payload = message["payload"];
if (message["foreground"]) {
// Notification is received while the app is in
// the foreground
// Do something appropriate with payload
}
if (!message["foreground"]) {
// Notification was received while the app was in
// the background, and the notification was clicked,
// bringing the app to the foreground
// Do something appropriate with payload
}
}
Android での転送通知の使用
Salesforce では、Google Cloud Messaging for Android (GCM) フレームワークを介して転送通知が Android アプリケーショ
ンに送信されます。このフレームワークの概要については、http://developer.android.com/google/gcm/index.html を
参照してください。
転送通知をサポートする Android アプリケーションを開発する場合、次の重要な点に留意してください。
• Android Developer Program のメンバーである必要があります。
• GCM 転送サービスは、Android Market アプリケーションまたは Google Play サービスのいずれかがインストール
された Android デバイスでのみテストできます。転送通知は、Android エミュレータでは動作しません。
• 接続アプリケーションの詳細ビューにある [テスト通知の送信] リンクを使用して、デバイスを ping するこ
となく GCM 設定の「模擬実行」テストを行うこともできます。
まず、アプリケーションに Google API プロジェクトを作成します。プロジェクトでは、GCM for Android 機能が有
効になっている必要があります。プロジェクトの設定手順については、http://developer.android.com/google/gcm/gs.html
を参照してください。
Google API プロジェクトの設定プロセスでは、アプリケーションのキーが作成されます。プロジェクトの設定
が完了したら、GCM キーを接続アプリケーションの設定に追加する必要があります。
メモ: 転送通知の登録は、OAuth ログインフローの最後に行われます。そのため、ユーザが Salesforce 組織
にログインするまで、転送通知はアプリケーションで受信されません。
GCM (Android) 用に接続アプリケーションを設定する
転送通知をサポートするように Salesforce 接続アプリケーションを設定する手順は、次のとおりです。
269
転送通知と Mobile SDK
コードの変更 (Android)
1. Salesforce 組織で、[設定] > [作成] > [アプリケーション] に移動します。
2. [接続アプリケーション] で、既存の接続アプリケーションの横にある [編集] をクリックするか、[新規] をク
リックして新しい接続アプリケーションを作成します。
+新しい接続アプリケーションを作成する場合は、「接続アプリケーションを作成する」を参照してくださ
い。
3. [モバイルアプリケーション設定] で、[プッシュメッセージングの有効化] を選択します。
4. [サポートされているプッシュプラットフォーム] で [Android GCM] を選択します。
5. [サーバアプリケーションのキー (API キー)] に、Google への開発者登録時に取得したキーを入力します。
6. [保存] をクリックします。
メモ: 新しい接続アプリケーションを保存したら、コンシューマ鍵を取得します。モバイルアプリケー
ションは、このキーを接続トークンとして使用します。
コードの変更 (Android)
転送通知をサポートするように Mobile SDK アプリケーションを設定する手順は、次のとおりです。
1. androidPushNotificationClientId のエントリを追加します。
• res/values/bootconfig.xml は次のようになります (ネイティブアプリケーションの場合)。
<string name="androidPushNotificationClientId">35123627573</string>
• assets/www/bootconfig.json は次のようになります (ハイブリッドアプリケーションの場合)。
"androidPushNotificationClientId": "35123627573"
この値は、Android デバイスに対して転送通知の送信が承認された Google プロジェクトのプロジェクト番号
を表します。
Mobile SDK はこの値を自動的に読み取り、それを使用して、Salesforce 接続アプリケーションに対してデバイ
スを登録します。この検証により、Salesforce から接続アプリケーションに通知を送信できます。また、ロ
グアウト時には転送通知用のデバイスが Mobile SDK で自動的に登録解除されます。
2. PushNotificationInterface を実装するアプリケーションでクラスを作成します。
PushNotificationInterface は、転送通知を処理するための Mobile SDK Android インターフェースです。
PushNotificationInterface には、onPushMessageReceived(Bundle message) という 1 つのメソッ
ドがあります。
public interface PushNotificationInterface {
public void onPushMessageReceived(Bundle message);
}
270
転送通知と Mobile SDK
iOS での転送通知の使用
このメソッドでは、転送通知を表示または破棄するカスタム機能を実装します。
3. Application サブクラスの onCreate() メソッドで、PushNotificationInterface の実装を渡して
SalesforceSDKManager.setPushNotificationReceiver() メソッドをコールします。
SalesforceSDKManager.initNative() コールの直後に、このメソッドをコールします。次に例を示し
ます。
@Override
public void onCreate() {
super.onCreate();
SalesforceSDKManager.initNative(getApplicationContext(),
new KeyImpl(), MainActivity.class);
SalesforceSDKManager.getInstance().
setPushNotificationReceiver(myPushNotificationInterface);
}
iOS での転送通知の使用
転送通知をサポートする iOS アプリケーションを開発する場合、次の重要な点に留意してください。
• iOS Developer Program のメンバーである必要があります。
• Apple 転送サービスは、iOS 物理デバイスでのみテストできます。転送通知は、iOS エミュレータでは動作し
ません。
• 通知が Apple で受け入れられても、すべての転送通知が対象デバイスに到達するという保証はありません。
• Apple Push Notification Services 設定では、Mac OS X で提供されている OpenSSL コマンドラインユーティリティを
使用する必要があります。
Salesforce 側で登録を完了する前に、Apple Push Notification Services に登録する必要があります。以下の手順では、
必要な処理の概要を示します。完全な手順は、http://www.raywenderlich.com/32960/ を参照してください。
Apple Push Notification Services の設定
Apple Push Notification Services (APNS) に登録するには、次のものが必要です。
証明書署名要求 (CSR) ファイル
Mac OS X の Keychain Access 機能を使用して、この要求を生成します。また、後で使用するために、OpenSSL を
使用して、CSR 秘密鍵をファイルにエクスポートします。
iOS Developer Program のアプリケーション ID
iOS Developer Member Center で、アプリケーションの ID を作成し、CSR ファイルを使用して証明書を生成しま
す。次に、OpenSSL を使用して、この証明書と秘密鍵のファイルを組み合わせて .p12 ファイルを作成しま
す。このファイルは、接続アプリケーションを後で設定するときに必要になります。
iOS Provisioning Profile
iOS Developer Member Center から、iOS アプリケーション ID と開発者証明書を使用して新しいプロビジョニン
グプロファイルを作成します。次に、プロファイルに含めるデバイスを選択して、プロビジョニングプロ
ファイルをダウンロードして作成します。このようにすると、プロファイルを Xcode に追加できます。Xcode
の Organizer を使用して、テストデバイスにプロファイルをインストールします。
271
転送通知と Mobile SDK
APNS (iOS) 用に接続アプリケーションを設定する
設定が完了したら、Xcode でアプリケーションに署名し、アプリケーションを作成します。アプリケーション
で正しいプロビジョニングプロファイルが使用されていることを、作成ログで確認します。プロビジョニング
プロファイルの内容を表示するには、ターミナルウィンドウでコマンド security cms -D -i <your
profile>.mobileprovision を実行します。
APNS (iOS) 用に接続アプリケーションを設定する
Apple Push Notification Services (APNS) を使用した転送通知をサポートするように Salesforce 接続アプリケーションを
設定する手順は、次のとおりです。
1. Salesforce 組織で、[設定] > [作成] > [アプリケーション] にアクセスします。
2. [接続アプリケーション] で、既存の接続アプリケーションの横にある [編集] をクリックするか、[新規] をク
リックして新しい接続アプリケーションを作成します。+新しい接続アプリケーションを作成する場合は、
「接続アプリケーションを作成する」を参照してください。
3. [モバイルアプリケーション設定] で、[プッシュメッセージングの有効化] を選択します。
4. [サポートされているプッシュプラットフォーム]で [Apple] を選択します。
ページが展開されて、追加設定が表示されます。
5. APNS 証明書に対応する Apple 環境を選択します。
6. [モバイルアプリケーション設定] > [証明書] および [モバイルアプリケーション設定] > [証明書のパスワード]
で、.p12 ファイルとそのパスワードを追加します。
メモ: Apple 環境、証明書、証明書のパスワードの値は、APNS でアプリケーションを設定するときに取
得します。
272
転送通知と Mobile SDK
コードの変更 (iOS)
7. [保存] をクリックします。
コードの変更 (iOS)
Salesforce Mobile SDK for iOS には、転送登録を処理するための SFPushNotificationManager クラスが備えられ
ています。これを使用するには、import <SalesforceSDKCore/SFPushNotificationManager> を実行し
ます。SFPushNotificationManager クラスは、ランタイムシングルトンとして使用できます。
[SFPushNotificationManager sharedInstance]
このクラスは、次の 4 つの登録メソッドを実装します。
-
(void)registerForRemoteNotifications;
(void)didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceTokenData;
(BOOL)registerForSalesforceNotifications; // for internal use
(BOOL)unregisterSalesforceNotifications; // for internal use
Mobile SDK では、ログイン後に registerForSalesforceNotifications をコールし、ログアウト時に
unregisterSalesforceNotifications をコールします。他の 2 つのメソッドは、AppDelegate クラスか
らコールします。
例: SFPushNotificationManager の例
転送通知をサポートするように AppDelegate クラスを設定する手順は、次のとおりです。
1. registerForRemoteNotifications をコールして、Apple に転送通知を登録します。コールを
application:didFinishLaunchingWithOptions: メソッドに配置します。
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window =
[[UIWindow alloc] initWithFrame:
[UIScreen mainScreen].bounds];
[self initializeAppViewState];
//
// Register with APNS for push notifications. Note that,
// to receive push notifications from Salesforce,
// you also need to register for Salesforce notifications
// in the application:
// didRegisterForRemoteNotificationsWithDeviceToken:
// method (as demonstrated below.)
//
[[SFPushNotificationManager sharedInstance]
registerForRemoteNotifications];
[[SFAuthenticationManager sharedManager]
loginWithCompletion:self.initialLoginSuccessBlock
failure:self.initialLoginFailureBlock];
return YES;
}
273
転送通知と Mobile SDK
コードの変更 (iOS)
登録に成功すると、Apple から AppDelegate クラスの
application:didRegisterForRemoteNotificationsWithDeviceToken: メソッドにデバイス
トークンが渡されます。
2. SFPushNotificationManager 共有インスタンスで
didRegisterForRemoteNotificationsWithDeviceToken をコールして、デバイストークンを
Apple から SFPushNotificationManager に転送します。
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken
{
//
// Register your device token with the push notification manager
//
[[SFPushNotificationManager sharedInstance]
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
}}
3. registerForSalesforceNotifications をコールして、接続アプリケーション経由で Salesforce 通
知を受信するよう登録します。このコールは、現在のセッションのアクセストークンが有効な場合に
のみ行います。
- (void)application:(UIApplication*)application
didRegisterForRemoteNotificationsWithDeviceToken:
(NSData*)deviceToken
{
//
// Register your device token with the
// push notification manager
//
[[SFPushNotificationManager sharedInstance]
didRegisterForRemoteNotificationsWithDeviceToken:deviceToken];
if ([SFAccountManager sharedInstance].
credentials.accessToken != nil) {
[[SFPushNotificationManager sharedInstance]
registerForSalesforceNotifications];
}}
4. Apple への登録が失敗した場合にエラーをログ記録するために、次のメソッドを追加します。
- (void)application:(UIApplication*)application
didFailToRegisterForRemoteNotificationsWithError:(NSError*)error
{
NSLog(@"Failed to get token, error: %@", error);
}
274
第9章
トピック:
•
OAuth の用語
•
OAuth2 認証フロー
•
接続アプリケー
ション
•
OAuth 2.0 サイトお
よび Force.com サイ
トを使用したポー
タル認証
モバイルアプリケーションでの認証、
セキュリティ、ID
モバイルデバイスで実行されているエンタープライズアプリケーションにとって、
安全な認証は不可欠です。OAuth2 は、ユーザのデータへのアクセスに安全な認証を
許可する業界標準のプロトコルです。ユーザ名およびパスワードを渡す必要はあり
ません。OAuth は、ソフトウェアアクセスのバレットキーと呼ばれることがよくあ
ります。バレットキーとは、自動車の特定の部分のみ開けられるキーのことで、ト
ランクやダッシュボードの小物入れなどは開けられないようになっています。
モバイルアプリケーションの開発者は、Salesforce OAuth2 の実装をすばやく簡単に組
み込むことができます。実装では HTML ビューを使用してユーザ名とパスワードが収
集され、それがサーバに送信されます。セッショントークンが返され、今後のやり
取りのためにデバイスに保存されます。
Salesforce 接続アプリケーションは、モバイルデバイスを Salesforce に接続するための
主要な手段です。接続アプリケーションにより、開発者と管理者は、アプリケーショ
ンの接続方法およびアクセス権を付与するユーザを制御できます。たとえば、接続
アプリケーションを特定のユーザに制限したり、IP 範囲の設定または緩和などを行
うことができます。
275
モバイルアプリケーションでの認証、セキュリティ、ID
OAuth の用語
OAuth の用語
アクセストークン
ユーザの Salesforce ログイン情報を使用する代わりに、保護されたリソースへのユーザのアクセスを許可す
るためにコンシューマにより使用される値。アクセストークンはセッション ID であり、直接使用できま
す。
認証コード
エンドユーザによって付与されるアクセスを表示する、有効期間の短いトークンです。認証コードは、ア
クセストークンと更新トークンを取得するために使用されます。
接続アプリケーション
OAuth プロトコルを使用して Salesforce ユーザと外部アプリケーションの両方を検証する、Salesforce の外部ア
プリケーションです。リモートアクセスアプリケーションに置き換わります。
コンシューマ鍵
Salesforce で識別するためのコンシューマにより使用される値。client_id とも呼ばれます。
更新トークン
新しいアクセストークンを取得するためにコンシューマが使用するトークン。エンドユーザがアクセスを
再度承認する必要がありません。
リモートアクセスアプリケーション (廃止)
リモートアクセスアプリケーションとは、OAuth プロトコルを使用して Salesforce ユーザと外部アプリケー
ションの両方を検証する、Salesforceの外部アプリケーションです。リモートアクセスアプリケーションは、
Salesforce ヘルプの 接続アプリケーションとして実装されています。リモートアクセスアプリケーションは
廃止され、接続アプリケーションになりました。
OAuth2 認証フロー
認証フローは、デバイスにおける認証状態によって異なります。
初回の認証フロー
1. モバイルアプリケーションを開きます。
2. 認証ダイアログ/ウィンドウ/フロート表示が画面に表示されます。
3. ユーザ名とパスワードを入力します。
4. アプリケーションでセッション ID を受信します。
5. アプリケーションへのアクセスを許可します。
6. アプリケーションが起動します。
継続的な認証
1. モバイルアプリケーションを開きます。
276
モバイルアプリケーションでの認証、セキュリティ、ID
OAuth 2.0 ユーザエージェントフロー
2. セッション ID が有効な場合は、アプリケーションが直ちに起動します。セッション ID が期限切れの場合
は、初期認証から取得された更新トークンをアプリケーションで使用して、更新されたセッション ID を取
得します。
3. アプリケーションが起動します。
PIN の認証 (省略可能)
1. しばらく使用せずに時間を置いた後、モバイルアプリケーションを開きます。
2. 経過時間が設定済みの PIN タイムアウト値を超えている場合は、パスコード入力画面が表示されます。PIN
を入力します。
メモ: PIN の保護は、モバイルポリシーの機能であり、Salesforce 接続アプリケーション定義で有効になっ
ている場合にのみ使用されます。ユーザがオンラインかオフラインかに関わらず、アプリケーション
を最後に使用してから一定時間が経過すると表示されます。「PIN セキュリティについて」 を参照し
てください。
3. アプリケーションで既存のセッション ID が使用されます。
4. アプリケーションが起動します。
OAuth 2.0 ユーザエージェントフロー
ユーザエージェント認証フローは、ユーザのモバイルデバイスにあるクライアントアプリケーションで使用さ
れます。認証は、ユーザエージェントの発生元が同じポリシーに基づいています。
ユーザエージェントフローでは、クライアントアプリケーションは HTTP リダイレクトの形式でアクセストー
クンを受信します。クライアントアプリケーションは、ユーザエージェントにアクセスできる他の Web サー
バまたはローカルリソースにユーザエージェントをリダイレクトするよう認証サーバに要求します。この要求
により、レスポンスからアクセストークンを抽出し、アクセストークンがクライアントアプリケーションに渡
されます。トークンレスポンスは、URL でハッシュ (#) フラグメントとして指定されます。これは、セキュリ
ティ保護のためであり、そのサーバだけでなく、参照ヘッダーで指定されている他のサーバにトークンが渡さ
れないようにします。
このユーザエージェント認証フローでは、クライアントの秘密は使用しません。これは、クライアントの実行
可能ファイルがエンドユーザのコンピュータ上またはデバイス上にあり、クライアントの秘密にアクセスでき
たり、探索したりすることができるためです。
警告: アクセストークンは符号化され、リダイレクト URI になっているため、エンドユーザや、コンピュー
タまたはデバイス上にある他のアプリケーションに公開できます。
JavaScript を使用して認証する場合、window.location.replace(); をコールし、ブラウザの履歴から
のコールバックを削除します。
277
モバイルアプリケーションでの認証、セキュリティ、ID
OAuth 2.0 更新トークンフロー
1. クライアントアプリケーションでは、アプリケーションを認証および承認するために、ユーザを Salesforce
に移動します。
2. ユーザは常に、この認証フローへのアクセスを承認する必要があります。アクセス承認後、アプリケーショ
ンは Salesforce からのコールバックを受信します。
コンシューマがアクセストークンを入手したら、そのアクセストークンを使用して、エンドユーザの代わりに
データにアクセスし、更新トークンを取得できます。更新トークンを使用すると、アクセストークンが何らか
の理由で無効になった場合に、コンシューマが新しいアクセストークンを取得できます。
OAuth 2.0 更新トークンフロー
コンシューマがアクセスを認証されたら、トークンを更新して新しいアクセストークン (セッション ID) を取得
できます。これは、コンシューマが Web サーバまたはユーザエージェントフローのいずれかを使用して、更
新トークンをすでに受信した場合のみに実行できます。アクセストークンを無効にするタイミングおよび新し
いトークンを適用するタイミングを決定するのは、コンシューマです。べアラーフローは、コンシューマが更
新トークンフローを受信した後でのみ使用できます。
更新トークン認証フローの手順は、次のとおりです。各ステップの詳細は次のとおりです。
1. コンシューマは既存の更新トークンを使用して、新しいアクセストークンを要求します。
2. 要求の確認後、Salesforce からクライアントに応答が送信されます。
メモ: Mobile SDK アプリケーションでは、SmartStore 機能を使用してデータをオフラインで使用するために
ローカルに保存できます。SmartStore データは、本質的に揮発性です。有効期限は、認証済みユーザおよ
び OAuth トークンの状態に関係しています。ユーザがアプリケーションからログアウトすると、そのユー
ザに関連付けられているスープデータは SmartStore によりすべて削除されます。同様に、OAuth 更新トー
クンが取り消されるか期限切れになると、ユーザのアプリケーション状態がリセットされ、SmartStore の
すべてのデータが消去されます。アプリケーションの設計時には、SmartStore データの揮発性を十分に考
278
モバイルアプリケーションでの認証、セキュリティ、ID
範囲パラメータの値
慮してください。この警告は、組織で更新トークンに短期の有効期限を設定している場合に特に重要で
す。
範囲パラメータの値
OAuth では、サーバおよびクライアントの両方に範囲設定が必要です。サーバ側とクライアント側間の同意に
よって、範囲に関する契約が定義されます。
• サーバ側 — Salesforce サーバの接続アプリケーションで、範囲権限を定義します。この設定により、Mobile
SDK アプリケーションなど、クライアントアプリケーションが要求できる範囲が決まります。ほとんどの
ネイティブ Mobile SDK アプリケーションでは、refresh_token および api で十分です。
• クライアント側 — Mobile SDK アプリケーションで範囲要求を定義します。クライアントの範囲要求は、接
続アプリケーションの範囲権限のサブセットである必要があります。
サーバ側の設定
scope パラメータによって、Salesforce組織でクライアントアプリケーションがアクセスできる項目を細かく設
定できます。scope の有効値は次のとおりです。
値
説明
api
REST API や Bulk API などの API を使用して、現在のログインユーザの取引先へのア
クセスを許可します。この値には、Chatter REST APIリソースへのアクセスを許可す
る chatter_api も含まれます。
chatter_api
Chatter REST API リソースへのアクセスのみを許可します。
custom_permissions
接続アプリケーションに関連付けられている組織のカスタム権限へのアクセスを
許可し、現在のユーザで各権限が有効かどうかを示します。
full
ログインユーザがアクセスできるすべてのデータへのアクセスを許可し、その他
すべての範囲が対象となります。full は更新トークンを返しません。更新トー
クンを取得するには、refresh_token の範囲を明示的に要求する必要がありま
す。
id
ID URL サービスへのアクセスを許可します。profile、email、address、phone
を要求すれば、id を使用した場合と同じ結果を個別に得られます。これらの結
果はすべて一致します。
openid
OpenID Connect アプリケーションの現在のログインユーザの一意の識別子へのア
クセスを許可します。
アクセストークンの他にも、「OpenID Connect の仕様」に従って、OAuth 2.0 ユーザ
エージェントフローおよび OAuth 2.0 Web サーバ認証フローで openid 範囲を使用
して、署名付き ID トークンを再度取得できます。
refresh_token
更新トークンを受信できる場合に、それを返すように指定します。これにより、
ユーザがオフラインのときにアプリケーションがユーザのデータを操作できま
す。これは、offline_access を要求した場合と同じ意味になります。
279
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
値
説明
visualforce
Visualforce ページへのアクセスを許可します。
web
Web で access_token を使用することを許可します。これには visualforce
も含まれ、Visualforce ページへのアクセスが許可されます。
メモ: Mobile SDK アプリケーションでは、サーバ側の [接続アプリケーション] 設定で常に refresh_token
を選択する必要があります。範囲に full を選択しても、refresh_token を明示的に選択する必要があ
ります。
クライアント側の設定
Mobile SDK アプリケーションの範囲の設定は、次のルールで制御されます。
範囲
Mobile SDK アプリケーションの設定
refresh_token
アプリケーションの Mobile SDK から暗黙的に要求され
ます。要求に含める必要はありません。
api
Salesforce REST API コールを行う場合に、要求に含めま
す (ほとんどのアプリケーションに適用されます)。
web
Salesforce組織で定義されたページにアプリケーション
からアクセスする場合に、要求に含めます (Salesforce
ベースの Web ページを読み込むハイブリッドアプリ
ケーションおよびネイティブアプリケーションの場
合)。
full
すべての権限を要求する場合に含めます (Mobile SDK で
は、refresh_token が暗黙的に要求されます)。
chatter_api
アプリケーションから Chatter REST API をコールする場
合に、要求に含めます。
id
(不要)
visualforce
代わりに、web を使用します。
ID URL の使用
id 範囲パラメータでは、アクセストークンのほか、トークン応答の一部として ID URL も返されます。
ID URL は、ユーザを一意に識別する文字列であるだけでなく、ユーザの詳細情報について (有効なアクセストー
クンを使用して) クエリするために使用できる RESTful API でもあります。Salesforce は、ユーザに関する基本的な
パーソナライズ設定情報、ユーザの写真などのクライアントが通信する重要なエンドポイント、およびアクセ
ス可能な API エンドポイントを返します。
280
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
URL の形式は、https://login.salesforce.com/id/orgID/userID です。ここで、orgId はユーザが属
する Salesforce 組織の ID で、userID は Salesforce のユーザ ID です。
メモ: Sandbox では、login.salesforce.com は test.salesforce.com に置き換えられます。
URL は必ず https である必要があります。
ID URL パラメータ
次のパラメータは、アクセストークンや ID URL と併用できます。アクセストークンは、認証要求ヘッダーや
oauth_token パラメータのある要求で使用できます。
パラメータ
説明
Access token
Salesforce ヘルプの 「アクセストークンの使用」を参照してください。
Format
このパラメータは省略可能です。返される出力の形式を指定します。有効
な値は、次のとおりです。
• json
• xml
format パラメータを使用する代わりに、クライアントは次のいずれかを使
用して、受け入れ要求ヘッダーの返される形式も指定できます。
• Accept: application/json
• Accept: application/xml
• Accept: application/x-www-form-urlencoded
次の点に注意してください。
• ワイルドカードを受け入れるヘッダーが許可されます。*/* が受け入れ
られ、JSON を返します。
• 値のリストも受け入れられ、左から右に確認されます。たとえば、
application/xml,application/json,application/html,*/* は
XML を返します。
• format パラメータは、受け入れ要求ヘッダーより優先されます。
version
このパラメータは省略可能です。SOAP APIバージョン番号またはリテラル文
字列 latest を指定します。この値が指定されていない場合、返される API
URL に、クライアントが文字列置換を実行するためのバージョン番号の代わ
りに、リテラル値 {version} が含まれます。値が latest として指定さ
れると、最新の API バージョンが使用されます。
PrettyPrint
このパラメータは省略可能で、ヘッダー内でのみ使用できます。URL パラ
メータとしては使用できません。最適なフォーマットになるように出力を
指定します。たとえば、ヘッダーで X-PrettyPrint:1 を使用します。こ
の値が指定されない場合、返される XML または JSON は読みやすさではなく
サイズで最適化されます。
281
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
パラメータ
説明
Callback
このパラメータは省略可能です。有効な JavaScript 関数名を指定します。こ
のパラメータは、形式が JSON として指定されている場合にのみ使用されま
す。出力はこの関数名 (JSONP) でラップされます。たとえば、
https://server/id/orgid/userid/ に対する要求では {"foo":"bar"}
を返し、https://server/id/orgid/userid/?callback=baz に対する
要求では baz({"foo":"bar"}); を返します。
ID URL レスポンス
有効な要求では、JSON 形式で次の情報が返されます。
• id — ID URL (クエリされた URL と同じ)
• asserted_user — 指定されたアクセストークンがこの ID に発行されたかどうかを示す Boolean 値
• user_id — Salesforce のユーザ ID
• username — Salesforce ユーザ名
• organization_id — Salesforce 組織 ID
• nick_name — クエリ対象のユーザのコミュニティのニックネーム
• display_name — クエリ対象のユーザの表示名 (氏名)
• email — クエリ対象のユーザのメールアドレス
• email_verified — 組織でメールの確認が有効化されているか (true)、否か (false) を示します。
• first_name — ユーザの名
• last_name — ユーザの姓
• timezone — ユーザの設定のタイムゾーン
• photos — ユーザプロファイルの写真への URL の対応付け
メモ: これらの URL にアクセスするには、アクセストークンを渡す必要があります。Salesforce ヘルプの
「アクセストークンの使用」を参照してください。
– picture
– thumbnail
• addr_street — ユーザの設定の住所で指定されている町名・番地
• addr_city — ユーザの設定の住所で指定されている市区郡
• addr_state — ユーザの設定の住所で指定されている都道府県
• addr_country — ユーザの設定の住所で指定されている国
• addr_zip — ユーザの設定の住所で指定されている郵便番号
• mobile_phone — ユーザの設定の携帯電話番号
• mobile_phone_verified — 有効な番号であることをユーザが確認した携帯電話番号。[モバイルユーザ]
項目の説明を参照してください。
• status — ユーザの現在の Chatter 状況
282
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
– created_date: 2010-05-08T05:17:51.000Z など、ユーザの前回の投稿の作成日付の xsd datetime 値
– body: 投稿の本文
• urls — 指定されたユーザで使用できる、さまざまな API エンドポイントを含む対応付け
メモ: REST エンドポイントへのアクセスでは、アクセストークンを渡す必要があります。Salesforce ヘル
プの 「アクセストークンの使用」を参照してください。
– enterprise (SOAP)
– metadata (SOAP)
– partner (SOAP)
– rest (REST)
– sobjects (REST)
– search (REST)
– query (REST)
– recent (REST)
– profile
– feeds (Chatter)
– feed-items (Chatter)
– groups (Chatter)
– users (Chatter)
– custom_domain — 組織に設定または伝搬されたカスタムドメインがない場合、この値は省略されま
す。
• active — クエリ対象のユーザが有効であるかどうかを指定する Boolean 値
• user_type — クエリ対象のユーザのタイプ
• language — クエリ対象のユーザの言語
• locale — クエリ対象のユーザのロケール
• utcOffset — クエリ対象のユーザのタイムゾーンの UTC からのオフセット (ミリ秒単位)
• last_modified_date — 2010-06-28T20:54:09.000Z など、ユーザの前回の変更の xsd datetime 形式
• is_app_installed — この値は、接続アプリケーションが現在のユーザの組織にインストールされてい
て、ユーザのアクセストークンが OAuth フローを使用して作成されている場合に true になります。接続
アプリケーションがインストールされていない場合、このプロパティは (false になるのではなく) 存在し
ません。応答を解析する場合、このプロパティの有無と値の両方を確認してください。
• mobile_policy — モバイル接続アプリケーションを管理する値を指定します。これらの値は、接続アプ
リケーションが現在のユーザの組織にインストールされていて、アプリケーションでセッションタイムア
ウト値と PIN (個人識別番号) の長さの値が定義されている場合にのみ使用できます。
– screen_lock — 非活動状態になってから画面をロックするまでの待機時間
– pin_length — モバイルアプリケーションにアクセスするために必要な識別番号の長さ
• push_service_type — この応答値は、接続アプリケーションが Apple Push Notification Service (APNS) for iOS 転
送通知に登録されている場合は apple に設定され、Google Cloud Messaging (GCM) for Android 転送通知に登録さ
れている場合は androidGcm に設定されます。応答値は配列型です。
283
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
• custom_permissions — custom_permissions 範囲パラメータが要求にある場合、接続アプリケーショ
ンに関連付けられた組織のカスタム権限を含む対応付けが応答にあります。接続アプリケーションが組織
にインストールされていない場合や、カスタム権限に関連付けられていない場合、custom_permissions
の対応付けは応答にありません。次に、要求の例を示します。
http://login.salesforce.com/services/oauth2/authorize?response_type=token&client_
id=3MVG9lKcPoNINVBKV6EgVJiF.snSDwh6_2wSS7BrOhHGEJkC_&redirect_uri=http://www.example.org/qa/security/oauth
/useragent_flow_callback.jsp&scope=api%20id%20custom_permissions
次に、ID URL レスポンスの JSON ブロックを示します。
"custom_permissions":
{
"Email.View":true,
"Email.Create":false,
"Email.Delete":false
}
XML 形式のレスポンスは、次のとおりです。
<?xml version="1.0" encoding="UTF-8"?>
<user xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<id>http://na1.salesforce.com/id/00Dx0000001T0zk/005x0000001S2b9</id>
<asserted_user>true</asserted_user>
<user_id>005x0000001S2b9</user_id>
<organization_id>00Dx0000001T0zk</organization_id>
<nick_name>admin1.2777578168398293E12foofoofoofoo</nick_name>
<display_name>Alan Van</display_name>
<email>[email protected]</email>
<status>
<created_date xsi:nil="true"/>
<body xsi:nil="true"/>
</status>
<photos>
<picture>http://na1.salesforce.com/profilephoto/005/F</picture>
<thumbnail>http://na1.salesforce.com/profilephoto/005/T</thumbnail>
</photos>
<urls>
<enterprise>http://na1.salesforce.com/services/Soap/c/{version}/00Dx0000001T0zk
</enterprise>
<metadata>http://na1.salesforce.com/services/Soap/m/{version}/00Dx0000001T0zk
</metadata>
<partner>http://na1.salesforce.com/services/Soap/u/{version}/00Dx0000001T0zk
</partner>
<rest>http://na1.salesforce.com/services/data/v{version}/
</rest>
<sobjects>http://na1.salesforce.com/services/data/v{version}/sobjects/
</sobjects>
<search>http://na1.salesforce.com/services/data/v{version}/search/
</search>
<query>http://na1.salesforce.com/services/data/v{version}/query/
</query>
<profile>http://na1.salesforce.com/005x0000001S2b9
</profile>
284
モバイルアプリケーションでの認証、セキュリティ、ID
ID URL の使用
</urls>
<active>true</active>
<user_type>STANDARD</user_type>
<language>en_US</language>
<locale>en_US</locale>
<utcOffset>-28800000</utcOffset>
<last_modified_date>2010-06-28T20:54:09.000Z</last_modified_date>
</user>
JSON 形式のレスポンスは、次のとおりです。
{"id":"http://na1.salesforce.com/id/00Dx0000001T0zk/005x0000001S2b9",
"asserted_user":true,
"user_id":"005x0000001S2b9",
"organization_id":"00Dx0000001T0zk",
"nick_name":"admin1.2777578168398293E12foofoofoofoo",
"display_name":"Alan Van",
"email":"[email protected]",
"status":{"created_date":null,"body":null},
"photos":{"picture":"http://na1.salesforce.com/profilephoto/005/F",
"thumbnail":"http://na1.salesforce.com/profilephoto/005/T"},
"urls":
{"enterprise":"http://na1.salesforce.com/services/Soap/c/{version}/00Dx0000001T0zk",
"metadata":"http://na1.salesforce.com/services/Soap/m/{version}/00Dx0000001T0zk",
"partner":"http://na1.salesforce.com/services/Soap/u/{version}/00Dx0000001T0zk",
"rest":"http://na1.salesforce.com/services/data/v{version}/",
"sobjects":"http://na1.salesforce.com/services/data/v{version}/sobjects/",
"search":"http://na1.salesforce.com/services/data/v{version}/search/",
"query":"http://na1.salesforce.com/services/data/v{version}/query/",
"profile":"http://na1.salesforce.com/005x0000001S2b9"},
"active":true,
"user_type":"STANDARD",
"language":"en_US",
"locale":"en_US",
"utcOffset":-28800000,
"last_modified_date":"2010-06-28T20:54:09.000+0000"}
無効な要求を作成した後は、Salesforce から次のレスポンスを受信する可能性があります。
エラーコード
要求の問題
403 (forbidden) — HTTPS_Required
HTTP
403 (forbidden) — Missing_OAuth_Token
アクセストークンがない
403 (forbidden) — Bad_OAuth_Token
アクセストークンが無効
403 (forbidden) — Wrong_Org
異なる組織のユーザ
404 (not found) — Bad_Id
ユーザ ID または組織 ID が無効または間違って
いる
404 (not found) — Inactive
無効になったユーザまたは無効な組織
285
モバイルアプリケーションでの認証、セキュリティ、ID
カスタムログインサーバの設定
エラーコード
要求の問題
404 (not found) — No_Access
ユーザに組織または情報への適切なアクセス権
がない
404 (not found) — No_Site_Endpoint
サイトの無効なエンドポイントへの要求
404 (not found) — Internal Error
サーバから応答がない
406 (not acceptable) — Invalid_Version
無効なバージョン
406 (not acceptable) — Invalid_Callback
無効なコールバック
カスタムログインサーバの設定
Trialforce を使用する Salesforce パートナーなど、特殊な場合は、カスタムログイン要求を非標準のログイン URI
にリダイレクトする必要がある場合があります。iOS アプリケーションでは、アプリケーションの iOS 設定バン
ドルでカスタムホストを設定します。これが設定済みである場合は、デフォルトの接続として使用されます。
Android の設定
Android では、ログインホストはサーバ接続と呼ばれます。Mobile SDK バージョン 1.4 より前のバージョンでは、
Android アプリケーションのサーバ接続が SalesforceSDK プロジェクトでハードコードされていました。バージョ
ン 1.4 以降では、ホストのリストが res/xml/servers.xml ファイルで定義されています。SalesforceSDK ライ
ブラリプロジェクトでは、このファイルを使用して本番サーバと Sandbox サーバを定義します。
アプリケーションプロジェクトで独自の res/xml/servers.xml ファイルを作成することで、サーバをラン
タイムリストに追加できます。このファイルのルート XML 要素は <servers> です。このルートには、<server>
エントリをいくつでも含めることができます。各 <server> エントリには、name (わかりやすい任意のラベ
ル) と url (ログインサーバの Web アドレス) という 2 つの属性が必要です。
servers.xml ファイルの例を次に示します。
<?xml version="1.0" encoding="utf-8"?>
<servers>
<server name="XYZ.com Login" url="https://<username>.cloudforce.com"/>
</servers>
サーバのホワイトリストエラー
ホワイトリスト却下エラーが発生した場合は、カスタムログインドメインをプロジェクトの ExternalHosts
リストに追加する必要があります。このリストは、<project_name>/<platform_path>/config.xml ファ
イルで定義されます。ドメイン (cloudforce.com など) を、次のファイルのアプリケーションのホワイトリストに
追加します。
Mobile SDK 2.0 の場合:
• iOS: /Supporting Files/config.xml
• Android: /res/xml/config.xml
286
モバイルアプリケーションでの認証、セキュリティ、ID
OAuth トークンの取り消し
OAuth トークンの取り消し
ユーザがアプリケーションからログアウトした、アプリケーションがタイムアウトした、または他の理由によ
り無効になった場合、ログインしたユーザのログイン情報はモバイルアプリケーションからクリアされます。
これにより、サーバ接続が効果的に終了します。また、Mobile SDK では、ログアウトの一環としてサーバから
更新トークンも取り消されます。
トークンの取り消し
OAuth 2.0 トークンを取り消すには、取り消しのエンドポイントを使用します。
https://login.salesforce.com/services/oauth2/revoke
HTTP 要求の entity-body に application/x-www-form-urlencoded 形式を使用して、次のパラメータを含む
POST 要求を記述します。次に例を示します。
POST /revoke HTTP/1.1
Host: https://login.salesforce.com/services/oauth2/revoke
Content-Type: application/x-www-form-urlencoded
token=currenttoken
アクセストークンが含まれる場合、それを無効化してトークンを取り消します。要求トークンが含まれる場
合、それを取り消して、すべての関連するアクセストークンを取り消します。
認証サーバは、HTTP ステータスコード 200 を返し、要求が正常に処理されたことを示します。すべてのエラー
条件については、ステータスコード 400 と次のいずれかのエラーレスポンスが使用されます。
• unsupported_token_type — サポートされていないトークンのタイプ
• invalid_token — トークンが無効
Sandbox には、login.salesforce.com ではなく test.salesforce.com を使用してください。
Android ネイティブアプリケーションでの更新トークンの取り消し
更新トークンが管理者によって取り消されると、デフォルトの動作では現在のユーザが自動的にログアウトさ
れます。その結果、次のようになります。
• アプリケーションで行う後続の REST API コールがすべて失敗する。
• ユーザのアカウント情報と、キャッシュされたオフラインデータが破棄される。
• ユーザがページから強制的に移動される。
• アプリケーションを引き続き使用するには、ユーザが Salesforce に再度ログインする必要がある。
これらの副次的影響として、管理者のアクションに対して安全な応答が行われます。
トークンの取り消しイベント
トークンの取り消しイベントが発生すると、ClientManager オブジェクトから Android スタイルの通知が送信
されます。この通知が意図するアクションは、ClientManager.ACCESS_TOKEN_REVOKE_INTENT 定数で宣
言されます。
287
モバイルアプリケーションでの認証、セキュリティ、ID
接続アプリケーション
ACCESS_TOKEN_REVOKE_INTENT イベントリスナーは、SalesforceActivity.java、
SalesforceListActivity.java、SalesforceExpandableListActivity.java、および
SalesforceDroidGapActivity.java で実装されます。更新トークンが取り消されると、これらのリスナー
によりユーザがログインページに自動的にログアウトされます。このことは、トーストメッセージによりユー
ザに通知されます。
接続アプリケーション
接続アプリケーションは、API を使用してアプリケーションを Salesforce と統合します。接続アプリケーション
では、標準の SAML および OAuth プロトコルを使用して、認証、シングルサインオンの提供、Salesforce API で使
用するトークンの提供を行います。接続アプリケーションでは、標準の OAuth 機能に加え、システム管理者が
さまざまなセキュリティポリシーを設定したり、対応するアプリケーションを使用できるユーザを明示的に制
御したりできます。
開発者またはシステム管理者は、次の情報を指定して Salesforce の接続アプリケーションを定義します。
• 名前、説明、ロゴ、連絡先情報
• Salesforce がアプリケーションを見つけて認証または識別できるようにするための URL
• 認証プロトコル: OAuth、SAML、またはその両方
• 接続アプリケーションが実行されている可能性のある省略可能な IP 範囲
• 接続アプリケーションが適用できるモバイルポリシーに関する省略可能な情報
Salesforce Mobile SDK アプリケーションは、接続アプリケーションを使用して Salesforce OAuth サービスにアクセス
し、Salesforce REST API をコールします。
PIN セキュリティについて
Salesforce 接続アプリケーションには、アプリケーションでの PIN 保護を介した追加のセキュリティレイヤがあ
ります。この PIN 保護はモバイルアプリケーションそれ自体用であり、Salesforce 組織が提供する、デバイスま
たはログインセキュリティの PIN 保護とは異なります。
PIN 保護を使用するためには、開発者は接続アプリケーションの作成時に[画面ロックと固定保護を実装]チェッ
クボックスをオンにする必要があります。オンにすることで、モバイルアプリケーション管理者は、PIN 保護
の強制実行、タイムアウト期間のカスタマイズ、PIN の長さの設定を行うかどうかを選択できます。
メモ: PIN セキュリティはモバイルデバイスのオペレーティングシステムで実装されるため、ネイティブ
およびハイブリッドのモバイルアプリケーションのみが PIN 保護を使用でき、HTML5 Web アプリケーショ
ンは PIN 保護を使用できません。
PIN 保護は実際面では、モバイルアプリケーションが指定の時間 (分単位) 使用されていないかどうかを調べる
ために使用できます。モバイルアプリケーションがバックグラウンドに渡されても、経過時間は引き続き記録
されます。
PIN 保護の仕組みは、次のとおりです。
1. 電話を有効にし、デバイスの PIN を入力します。
2. モバイルアプリケーション (接続アプリケーション) を開始します。
3. Salesforce 組織のログイン情報を入力します。
288
モバイルアプリケーションでの認証、セキュリティ、ID
OAuth 2.0 サイトおよび Force.com サイトを使用したポー
タル認証
4. モバイルアプリケーションの PIN コードを入力します。
5. アプリケーションで操作し、別のアプリケーションを開く (コールの受信など) ことによってアプリケーショ
ンをバックグラウンドに送ります。
6. モバイルアプリケーションがタイムアウトになります。
7. アプリケーションを再び開き、アプリケーションの PIN 画面 (デバイス用ではなく、モバイルアプリケーショ
ン用) が表示されます。
8. アプリケーションの PIN を入力し、操作を再開できます。
OAuth 2.0 サイトおよび Force.com サイトを使用したポータル認
証
Salesforce Spring '13 リリースでは、ポータル認証の柔軟性が強化されました。アプリケーションが Salesforce ポー
タルで実行されている場合、Force.com サイトで OAuth 2.0 を使用して、ポータルユーザの代わりに API アクセス
トークンを取得できます。この設定では、次の操作を実行できます。
• SOAP API login() コールではなく、認証プロバイダおよび SAML を使用してポータルユーザを認証する。
• アプリケーション内でのユーザのログイン情報の処理を回避する。
• Force.com サイトで提供されるログイン画面をカスタマイズする。
開始方法は次のとおりです。
1. Force.com サイトをポータルに関連付けます。サイトで、ポータルに一意の URL が生成されます。「ポータ
ルと Force.com サイトの関連付け」 を参照してください。
2. Force.com サイトで、カスタムログインページを作成します。「Force.com Site のログインおよび登録設定の管
理」を参照してください。
3. サイトで生成された一意の URL を、ユーザのログイン要求のリダイレクトドメインとして使用します。
OAuth 2.0 サービスでカスタムホスト名が認識され、ユーザがまだ認証されていない場合はサイトのログイン
ページにリダイレクトされます。
例: たとえば、次のように https://login.salesforce.com にはリダイレクトしません。
https://login.salesforce.com/services/oauth2/authorize?response_type=
code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>
次のように、https://mysite.secure.force.com などの一意の Force.com サイト URL にリダイレクト
します。
https://mysite.secure.force.com/services/oauth2/authorize?response_type=
code&client_id=<your_client_id>&redirect_uri=<your_redirect_uri>
詳細およびデモビデオについては、Force.com Developer Relations Blogs ページの「OAuth for Portal Users」を参照
してください。
289
第 10 章
トピック:
•
コミュニティと
Mobile SDK アプリ
ケーション
•
「API の有効化」プ
ロファイルを設定
する
•
権限セットを設定
する
•
API アクセス権を
ユーザに付与する
•
ログインエンドポ
イントを設定する
•
コミュニティのブ
ランド設定
•
コミュニティのロ
グイン、ログアウ
ト、およびセルフ
登録のカスタマイ
ズ
•
コミュニティでの
外部認証の使用
•
例: Mobile SDK アプ
リケーションから
アクセスできるよ
うにコミュニティ
を設定する
•
例: Facebook 認証で
きるようにコミュ
ニティを設定する
Mobile SDK アプリケーションでの
Communities の使用
Salesforce Communities は、以前のリリースのポータル機能に置き換わるソーシャルア
グリゲーション機能です。Communitiesには、最大 500 万ユーザを含めることができ、
アイデア、アンサーおよび Chatter アンサーを使用して知識を共有する論理ゾーンが
備わっています。適切に設定すれば、コミュニティユーザは、コミュニティログイ
ン情報を使用して、Mobile SDK アプリケーションにアクセスできます。Communities で
は、Site.comを利用して、コミュニティサイトやログイン画面をブランド設定するこ
ともできます。
290
Mobile SDK アプリケーションでの Communities の使用
コミュニティと Mobile SDK アプリケーション
コミュニティと Mobile SDK アプリケーション
コミュニティメンバーが Mobile SDK アプリケーションにログインできるようにするには、Salesforce で適切に権
限を設定し、コミュニティ URL を認識するようにアプリケーションのログインサーバ設定を変更します。
コミュニティでは、指定のメンバーが Mobile SDK アプリケーションを使用して Salesforce にアクセスできます。
独自のコミュニティログインエンドポイントを定義し、コミュニティ機能を使用して、仕様に従ってブランド
化されたコミュニティログインページを作成します。また、一般的なプロバイダのリストから認証プロバイダ
および SAML ID プロバイダを選択することもできます。
コミュニティのメンバーシップは、プロファイルと権限セットで決まります。コミュニティメンバーがMobile
SDK アプリケーションを使用できるようにするには、次のように設定します。
• 各コミュニティメンバーに「API の有効化」権限があることを確認します。この権限は、プロファイルまた
は権限セットを使用して設定できます。
• 「API の有効化」プロファイルまたは権限セットを含めるようにコミュニティを設定します。
• コミュニティのログインエンドポイントを使用するように Mobile SDK アプリケーションを設定します。
これらの手順の概要の他に、必要な手順を実行してユーザを適切に設定する必要があります。「例: Mobile SDK
アプリケーションからアクセスできるようにコミュニティを設定する」では、Mobile SDK アプリケーションの
コミュニティ設定プロセスについて説明します。コミュニティ機能についての詳細は、『Salesforce Communites
実装ガイド』を参照してください。
メモ: コミュニティログインは、Android や iOS のネイティブおよびハイブリッドローカル Mobile SDK でサ
ポートされています。現在、Visualforce を使用するハイブリッドリモートアプリケーションではサポート
されていません。
「API の有効化」プロファイルを設定する
コミュニティを初めて使用する場合は、まず組織のコミュニティ機能を有効にします。Salesforce のヘルプの
「Salesforce コミュニティの有効化」を参照してください。ドメイン名を作成するように求められた場合、ドメ
イン名に SSL (https://) を使用しないでください。
コミュニティを設定する場合は、Salesforce のヘルプの「コミュニティの作成」を参照してください。コミュニ
ティ機能を有効にしたときに作成したドメイン名に基づいて、コミュニティ URL を定義します。
次に、「API の有効化」権限のあるプロファイルを 1 つ以上設定します。これらのプロファイルを使用して、
コミュニティメンバーの Mobile SDK アプリケーションを有効にできます。詳細は、「例: Mobile SDK アプリケー
ションからアクセスできるようにコミュニティを設定する」のチュートリアルを参照してください。
1. 新しいプロファイルを作成するか、既存のプロファイルを編集します。
2. プロファイルを詳細を編集して、[システム管理者権限] の [API の有効化] を選択します。
3. 変更を保存してから、[設定] > [カスタマイズ] > [コミュニティ] > [コミュニティを管理する] でコミュニティ
を編集します。
4. [<あなたのコミュニティ>: コミュニティ設定] で、[メンバー] をクリックします。
291
Mobile SDK アプリケーションでの Communities の使用
権限セットを設定する
5. 「API の有効化」プロファイルを [選択済みプロファイル] に追加します。
これで、これらのプロファイルが割り当てられているユーザに API アクセス権が付与されました。プロファイ
ルの概要は、Salesforce ヘルプの「ユーザプロファイルの概要」を参照してください。
権限セットを設定する
権限セットを使用して、コミュニティのモバイルアプリケーションを有効にすることもできます。
1. 「API の有効化」権限を既存の権限セットに追加するには、[設定] で [ユーザの管理] > [権限セット] をクリッ
クして権限セットを選択し、ステップ 6 に進みます。
2. 権限セットを作成するには、[設定] で [管理] > [ユーザの管理] > [権限セット] をクリックします。
3. [新規] をクリックします。
4. 権限セットに表示ラベルを指定して、Enter キーを押すと、自動的に API 名が作成されます。
5. [次へ] をクリックします。
6. [アプリケーション] セクションで、[アプリケーション権限] をクリックします。
292
Mobile SDK アプリケーションでの Communities の使用
API アクセス権をユーザに付与する
7. [アプリケーション権限] をクリックして [システム] > [システム権限] を選択します。
8. [システム権限] ページで [編集] をクリックして [API の有効化] を選択します。
9. [保存] をクリックします。
10. [設定] > [カスタマイズ] > [コミュニティ] > [コミュニティを管理する] に移動し、コミュニティ名の横にある
[編集] をクリックします。
11. [私のコミュニティ: コミュニティ設定] で、[メンバー] をクリックします。
12. [権限セットを選択] で、「API の有効化」権限セットを [選択済みの権限セット] に追加します。
これで、この権限セットのユーザに API アクセス権が付与されました。
API アクセス権をユーザに付与する
API アクセス権をコミュニティユーザに拡張するには、「API の有効化」権限を設定するプロファイルまたは権
限セットにコミュニティユーザを追加します。この権限を含むプロファイルまたは権限セットをまだ設定して
いない場合は、「「API の有効化」プロファイルを設定する」および「権限セットを設定する」を参照してく
ださい。
293
Mobile SDK アプリケーションでの Communities の使用
ログインエンドポイントを設定する
ログインエンドポイントを設定する
最後に、コミュニティログインエンドポイントを使用するようにアプリケーションを設定します。アプリケー
ションのモバイルプラットフォームにより、この設定方法が決まります。
Android
Android では、ログインホストはサーバ接続と呼ばれます。Mobile SDK バージョン 1.4 より前のバージョンでは、
Android アプリケーションのサーバ接続が SalesforceSDK プロジェクトでハードコードされていました。バージョ
ン 1.4 以降では、ホストのリストが res/xml/servers.xml ファイルで定義されています。SalesforceSDK ライ
ブラリプロジェクトでは、このファイルを使用して本番サーバと Sandbox サーバを定義します。アプリケーショ
ンプロジェクトで独自の res/xml/servers.xml ファイルを作成することで、サーバをランタイムリストに
追加できます。このファイルのルート XML 要素は <servers> です。このルートには、<server> エントリを
いくつでも含めることができます。各 <server> エントリには、name (わかりやすい任意のラベル) と url (ロ
グインサーバの Web アドレス) という 2 つの属性が必要です。
次に例を示します。
<?xml version="1.0" encoding="utf-8"?>
<servers>
<server name="XYZ.com Login" url="https://<username>.cloudforce.com"/>
</servers>
iOS
iOS アプリケーションでは、アプリケーションの iOS 設定バンドルでカスタムホストを設定します。これが設定
済みである場合は、デフォルトの接続として使用されます。次のキー - 値のペアを <アプリケーション名>-Info.plist
ファイルに追加します。
<key>SFDCOAuthLoginHost</key>
<string>your_community_login_url_minus_the_https://_prefix</string>
URL から HTTP プレフィックスを削除することが重要です。たとえば、コミュニティログイン URL が
https://mycommunity-developer-edition.na15.force.com/fineapps の場合、キー - 値のペアは次の
ようになります。
<key>SFDCOAuthLoginHost</key>
<string>mycommunity-developer-edition.na15.force.com/fineapps</string>
ユーザがこの値を変更できないようにする場合、必要に応じてクラスから Settings.bundle を削除できま
す。
294
Mobile SDK アプリケーションでの Communities の使用
コミュニティのブランド設定
コミュニティのブランド設定
Salesforce タブ + Visualforce テンプレートを使用している場合は、会社のロゴ、色、
著作権表示を追加して、コミュニティ管理でコミュニティのデザインをカスタ
マイズできます。これにより、コミュニティが会社のブランド設定と一致し、
コミュニティメンバーがただちに認識できるようになります。
重要: セルフサービステンプレートを使用しているか、カスタムページを
作成するために標準 Salesforce タブではなくコミュニティビルダーを選択し
た場合は、コミュニティビルダーを使用してコミュニティのブランド設定
を行うこともできます。
1. 次のいずれかの方法で、コミュニティ管理にアクセスします。
• コミュニティから、グローバルヘッダーの
をクリックします。
• [設定] から、[カスタマイズ] > [コミュニティ] > [すべてのコミュニティ] を
クリックし、コミュニティ名の横にある [管理] をクリックします。
エディション
使用可能なエディション:
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
ユーザ権限
コミュニティを作成、カ
スタマイズ、有効化する
• 「コミュニティの作成
および設定」
および
2. [管理] > [ブランド] をクリックします。
3. ルックアップを使用して、コミュニティのヘッダーとフッターを選択しま
す。
アクセスしようとする
[コミュニティ管理]
ページのコミュニティ
メンバーである
ヘッダーとフッター用に選択するファイルは、[ドキュメント] タブにアップ
ロード済みで、公開されている必要があります。ヘッダーに
は、.html、.gif、.jpg、または .png を使用できます。フッターは、.html ファイ
ルである必要があります。.html ファイルの合計最大サイズは 100 KB です。.gif、.jpg、または .png ファイルの
最大サイズは 20 KB です。このため、ヘッダーの .html ファイルが 70 KB で、.html ファイルをフッターにも使
用する場合は、30 KB 以内にする必要があります。
選択したヘッダーは、グローバルヘッダーの下にある Salesforce ロゴに置き換わります。選択したフッター
は、Salesforce 標準の著作権とプライバシーのフッターに置き換わります。
4. [配色を選択] をクリックして事前定義された配色を選択するか、ページ選択項目の横にあるテキストボッ
クスをクリックしてカラーピッカーから色を選択します。
選択した色の中には、コミュニティのログインページと、Salesforce1のコミュニティの外観にも影響を与え
るものもあります。
色の選択肢
表示場所
ヘッダー背景
黒のグローバルヘッダーの下のページ上部。[ヘッダー] 項目で HTML ファイルを選択
した場合は、この色が上書きされます。
ログインページ上部。
Salesforce1 のログインページ。
ページ背景
ログインページを含む、コミュニティのすべてのページの背景色。
プライマリ
選択されたタブ。
295
Mobile SDK アプリケーションでの Communities の使用
コミュニティのログイン、ログアウト、およびセルフ登
録のカスタマイズ
色の選択肢
表示場所
セカンダリ
リストとテーブルの上境界線。
ログインページのボタン。
ターティアリ
編集と詳細ページのセクションヘッダーの背景色。
5. [保存] をクリックします。
コミュニティのログイン、ログアウト、およびセルフ登録のカス
タマイズ
標準で使用できるコミュニティのログイン、ログアウト、およびセルフ登録オ
プションを設定するか、Apex および Visualforce またはコミュニティビルダーの
ページの動作をカスタマイズします。
デフォルトでは、各コミュニティは、デフォルトのログインページ
(CommunitiesLogin) とセルフ登録ページ (CommunitiesSelfReg)、およびそ
れに関連する Apex コントローラに関連付けられます。デフォルトは、次の方法
でカスタマイズできます。
• デフォルトのログインページのブランド設定をカスタマイズする。
• デフォルトのログインページ動作の変更、カスタムログインページの使用、
他の認証プロバイダのサポートを行うことで、ログイン環境をカスタマイズ
する。
• ログアウト時にユーザを異なる URL にリダイレクトする。
• コミュニティでライセンスのないゲストユーザに対してセルフ登録を設定す
る。
コミュニティでの外部認証の使用
エディション
使用可能なエディション:
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
ユーザ権限
コミュニティを作成、カ
スタマイズ、有効化する
• 「コミュニティの作成
および設定」
および
アクセスしようとする
[コミュニティ管理]
ページのコミュニティ
メンバーである
Facebook© などの外部認証プロバイダを使用して、コミュニティユーザを Mobile
SDK アプリケーションにログインさせることができます。
メモ: Salesforce では、Janrain を認証プロバイダとして使用できますが、これは基本的に Salesforce で内部的
に使用することを目的としています。ここで Janrain を説明した理由は、すべての情報を網羅するためで
す。
296
Mobile SDK アプリケーションでの Communities の使用
外部認証プロバイダについて
外部認証プロバイダについて
Facebook©、Janrain©などの外部サービスプロバイダのログイン情報を使用して、
Salesforce 組織にユーザがログインできるようにできます。
エディション
シングルサインオン用認証プロバイダを正常に設定するには、次の操作を実行
します。
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
• サービスプロバイダの Web サイトを正しく設定する。
• Apex を使用して登録ハンドラを作成する。
• 組織の認証プロバイダを定義する。
設定が完了すると、認証プロバイダフローは次のようになります。
1. ユーザがサードパーティ ID を使用して Salesforce にログインしようとします。
2. ログイン要求はサードパーティの認証プロバイダにリダイレクトされます。
3. ユーザはサードパーティログインプロセスに従い、アクセスを承認します。
4. サードパーティ認証プロバイダは認証情報と共にユーザをSalesforceにリダイ
レクトします。
5. ユーザは Salesforce にサインインされます。
メモ: ユーザが既存の Salesforce セッションを持つ場合、サードパーティで
の認証後、Salesforce アカウントへのリンクを承認できるページに自動的に
リダイレクトされます。
認証プロバイダの定義
次のプロバイダをサポートしています。
• Facebook
• Google
• Janrain
• LinkedIn
• Microsoft アクセスコントロールサービス
• Salesforce
• Twitter
• OpenID Connect プロトコルを実装しているサービスプロバイダ
認証プロバイダへの機能の追加
追加の要求パラメータを使用して、認証プロバイダに機能を追加できます。
• Scope – サードパーティから要求された権限をカスタマイズする
• Site – プロバイダをサイトで使用可能にする
• StartURL – 認証後にユーザを指定された場所に送信する
• Community – 認証後にユーザを特定のコミュニティに送信する
297
ユーザ権限
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
および
「認証プロバイダの管
理」
Mobile SDK アプリケーションでの Communities の使用
コミュニティ URL パラメータの使用
• 認証エンドポイント – ユーザを認証のために特定の認証エンドポイントに送信する (Salesforce 認証プロバイ
ダのみ)
Apex 登録ハンドラの作成
登録ハンドラクラスはシングルサインオンフロー用の認証プロバイダを使用する必要があります。Apex登録ハ
ンドラクラスでは Auth.RegistrationHandler インターフェースを実装する必要があります。このインター
フェースでは 2 つのメソッドを定義します。Salesforce では、ユーザがこのプロバイダを以前使用したかどうか
に応じて、コールバックで適切なメソッドを起動します。認証プロバイダを作成する場合、テストのために
Apex テンプレートクラスを自動的に作成できます。
コミュニティ URL パラメータの使用
認証後に、ユーザを特定のコミュニティに送信します。
認証後にユーザを特定のコミュニティに転送するには、community 要求パラ
メータで URL を指定する必要があります。パラメータを追加しない場合、ユー
ザは認証完了後に /home/home.jsp (ポータルまたは標準アプリケーションの
場合) またはデフォルトのサイトページ (サイトの場合) に送信されます。
例: たとえば、[シングルサインオン初期化 URL] では、ユーザはログイン
後にこの場所に送信されます。[既存ユーザをリンクする URL] では、確認
ページの [Salesforce に進む] リンクによってこのページに送信されます。
次に、[シングルサインオン初期化 URL] に追加される community パラメー
タの例を示します。ここで、
• orgID は、認証プロバイダ ID です。
• URLsuffix は、認証プロバイダを定義したときに指定した値です。
https://login.salesforce.com/services/auth/sso/orgID/URLsuffix?community=https://acme.force.com/support
エディション
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
ユーザ権限
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
および
「認証プロバイダの管
理」
298
Mobile SDK アプリケーションでの Communities の使用
Scope パラメータの使用
Scope パラメータの使用
返されたアクセストークンが追加権限を持つように、Facebook や Janrain などの
サードパーティから要求された権限をカスタマイズします。
エディション
サードパーティへの要求をカスタマイズして、追加権限を持つアクセストーク
ンを受け取ることができます。その後、Auth.AuthToken メソッドを使用し
て、付与されたアクセストークンを取得し、これらの権限をサードパーティで
使用することができます。
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
デフォルトの範囲はサードパーティによって異なりますが、一般に、基本的な
ユーザ情報を超える情報へのアクセスは許可されません。各プロバイダタイプ
(Open ID Connect、Facebook、Salesforce など) には、要求と共に認証エンドポイント
に送信するデフォルトの範囲のセットがあります。たとえば、Salesforceのデフォ
ルトの範囲は id です。
範囲は、スペースで区切られた文字列で送信できます。要求された範囲の空白
で区切られた文字列がそのままでサードパーティに送信され、認証プロバイダ
によって要求されたデフォルトの権限を上書きします。
Janrain ではこのパラメータを使用しないため、Janrain 内で追加の権限を設定する
必要があります。
ユーザ権限
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
例: 次に、[シングルサインオン初期化 URL] に追加される、Salesforce の範
囲 api およびweb を要求する scope パラメータの例を示します。ここで、
および
「認証プロバイダの管
理」
• orgID は、認証プロバイダ ID です。
• URLsuffix は、認証プロバイダを定義したときに指定した値です。
https://login.salesforce.com/services/auth/sso/orgID/URLsuffix?scope=id%20api%20web
有効な範囲はサードパーティによって異なるため、個々のサードパーティのドキュメントを参照してくださ
い。たとえば、Salesforce の範囲は次のようになります。
値
説明
api
REST API や Bulk API などの API を使用して、現在のログインユーザの取引先へのア
クセスを許可します。この値には、Chatter REST APIリソースへのアクセスを許可す
る chatter_api も含まれます。
chatter_api
Chatter REST API リソースへのアクセスのみを許可します。
custom_permissions
接続アプリケーションに関連付けられている組織のカスタム権限へのアクセスを
許可し、現在のユーザで各権限が有効かどうかを示します。
full
ログインユーザがアクセスできるすべてのデータへのアクセスを許可し、その他
すべての範囲が対象となります。full は更新トークンを返しません。更新トー
クンを取得するには、refresh_token の範囲を明示的に要求する必要がありま
す。
299
Mobile SDK アプリケーションでの Communities の使用
Facebook 認証プロバイダの設定
値
説明
id
ID URL サービスへのアクセスを許可します。profile、email、address、phone
を要求すれば、id を使用した場合と同じ結果を個別に得られます。これらの結
果はすべて一致します。
openid
OpenID Connect アプリケーションの現在のログインユーザの一意の識別子へのア
クセスを許可します。
アクセストークンの他にも、「OpenID Connect の仕様」に従って、OAuth 2.0 ユーザ
エージェントフローおよび OAuth 2.0 Web サーバ認証フローで openid 範囲を使用
して、署名付き ID トークンを再度取得できます。
refresh_token
更新トークンを受信できる場合に、それを返すように指定します。これにより、
ユーザがオフラインのときにアプリケーションがユーザのデータを操作できま
す。これは、offline_access を要求した場合と同じ意味になります。
visualforce
Visualforce ページへのアクセスを許可します。
web
Web で access_token を使用することを許可します。これには visualforce
も含まれ、Visualforce ページへのアクセスが許可されます。
Facebook 認証プロバイダの設定
Facebook を認証プロバイダとして使用する手順は、次のとおりです。
1. Facebook アプリケーションを設定し、Salesforce をアプリケーションのドメイ
ンにします。
2. Salesforce 組織の Facebook 認証プロバイダを定義します。
3. Salesforce によって生成される [コールバック URL] を Facebook の [Web サイ
トの URL] として使用するように、Facebook アプリケーションを更新しま
す。
エディション
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
4. 接続をテストします。
ユーザ権限
Facebook アプリケーションの設定
Salesforce 組織で Facebook を設定するには、次の手順で Facebook でアプリケーショ
ンを設定する必要があります。
メモ: Salesforce に Google 独自のデフォルトアプリケーションの使用を許可す
ると、この手順を省略できます。詳細は、「Salesforce 管理値を使用した認
証プロバイダの設定」を参照してください。
1. Facebook の Web サイトに移動して、新しいアプリケーションを作成します。
2. アプリケーション設定を変更し、アプリケーションドメインをSalesforceに設
定します。
3. アプリケーション ID とアプリケーションシークレットを確認します。
300
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
および
「認証プロバイダの管
理」
Mobile SDK アプリケーションでの Communities の使用
Facebook 認証プロバイダの設定
Salesforce 組織での Facebook プロバイダの定義
Salesforce 組織で Facebook プロバイダを設定するには Facebook のアプリケーション ID とアプリケーションシーク
レットが必要です。
メモ: Salesforce に値の管理を許可すると、プロバイダ設定の主要な値の指定を省略できます。詳細は、
「Salesforce 管理値を使用した認証プロバイダの設定」を参照してください。
1. [設定] で、[セキュリティのコントロール] > [認証プロバイダ] をクリックします。
2. [新規] をクリックします。
3. [プロバイダタイプ] には Facebook を選択します。
4. プロバイダの [名前] を入力します。
5. [URL 接尾辞] を入力します。これは、クライアント設定 URL で使用されます。たとえば、プロバイダの
URL サフィックスが「MyFacebookProvider」である場合、シングルサインオン URL は
https://login.salesforce.com/auth/sso/00Dx00000000001/MyFacebookProvider のようになり
ます。
6. [コンシューマ鍵] 項目には、Facebook のアプリケーション ID を使用します。
7. [コンシューマの秘密] 項目には、Facebook のアプリケーションシークレットを使用します。
8. 必要に応じて、次の項目を設定します。
a. [承認エンドポイント URL] に Facebook から入手したベース URL を入力します。たとえば、
https://www.facebook.com/v2.2/dialog/oauth です。この項目を空白のままにした場合は、ア
プリケーションが使用する Facebook API のバージョンが使用されます。
ヒント: 必要に応じて、クエリ文字列パラメータをベース URL に追加できます。たとえば、オフラ
インアクセス用に Google から更新トークンを取得するには、
https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force
を使用します。この例では、更新アクションの承認をユーザに求めるには追加の approval_prompt
パラメータが必要となるため、Google では最初の更新トークンの後にも更新トークンが引き続き提
供されます。
b. Facebook から入手した [トークンエンドポイント URL] を入力します。たとえば、
https://www.facebook.com/v2.2/dialog/oauth です。この項目を空白のままにした場合は、ア
プリケーションが使用する Facebook API のバージョンが使用されます。
c. Facebook のプロファイル API から要求された値を変更する場合は、[ユーザ情報エンドポイント URL] を
入力します。項目についての詳細は、
https://developers.facebook.com/docs/facebook-login/permissions/v2.0#reference-public_profileを参照してください。
要求された項目は、要求された範囲に対応する必要があります。この項目を空白のままにした場合は、
アプリケーションが使用する Facebook API のバージョンが使用されます。
d. 認証エンドポイントへの要求と共に送信する [デフォルトの範囲]。送信しない場合は、プロバイダタイ
プのハードコード化されたデフォルトが使用されます (デフォルトについてはFacebook の開発者向けド
キュメントを参照)。
詳細は、「Scope パラメータの使用」を参照してください。
e. エラーのレポートに使用するプロバイダの [カスタムエラー URL]。
301
Mobile SDK アプリケーションでの Communities の使用
Facebook 認証プロバイダの設定
f. ユーザがシングルサインオンフローを使用して認証された場合に、ログアウト後の特定の移動先を指定
する [カスタムログアウト URL]。この項目を使用して、ユーザをブランド設定されたログアウトペー
ジか、またはデフォルトの Salesforce ログアウトページ以外の場所のいずれかに移動します。URL は、
http または https プレフィックスで完全修飾する必要があります (https://acme.my.salesforce.com
など)。
g. 既存のApexクラスを [登録ハンドラ] クラスとして選択するか、[登録ハンドラテンプレートを自動作成]
をクリックして、登録ハンドラのApexクラステンプレートを作成します。このクラスを編集してデフォ
ルトのコンテンツを変更してから使用する必要があります。
メモ: Salesforce の登録ハンドラクラスを指定して、[シングルサインオン初期化 URL] を生成する必
要があります。
h. [他のアカウントで登録を実行] で Apex ハンドラクラスを実行するユーザを選択します。このユーザは
「ユーザの管理」権限を持っている必要があります。登録ハンドラを選択した場合、または登録ハンド
ラを自動作成する場合にはユーザが必要です。
i. プロバイダでポータルを使用するには、[ポータル] ドロップダウンリストからポータルを選択します。
j. [アイコン URL] 項目を使用して、コミュニティのログインページのボタンとして表示するアイコンの
パスを追加します。このアイコンは、コミュニティにのみ適用され、Salesforce 組織のログインページ
や、[私のドメイン] で作成されたカスタムドメインのログインページには表示されません。ユーザは、
このボタンをクリックし、コミュニティに関連付けられた認証プロバイダを使用してログインします。
独自の画像へのパスを指定することも、いずれかのサンプルアイコンの URL を項目にコピーすることも
できます。
9. [保存] をクリックします。
生成された [認証プロバイダ ID] の値を確認しておいてください。この値は、Auth.AuthToken Apex クラス
と共に使用する必要があります。
認証プロバイダを定義した後、複数のクライアント設定 URL が生成されます。
• テスト専用初期化 URL: システム管理者は、この URL を使用して、サードパーティプロバイダが正しく設定
されていることを確認します。システム管理者がこの URL をブラウザで開き、サードパーティにサインイ
ンすると、属性の対応付けと共に Salesforce にリダイレクトされます。
• シングルサインオン初期化 URL: この URL を使用して、サードパーティから Salesforce にシングルサインオン
を実行します (サードパーティの認証情報が使用されます)。エンドユーザは、この URL をブラウザで開き、
サードパーティにサインインします。エンドユーザの新規ユーザを作成するか、既存のユーザを更新して
から、そのユーザとして Salesforce にサインインします。
• 既存ユーザをリンクする URL: この URL を使用して、既存の Salesforce ユーザをサードパーティアカウントに
リンクします。エンドユーザは、この URL をブラウザで開き、サードパーティにサインインして Salesforce
にサインインし、リンクを承認します。
• Oauth 専用初期化 URL: この URL を使用して、サードパーティの OAuth アクセストークンを取得します。
サードパーティサービスでトークンを取得するには、ユーザは Salesforce の認証を受ける必要があります。
このフローでは、以降のシングルサインオン機能は提供されません。
302
Mobile SDK アプリケーションでの Communities の使用
Salesforce 認証プロバイダの設定
• コールバック URL: 認証プロバイダが設定のためにコールバックするエンドポイントに、コールバック URL
を使用します。認証プロバイダは、前述の各クライアント設定 URL の情報と共に、[コールバック URL] に
リダイレクトする必要があります。
クライアント設定 URL では、ユーザの特定サイトへのログイン、サードパーティからのカスタマイズされた権
限の取得、認証後の特定の場所への移動を行うための、追加の要求パラメータをサポートしています。
Facebook アプリケーションの更新
Facebook 認証プロバイダを Salesforce 組織に定義したら、Facebook に戻り、[コールバック URL] を Facebook の
[Web サイトの URL] として使用するようにアプリケーションを更新します。
シングルサインオン接続のテスト
ブラウザの認証プロバイダの詳細ページで [テスト専用初期化 URL] を開きます。このページによりユーザは
Facebook にリダイレクトされ、サインインするよう求められます。サインイン時に、アプリケーションを認証
する求められます。認証後、ユーザは Salesforce にリダイレクトされます。
Salesforce 認証プロバイダの設定
接続アプリケーションを認証プロバイダとして使用できます。次の手順を実行
します。
エディション
1. 接続アプリケーションを定義します。
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
2. 組織の Salesforce 認証プロバイダを定義します。
3. 接続をテストします。
接続アプリケーションの定義
Salesforce 組織の Salesforce プロバイダを設定する前に、シングルサインオンを使
用する接続アプリケーションを定義する必要があります。[設定] の[作成] > [アプ
リケーション] で、接続アプリケーションを定義します。
接続アプリケーションの定義の完了後は、[コンシューマ鍵] 項目および [コン
シューマの秘密] 項目の値を保存します。
メモ: Salesforce に Google 独自のデフォルトアプリケーションの使用を許可す
ると、この手順を省略できます。詳細は、「Salesforce 管理値を使用した認
証プロバイダの設定」を参照してください。
組織の Salesforce 認証プロバイダの定義
ユーザ権限
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
および
「認証プロバイダの管
理」
組織の認証プロバイダを設定するには、接続アプリケーション定義の [コンシュー
マ鍵] 項目および [コンシューマの秘密] 項目の値が必要です。
メモ: Salesforce に値の管理を許可すると、プロバイダ設定の主要な値の指定を省略できます。詳細は、
「Salesforce 管理値を使用した認証プロバイダの設定」を参照してください。
303
Mobile SDK アプリケーションでの Communities の使用
Salesforce 認証プロバイダの設定
1. [設定] で、[セキュリティのコントロール] > [認証プロバイダ] をクリックします。
2. [新規] をクリックします。
3. [プロバイダタイプ] には Salesforce を選択します。
4. プロバイダの [名前] を入力します。
5. [URL 接尾辞] を入力します。これは、クライアント設定 URL で使用されます。たとえば、プロバイダの
URL サフィックスが「MySFDCProvider」である場合、シングルサインオン URL は
https://login.salesforce.com/auth/sso/00Dx00000000001/MySFDCProvider のようになりま
す。
6. 接続アプリケーション定義の [コンシューマ鍵] 項目の値を [コンシューマ鍵] 項目に貼り付けます。
7. 接続アプリケーション定義の [コンシューマの秘密] 項目の値を [コンシューマの秘密] 項目に貼り付けま
す。
8. 必要に応じて、次の項目を設定します。
a. OAuth 認証の URL を指定するための [承認エンドポイント URL]。
[承認エンドポイント URL] の場合、ホスト名に Sandbox やカスタムドメイン名 ([私のドメイン] を使用し
て作成) を含めることができますが、URL は .salesforce.com で終わり、パスは
/services/oauth2/authorize で終わる必要があります。たとえば、
https://test.salesforce.com/services/oauth2/authorize です。
b. OAuth トークンの URL を指定するための [トークンエンドポイント URL]。
[トークンエンドポイント URL] の場合、ホスト名に Sandbox やカスタムドメイン名 ([私のドメイン] を使
用して作成) を含めることができますが、URL は .salesforce.com で終わり、パスは
/services/oauth2/token で終わる必要があります。たとえば、
https://test.salesforce.com/services/oauth2/token です。
c. 認証エンドポイントへの要求と共に送信する [デフォルトの範囲]。送信しない場合は、ハードコード化
されたデフォルトが使用されます。
詳細は、「Scope パラメータの使用」を参照してください。
メモ: 既存の Salesforce 認証プロバイダの設定を編集する場合、サードパーティアカウントのリンク
の組織 ID を含むようにチェックボックスをオンにできることがあります。Summer '14 リリース以前
に設定された Salesforce 認証プロバイダでは、組織が提供するユーザ ID に組織 ID が含まれません。
そのため、対象組織は 2 つのソース (2 つの Sandbox など) の同じユーザ ID を持つユーザを区別でき
ません。(各 Sandbox から 1 人の) 2 人のユーザが対象組織で同じユーザに対応付けられている既存の
組織があり、ID を別にする場合は、このチェックボックスをオンにします。そうでない場合は、こ
のチェックボックスをオフのままにします。この機能を有効にした後に、ユーザはすべてのサード
パーティのリンクの連結を再承認する必要があります。これらのリンクは、ユーザの詳細ページの
[サードパーティアカウントのリンク] セクションに一覧表示されます。Winter '15 リリース以降に作
成されたSalesforce認証プロバイダは、デフォルトでこの設定が有効になり、チェックボックスは表
示されません。
d. エラーのレポートに使用するプロバイダの [カスタムエラー URL]。
304
Mobile SDK アプリケーションでの Communities の使用
Salesforce 認証プロバイダの設定
e. ユーザがシングルサインオンフローを使用して認証された場合に、ログアウト後の特定の移動先を指定
する [カスタムログアウト URL]。この項目を使用して、ユーザをブランド設定されたログアウトペー
ジか、またはデフォルトの Salesforce ログアウトページ以外の場所のいずれかに移動します。URL は、
http または https プレフィックスで完全修飾する必要があります (https://acme.my.salesforce.com
など)。
9. 既存の Apex クラスを [登録ハンドラ] クラスとして選択するか、[登録ハンドラテンプレートを自動作成] を
クリックして、登録ハンドラの Apex クラスを作成します。このテンプレートクラスを使用する前に、編集
してデフォルトのコンテンツを変更する必要があります。
メモ: Salesforce の登録ハンドラクラスを指定して、[シングルサインオン初期化 URL] を生成する必要
があります。
10. [他のアカウントで登録を実行] でApexハンドラクラスを実行するユーザを選択します。このユーザは「ユー
ザの管理」権限を持っている必要があります。登録ハンドラを選択した場合、または登録ハンドラを自動
作成する場合にはユーザが必要です。
11. プロバイダでポータルを使用するには、[ポータル] ドロップダウンリストからポータルを選択します。
12. [アイコン URL] 項目を使用して、コミュニティのログインページのボタンとして表示するアイコンのパス
を追加します。このアイコンは、コミュニティにのみ適用され、Salesforce 組織のログインページや、[私の
ドメイン] で作成されたカスタムドメインのログインページには表示されません。ユーザは、このボタンを
クリックし、コミュニティに関連付けられた認証プロバイダを使用してログインします。
独自の画像へのパスを指定することも、いずれかのサンプルアイコンの URL を項目にコピーすることもで
きます。
13. [保存] をクリックします。
クライアント設定 URL の値を確認します。最後のステップを完了するには [コールバック URL] が必要で
す。また、[テスト専用初期化 URL] を使用して、設定をチェックします。Auth.AuthToken Apex クラス
と共に [認証プロバイダ ID] 値を使用する必要があるため、その値を確認しておく必要もあります。
14. 前のステップで作成した接続アプリケーション定義に戻り ([設定] の [作成] > [アプリケーション] で接続ア
プリケーション名をクリックする)、認証プロバイダの [コールバック URL] の値を [コールバック URL]
項目に貼り付けます。
認証プロバイダを定義した後、複数のクライアント設定 URL が生成されます。
• テスト専用初期化 URL: システム管理者は、この URL を使用して、サードパーティプロバイダが正しく設定
されていることを確認します。システム管理者がこの URL をブラウザで開き、サードパーティにサインイ
ンすると、属性の対応付けと共に Salesforce にリダイレクトされます。
• シングルサインオン初期化 URL: この URL を使用して、サードパーティから Salesforce にシングルサインオン
を実行します (サードパーティの認証情報が使用されます)。エンドユーザは、この URL をブラウザで開き、
サードパーティにサインインします。エンドユーザの新規ユーザを作成するか、既存のユーザを更新して
から、そのユーザとして Salesforce にサインインします。
• 既存ユーザをリンクする URL: この URL を使用して、既存の Salesforce ユーザをサードパーティアカウントに
リンクします。エンドユーザは、この URL をブラウザで開き、サードパーティにサインインして Salesforce
にサインインし、リンクを承認します。
305
Mobile SDK アプリケーションでの Communities の使用
OpenID Connect 認証プロバイダの設定
• Oauth 専用初期化 URL: この URL を使用して、サードパーティの OAuth アクセストークンを取得します。
サードパーティサービスでトークンを取得するには、ユーザは Salesforce の認証を受ける必要があります。
このフローでは、以降のシングルサインオン機能は提供されません。
• コールバック URL: 認証プロバイダが設定のためにコールバックするエンドポイントに、コールバック URL
を使用します。認証プロバイダは、前述の各クライアント設定 URL の情報と共に、[コールバック URL] に
リダイレクトする必要があります。
クライアント設定 URL では、ユーザの特定サイトへのログイン、サードパーティからのカスタマイズされた権
限の取得、認証後の特定の場所への移動を行うための、追加の要求パラメータをサポートしています。
シングルサインオン接続のテスト
ブラウザの認証プロバイダの詳細ページで [テスト専用初期化 URL] を開きます。認証する側の組織および認
証される側の組織の両方が、本番または Sandbox など、同じ環境内にある必要があります。
OpenID Connect 認証プロバイダの設定
Amazon、Google、PayPal など、OpenID Connect プロトコルのサーバ側を実装する
サードパーティの Web アプリケーションを認証プロバイダとして使用できます。
エディション
OpenID 認証プロバイダを設定するには、次の手順を実行します。
使用可能なエディション:
Professional Edition、
Enterprise Edition、
Performance Edition、
Unlimited Edition、および
Developer Edition
1. アプリケーションを登録して、Salesforce をアプリケーションドメインにしま
す。
2. Salesforce 組織の OpenID Connect 認証プロバイダを定義します。
3. Salesforce によって生成される [コールバック URL] をコールバック URL とし
て使用するように、アプリケーションを更新します。
ユーザ権限
4. 接続をテストします。
OpenID Connect アプリケーションの登録
Salesforce組織の Web アプリケーションを設定する前に、アプリケーションをサー
ビスプロバイダに登録する必要があります。このプロセスは、サービスプロバ
イダによって異なります。たとえば、Google アプリケーションを登録するには、
OAuth 2.0 クライアント ID を作成します。
1. サービスプロバイダの Web サイトにアプリケーションを登録します。
2. アプリケーション設定を変更し、アプリケーションドメイン (または [ホーム
ページの URL]) を Salesforce に設定します。
設定を参照する
• 「設定・定義を参照す
る」
設定を編集する
• 「アプリケーションの
カスタマイズ」
および
「認証プロバイダの管
理」
3. プロバイダのドキュメントに記載されている、クライアント ID とクライアントの秘密、承認エンドポイン
ト URL、トークンエンドポイント URL、ユーザ情報エンドポイント URL をメモします。一般的な OpenID Connect
サービスプロバイダとして、次のようなプロバイダがあります。
• Amazon
• Google
• PayPal
306
Mobile SDK アプリケーションでの Communities の使用
OpenID Connect 認証プロバイダの設定
Salesforce 組織の OpenID Connect プロバイダの定義
Salesforce 組織のアプリケーションを設定するには、プロバイダからの情報 (クライアント ID とクライアントの
秘密、承認エンドポイント URL、トークンエンドポイント URL、ユーザ情報エンドポイント URL) が必要です。
1. [設定] で、[セキュリティのコントロール] > [認証プロバイダ] をクリックします。
2. [新規] をクリックします。
3. [プロバイダタイプ] では [OpenID Connect] を選択します。
4. プロバイダの [名前] を入力します。
5. [URL 接尾辞] を入力します。これは、クライアント設定 URL で使用されます。たとえば、プロバイダの
URL サフィックスが「MyOpenIDConnectProvider」である場合、シングルサインオン URL は
https://login.salesforce.com/auth/sso/00Dx00000000001/MyOpenIDConnectProvider のよう
になります。
6. [コンシューマ鍵] 項目には、プロバイダから入手したクライアント ID を使用します。
7. [コンシューマの秘密] 項目には、プロバイダから入手したクライアントの秘密を使用します。
8. [承認エンドポイント URL] には、プロバイダから入手したベース URL を入力します。
ヒント: 必要に応じて、クエリ文字列パラメータをベース URL に追加できます。たとえば、オフライ
ンアクセス用に Google から更新トークンを取得するには、
https://accounts.google.com/o/oauth2/auth?access_type=offline&approval_prompt=force
を使用します。この場合、更新アクションの承認をユーザに求めるには追加の approval_prompt パ
ラメータが必要となるため、Google では最初の更新トークンの後にも更新トークンが引き続き提供さ
れます。
9. プロバイダから入手した [トークンエンドポイント URL] を入力します。
10. 必要に応じて、次の項目を設定します。
a. プロバイダから入手した [ユーザ情報エンドポイント URL]。
b. [トークン発行者]。この値には、認証トークンのソースを https: URL 形式で指定します。この値が指
定された場合、プロバイダはトークン要求への応答に id_token 値を含める必要があります。id_token
値は更新トークンフローでは必要ありません (ただし、指定された場合は Salesforce によって検証されま
す)。
c. 認証エンドポイントへの要求と共に送信する [デフォルトの範囲]。送信しない場合は、プロバイダタイ
プのハードコード化されたデフォルトが使用されます (デフォルトについてはOpenID Connect の開発者用
ドキュメントを参照)。
詳細は、「Scope パラメータの使用」を参照してください。
11. [ヘッダーでアクセストークンを送信] を選択すると、トークンをクエリ文字列ではなくヘッダーに送信で
きます。
12. 必要に応じて、次の項目を設定します。
a. エラーのレポートに使用するプロバイダの [カスタムエラー URL]。
b. ユーザがシングルサインオンフローを使用して認証された場合に、ログアウト後の特定の移動先を指定
する [カスタムログアウト URL]。この項目を使用して、ユーザをブランド設定されたログアウトペー
307
Mobile SDK アプリケーションでの Communities の使用
OpenID Connect 認証プロバイダの設定
ジか、またはデフォルトの Salesforce ログアウトページ以外の場所のいずれかに移動します。URL は、
http または https プレフィックスで完全修飾する必要があります (https://acme.my.salesforce.com
など)。
c. 既存のApexクラスを [登録ハンドラ] クラスとして選択するか、[登録ハンドラテンプレートを自動作成]
をクリックして、登録ハンドラのApexクラステンプレートを作成します。このクラスを編集してデフォ
ルトのコンテンツを変更してから使用する必要があります。
メモ: Salesforce の登録ハンドラクラスを指定して、[シングルサインオン初期化 URL] を生成する必
要があります。
d. [他のアカウントで登録を実行] で Apex ハンドラクラスを実行するユーザを選択します。このユーザは
「ユーザの管理」権限を持っている必要があります。登録ハンドラを選択した場合、または登録ハンド
ラを自動作成する場合にはユーザが必要です。
e. プロバイダでポータルを使用するには、[ポータル] ドロップダウンリストからポータルを選択します。
f. [アイコン URL] 項目を使用して、コミュニティのログインページのボタンとして表示するアイコンの
パスを追加します。このアイコンは、コミュニティにのみ適用され、Salesforce 組織のログインページ
や、[私のドメイン] で作成されたカスタムドメインのログインページには表示されません。ユーザは、
このボタンをクリックし、コミュニティに関連付けられた認証プロバイダを使用してログインします。
独自の画像へのパスを指定することも、いずれかのサンプルアイコンの URL を項目にコピーすることも
できます。
13. [保存] をクリックします。
生成された [認証プロバイダ ID] の値を確認しておいてください。この値は、Auth.AuthToken Apex クラス
と共に使用する必要があります。
認証プロバイダを定義した後、複数のクライアント設定 URL が生成されます。
• テスト専用初期化 URL: システム管理者は、この URL を使用して、サードパーティプロバイダが正しく設定
されていることを確認します。システム管理者がこの URL をブラウザで開き、サードパーティにサインイ
ンすると、属性の対応付けと共に Salesforce にリダイレクトされます。
• シングルサインオン初期化 URL: この URL を使用して、サードパーティから Salesforce にシングルサインオン
を実行します (サードパーティの認証情報が使用されます)。エンドユーザは、この URL をブラウザで開き、
サードパーティにサインインします。エンドユーザの新規ユーザを作成するか、既存のユーザを更新して
から、そのユーザとして Salesforce にサインインします。
• 既存ユーザをリンクする URL: この URL を使用して、既存の Salesforce ユーザをサードパーティアカウントに
リンクします。エンドユーザは、この URL をブラウザで開き、サードパーティにサインインして Salesforce
にサインインし、リンクを承認します。
• Oauth 専用初期化 URL: この URL を使用して、サードパーティの OAuth アクセストークンを取得します。
サードパーティサービスでトークンを取得するには、ユーザは Salesforce の認証を受ける必要があります。
このフローでは、以降のシングルサインオン機能は提供されません。
• コールバック URL: 認証プロバイダが設定のためにコールバックするエンドポイントに、コールバック URL
を使用します。認証プロバイダは、前述の各クライアント設定 URL の情報と共に、[コールバック URL] に
リダイレクトする必要があります。
308
Mobile SDK アプリケーションでの Communities の使用
例: Mobile SDK アプリケーションからアクセスできるよ
うにコミュニティを設定する
クライアント設定 URL では、ユーザの特定サイトへのログイン、サードパーティからのカスタマイズされた権
限の取得、認証後の特定の場所への移動を行うための、追加の要求パラメータをサポートしています。
OpenID Connect アプリケーションの更新
認証プロバイダを Salesforce 組織に定義したら、プロバイダに戻り、アプリケーションの [コールバック URL]
(Google では [承認済みリダイレクト URI]、PayPal では [戻り URL] とも呼ばれる) を更新します。
シングルサインオン接続のテスト
ブラウザの認証プロバイダの詳細ページで [テスト専用初期化 URL] を開きます。これによりユーザはプロバ
イダのサービスにリダイレクトされ、サインインするよう求められます。サインインすると、アプリケーショ
ンを認証するように求められます。認証後、ユーザは再び Salesforce にリダイレクトされます。
例: Mobile SDK アプリケーションからアクセスできるようにコミュ
ニティを設定する
Mobile SDK アプリケーションからログインできるようにコミュニティを設定する場合、注意が必要です。この
チュートリアルでは、詳細と適切な順序を直接確認できます。
モバイルアクセス用にコミュニティユーザを設定する場合、設定の順序と方法が成功を左右します。たとえ
ば、作成したユーザに取引先責任者が関連付けられていないと、そのユーザはモバイルデバイスでログインで
きません。次に、留意すべき重要なガイドラインを示します。
• 取引先に属する取引先責任者からのみユーザを作成します。ユーザを作成してから、後で取引先責任者に
関連付けることはできません。
• 使用する取引先の所有者にロールを割り当てていることを確認してください。割り当てていない場合、ユー
ザがログインしようとするとエラーが発生します。
• iOS デバイスの [設定] でアプリケーションのカスタムホストを作成する場合、http[s]:// プレフィックス
を削除します。実行時に iOS コアによってプレフィックスが追加されるため、明示的にプレフィックスを含
めると、無効なアドレスになる可能性があります。
1. プロファイルに権限を追加する
2. コミュニティを作成する
3. コミュニティに API ユーザプロファイルを追加する
4. 新しい取引先責任者およびユーザを作成する
5. 新しいコミュニティログインをテストする
プロファイルに権限を追加する
「API の有効化」および「Chatter の有効化」権限のあるプロファイルを作成します。
1. [設定] > [ユーザの管理] > [プロファイル] に移動します。
2. [新規プロファイル] をクリックします。
309
Mobile SDK アプリケーションでの Communities の使用
コミュニティを作成する
3. [既存のプロファイル] で、[Customer Community User (カスタマーコミュニティユーザ)] を選択します。
4. [プロファイル名] に「FineApps API User」(FineApps API ユーザ) と入力します。
5. [保存] をクリックします。
6. [FineApps API User (FineApps API ユーザ)] ページで、[編集] をクリックします。
7. [システム管理者権限] で、[API の有効化] および [Chatter を有効化] を選択します。
メモ: 「Chatter の有効化」権限がないユーザは、Salesforceのコミュニティに正常にログインした直後に
「アクセス権がありません」エラーが表示されます。
8. [保存] をクリックします。
メモ: このチュートリアルではプロファイルを使用しますが、必要な権限がある権限セットを使用するこ
ともできます。
コミュニティを作成する
コミュニティおよびコミュニティログイン URL を作成します。
次の手順についての詳細は、Salesforce ヘルプの「Salesforce Communities の有効化」および「コミュニティの作
成」を参照してください。
1. [設定] で、[カスタマイズ] > [コミュニティ] に移動します。
2. [コミュニティを管理する] オプションが表示されない場合、次の手順を実行します。
a. [設定] をクリックします。
b. [コミュニティを有効化] で、[コミュニティを有効化] を選択します。
c. [ドメイン名を選択してください] で、[ドメイン名]に一意の名前 (fineapps.<あなたの名前>.force.com
など) を入力します。
d. [使用可能か調べる] をクリックして、ドメイン名がまだ使用されていないことを確認します。
e. [保存] をクリックします。
3. [設定] > [カスタマイズ] > [コミュニティ] > [コミュニティを管理する] に移動します。
4. [新規コミュニティ] をクリックします。
5. 新しいコミュニティに「FineApps Users」(FineApps ユーザ) という名前を付けて、説明を入力します。
6. サフィックス編集ボックスで、[URL] に「customers」(顧客) と入力します。
サフィックスが含まれる完全な URL が表示され、これがコミュニティの新しい URL になります。
7. [作成] をクリックし、[編集] をクリックします。
コミュニティに API ユーザプロファイルを追加する
API ユーザプロファイルを [メンバー] ページのコミュニティ設定に追加します。
1. [メンバー] をクリックします。
2. [検索] で、[すべて] を選択します。
310
Mobile SDK アプリケーションでの Communities の使用
新しい取引先責任者およびユーザを作成する
3. [選択可能なプロファイル] リストで [FineApps API ユーザ] を選択し、[追加] をクリックします。
4. [保存] をクリックします。
5. [公開] をクリックします。
6. 確認ダイアログボックスを閉じて、[閉じる] をクリックします。
新しい取引先責任者およびユーザを作成する
ユーザを直接作成する代わりに、取引先の取引先責任者を作成した後でその取引先責任者からユーザを作成し
ます。
現在、取引先がない場合、次の手順を実行します。
1. [取引先] タブをクリックします。
2. 組織にまだ取引先がない場合、次の手順を実行します。
a. [簡易作成] の [取引先名] に「My Test Account」(私のテスト取引先) と入力します。
b. [保存] をクリックします。
3. [最近の取引先] で、[My Test Account (私のテスト取引先)] またはその他の取引先名をクリックします。取引
先所有者の名前をメモします。
4. [ユーザの管理] > [ユーザ] に移動し、取引先所有者の横にある [編集] をクリックします。
5. [ロール] が CEO などの管理ロールに設定されていることを確認します。
6. [保存] をクリックします。
7. [取引先] タブをクリックして、取引先の名前を再度クリックします。
8. [取引先責任者] で、[新規取引先責任者] をクリックします。
9. [名] に「Jim」、[姓] に「Parker」と入力します。[保存] をクリックします。
10. Jim Parker の [取引先責任者] ページで、[外部ユーザの管理] をクリックし、[カスタマーユーザを有効化] を選
択します。
11. [ユーザライセンス] で、[Customer Community (カスタマーコミュニティ)] を選択します。
12. [プロファイル] で、[FineApps API User (FineApps API ユーザ)]を選択します。
13. その他の必須項目に次の値を使用します。
項目
値
メール
有効なメールアドレスを入力します。
ユーザ名
[email protected]
ニックネーム
jimmyp
必須でない情報は、ブラウザによって自動的に入力される場合は削除できます。
14. [保存] をクリックします。
311
Mobile SDK アプリケーションでの Communities の使用
新しいコミュニティログインをテストする
15. Jim Parker への歓迎メールが受信箱に届くの待ってから、そのメールのリンクをクリックしてパスワードを
作成します。パスワードを「mobile333」に設定します。
新しいコミュニティログインをテストする
新しい取引先責任者としてMobile SDKネイティブまたはハイブリッドローカルアプリケーションにログインし、
コミュニティ設定をテストします。
コミュニティを介してモバイルアプリケーションにログインするには、/fineapps で終わるコミュニティロ
グイン URL を識別するように Mobile SDK アプリケーションの設定を指定します。
1. Android の場合:
a. Eclipse で Android プロジェクトを開きます。
b. プロジェクトエクスプローラで、res フォルダに移動し、新しい xml フォルダを作成するか、既存の
フォルダを選択します。
c. xml フォルダで、新しいテキストファイルを作成します。これは、[ファイル]メニューまたは Ctrl-ク
リック (または右クリック) メニューを使用して行うことができます。
d. 新しいテキストファイルで、次の XML を追加します。サーバ URL をコミュニティログイン URL で置き換
えます。
<?xml version="1.0" encoding="utf-8"?>
<servers>
<server name="Community Login"
url="https://fineapps-developer-edition.<instance>.force.com/fineapps">
</servers>
e. ファイルを servers.xml として保存します。
2. iOS の場合:
a. Xcode で iOS プロジェクトを開きます。
b. プロジェクトナビゲータで、[Supporting Files (補助ファイル)] > [<appname>-Info.plist] を開きます。
c. [SFDCOAuthLoginHost] の値を https:// プレフィックスを除いたコミュニティログイン URL に変更しま
す。次に例を示します。
fineapps-developer-edition.<instance>.force.com/fineapps
d. iOS シミュレータまたはデバイスで、[設定] > [<your_app_name>] に移動します。
e. [Login Host (ログインホスト)] をクリックして [Custom Host (カスタムホスト)] を選択します。
f. [戻る] をクリックします。
g. [Custom Host (カスタムホスト)] を編集し、<appname>-Info.plist ファイルで指定した
SFDCOAuthLoginHost の値に設定します。
3. デバイス、シミュレータ、またはエミュレータでアプリケーションを起動し、ユーザ名
[email protected]、パスワード mobiletest1234 でログインします。
312
Mobile SDK アプリケーションでの Communities の使用
例: Facebook 認証できるようにコミュニティを設定する
メモ: ログイン画面で長期間ログインせずにモバイルアプリケーションから離れていると、ログインしよ
うとしたときに「アクセス権がありません」エラーが発生する可能性があります。この場合、アプリケー
ションを閉じてから再度開き、すぐにログインします。
例: Facebook 認証できるようにコミュニティを設定する
コミュニティログインを処理するように外部認証プロバイダを設定して、コミュニティへのアクセスを拡張で
きます。
この例では、Facebook を認証フロントエンドとして使用するように前の例を拡張します。この簡単なシナリオ
では、認証された Facebook ユーザのコミュニティへの参加を許可できるように外部認証プロバイダを設定しま
す。
モバイルアプリケーションにログインできるようにコミュニティがすでに設定されている場合、外部認証を使
用するようにモバイルアプリケーションまたは接続アプリケーションを変更する必要はありません。代わり
に、Facebook アプリケーション、Salesforce 認証プロバイダ、および認証プロバイダ Apex クラスを定義します。
また、コミュニティの設定も若干変更します。
Facebook アプリケーションを作成する
Facebook を介したコミュニティログインを有効にするには、まず Facebook アプリケーションを作成します。
Facebook アプリケーションは、Salesforce 接続アプリケーションに相当します。接続アプリケーションは、モバ
イルデバイスのアプリケーションの接続および認証を管理する設定用コンテナです。
1. developers.facebook.com に移動します。
2. Facebook 開発者アカウントでログインします。Facebook 開発者として登録していない場合は、登録します。
3. [アプリケーション] > [新規アプリケーションを作成] に移動します。
4. 表示名を「FineApps Community Test」(FineApps コミュニティテスト) に設定します。
5. 必要に応じて、名前空間を追加します。Facebook の要件に従って、小文字、ダッシュ、およびアンダース
コアのみで 20 文字以下の名前空間表示ラベルを入力する必要があります。たとえば、「my_fb_goodapps」
のようになります。
6. [カテゴリ] で、[公益事業] を選択します。
7. 後で使用するためにアプリ ID とアプリのシークレットキーをコピーして保存します。
次の URL を使用してアプリケーションにログインできます。
https://developers.facebook.com/apps/<App ID>/dashboard/
Salesforce 認証プロバイダを定義する
Salesforce で外部認証を有効にするには、認証プロバイダを作成します。
Facebook を介した外部認証には、前のステップで作成した Facebook アプリケーションのアプリケーション ID と
アプリケーションのシークレットキーが必要です。
1. [設定] で [セキュリティのコントロール] > [認証プロバイダ] にアクセスします。
313
Mobile SDK アプリケーションでの Communities の使用
Facebook アプリケーションを設定する
2. [新規] をクリックします。
3. 次の表に示すように、認証プロバイダの項目を設定します。
項目
値
プロバイダタイプ
[Facebook] を選択します。
名前
「FB Community Login」(FB コミュニティログイ
ン) と入力します。
URL 接尾辞
デフォルトを受け入れます。
メモ: URL 構文に適合するその他の文字列を入
力することもできますが、この例ではデフォ
ルトが最適です。
コンシューマ鍵
Facebook アプリケーションのアプリケーション ID を
入力します。
コンシューマの秘密
Facebook アプリケーションのアプリのシークレット
キーを入力します。
カスタムエラー URL
空白のままにします。
4. [登録ハンドラ] で、[登録ハンドラテンプレートを自動作成] をクリックします。
5.
[他のアカウントで登録を実行] で、[検索]
択します。
をクリックし、管理権限のあるコミュニティメンバーを選
6. [ポータル] は空白のままにします。
7. [保存] をクリックします。
Salesforce によって、RegistrationHandler を拡張する新しい Apex クラスが作成されます。このクラス名
は、AutocreatedRegHandlerxxxxxx… の形式を取ります。
8. 後で使用するために認証プロバイダ ID をコピーします。
9. 新しい認証プロバイダの詳細ページの [クライアント設定] で、後で使用するためにコールバック URL をコ
ピーします。
このコールバック URL は、
https://login.salesforce.com/services/authcallback/<id>/<Auth.Provider_URL_Suffix>.
の形式を取ります。
Facebook アプリケーションを設定する
次に、ログインに Salesforce 認証プロバイダを使用するようにコミュニティを設定します。
314
Mobile SDK アプリケーションでの Communities の使用
認証プロバイダの Apex クラスをカスタマイズする
Salesforce 認証プロバイダを定義したので、Facebook アプリケーションを認証プロバイダにリンクして認証プロ
トコルを完成させます。Salesforce ログイン URL およびコールバック URL を指定します。この URL には、認証プ
ロバイダ ID と認証プロバイダの URL サフィックスが含まれます。
1. Facebook アプリケーションで、[設定] に移動します。
2. [App Domains (アプリのドメイン)] に、「login.salesforce.com」と入力します。
3. [+プラットフォームを追加] をクリックします。
4. [Web サイト] を選択します。
5. [サイト URL] に、認証プロバイダのコールバック URL を入力します。
6. [連絡先メールアドレス] に、有効なメールアドレスを入力します。
7. 左パネルで、[Status & Review (ステータス & レビュー)] を [はい] に設定します。この設定により、すべての
Facebook ユーザは Facebook ログインを使用して、コミュニティのユーザアカウントを作成できます。
8. [保存] をクリックします。
9. [確認] をクリックします。
認証プロバイダの Apex クラスをカスタマイズする
認証プロバイダの Apex クラスを使用して、コミュニティに参加できるユーザを制御する条件ロジックを定義
します。
1. [設定] で [開発] > [Apex クラス] にアクセスします。
2. 認証プロバイダクラスの横にある [編集] をクリックします。デフォルトのクラス名は、
「AutocreatedRegHandlerxxxxxx…」で始まります。
3. canCreateUser() メソッドを実装するには、true を返します。
global boolean canCreateUser(Auth.UserData data) {
return true;
}
この実装により、Facebook を介してログインするすべてのユーザがコミュニティに参加できます。
メモ: 既存のコミュニティメンバーのみがコミュニティにアクセスできるようにするには、検索条件
を実装してコミュニティのすべての有効ユーザを識別できるようにします。Facebook パケットの一意
のデータ (ユーザ名やメールアドレスなど) の条件に基づいて、コミュニティメンバーのレコードの同
様の項目に対してそのデータを検証します。
4. createUser() コードを変更します。
a. アカウント名クエリの「Acme」を「FineApps」に置き換えます。
b. ユーザ名のサフィックス (「@acmecorp.com」) を「@fineapps.com」に置き換えます。
c. プロファイルクエリのプロファイル名 (「カスタマーポータルユーザ」) を「API の有効化」に変更しま
す。
5. updateUser() コードで、ユーザ名 (「myorg.com」) のサフィックスを「@fineapps.com」に置き換えま
す。
315
Mobile SDK アプリケーションでの Communities の使用
Salesforce コミュニティを設定する
6. [保存] をクリックします。
Salesforce コミュニティを設定する
最後のステップでは、ログインに Salesforce 認証プロバイダを使用するようにコミュニティを設定します。
1. [設定] で [カスタマイズ] > [コミュニティ] > [コミュニティを管理する] にアクセスします。
2. コミュニティ名の横にある [編集] をクリックします。
3. [ログインページ] をクリックします。
4. [外部ユーザのオプション] で、新しい認証プロバイダを選択します。
5. [保存] をクリックします。
これで完了です。コミュニティログイン URL を使用してモバイルアプリケーションにログインするときに、
Facebook を使用したログインを促す追加のボタンが表示されます。そのボタンをクリックして画面の指示に従
い、ログインがどのように機能するのかを確認します。
ブラウザで外部認証設定をテストするには、(認証プロバイダから) シングルサインオン初期化 URL をカスタマ
イズします。
https://login.salesforce.com/services/auth/sso/orgID/
URLsuffix?community=<community_login_url>
次に例を示します。
https://login.salesforce.com/services/auth/sso/00Da0000000TPNEAA4/
FB_Community_Login?community=
https://mobilesdk-developer-edition.server_instance.force.com/fineapps
既存ユーザをリンクする URLを作成するには、sso を link に置き換えます。
https://login.salesforce.com/services/auth/link/00Da0000000TPNEAA4/
FB_Community_Login?community=
https://mobilesdk-developer-edition.server_instance.force.com/fineapps
316
第 11 章
トピック:
•
マルチユーザのサ
ポートについて
•
マルチユーザのサ
ポートの実装
Mobile SDK でのマルチユーザのサポー
ト
複数のユーザが同時にログインできるようにするために、Mobile SDKには、ユーザの
切り替えの基本的な実装と、Android、iOS、およびハイブリッドアプリケーション用
の API が用意されています。
Mobile SDKには、認証されたアカウントから選択できるデフォルトのダイアログボッ
クスが用意されています。アプリケーションでこのダイアログボックスを起動する
手段を実装し、ユーザの切り替えフローを開始する API をコールします。
317
Mobile SDK でのマルチユーザのサポート
マルチユーザのサポートについて
マルチユーザのサポートについて
バージョン 2.2 以降、Mobile SDK では、複数のユーザアカウントから同時にログインできます。これらのアカウ
ントは、同じ組織の異なるユーザか、異なる組織 (本番組織と Sandbox 組織など) の異なるユーザを表します。
ユーザがログインすると、サーバに対して再認証することなくアカウント間のシームレスな切り替えを行うこ
とができるようにそのユーザのログイン情報が保存されます。複数のログインをサポートしない場合は、アプ
リケーションを変更する必要はありません。既存の Mobile SDK API は、シングルユーザの場合と同じように機能
します。
Mobile SDK では、各ユーザアカウントが、認証された他のユーザアカウントに関連していないと想定していま
す。それに応じて、Mobile SDK では、各アカウントに関連付けられたデータと他のすべてのユーザのデータが
分離されます。これにより、アカウント間でデータが混じることを回避できます。データの分離により、アカ
ウントに関連付けられた SharedPreferences ファイル、SmartStore データベース、AccountManager デー
タ、およびその他のフラットファイルが保護されます。
例: 次の Mobile SDK サンプルアプリケーションでは、マルチユーザの切り替えについて説明します。
• Android ネイティブ (SmartStore なし): RestExplorer
• Android ネイティブ (SmartStore あり): NativeSqlAggregator
• iOS ネイティブ: RestAPIExplorer
• iOS ハイブリッド: ContactExplorer
• ハイブリッド (SmartStore なし): ContactExplorer
• ハイブリッド (SmartStore あり): AccountEditor
マルチユーザのサポートの実装
Mobile SDK では、ネイティブ Android、ネイティブ iOS、およびハイブリッドアプリケーションでマルチユーザの
サポートを有効にする API が用意されています。
Mobile SDK では基礎となる機能は実装されますが、アプリケーションで API をコールして別のユーザに切り替え
ない限り、実行時にマルチユーザの切り替えが初期化されません。ユーザを切り替える API は次のとおりです。
Android ネイティブ (UserAccountManager クラスメソッド)
public void switchToUser(UserAccount user)
public void switchToNewUser()
iOS ネイティブ (SFUserAccountManager クラスメソッド)
- (void)switchToUser:(SFUserAccount *)newCurrentUser
- (void)switchToNewUser
ハイブリッド (JavaScript メソッド)
switchToUser
ユーザが別のアカウントに切り替えるようにするには、ユーザインターフェースのボタン、メニュー、または
その他のコントロールから選択画面を起動します。Mobile SDK では、現在認証されているすべてのアカウント
をラジオボタンリストに表示する標準のマルチユーザの切り替え画面が用意されています。この画面をカスタ
318
Mobile SDK でのマルチユーザのサポート
マルチユーザのサポートの実装
マイズすることも、デフォルトバージョンをそのまま表示することもできます。ユーザが選択すると、マルチ
ユーザフローを起動する Mobile SDK メソッドをコールします。
API の使用を開始する前に、Mobile SDK とアプリケーションの分業を理解しておくことが重要です。次のリスト
に、Mobile SDK が実行するタスクと、複数のユーザがいる状況でアプリケーションが実行する必要のあるタス
クを示します。特に、以下の管理方法を考慮してください。
• 転送通知 (アプリケーションでサポートしている場合)
• SmartStore スープ (アプリケーションで SmartStore を使用している場合)
• アカウント管理
転送通知のタスク
Mobile SDK (すべてのアカウント):
• ログイン時に転送通知を登録する
• ログアウト時に転送通知を登録解除する
• 転送通知を配信する
アプリケーション
• 対象ユーザアカウントに応じて通知を識別する
• 適切なユーザコンテキストを起動して各通知を表示する
SmartStore のタスク
Mobile SDK (すべてのアカウント):
• 認証されたユーザアカウントごとに個別の SmartStore データベースを作成する
• ユーザの切り替えが発生するたびに適切なバッキングデータベースに切り替える
アプリケーション
• ユーザの切り替えまたはログアウトが発生するたびに、キャッシュされたログイン情報 (メモリに保持され
た SmartStore のインスタンスなど) を更新する
アカウント管理のタスク
Mobile SDK (すべてのアカウント):
• ユーザの切り替えが発生するたびに適切なアカウントログイン情報を読み込む
アプリケーション
• ユーザの切り替えまたはログアウトが発生するたびに、キャッシュされたログイン情報 (メモリに保持され
た RestClient のインスタンスなど) を更新する
319
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
Android ネイティブ API
Mobile SDK for Android のネイティブクラスは、マルチユーザのサポートの大半の作業を行います。アプリケー
ションは、いくつかの簡単なコールを行い、メモリにキャッシュされたすべてのデータを処理します。ユーザ
の切り替えアクティビティをカスタマイズすることもできます。
Mobile SDK for Android では、ユーザの切り替えをサポートするために、
com.salesforce.androidsdk.accounts、com.salesforce.androidsdk.ui、および
com.salesforce.androidsdk.util パッケージのネイティブクラスを定義します。
com.salesforce.androidsdk.accounts パッケージには、次のクラスがあります。
• UserAccount
• UserAccountManager
com.salesforce.androidsdk.ui パッケージには、AccountSwitcherActivity クラスがあります。この
クラスを拡張して、アカウントの切り替えアクティビティを高度にカスタマイズできます。
com.salesforce.androidsdk.util パッケージには、UserSwitchReceiver 抽象クラスがあります。アプ
リケーションでトークン以外のデータをキャッシュする場合、このクラスを実装する必要があります。
次セクションでは、これらのクラスについて簡単に説明します。完全な API リファレンスドキュメントについ
ては、http://forcedotcom.github.io/SalesforceMobileSDK-Android/index.html を参照してください。
マルチユーザフロー
ネイティブ Android アプリケーションの場合、UserAccountManager.switchToUser() Mobile SDK メソッドが
マルチユーザフローを起動します。アプリケーションでこのメソッドがコールされると、Mobile SDK コアがす
べてのパスで実行フローを処理します。次のダイアグラムに、このフローを示します。
320
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
このセクションの内容:
UserAccount クラス
UserAccount クラスは、現在認証されている単一のユーザアカウントを表します。このクラスは、ユーザ
アカウントを一意に識別するために使用できるデータをカプセル化します。
UserAccountManager クラス
UserAccountManager クラスは、認証されたアカウントへのアクセス、新しいアカウントの追加、既存の
アカウントのログアウト、既存のアカウント間の切り替えを行うメソッドを提供します。
AccountSwitcherActivity クラス
AccountSwitcherActivity クラスを使用または拡張して、ユーザの切り替えのインターフェースを表示
します。
UserSwitchReceiver クラス
ネイティブ Android アプリケーションがトークン以外のデータをキャッシュする場合、UserSwitchReceiver
抽象クラスを実装して、ユーザの切り替えイベントの通知を受信します。
UserAccount クラス
UserAccount クラスは、現在認証されている単一のユーザアカウントを表します。このクラスは、ユーザア
カウントを一意に識別するために使用できるデータをカプセル化します。
321
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
コンストラクタ
JSON オブジェクトまたはバンドルから直接 UserAccount オブジェクトを作成できます。
コンストラクタ
public UserAccount(String authToken,
String refreshToken,
String loginServer,
String idUrl,
String instanceServer,
String orgId,
String userId,
String username,
String accountName,
String clientId,
String communityId,
String communityUrl
)
説明
指定した値を使用して UserAccount オブジェクトを
作成します。
public UserAccount(JSONObject object)
JSON 文字列から UserAccount オブジェクトを作成し
ます。
public UserAccount(Bundle bundle)
Android アプリケーションバンドルから UserAccount
オブジェクトを作成します。
メソッド
メソッド
説明
public String getOrgLevelStoragePath()
このユーザアカウントの組織レベルのストレージパス
(アプリケーションデータの上位レベルのディレクト
リに対する相対パス) を返します。上位レベルのディ
レクトリは files などになります。出力の形式
は、/{orgID}/ になります。これは、同じ組織の複
数のユーザで共有できるデータのストレージパスで
す。
public String getUserLevelStoragePath()
このユーザアカウントのユーザレベルのストレージパ
ス (アプリケーションデータの上位レベルのディレク
トリに対する相対パス)を返します。上位レベルのディ
レクトリは files などになります。出力の形式
は、/{orgID}/{userID}/ になります。これは、組
織の特定のユーザに固有のデータのストレージパスで
すが、そのユーザがメンバーであるその組織内のすべ
てのコミュニティで共有されるデータのストレージパ
スでもあります。
322
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
メソッド
説明
public String
getCommunityLevelStoragePath(String
communityId)
このユーザアカウントのコミュニティレベルのスト
レージパス (アプリケーションデータの上位レベルの
ディレクトリに対する相対パス) を返します。上位レ
ベルのディレクトリは files などになります。出力
の形式は、/{orgID}/{userID}/{communityID}/
になります。communityID が null の場合、出力は
/{orgID}/{userID}/internal/ のようになりま
す。これは、特定のコミュニティの特定のユーザに固
有のデータのストレージパスです。
public String getOrgLevelFilenameSuffix() このユーザアカウントの一意のサフィックスを返しま
す。このサフィックスをファイルに追加して、組織レ
ベルでこのアカウントを一意に識別できます。出力の
形式は、_{orgID} になります。これは、同じ組織の
複数のユーザで共有できるデータのサフィックスで
す。
public String getUserLevelFilenameSuffix() このユーザアカウントの一意のサフィックスを返しま
す。このサフィックスをファイルに追加して、ユーザ
レベルでこのアカウントを一意に識別できます。出力
の形式は、_{orgID}_{userID} になります。これ
は、組織の特定のユーザに固有のデータのサフィック
スですが、そのユーザがメンバーであるその組織内の
すべてのコミュニティで共有されるデータのサフィッ
クスでもあります。
public String
getCommunityLevelFilenameSuffix(String
communityId)
このユーザアカウントの一意のサフィックスを返しま
す。このサフィックスをファイルに追加して、コミュ
ニティレベルでこのアカウントを一意に識別できま
す。出力の形式は、
_{orgID}_{userID}_{communityID} になります。
communityID が null の場合、出力は
_{orgID}_{userID}_internal のようになります。
これは、特定のコミュニティの特定のユーザに固有の
データのサフィックスです。
UserAccountManager クラス
UserAccountManager クラスは、認証されたアカウントへのアクセス、新しいアカウントの追加、既存のア
カウントのログアウト、既存のアカウント間の切り替えを行うメソッドを提供します。
UserAccountManager のインスタンスは直接作成しません。代わりに、次のコールを使用してインスタンス
を取得します。
SalesforceSDKManager.getInstance().getUserAccountManager();
323
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
メソッド
メソッド
説明
public UserAccount getCurrentUser()
現在有効なユーザアカウントを返します。
public List<UserAccount>
getAuthenticatedUsers()
認証されたユーザアカウントのリストを返します。
public boolean
指定されたユーザアカウントがすでに認証されている
doesUserAccountExist(UserAccount account) かどうかを確認します。
public void switchToUser(UserAccount user) 指定されたユーザアカウントにアプリケーションコン
テキストを切り替えます。指定されたユーザアカウン
トが無効または null の場合、このメソッドはログイン
フローを起動します。
public void switchToNewUser()
新しいユーザがログインするためのログインフローを
起動します。
public void signoutUser(UserAccount
userAccount, Activity frontActivity)
指定されたユーザをアプリケーションからログアウト
させて、そのユーザのログイン情報を消去します。
AccountSwitcherActivity クラス
AccountSwitcherActivity クラスを使用または拡張して、ユーザの切り替えのインターフェースを表示し
ます。
AccountSwitcherActivity クラスは、マルチユーザログインを処理する画面を提供します。この画面では、
既存のユーザアカウントのリストが表示され、ユーザは既存のアカウントを切り替えたり、新しいアカウント
にサインインしたりできます。マルチユーザログインを有効にするには、次のコードを使用してアプリケー
ションの任意の場所からアクティビティを起動します。
final Intent i = new Intent(this,
SalesforceSDKManager.getInstance().getAccountSwitcherActivityClass());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(i);
たとえば、ユーザインターフェースの「ユーザの切り替え」ボタンからこのアクティビティを起動できます。
例については、SampleApps/RestExplorerを参照してください。
必要に応じて、XML を介して AccountSwitcherActivity をカスタマイズおよびスタイル設定できます。
さらに詳細に制御するために、AccountSwitcherActivity を拡張したり、独自のカスタムサブクラスに置
き換えたりできます。デフォルトクラスを置き換えるには、
SalesforceSDKManager.setAccountSwitcherActivityClass() をコールします。置き換わるアクティ
ビティクラス (AccountSwitcherActivity.class など) のクラスファイルに参照を渡します。
324
Mobile SDK でのマルチユーザのサポート
Android ネイティブ API
UserSwitchReceiver クラス
ネイティブ Android アプリケーションがトークン以外のデータをキャッシュする場合、UserSwitchReceiver
抽象クラスを実装して、ユーザの切り替えイベントの通知を受信します。
ユーザの切り替えが発生するたびに、Mobile SDKはインテントをブロードキャストします。インテントアクショ
ンは、次のように UserAccountManager クラスで宣言されます。
public static final String USER_SWITCH_INTENT_ACTION = "com.salesforce.USERSWITCHED";
このブロードキャストイベントにより、キャッシュされたリソースをアプリケーションで適切に更新して、
ユーザの切り替えに対応できます。アプリケーションがこのイベントをリスンできるように、Mobile SDKには、
UserSwitchReceiver 抽象クラスが用意されています。このクラスは、次の Salesforce アクティビティクラス
で実装されます。
• SalesforceActivity
• SalesforceListActivity
• SalesforceExpandableListActivity
メインアクティビティでいずれかのSalesforceアクティビティクラスを拡張する場合、UserSwitchReceiver
を実装する必要はありません。
メモリにトークンのみをキャッシュしている場合、何もする必要はありません。Mobile SDKが自動的にトー
クンを更新します。
トークン以外のユーザデータをキャッシュしている場合、カスタム更新アクションでアクティビティの
refreshIfUserSwitched() メソッドを上書きします。
メインアクティビティでいずれかのSalesforceアクティビティクラスを拡張しない場合、UserSwitchReceiver
を実装して、ユーザの切り替え時にキャッシュされたデータを処理します。
ブロードキャストレシーバを設定する手順は、次のとおりです。
1. UserSwitchReceiver のサブクラスを実装します。
2. アクティビティの onCreate() メソッドでサブクラスをレシーバとして登録します。
3. アクティビティの onDestroy() メソッドでレシーバを登録解除します。
例については、RestExplorer サンプルアプリケーションの ExplorerActivity クラスを参照してくだ
さい。
アプリケーションがハイブリッドアプリケーションの場合、作業は必要ありません。
SalesforceDroidGapActivity クラスは、ユーザの切り替えの発生時に必要に応じてキャッシュを更新
します。
メソッド
1 つのメソッドで実装が必要になります。
メソッド名
説明
protected abstract void onUserSwitch();
このメソッドを実装して、ユーザの切り替えの発生時
にキャッシュされたユーザデータ (トークン以外) を処
理します。
325
Mobile SDK でのマルチユーザのサポート
iOS ネイティブ API
iOS ネイティブ API
Mobile SDK for iOS のネイティブクラスは、マルチユーザのサポートの大半の作業を行います。アプリケーション
は、いくつかの簡単なコールを行い、メモリにキャッシュされたすべてのデータを処理します。ユーザの切り
替えアクティビティをカスタマイズすることもできます。
Mobile SDK for iOS では、ユーザの切り替えをサポートするために、SalesforceSDKCore ライブラリの Security
フォルダのネイティブクラスを定義します。クラスには、以下が含まれます。
• SFUserAccount
• SFUserAccountManager
次セクションでは、これらのクラスについて簡単に説明します。完全な API リファレンスドキュメントについ
ては、http://forcedotcom.github.io/SalesforceMobileSDK-iOS/Documentation/masterTOC.html を参照してください。
このセクションの内容:
SFUserAccount クラス
SFUserAccount クラスは、現在認証されている単一のユーザアカウントを表します。このクラスは、ユー
ザアカウントを一意に識別するために使用できるデータをカプセル化します。
SFUserAccountManager クラス
SFUserAccountManager クラスは、認証されたアカウントへのアクセス、新しいアカウントの追加、ア
カウントのログアウト、アカウント間の切り替えを行うメソッドを提供します。
SFUserAccount クラス
SFUserAccount クラスは、現在認証されている単一のユーザアカウントを表します。このクラスは、ユーザ
アカウントを一意に識別するために使用できるデータをカプセル化します。
プロパティ
JSON オブジェクトまたはバンドルから直接 SFUserAccount オブジェクトを作成できます。
プロパティ
説明
このユーザのアクセス範囲。
@property (nonatomic, copy) NSSet
*accessScopes
このユーザに関連付けられたログイン情報。
@property (nonatomic, strong)
SFOAuthCredentials *credentials;
@property (nonatomic, strong) SFIdentityData
*idData;
@property (nonatomic, copy, readonly) NSURL
*apiUrl;
このユーザに関連付けられた ID データ。
サーバ側の API を呼び出するために使用できる URL。
この URL では、現在のコミュニティが考慮されます
(使用可能な場合)。
326
Mobile SDK でのマルチユーザのサポート
iOS ネイティブ API
プロパティ
説明
@property (nonatomic, copy) NSString *email;
@property (nonatomic, copy) NSString
*organizationName;
@property (nonatomic, copy) NSString
*fullName;
@property (nonatomic, copy) NSString
*userName;
@property (nonatomic, strong) UIImage
*photo;
@property (nonatomic)
SFUserAccountAccessRestriction
accessRestrictions;
@property (nonatomic, copy) NSString
*communityId;
@property (nonatomic, readonly, getter =
isSessionValid) BOOL sessionValid;
@property (nonatomic, copy) NSDictionary
*customData;
ユーザのメールアドレス。
ユーザの組織の名前。
ユーザの名と姓。
ユーザのユーザ名。
ユーザの写真 (通常、ユーザのサムネイル)。このクラ
スのコンシューマは、写真を使用するために少なくと
も 1 回はこのプロパティを設定する必要があります。
このクラスは、サーバから写真を取得しません。写真
はローカルで保存および取得されます。
このユーザに関連付けられたアクセス制限。
現在のコミュニティ ID (ユーザがコミュニティにログ
インしている場合)。コミュニティにログインしてい
ない場合、このプロパティは nil になります。
ユーザにアクセストークンがあり、有効なセッション
だと想定される場合、YES を返します。
ユーザのカスタムデータ。このデータは逐次化できる
ため、customData に含まれるオブジェクトは
NSCoding プロトコルに準拠する必要があります。
グローバル関数
関数名
説明
NSString *SFKeyForUserAndScope
(SFUserAccount *user, SFUserAccountScope
scope);
特定の範囲でこのユーザアカウントを一意に識別する
キーを返します。scope を
SFUserAccountScopeGlobal に設定すると、ユー
ザアカウントに関係なく同じキーが返されます。
327
Mobile SDK でのマルチユーザのサポート
iOS ネイティブ API
SFUserAccountManager クラス
SFUserAccountManager クラスは、認証されたアカウントへのアクセス、新しいアカウントの追加、アカウ
ントのログアウト、アカウント間の切り替えを行うメソッドを提供します。
シングルトン SFUserAccountManager インスタンスにアクセスするには、次のメッセージを送信します。
[SFUserAccountManager sharedInstance]
プロパティ
プロパティ
説明
@property (nonatomic, strong) SFUserAccount 現在のユーザアカウント。 ユーザがログインしてい
*currentUser
ない場合、このプロパティは nil になる可能性があり
ます。
@property (nonatomic, readonly) NSString
*currentUserId
現在のユーザの ID を取得する便利なプロパティ。こ
のプロパティは、
currentUser.credentials.userId の別名です。
@property (nonatomic, readonly) NSString
*currentCommunityId
現在のユーザのコミュニティ ID を取得する便利なプ
ロパティ。このプロパティは、
currentUser.communityId の別名です。
@property (nonatomic, readonly) NSArray
*allUserAccounts
アプリケーションのすべての SFUserAccount インス
タンスの NSArray。
@property (nonatomic, readonly) NSArray
*allUserIds
すべてのユーザ ID を含む配列を返します。
@property (nonatomic, copy) NSString
*activeUserId
最後の有効なユーザ ID。activeUserId によって指
定されたユーザがアカウントリストから削除されてい
ると、このユーザは現在のユーザとは一時的に異なる
場合があります。
@property (nonatomic, strong) NSString
*loginHost
ログインに使用されるホスト。
@property (nonatomic, assign) BOOL
retryLoginAfterFailure
ログインプロセスが失敗した場合にログインプロセス
を再起動するかどうかを制御するフラグ。デフォルト
値は YES です。
@property (nonatomic, copy) NSString
*oauthClientId
ログインに使用される OAuth クライアント ID。このプ
ロパティは、ログイン前にアプリケーションによって
カスタマイズされている場合があります。カスタマイ
ズされていない場合、この値は、設定バンドルで設定
された SFDCOAuthClientIdPreference プロパティ
によって決まります。
328
Mobile SDK でのマルチユーザのサポート
iOS ネイティブ API
プロパティ
説明
@property (nonatomic, copy) NSString
*oauthCompletionUrl
OAuth ログインプロセスに使用される OAuth コールバッ
ク URL。このプロパティは、ログイン前にアプリケー
ションによってカスタマイズされている場合がありま
す。デフォルトでは、プロパティの値は、メインバン
ドルの SFDCOAuthRedirectUri プロパティからコ
ピーされます。デフォルト値は、
@"sfdc:///axm/detect/oauth/done" です。
@property (nonatomic, copy) NSSet *scopes アプリケーションに関連付けられた OAuth 範囲。
メソッド
メソッド
説明
- (NSString*)userAccountPlistFileForUser:(SFUserAccount*)user 指定されたユーザアカウントの
.plist ファイルのパスを返し
ます。
このユーザアカウントマネー
(void)addDelegate:(id<SFUserAccountManagerDelegate>)delegate ジャに代理を追加します。
このユーザアカウントマネー
(void)removeDelegate:(id<SFUserAccountManagerDelegate>)delegate ジャから代理を削除します。
- (SFLoginHostUpdateResult *)updateLoginHost
アプリケーション設定でアプリ
ケーションレベルのログインホ
ストをこの値に設定します。
- (BOOL)loadAccounts:(NSError**)error
すべてのアカウントを読み込み
ます。
- (BOOL)saveAccounts:(NSError**)error
すべてのアカウントを保存しま
す。
- (SFUserAccount*)createUserAccount
すべてのアカウント情報を自分
自身で設定する場合に空のユー
ザアカウントを作成するために
使用できます。それ以外の場合
は、必要に応じて
[SFAuthenticationManager
loginWithCompletion:failure:]
を使用し、アカウントを自動的
に作成します。
329
Mobile SDK でのマルチユーザのサポート
iOS ネイティブ API
メソッド
説明
- (SFUserAccount*)userAccountForUserId:(NSString*)userId
特定のユーザ ID に関連付けられ
たユーザアカウントを返しま
す。
- (NSArray *)accountsForOrgId:(NSString *)orgId
特定の組織にアクセスできるす
べてのアカウントを返します。
- (NSArray *)accountsForInstanceURL:(NSString *)instanceURL 特定のインスタンス URL に一致
するすべてのアカウントを返し
ます。
- (void)addAccount:(SFUserAccount *)acct
ユーザアカウントを追加しま
す。
- (BOOL)deleteAccountForUserId:(NSString*)userId
error:(NSError **)error
特定のユーザ ID に関連付けられ
たユーザアカウントを削除しま
す。
- (void)clearAllAccountState
メモリ内のアカウントの状態を
クリアします (ただし、ディス
クの内容は何も変更されませ
ん)。
- (void)applyCredentials:(SFOAuthCredentials*)credentials
指定されたログイン情報を現在
のユーザに適用します。ユーザ
が存在しない場合、ユーザが作
成されます。
- (void)applyCustomDataToCurrentUser:(NSDictionary
*)customData
そのユーザの Sandbox の外部か
らアクセスできる
SFUserAccount にカスタム
データを適用します。このデー
タは、アプリケーションの起動
ごとに変わることはありませ
ん。このデータは逐次化される
ため、customData に含まれる
オブジェクトが NSCoding プロ
トコルに準拠していることを確
認してください。
重要: このメソッドは、機
密情報以外にのみに使用
します。
現在のユーザから新しいユーザ
コンテキストに切り替えます。
- (void)switchToNewUser
330
Mobile SDK でのマルチユーザのサポート
ハイブリッド API
メソッド
説明
- (void)switchToUser:(SFUserAccount *)newCurrentUser
現在のユーザを指定されたユー
ザアカウントに切り替えます。
- (void)userChanged:(SFUserAccountChange)change
現在のユーザに何らかの変更が
あったことを
SFUserAccountManager オブ
ジェクトに通知します。
ハイブリッド API
ハイブリッドアプリケーションは、Mobile SDK JavaScript API を介して、マルチユーザのサポートを有効にできま
す。これらの API は、SFAccountManagerPlugin Cordova ベースのモジュールにあります。
SFAccountManagerPlugin メソッド
これらのメソッドをコールする前に、sfaccountmanager プラグインを読み込む必要があります。次に例を
示します。
cordova.require("com.salesforce.plugin.sfaccountmanager").logout();
メソッド名
説明
getUsers
すでにログインしているユーザのリストを返します。
getCurrentUser
現在の有効なユーザを返します。
logout
ユーザが渡された場合は指定されたユーザをログアウ
トさせます。引数を指定しないでコールした場合は、
現在のユーザをログアウトさせます。
switchToUser
指定したユーザにアプリケーションコンテキストを切
り替えます。ユーザが指定されていない場合は、アカ
ウントの切り替え画面を起動します。
ハイブリッドアプリケーションでは、マルチユーザの切り替えのブロードキャストイベントのレシーバを実装
する必要はありません。このハンドラは、SalesforceDroidGapActivity クラスで実装されます。
331
第 12 章
トピック:
•
ハイブリッドアプ
リケーションを 3.0
から 3.1 に移行する
•
Android ネイティブ
アプリケーション
を 3.0 から 3.1 に移
行する
•
iOS ネイティブアプ
リケーションを 3.0
から 3.1 に移行する
•
ハイブリッドアプ
リケーションを 2.3
から 3.0 に移行する
•
Android ネイティブ
アプリケーション
を 2.3 から 3.0 に移
行する
•
iOS ネイティブアプ
リケーションを 2.3
から 3.0 に移行する
•
以前のリリースか
らの移行
以前のリリースからの移行
Salesforce Mobile SDK 2.2 を使用して作成されたアプリケーションをアップグレードする
場合は、次の手順に従ってアプリケーションをバージョン 2.3 に更新します。
Salesforce Mobile SDK より前のバージョンを使用して作成されたアプリケーションを
アップグレードする場合は、以前のリリースからの移行を参照してアップグレード
を開始します。
332
以前のリリースからの移行
ハイブリッドアプリケーションを 3.0 から 3.1 に移行す
る
ハイブリッドアプリケーションを 3.0 から 3.1 に移行する
既存の Mobile SDK 3.0 ハイブリッドアプリケーションは、Mobile SDK 3.1 でコードを変更しなくても動作します。
行う操作は、Salesforce Cordova プラグインのアップグレードだけです。Mobile SDK 3.1 では、Cordova 3.5 以降がサ
ポートされ、Cordova 3.6.3 までテスト済みで、Cordova 3.7 でも動作することが予想されます。
Salesforce Cordova プラグインをアップグレードするには、次に示すように Cordova コマンドラインツールを使用
して削除してから、プラグインを再度追加します。
例:
$
$
$
$
cd <your_Cordova_app_folder>
cordova plugin rm com.salesforce
cordova plugin add https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin
cordova prepare
Android ネイティブアプリケーションを 3.0 から 3.1 に移行する
Android ネイティブアプリケーションを Salesforce Mobile SDK 3.0 からバージョン 3.1 にアップグレードするには、
次の手順を実行します。
1. Eclipse で Mobile SDK プロジェクトワークスペースを開きます。
2. 既存の Cordova プロジェクトを Mobile SDK 3.1 Cordova プロジェクトに置き換えます。
3. 既存の SalesforceSDK プロジェクトを新しい SalesforceSDK プロジェクトに置き換えます。
4. アプリケーションで SmartStore を使用する場合は、既存の SmartStore プロジェクトを 新しい SmartStore プロ
ジェクトに置き換えます。
5. アプリケーションで SmartSync を使用する場合は、既存の SmartSync プロジェクトを 新しい SmartSync プロジェ
クトに置き換えます。
6. プロジェクトエクスプローラで、プロジェクトを右クリックして [Properties (プロパティ)] を選択します。
7. 左パネルで、[Android] を選択します。
8. [Library (ライブラリ)] セクションで、既存の SalesforceSDK エントリをワークスペースの新しい SalesforceSDK プ
ロジェクトに置き換えます。
9. アプリケーションで SmartStore を使用する場合は、SmartStore プロジェクトでステップ 8 を繰り返します。
10. アプリケーションで SmartSync を使用する場合は、SmartSync プロジェクトでステップ 8 を繰り返します。
iOS ネイティブアプリケーションを 3.0 から 3.1 に移行する
Mobile SDK 3.1 への移行は、わずかな作業で実行できます。現在サポートされている Xcode の最小バージョンは
6.0 です。また、既存のバイナリパッケージの更新に加えて、新しい SalesforceSDKCommon
(SalesforceSDKCommon-[Debug/Release].zip) パッケージが追加されました。このパッケージには、下位
レベルのネットワークおよびセキュリティユーティリティが含まれています。
333
以前のリリースからの移行
Mobile SDK ライブラリパッケージを 3.0 から 3.1 に更新
する
Mobile SDK 3.0 アプリケーションを Mobile SDK 3.1 にアップグレードするには、「Mobile SDK ライブラリパッケージ
を 3.0 から 3.1 に更新する」の手順を実行します。
Mobile SDK ライブラリパッケージを 3.0 から 3.1 に更新する
ライブラリパッケージを更新するには、アプリケーションの Xcode プロジェクトの Dependencies フォルダを削
除して再作成し、新しいライブラリをこのフォルダに追加します。
1. SalesforceMobileSDK-iOS-Distribution リポジトリ (https://github.com/forcedotcom/SalesforceMobileSDK-iOS-Distribution) か
ら次のバイナリパッケージをダウンロードします。
• MKNetworkKit-iOS-Release.zip
• SalesforceRestAPI-Release.zip
• SalesforceNetworkSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCommon-Release.zip
• SalesforceSDKCore-Release.zip
• SalesforceSecurity-Release.zip
• SmartSync-Release.zip
2. また、配布リポジトリの ThirdParty フォルダリンクから次のフォルダもダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
3. Xcode で Mobile SDK プロジェクトを開きます。
4. プロジェクトナビゲータで、Dependencies フォルダを見つけます。
5. Ctrl キーを押しながらフォルダをクリックします。[Delete (削除)] を選択し、[Move to Trash (ゴミ箱に移動)]
を選択します。
6. Xcode プロジェクトで、アプリケーションフォルダの下に Dependencies フォルダを再作成します。
7. Dependencies フォルダに、ステップ 1 の新しいパッケージを解凍し、ステップ 2 のフォルダをコピーします。
8. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<App Name>"... (「<アプリケーション名>」にファイルを追加...)] を選択します。
9. Dependencies フォルダを選択し、追加したフォルダで [Create groups (グループを作成)] が選択されているこ
とを確認します。
10. [追加] をクリックします。
ハイブリッドアプリケーションを 2.3 から 3.0 に移行する
既存のハイブリッドアプリケーションは、Mobile SDK 3.0 で変更しなくても引き続き機能します。Mobile SDK 3.0
は Cordova 3.5 以降がサポートされ、Cordova 3.6.3 までテスト済みで、Cordova 3.7 でも動作することが予想されま
す。
334
以前のリリースからの移行
Android ネイティブアプリケーションを 2.3 から 3.0 に
移行する
ハイブリッドアプリケーションの 2.3 から 3.0 へのアップグレードは、Salesforce Cordova プラグインをアップグ
レードするだけの簡単な処理です。アップグレードするには、次に示すように、Cordova コマンドラインツー
ルを使用してプラグインを削除してから再追加します。
$
$
$
$
cd <your_Cordova_app_folder>
cordova plugin rm com.salesforce
cordova plugin add https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin
cordova prepare
Android ネイティブアプリケーションを 2.3 から 3.0 に移行する
Android ネイティブアプリケーションを Salesforce Mobile SDK 2.3 からバージョン 3.0 にアップグレードするには、
次の手順を実行します。
1. Eclipse で Mobile SDK プロジェクトワークスペースを開きます。
2. 既存の Cordova プロジェクトを Mobile SDK 3.0 Cordova プロジェクトに置き換えます。
3. 既存の SalesforceSDK プロジェクトを新しい SalesforceSDK プロジェクトに置き換えます。
4. アプリケーションで SmartStore を使用する場合は、既存の SmartStore プロジェクトを 新しい SmartStore プロ
ジェクトに置き換えます。
5. プロジェクトエクスプローラで、プロジェクトを右クリックして [Properties (プロパティ)] を選択します。
6. 左パネルで、[Android] を選択します。
7. [Library (ライブラリ)] セクションで、既存の SalesforceSDK エントリをワークスペースの新しい SalesforceSDK プ
ロジェクトに置き換えます。
8. アプリケーションでSmartStoreを使用する場合は、SmartStoreプロジェクトで前のステップを繰り返します。
9. アプリケーションで使用される最小 Android SDK バージョンがレベル 17 以降であることを確認します。
iOS ネイティブアプリケーションを 2.3 から 3.0 に移行する
iOS ネイティブアプリケーションを Mobile SDK 2.3 からバージョン 3.0 に移行するには、2 つのステップからなる
次の手順を実行します。
1. Mobile SDK ライブラリパッケージを更新する
2. SalesforceSDKManager を使用するようにアプリケーションブートストラップフローを更新する
Mobile SDK ライブラリパッケージを更新する
ライブラリパッケージを最も簡単な方法でアップグレードするには、アプリケーションの Xcode プロジェクト
の既存の Dependencies フォルダを削除してから、再作成した Dependencies フォルダに新しいライブラリを追加
します。
1. SalesforceMobileSDK-iOS-Distribution リポジトリ (https://github.com/forcedotcom/SalesforceMobileSDK-iOS-Distribution) か
ら次のバイナリパッケージをダウンロードします。
• MKNetworkKit-iOS-Release.zip
335
以前のリリースからの移行
SalesforceSDKManager を使用するようにアプリケーショ
ンブートストラップフローを更新する
• SalesforceRestAPI-Release.zip
• SalesforceNetworkSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
• SalesforceSecurity-Release.zip
• SmartSync-Release.zip
2. また、配布リポジトリの ThirdParty フォルダリンクから次のフォルダもダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
3. Xcode で Mobile SDK プロジェクトを開きます。
4. プロジェクトナビゲータで、Dependencies フォルダを見つけます。
5. Ctrl キーを押しながらフォルダをクリックします。[Delete (削除)] を選択し、[Move to Trash (ゴミ箱に移動)]
を選択します。
6. Xcode プロジェクトで、アプリケーションフォルダの下に Dependencies フォルダを再作成します。
7. Dependencies フォルダに、ステップ 1 の新しいパッケージを解凍し、ステップ 2 のフォルダをコピーします。
8. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<App Name>"... (「<アプリケーション名>」にファイルを追加...)] を選択します。
9. Dependencies フォルダを選択し、追加したフォルダで [Create groups (グループを作成)] が選択されているこ
とを確認します。
10. [追加] をクリックします。
SalesforceSDKManager を使用するようにアプリケーションブートス
トラップフローを更新する
Mobile SDK 3.0 以降、Mobile SDK ブートストラッププロセスの多くは SalesforceSDKManager のシングルトンク
ラスに移行されます。起動イベントを処理するほとんどのカスタムコードは再利用できますが、若干異なるコ
ンテキストに移行する必要があります。次の一覧に、ブートストラップおよび設定コードでの重要な移行と変
更点を示します。
1. アプリケーションの接続アプリケーション設定および OAuth 範囲を定義するコードを更新します。
a. [SFUserAccountManager sharedInstance].oauthClientId を [SalesforceSDKManager
sharedManager].connectedAppId に置き換えます。
b. [SFUserAccountManager sharedInstance].oauthCompletionUrl を [SalesforceSDKManager
sharedManager].connectedAppCallbackUri に置き換えます。
c. [SFUserAccountManager sharedInstance].scopes を [SalesforceSDKManager
sharedManager].authScopes に置き換えます。
2. アプリケーションが起動プロセスの最初に認証を行う場合 (デフォルト動作)、[[SFAuthenticationManager
sharedManager] loginWithCompletion:failure:] へのコールを次のように置き換えます。
336
以前のリリースからの移行
以前のリリースからの移行
a. [SalesforceSDKManager sharedManager].postLaunchAction を設定して完了ブロックを置き換
えます。
b. [SalesforceSDKManager sharedManager].launchErrorAction を設定して失敗ブロックを置き
換えます。
c. loginWithCompletion:failure: へのコールを [[SalesforceSDKManager sharedManager]
launch] に置き換えます。
3. アプリケーションが起動プロセスの一部として認証を行わない場合は、次の操作を実行します。
a. 起動をコールする前のいずれかの場所で [SalesforceSDKManager
sharedManager].authenticateAtLaunch を NO に設定します。
b. アプリケーションのライフサイクルの適切な時点で引き続き [[SFAuthenticationManager
sharedManager] loginWithCompletion:failure:] をコールします。
4. アプリケーションが起動時に認証を行うかどうかに関わらず、AppDelegate 実装で
application:didFinishLaunchingWithOptions: の [[SalesforceSDKManager sharedManager]
launch] をコールする必要があります。
5. AppDelegate クラスは、ブートストラップイベントで SFAuthenticationManagerDelegate または
SFUserAccountManagerDelegate プロトコルを実装する必要はなくなりました。
• [SalesforceSDKManager sharedManager].postLogoutAction ブロックが
[SFAuthenticationManagerDelegate authManagerDidLogout:] の代わりに使用されます。
• [SalesforceSDKManager sharedManager].switchUserAction ブロックが
[SFUserAccountManagerDelegate userAccountManager:didSwitchFromUser:toUser:] の代わ
りに使用されます。
6. アプリケーションイベント境界で次の SFAuthenticationManagerDelegate メソッドを登録している場
合、SalesforceSDKManagerDelegate の同等の代理メソッドの登録も必要になりました。
• authManagerWillResignActive:
• authManagerWillEnterForeground:
• authManagerDidBecomeActive:
• authManagerDidEnterBackground:
7. SFAuthenticationManager (useSnapshotView、snapshotView) のスナップショットビュー機能をカ
スタマイズしている場合、これらのカスタマイズを SalesforceSDKManager の同等の機能に移行します。
8. (まれなケース) SFAuthenticationManager でデフォルトの preferredPasscodeProvider 値の上書き
を指定している場合、カスタマイズを SalesforceSDKManager に移行します。
SalesforceSDKManager がアプリケーションの Mobile SDK ブートストラッププロセスに与える影響について
の詳細は、「ネイティブ iOS アプリケーションの開発 (ページ 30)」を参照してください。
以前のリリースからの移行
以前のリリースよりも古いバージョンから移行するには、現在のバージョンから始めて、介在するリリースご
とにコードのアップグレード手順を実行します。
337
以前のリリースからの移行
ハイブリッドアプリケーションを 2.2 から 2.3 に移行す
る
ハイブリッドアプリケーションを 2.2 から 2.3 に移行する
Mobile SDK 2.3 の焦点は、ハイブリッドコンテナを Cordova 3.5 にアップグレードすることです。Mobile SDK のこの
バージョンの移行要件はすべて、ハイブリッドアプリケーションに関連しています。バージョン 2.2 で作成さ
れたネイティブ iOS および Android アプリケーションについては、2.3 で実行するために必要な変更はありませ
ん。
Mobile SDK では、バージョン 2.3 以降、ハイブリッドコンテナを作成するための完全に独立したモジュールとし
て Cordova 3.5 以降を使用します。この新しいアーキテクチャでは、Cordova コマンドラインを直接実行する必要
があります。既存のハイブリッドアプリケーションをMobile SDK 2.3 に移行するには、新しい Cordova アプリケー
ションを作成してから、既存の Web アセットをそのアプリケーションに移動します。この操作には 2 通りの方
法があります。
• 新しい forceios または forcedroid アプリケーションを作成し、Web アセットをそのアプリケーションに移動し
てから、Cordova を使用してアプリケーションの設定を完了する。ハイブリッドアプリケーションを作成す
る (ページ 142)を参照してください。
• Cordova アプリケーションを作成してから、Salesforce Mobile SDK Cordova プラグインを他のプラグインや Web
アセットと一緒にこのアプリケーションに追加する。次のセクションでは、若干簡単なこの方法について
説明します。
Cordova アプリケーションの作成
Mac OS X ターミナルウィンドウまたは Windows コマンドプロンプトで次のコマンドを実行します。
1. Cordova 3.5 (以降) をインストールします。
npm -g install cordova
Cordova をインストール済みの場合は、バージョンが 3.5 以降であることを確認します。
cordova --version
2. Cordova に対応するアプリケーションディレクトリを作成します。
cordova create MyNewApplication
cordova create は 3 つの引数を取りますが、最初の引数 (<ディレクトリ>) のみが必須です。パッケージ
名 (com.acme.hello など) やアプリケーションに表示されるタイトルも指定できます。単一パラメータの
この例では、Cordova で io.cordova.hellocordova という名前のパッケージが作成され、「HelloCordova」
という表示名が使用されます。http://cordova.apache.org/docs/en/3.5.0 の「コマンドラインインターフェース」
を参照してください。
3. 新しいアプリケーションのディレクトリに移動します。
cd MyNewApplication
4. アプリケーションで iOS をサポートしている場合
cordova platform add ios
338
以前のリリースからの移行
ハイブリッドアプリケーションを 2.2 から 2.3 に移行す
る
5. アプリケーションで Android をサポートしている場合
cordova platform add android
6. Salesforce Mobile SDK プラグインを追加します。
cordova plugin add https://github.com/forcedotcom/SalesforceMobileSDK-CordovaPlugin
7. Cordova にプラグインがバンドルされなくなりました。アプリケーションが次のプラグインと連動している
場合は、連動関係ごとに cordova plugin add コマンドを実行します。
• org.apache.cordova.battery-status
• org.apache.cordova.camera
• org.apache.cordova.console
• org.apache.cordova.contacts
• org.apache.cordova.device-motion
• org.apache.cordova.device-orientation
• org.apache.cordova.dialogs
• org.apache.cordova.file
• org.apache.cordova.file-transfer
• org.apache.cordova.geolocation
• org.apache.cordova.globalization
• org.apache.cordova.inappbrowser
• org.apache.cordova.media
• org.apache.cordova.media-capture
• org.apache.cordova.network-information
• org.apache.cordova.splashscreen
• org.apache.cordova.statusbar
• org.apache.cordova.vibration
次に例を示します。
cordova plugin add org.apache.cordova.camera
8. アプリケーションの HTML、JavaScript、および CSS Web アセットおよび bootconfig.json ファイルを、新
しいアプリケーションの assets/www/ ディレクトリに移動します。
9. Web アセットをプラットフォーム固有のフォルダにリリースします。
cordova prepare
HTML および JavaScript コードの変更
cordova create MyProject を使用してプロジェクトを作成すると、Cordova に次のディレクトリが作成さ
れます。
• MyProject/www -- アプリケーションの HTML、JavaScript、および CSS コードが格納されます。
• MyProject/platforms -- サブディレクトリにプラットフォーム固有のプロジェクトが格納されます。
339
以前のリリースからの移行
ハイブリッドアプリケーションを 2.2 から 2.3 に移行す
る
• MyProject/plugins -- プラグインが格納されます。
cordova.js、cordova.force.js、その他の Cordova プラグインをアプリケーションの www/ ディレクトリ
に格納しないでください。これらのプラグインは、cordova prepare の実行時にプラットフォーム固有のプ
ロジェクトのディレクトリに自動的に格納されます。アプリケーションの開発作業は www/ ディレクトリで行
います。
アップグレード手順
1. HTML コードの <script> タグに cordova.js を含めます。各種の「cordova-xyz.js」ファイルではなく、標
準の cordova.js を指定してください。
<script src="cordova.js"></script>
2. 実行時に、cordova.require() を使用してインポートするコードが自動的に挿入されます。Cordova ツー
ルが、必須モジュールをファイルに対応付ける cordova_plugins.js ファイルを生成し、必要な <script>
埋め込みタグを挿入します。JavaScript プラグインの実行時の挿入と同期させるには、deviceready イベン
ト通知を受信するまで cordova.require() を実行しないようにします。
3. Salesforce プラグインの命名規則が変更されています。cordova.require() コールを更新して、次の新し
いパスを反映させます。
古い規則
新しい規則
salesforce/util/<util_class>
com.salesforce.util.<util_class>
com.salesforce.plugin.<plugin_name>
com.salesforce.plugin.<plugin_name>
例: 次の表に示すように、古いステートメントを新しいステートメントに置き換えます。
古い構文
新しい構文
cordova.require("salesforce/util/logger")
cordova.require("com.salesforce.util.logger")
cordova.require("salesforce/util/bootstrap")
cordova.require("com.salesforce.util.bootstrap")
cordova.require("salesforce/util/event")
cordova.require("com.salesforce.util.event")
cordova.require("salesforce/util/exec")
cordova.require("com.salesforce.util.exec")
cordova.require("salesforce/util/push")
cordova.require("com.salesforce.util.push")
cordova.require("salesforce/plugin/oauth")
cordova.require("com.salesforce.plugin.oauth")
340
以前のリリースからの移行
Android ネイティブアプリケーションを 2.2 から 2.3 に
移行する
古い構文
新しい構文
cordova.require("salesforce/plugin/smartstore")
cordova.require("com.salesforce.plugin.smartstore")
cordova.require("salesforce/plugin/sdkinfo")
cordova.require("com.salesforce.plugin.sdkinfo")
cordova.require("salesforce/plugin/sfdcaccountmanager")
cordova.require("com.salesforce.plugin.sfdcaccountmanager")
Android ネイティブアプリケーションを 2.2 から 2.3 に移行する
Android ネイティブアプリケーションを Salesforce Mobile SDK 2.2 からバージョン 2.3 にアップグレードするには、
次のタスクを実行します。Mobile SDK 2.3 では、Cordova モジュールがアップグレードされ、SDK から Cordova モ
ジュールへの参照方法が変更されました。Cordova はプロジェクトになり、ネイティブかハイブリッドかに関
係なく、すべての Android プロジェクトに含める必要があります。
1. SalesforceMobileSDK-Android GitHub リポジトリの主分岐から最新バージョンを取り込みます。
2. Eclipse で、Mobile SDK 2.2 プロジェクトワークスペースを開きます。
3. Eclipse で Cordova ライブラリプロジェクトをインポートします。
a. [ファイル] > [インポート] をクリックします。
b. [一般] タブを展開し、[Existing Projects into Workspace (既存のプロジェクトをワークスペースへ)] をクリッ
クし、[次へ] を選択します。
c. SalesforceMobileSDK-Android リポジトリディレクトリをルートとして選択します。
d. [すべて選択解除] をクリックします。
e. Cordova プロジェクトを選択します。
f. [完了] をクリックします。
4. Eclipse で、既存の SalesforceSDK プロジェクトを Mobile SDK 2.3 SalesforceSDK プロジェクトに置き換えます。
5. アプリケーションで SmartStore を使用する場合は、Eclipse で既存の SmartStore プロジェクトを Mobile SDK 2.3
SmartStore プロジェクトに置き換えます。
6. プロジェクトを右クリックし、[プロパティ] を選択します。
7. [Android] を選択します。
8. [ライブラリ] セクションで、既存の SalesforceSDK エントリをワークスペースの Mobile SDK 2.3 SalesforceSDK プロ
ジェクトに置き換えます。
9. アプリケーションで SmartStore を使用する場合は、[ライブラリ] セクションの既存の SmartStore エントリを
ワークスペースの Mobile SDK 2.3 SmartStore プロジェクトに置き換えます。
341
以前のリリースからの移行
iOS ネイティブアプリケーションを 2.2 から 2.3 に移行
する
iOS ネイティブアプリケーションを 2.2 から 2.3 に移行する
iOS ネイティブアプリケーションを Mobile SDK 2.3 に移行するには、Mobile SDK ライブラリパッケージを更新し、
SmartStore を使用している場合はスープを登録するコードを更新します。
ライブラリを更新するための最も簡単な方法は、アプリケーションの Xcode プロジェクトの Dependencies
フォルダ内にあるものをすべて削除してから、新しいライブラリを追加することです。
1. Xcode でプロジェクトを開きます。
2. プロジェクトナビゲータで、Ctrl キーを押しながら Dependencies フォルダをクリックします。
3. [Delete (削除)] を選択してから、[Move to Trash (ゴミ箱に移動)] を選択します。
4. ファインダでプロジェクトフォルダを検索し、Dependencies フォルダがまだ存在する場合は削除しま
す。
5. forcedotcom/SalesforceMobileSDK-iOS-Distribution GitHub リポジトリから次のバイナリパッケージをダウンロード
します。
• MKNetworkKit-iOS-Release.zip
• SalesforceNativeSDK-Release.zip
• SalesforceNetworkSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
• SalesforceSecurity-Release.zip
6. また、配布リポジトリの ThirdParty フォルダリンクから次のフォルダもダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
7. ファインダで、アプリケーションフォルダの下に Dependencies フォルダを再作成します。
8. Dependencies フォルダに、ステップ 2 の新しいパッケージを解凍し、ステップ 3 のフォルダをコピーし
ます。
9. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<App Name>"... (ファイルを「<App Name>」に追加...)] を選択します。
10. Dependencies フォルダを選択し、[Create groups for any added folder (追加されたフォルダのグループを作成す
る)] が選択されていることを確認します。
11. [Add (追加)] をクリックします。
これでライブラリが最新となったので、SmartStore インデックス指定オブジェクトを更新するの説明に従って
SmartStore コードを更新します。
SmartStore インデックス指定オブジェクトを更新する
iOS ネイティブアプリケーションで SmartStore を使用する場合は、スープを登録するときに、インデックス指定
を含むオブジェクトを変更します。Mobile SDK 2.3 より前のバージョンでは、インデックス指定は NSDictionary
342
以前のリリースからの移行
Mobile SDK Android アプリケーションを 2.1 から 2.2 に移
行する
オブジェクトの NSArray で収集されていました。Mobile SDK 2.3 以降 では、registerSoup:withIndexSpecs:
メソッドで SFSoupIndex オブジェクトの配列が必要になります。
例: コードの例については、「スープの登録」または NativeSqlAggregator サンプルアプリケーションを参照
してください。
Mobile SDK Android アプリケーションを 2.1 から 2.2 に移行する
Android アプリケーション (ネイティブまたはハイブリッド) を Salesforce Mobile SDK 2.1 からバージョン 2.2 にアッ
プグレードするには、次のタスクを実行します。
1. Eclipse で、既存の SalesforceSDK プロジェクトを Mobile SDK 2.2 SalesforceSDK プロジェクトに置き換えます。
2. アプリケーションで SmartStore を使用する場合は、Eclipse で既存の SmartStore プロジェクトを Mobile SDK 2.2
SmartStore プロジェクトに置き換えます。
3. プロジェクトを右クリックし、[プロパティ] を選択します。
4. [Android] を選択します。
5. [ライブラリ] セクションで、既存の SalesforceSDK エントリをワークスペースの Mobile SDK 2.2 SalesforceSDK プロ
ジェクトに置き換えます。
6. アプリケーションで SmartStore を使用する場合は、[ライブラリ] セクションの既存の SmartStore エントリを
ワークスペースの Mobile SDK 2.2 SmartStore プロジェクトに置き換えます。
Mobile SDK iOS アプリケーションを 2.1 から 2.2 に移行する
重要: ネイティブアプリケーションとハイブリッドアプリケーションをアップグレードするには、更新さ
れた forceios npm パッケージを使用して新しいアプリケーションを作成し、既存のコードおよびリソース
を新しいアプリケーションに移行することを強くお勧めします。
以下の手動のステップは、既存のアプリケーションで Mobile SDK アイテムを更新する場合にのみ実行してくだ
さい。
iOS ハイブリッドアプリケーション
Mobile SDK ライブラリパッケージを更新する
Mobile SDKライブラリパッケージを簡単にアップグレードするには、アプリケーションの Xcode オブジェクトの
Dependencies フォルダを削除してから、新しいライブラリを追加します。
1. Xcode プロジェクトのプロジェクトナビゲータで、Dependencies フォルダを探します。Ctrl キーを押しな
がらフォルダをクリックし、[Delete (削除)]、[Move to Trash (ゴミ箱に移動)] の順に選択します。
2. 次のバイナリパッケージを配布リポジトリからダウンロードします。
• Cordova/Cordova-Release.zip
• SalesforceHybridSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
343
以前のリリースからの移行
Mobile SDK iOS アプリケーションを 2.1 から 2.2 に移行す
る
• SalesforceSecurity-Release.zip
3. また、次のフォルダも配布リポジトリの ThirdParty フォルダリンクからダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
4. Dependencies フォルダをアプリケーションフォルダの下に再作成します。
5. Dependencies フォルダに、ステップ 2 の新しいパッケージを解凍し、ステップ 3 のフォルダをコピーし
ます。
6. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<app_name>” (「<app_name>」にファイルを追加)] を選択します。
7. Dependencies フォルダを選択し、[Create groups for any added folder (追加されたフォルダのグループを作
成する)] が選択されていることを確認します。
8. [Add (追加)] をクリックします。
SalesforceSecurity ヘッダーファイルの検索パスを追加する
Xcode プロジェクトのヘッダーファイル検索パスを更新します。
1. プロジェクトナビゲータで、プロジェクトを選択します。
2. メインターゲットの [Build Settings (ビルド設定)] タブを選択します。
3. [Header Search Paths (ヘッダー検索パス)] までスクロールダウン (または検索/絞り込み) します。
4. 次の検索パスを追加します。
• $(SRCROOT)/[App Name]/Dependencies/SalesforceSecurity/Headers
ハイブリッドローカルアイテムを更新する
1. ハイブリッドローカルアプリケーションの場合は、アプリケーションの www/ フォルダにある次のファイ
ルを、SalesforceMobileSDK-Shared repo の libs フォルダにある新バージョンのファイルに置き換えます。
• cordova.force.js
• forcetk.mobilesdk.js
• smartsync.js
AppDelegate 実装を更新する
ログアウトイベントおよびログインホストの変更イベントの処理パターンと共に、一部のユーザ管理 API が変
更されました。変更を確認する場合、2.2 バージョンの forceios ハイブリッドアプリケーションから AppDelegate
コードを参照することをお勧めします。次に、変更内容の概要を示します。
• ログアウトイベントの通知とログインホストの変更が代理メソッドに移行しました。
SFAuthenticationManagerDelegate および SFUserAccountManagerDelegate 代理メソッドを実装す
るように AppDelegate クラスを更新します。
344
以前のリリースからの移行
Mobile SDK iOS アプリケーションを 2.1 から 2.2 に移行す
る
– ユーザログアウトの通知の場合、[SFAuthenticationManagerDelegate authManagerDidLogout:]
を使用します。
– ログインホストの変更の場合、[SFUserAccountManagerDelegate
userAccountManager:didSwitchFromUser:toUser:] を使用します。
メモ: [設定] でログインホストを変更すると、実質的にアプリケーションで新しいユーザへの切り
替えが行われ、ログインが要求されます。
iOS ネイティブアプリケーション
Mobile SDK ライブラリパッケージを更新する
Mobile SDKライブラリパッケージを簡単にアップグレードするには、アプリケーションの Xcode オブジェクトの
Dependencies フォルダを削除してから、新しいライブラリを追加します。
1. Xcode プロジェクトのプロジェクトナビゲータで、Dependencies フォルダを探します。Ctrl キーを押しな
がらフォルダをクリックし、[Delete (削除)]、[Move to Trash (ゴミ箱に移動)] の順に選択します。
2. 次のバイナリパッケージを配布リポジトリからダウンロードします。
• MKNetworkKit-iOS-Release.zip
• SalesforceNetworkSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
• SalesforceSecurity-Release.zip
3. また、次のフォルダも配布リポジトリの ThirdParty フォルダリンクからダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
4. Dependencies フォルダをアプリケーションフォルダの下に再作成します。
5. Dependencies フォルダに、ステップ 2 の新しいパッケージを解凍し、ステップ 3 のフォルダをコピーし
ます。
6. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<app_name>” (「<app_name>」にファイルを追加)] を選択します。
7. Dependencies フォルダを選択し、[Create groups for any added folder (追加されたフォルダのグループを作
成する)] が選択されていることを確認します。
8. [Add (追加)] をクリックします。
SalesforceSecurity ヘッダーファイルの検索パスを追加する
SalesforceSecurity プロジェクトを検索できるようにヘッダーファイル検索パスを更新します。
1. プロジェクトナビゲータで、プロジェクトを選択します。
345
以前のリリースからの移行
Mobile SDK iOS アプリケーションを 2.1 から 2.2 に移行す
る
2. メインターゲットの [Build Settings (ビルド設定)] タブを選択します。
3. [Header Search Paths (ヘッダー検索パス)] までスクロールダウン (または検索/絞り込み) します。
4. 次の検索パスを追加します。
• $(SRCROOT)/[App Name]/Dependencies/SalesforceSecurity/Headers
パスコード関連のコードを新しい SalesforceSecurity クラスに移行する
SalesforceSecurity は、2.2 の新しいライブラリです。多くのセキュリティ関連のクラス (特にパスコード
管理関連のクラス) が SalesforceSDKCore から SalesforceSecurity に移行しました。SalesforceSDKCore
のパスコード関連の機能をコードで参照している場合、SalesforceSecurity の対応する適切な機能を使用
するようにそのコードを更新してください。
AppDelegate 実装を更新する
ログアウトイベントおよびログインホストの変更イベントの処理パターンと共に、一部のユーザ管理 API が変
更されました。変更を確認する場合、2.2 バージョンの forceios ネイティブアプリケーションから AppDelegate
コードを参照することをお勧めします。次に、変更内容の概要を示します。
• SFAccountManager の代わりに SFUserAccountManager を使用して、接続アプリケーション設定を指定
します。次の表に、使用されなくなったコードとそれに置き換わるコードを示します。
置換前...
...置換後
[SFAccountManager setClientId:]
[SFUserAccountManager
sharedInstance].oauthClientId
[SFAccountManager setRedirectUri:]
[SFUserAccountManager
sharedInstance].oauthCompletionUrl
[SFAccountManager setScopes:]
[SFUserAccountManager
sharedInstance].scopes
• ログアウトイベントの通知とログインホストの変更が代理メソッドに移行しました。
SFAuthenticationManagerDelegate および SFUserAccountManagerDelegate 代理メソッドを実装す
るように AppDelegate クラスを更新します。
– ユーザログアウトの通知の場合、[SFAuthenticationManagerDelegate authManagerDidLogout:]
を使用します。
– ログインホストの変更の場合、[SFUserAccountManagerDelegate
userAccountManager:didSwitchFromUser:toUser:] を使用します。
メモ: [設定] でログインホストを変更すると、実質的にアプリケーションで新しいユーザへの切り
替えが行われ、ログインが要求されます。
346
以前のリリースからの移行
バージョン 2.0 からバージョン 2.1 への移行
バージョン 2.0 からバージョン 2.1 への移行
Salesforce Mobile SDK 2.0 を使用してコードを開発した場合は、次の手順に従ってアプリケーションをバージョン
2.1 に更新します。
Mobile SDK Android アプリケーションを 2.0 から 2.1 に移行する
Android アプリケーション (ネイティブまたはハイブリッド) を Salesforce Mobile SDK 2.0 からバージョン 2.1 にアッ
プグレードするには、次のタスクを実行します。
1. Eclipse で、既存の SalesforceSDK プロジェクトを Mobile SDK 2.1 SalesforceSDK プロジェクトに置き換えます。
2. アプリケーションで SmartStore を使用する場合は、Eclipse で既存の SmartStore プロジェクトを Mobile SDK 2.1
SmartStore プロジェクトに置き換えます。
3. プロジェクトを右クリックし、[プロパティ] を選択します。
4. [Android] を選択します。
5. ワークスペースで、ライブラリプロジェクトセクションにある既存の SalesforceSDK エントリを新しい
SalesforceSDK プロジェクトに置き換えます。
6. アプリケーションでSmartStoreを使用する場合は、ワークスペースで、ライブラリプロジェクトセクション
にある既存の SmartStore エントリを新しい SmartStore プロジェクトに置き換えます。
Salesforce Mobile SDK の Activity および Service 宣言は、アプリケーションの AndroidManifest.xml ファイル
から SalesforceSDK プロジェクトの AndroidManifest.xml ファイルに移動済みです。manifestmerger 属
性を有効にすると、この設定がアプリケーションのマニフェストファイルに自動的にマージされます。
7. 次のコードをアプリケーションの project.properties ファイルに追加します。
manifestmerger.enabled=true
メモ: このステップは、転送通知などの一部の新しい Mobile SDK 2.1 機能を使用するために実行する必
要があります。
Mobile SDK iOS アプリケーションを 2.0 から 2.1 に移行する
ネイティブアプリケーションとハイブリッドアプリケーションをアップグレードするには、forceios npm パッ
ケージのアプリケーションテンプレートから新しいアプリケーションを作成し、アプリケーション固有のアイ
テムを新しいテンプレートに追加することを強くお勧めします。
以下の手動のステップは、既存のアプリケーションで Mobile SDK アイテムを更新する場合にのみ実行してくだ
さい。
iOS ハイブリッドアプリケーション
Mobile SDK ライブラリパッケージを更新する
Mobile SDKライブラリパッケージを簡単にアップグレードするには、アプリケーションの Xcode オブジェクトの
Dependencies フォルダを削除してから、新しいライブラリを追加します。
347
以前のリリースからの移行
バージョン 2.0 からバージョン 2.1 への移行
1. Xcode プロジェクトのプロジェクトナビゲータで、Dependencies フォルダを探します。Ctrl キーを押しな
がらフォルダをクリックし、[Delete (削除)]、[Move to Trash (ゴミ箱に移動)] の順に選択します。
2. 次のバイナリパッケージを配布リポジトリからダウンロードします。
• Cordova/Cordova-Release.zip
• SalesforceHybridSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
3. また、次のフォルダも配布リポジトリの ThirdParty フォルダリンクからダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
4. Dependencies フォルダをアプリケーションフォルダの下に再作成します。
5. Dependencies フォルダに、ステップ 2 の新しいパッケージを解凍し、ステップ 3 のフォルダをコピーし
ます。
6. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<app_name>” (「<app_name>」にファイルを追加)] を選択します。
7. Dependencies フォルダを選択し、[Create groups for any added folder (追加されたフォルダのグループを作
成する)] が選択されていることを確認します。
8. [Add (追加)] をクリックします。
ヘッダーファイルの検索パスを更新する
Xcode プロジェクトのヘッダーファイル検索パスを更新します。
1. プロジェクトナビゲータで、プロジェクトを選択します。
2. メインターゲットの [Build Settings (ビルド設定)] タブを選択します。
3. [Header Search Paths (ヘッダー検索パス)] までスクロールダウン (または検索/絞り込み) します。
4. 次の検索パスを追加します。
• $(SRCROOT)/[App Name]/Dependencies/SalesforceSDKCore/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceOAuth/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceCommonUtils/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceHybridSDK/Headers
ハイブリッドローカルアイテムを更新する
1. ハイブリッドローカルアプリケーションの場合は、アプリケーションの www/ フォルダにある次のファイ
ルを、SalesforceMobileSDK-Shared repo の libs フォルダにある新バージョンのファイルに置き換えます。
• cordova.force.js
• forcetk.mobilesdk.js
• smartsync.js
348
以前のリリースからの移行
バージョン 2.0 からバージョン 2.1 への移行
iOS ネイティブアプリケーション
Mobile SDK ライブラリパッケージを更新する
Mobile SDKライブラリパッケージを簡単にアップグレードするには、アプリケーションの Xcode オブジェクトの
Dependencies フォルダを削除してから、新しいライブラリを追加します。
1. Xcode プロジェクトのプロジェクトナビゲータで、Dependencies フォルダを探します。Ctrl キーを押しな
がらフォルダをクリックし、[Delete (削除)]、[Move to Trash (ゴミ箱に移動)] の順に選択します。
2. 次のバイナリパッケージを配布リポジトリからダウンロードします。
• Cordova/Cordova-Release.zip
• SalesforceHybridSDK-Release.zip
• SalesforceNetworkSDK-Release.zip
• SalesforceOAuth-Release.zip
• SalesforceSDKCore-Release.zip
3. また、次のフォルダも配布リポジトリの ThirdParty フォルダリンクからダウンロードします。
• SalesforceCommonUtils
• openssl
• sqlcipher
4. Dependencies フォルダをアプリケーションフォルダの下に再作成します。
5. Dependencies フォルダに、ステップ 2 の新しいパッケージを解凍し、ステップ 3 のフォルダをコピーし
ます。
6. プロジェクトナビゲータで、Ctrl キーを押しながらアプリケーションフォルダをクリックし、[Add Files to
"<app_name>” (「<app_name>」にファイルを追加)] を選択します。
7. Dependencies フォルダを選択し、[Create groups for any added folder (追加されたフォルダのグループを作
成する)] が選択されていることを確認します。
8. [Add (追加)] をクリックします。
ヘッダーファイルの検索パスを更新する
Xcode プロジェクトのヘッダーファイル検索パスを更新します。
1. プロジェクトナビゲータで、プロジェクトを選択します。
2. メインターゲットの [Build Settings (ビルド設定)] タブを選択します。
3. [Header Search Paths (ヘッダー検索パス)] までスクロールダウン (または検索/絞り込み) します。
4. 次の検索パスを追加します。
• $(SRCROOT)/[App Name]/Dependencies/SalesforceSDKCore/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceOAuth/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceNetworkSDK/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceCommonUtils/Headers
• $(SRCROOT)/[App Name]/Dependencies/SalesforceHybridSDK/Headers
349
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
ネイティブ Mobile SDK ライブラリの変更
バージョン 2.1 では、Mobile SDK の RestKit が、ネイティブアプリケーションのネットワークライブラリとして
MKNetworkKit に置き換えられました。MKNetworkKit は新しい SalesforceNetworkSDK ライブラリでラップされており、
このライブラリは SFRestAPI クラスおよびそのサポートクラスでラップされています。ほとんどのインター
フェースに変更はありません。重要な変更のリストを次に示します。
• [SFRestAPI sharedInstance].rkClient は存在しなくなりました。
• [SFRestAPI send:delegate:] で、要求に関連付けられた新しい SFNetworkOperation が返されるよ
うになりました。
• SFRestRequest.networkOperation では、要求に関連付けられた基盤の SFNetworkOperation オブ
ジェクトがポイントされます。
アプリケーションでネットワーク用に基盤の RestKit メンバーを使用していた場合は、MKNetworkKit ライブラリ
と SalesforceNetworkSDK ライブラリの同等の機能を確認する必要があります。
バージョン 1.5 からバージョン 2.0 への移行
Salesforce Mobile SDK 1.5 を使用してコードを開発した場合は、次の手順に従ってアプリケーションをバージョン
2.0 に更新します。
Mobile SDK Android アプリケーションを 1.5 から 2.0 に移行する
Android アプリケーションを Salesforce Mobile SDK 1.5.3 からバージョン 2.0.0 にアップグレードするには、次のタス
クを実行します。
ネイティブ Android アプリケーションのアップグレード
• アプリケーションの Eclipse ワークスペースで、既存の SalesforceSDK プロジェクトを 2.0 SalesforceSDK プロジェ
クトに置き換えます。アプリケーションで SmartStore を使用する場合は、Eclipse で既存の SmartStore プロジェ
クトを 2.0 SmartStore プロジェクトに置き換えます。
1. プロジェクトを右クリックし、[プロパティ] を選択します。
2. Android タブをクリックし、ワークスペースで一番下 (ライブラリプロジェクトセクション) にある既
存の SalesforceSDK エントリを新しい SalesforceSDK プロジェクトに置き換えます。アプリケーションで
SmartStore を使用する場合は、SmartStore プロジェクトでこの手順を繰り返します。
• ForceApp または ForceAppWithSmartStore を拡張するクラスを、Application を拡張するように変更
します。このクラス SampleApp は、残りの手順でコールします。
• KeyInterface を実装する新しいクラスを作成します。そのクラスに KeyImpl という名前 (または任意の
別の名前) を付けます。getKey() の実装を SampleApp から KeyImpl に移動します。
• ForceApp を SalesforceSDKManager という名前に変更し、ForceAppWithSmartStore を
SalesforceSDKManagerWithSmartStore という名前に変更しました。
– ForceApp のすべてのインスタンスを SalesforceSDKManager に置き換えます。
– ForceAppWithSmartStore のすべてのインスタンスを SalesforceSDKManagerWithSmartStore に
置き換えます。
350
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
– この変更が反映されるようにアプリケーションのクラスのインポートを更新します。
– ForceApp.APP のすべてのインスタンスを SalesforceSDKManager.getInstance() に置き換えま
す。
– ForceAppWithSmartStore.APP のすべてのインスタンスを
SalesforceSDKManagerWithSmartStore.getInstance() に置き換えます。
• SampleApp の onCreate() メソッドに、次のコードを追加します。
SalesforceSDKManager.initNative(getApplicationContext(), new KeyImpl(),
<mainActivityClass>.class);
<mainActivityClass> は、ログインフローの完了時に起動するクラスです。
メモ:
– アプリケーションで独自のログインアクティビティを指定する場合は、それを追加の引数として
initNative() メソッドコールに渡すことができます。
– アプリケーションで SmartStore を使用する場合は、SalesforceSDKManager の代わりに
SalesforceSDKManagerWithSmartStore で initNative() をコールします。
• ForceApp の上書きされたメソッド (getKey()、getMainActivityClass()、その他の上書きされたメ
ソッドなど) を SampleApp から削除します。
• LoginOptions オブジェクトを作成する必要はなくなりました。Salesforce Mobile SDK によって、これらのオ
プションが XML ファイル bootconfig.xml から自動的に読み取られます。このファイルはプロジェクトの
res/values フォルダにあります。
– プロジェクトの res/values フォルダに、bootconfig.xml というファイルを作成します。アプリケー
ションのログインオプション設定を、コードから bootconfig.xml に移動します。例については、
SalesforceSDK プロジェクトまたはいずれかのサンプルネイティブアプリケーションにある
res/values/bootconfig.xml を参照してください。
• NativeMainActivity は SalesforceActivity という名前に変更され、
com.salesforce.androidsdk.ui.sfnative という名前の新しいパッケージに移動されました。
– アプリケーションのいずれかのクラスで NativeMainActivity を拡張する場合は、
NativeMainActivity へのすべての参照を SalesforceActivity に置き換えます。
– この変更が反映されるようにアプリケーションのクラスのインポートを更新します。
• SmartStore を com.salesforce.androidsdk.smartstore という名前の新しいパッケージに移動しまし
た。アプリケーションで SmartStore プロジェクトを使用する場合は、この変更が反映されるようにアプリ
ケーションのクラスのインポートと他のコード参照を更新します。
ハイブリッド Android アプリケーションのアップグレード
• アプリケーションの Eclipse ワークスペースで、既存の SalesforceSDK プロジェクトを 2.0 SalesforceSDK プロジェ
クトに置き換えます。アプリケーションで SmartStore を使用する場合は、Eclipse で既存の SmartStore プロジェ
クトを 2.0 SmartStore プロジェクトに置き換えます。
1. プロジェクトを右クリックし、[プロパティ] を選択します。
351
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
2. Android タブをクリックし、ワークスペースで一番下 (ライブラリプロジェクトセクション) にある既
存の SalesforceSDK エントリを新しい SalesforceSDK プロジェクトに置き換えます。アプリケーションで
SmartStore を使用する場合は、SmartStore プロジェクトでこの手順を繰り返します。
• ForceApp または ForceAppWithSmartStore を拡張するクラスを、Application を拡張するように変更
します。このクラス SampleApp は、残りの手順でコールします。
• KeyInterface を実装する新しいクラスを作成します。そのクラスに KeyImpl という名前 (または任意の
別の名前) を付けます。getKey() の実装を SampleApp から KeyImpl に移動します。
• ForceApp を SalesforceSDKManager という名前に変更し、ForceAppWithSmartStore を
SalesforceSDKManagerWithSmartStore という名前に変更しました。
– ForceApp のすべてのインスタンスを SalesforceSDKManager に置き換えます。
– ForceAppWithSmartStore のすべてのインスタンスを SalesforceSDKManagerWithSmartStore に
置き換えます。
– この変更が反映されるようにアプリケーションのクラスのインポートを更新します。
– ForceApp.APP のすべてのインスタンスを SalesforceSDKManager.getInstance() に置き換えま
す。
– ForceAppWithSmartStore.APP のすべてのインスタンスを
SalesforceSDKManagerWithSmartStore.getInstance() に置き換えます。
• SampleApp の onCreate() メソッドに、次のコードを追加します。
SalesforceSDKManager.initHybrid(getApplicationContext(), new KeyImpl());
メモ:
– アプリケーションで独自のログインアクティビティを指定する場合は、それを追加の引数として
initHybrid() メソッドコールに渡すことができます。
– アプリケーションで SmartStore を使用する場合は、SalesforceSDKManager の代わりに
SalesforceSDKManagerWithSmartStore で initHybrid() をコールします。
• ForceApp の上書きされたメソッド (getKey()、getMainActivityClass()、その他の上書きされたメ
ソッドなど) を SampleApp から削除します。
• LoginOptions オブジェクトを作成する必要はなくなりました。Salesforce Mobile SDK によって、これらのオ
プションが XML ファイル bootconfig.xml から自動的に読み取られます。このファイルはプロジェクトの
res/values フォルダにあります。
– プロジェクトの res/values フォルダに、bootconfig.xml というファイルを作成します。アプリケー
ションのログインオプション設定を、コードから bootconfig.xml に移動します。例については、
SalesforceSDK プロジェクトまたはいずれかのサンプルネイティブアプリケーションにある
res/values/bootconfig.xml を参照してください。
• NativeMainActivity は SalesforceActivity という名前に変更され、
com.salesforce.androidsdk.ui.sfnative という名前の新しいパッケージに移動されました。
– アプリケーションのいずれかのクラスで NativeMainActivity を拡張する場合は、
NativeMainActivity へのすべての参照を SalesforceActivity に置き換えます。
– この変更が反映されるようにアプリケーションのクラスのインポートを更新します。
352
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
• SmartStore を com.salesforce.androidsdk.smartstore という名前の新しいパッケージに移動しまし
た。アプリケーションで SmartStore プロジェクトを使用する場合は、この変更が反映されるようにアプリ
ケーションのクラスのインポートと他のコード参照を更新します。
• bootconfig.js を bootconfig.json で置き換えました。既存の bootconfig.js を新しい
bootconfig.json 形式に変換します。例については、「ハイブリッドサンプルアプリケーション」を参
照してください。
• SalesforceSDK Cordova プラグイン (SFHybridApp.js、cordova.force.js、および
SalesforceOAuthPlugin.js) は、filecordova.force.js という名前の 1 つのファイルに結合されま
した。
– これらの Cordova プラグインファイルを cordova.force.js に置き換えます。
– SFHybridApp.js、cordova.force.js、および SalesforceOAuthPlugin.js へのすべての参照を
cordova.force.js に置き換えます。
• forcetk.js は forcetk.mobilesdk.js という名前に変更されました。forcetk.js の既存のコピーを
最新バージョンの forcetk.mobilesdk.js に置き換えます。forcetk.js へのすべての参照を新しい名
前に更新します。
• bootstrap.html ファイルは不要になったため、安全に削除できます。
• SalesforceDroidGapActivity および SalesforceGapViewClient を、
com.salesforce.androidsdk.ui.sfhybrid という名前の新しいパッケージに移動しました。アプリ
ケーションでこれらのクラスを参照する場合は、その参照および関連するクラスのインポートを更新しま
す。
Mobile SDK iOS アプリケーションを 1.5 から 2.0 に移行する
iOS アプリケーションを Salesforce Mobile SDK 1.5 からバージョン 2.0 にアップグレードするには、次のタスクを実
行します。
ネイティブ iOS アプリケーションのアップグレード
すべてのアップグレードの場合と同様に、既存のアプリケーションをアップグレードするには 2 通りの方法が
あります。
• アプリケーション種別 (ネイティブ、ハイブリッド) の Mobile SDK 2.0 テンプレートアプリケーションを使用
して新しいプロジェクトを作成し、既存のコードおよびアイテムを新しいアプリケーションに移動する。
• Mobile SDK 2.0 アイテムを既存のアプリケーションに組み込む。
バージョン 2.0 の場合は、最初の方法を使用することを強くお勧めします。2 番目の方法を使用する場合でも、
サンプルアプリケーションを作成することで、AppDelegate クラスでワークフローの変更を確認できるとい
う利点があります。ネイティブとハイブリッドの両方で、親アプリケーションの代理クラス
(SFNativeRestAppDelegate および SFContainerAppDelegate) がサポートされなくなりました。アプリ
ケーションの AppDelegate クラスで、起動プロセスが統制されるようになりました。
• 置き換えられた SalesforceHybridSDK.framework を削除します。
• Mobile SDK ライブラリとリソースの連動関係を SalesforceMobileSDK-iOS-Package repo から更新します。
– SalesforceSDK を削除します。
353
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
– SalesforceNativeSDK (Dependencies/ フォルダにある) を追加します。
– SalesforceSDKCore (Dependencies/ フォルダにある) を追加します。
– SalesforceOAuth (Dependencies/ フォルダにある) を更新します。
– SalesforceSDKResources.bundle (Dependencies/ フォルダにある) を更新します。
– RestKit (Dependencies/ThirdParty/RestKit/ フォルダにある) を更新します。
– SalesforceCommonUtils (Dependencies/ThirdParty/SalesforceCommonUtils フォルダにある)
を更新します。
– openssl (Dependencies/ThirdParty/openssl フォルダにある libcrypto.a と libssl.a) を更新し
ます。
– sqlcipher (Dependencies/ThirdParty/sqlcipher フォルダにある) を更新します。
• AppDelegate クラスを更新します。AppDelegate.h および AppDelegate.m ファイルを新しい設計パ
ターンに適合します。次の重要なポイントを参考にしてください。
– AppDelegate.h では、AppDelegate を SFNativeRestAppDelegate から継承しないようにする必要
があります。
– AppDelegate.m では、認証フローとルートビューコントローラのステージングの移動を AppDelegate
で主に行うようになりました。また、ユーザがログアウトしたりログインホストを切り替えたりすると
きの境界イベントも処理します。
メモ: 新しい AppDelegate の設計パターンはあくまでも目安です。Mobile SDK に、特定のフローは
不要になりました。アプリケーションの起動および境界使用例に関して、ニーズに合った認証フ
ロー (更新された単一の SFAuthenticationManager を使用) を使用します。
– 認証を使用する場合の唯一の前提条件は、SFAccountManager 構成設定が [AppDelegate init] の
一番上にあるということです。これらの設定が、接続アプリケーションで指定されたものと一致してい
ることを確認します。また、[SFAuthenticationManager loginWithCompletion:failure:] に初
めてコールする前に、この設定が完了していることも確認します。
ハイブリッド iOS アプリケーションのアップグレード
Mobile SDK 2.0 では、ブートストラップ時のハイブリッド設定はネイティブコードに移動されます。
SFHybridViewController で、新しい設定を確認してください (この変更を、ハイブリッドテンプレートア
プリケーションの AppDelegate で確認することもできます)。
新しいアプリケーションテンプレートが、forceios NPM パッケージで使用できるようになりました。テンプレー
トをインストールするには、まず node.js をインストールします。テンプレートのインストールおよびそれを使
用したアプリケーションの作成についての詳細は、npmjs.org の forceios README を参照してください。
以前のコンテンツを 2.0 アプリケーションシェルにエクスポートしない場合でも、新しいハイブリッドアプリ
ケーションをテンプレートから作成して進めることをお勧めします。
• SalesforceHybridSDK.framework を削除します。このプロジェクトは置き換え済みです。
• Mobile SDK ライブラリとリソースの連動関係を SalesforceMobileSDK-iOS-Package repo から更新します。Mobile SDK
1.5 アプリケーションに、次のモジュールが新しく追加されました。
– SalesforceHybridSDK (Dependencies/ フォルダにある)
354
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
– SalesforceOAuth (Dependencies/ フォルダにある)
– SalesforceSDKCore (Dependencies/ フォルダにある)
– SalesforceSDKResources.bundle (Dependencies/ フォルダにある)
– Cordova (Dependencies/Cordova/ フォルダにある)
– SalesforceCommonUtils (Dependencies/ThirdParty/SalesforceCommonUtils フォルダにある)
– openssl (Dependencies/ThirdParty/openssl フォルダにある libcrypto.a と libssl.a)
– sqlcipher (Dependencies/ThirdParty/sqlcipher フォルダにある)
– libxml2.dylib (システムライブラリ)
• アプリケーションの www/ フォルダで、ハイブリッドの連動関係を更新します。
メモ: Visualforce アプリケーションを更新する場合は、bootconfig.js の変更のみが必要です。ハイ
ブリッドアプリケーションでは、他のファイルは使用しません。
– bootconfig.js 設定を新しい bootconfig.json 形式に移行します。
– SalesforceOAuthPlugin.js、SFHybridApp.js、cordova.force.js、および forcetk.js を削除
します。
– SFTestRunnerPlugin.js、qunit.css、および qunit.js は、使用していなければ削除できます。
– cordova.force.js (HybridShared/libs/ フォルダにある) を追加します。
– ForceTK を使用している場合は、forcetk.mobilesdk.js (HybridShared/libs/ フォルダにある) を追
加します。
– jQuery を使用している場合は、jQuery (HybridShared/external/ フォルダにある) を更新します。
– smartsync.js (HybridShared/libs/ フォルダにある) を追加します。
– backbone-1.0.0.min.js と underscore-1.4.4.min.js (HybridShared/external/backbone/
フォルダにある) を追加します。
– jQuery (HybridShared/external/jquery/ フォルダにある) をまだ追加していない場合は、追加しま
す。
– 新しい SmartSync Data Framework を使用するには、次の操作を実行します。
• smartsync.js (HybridShared/libs/ フォルダにある) を追加します。
• backbone-1.0.0.min.js と underscore-1.4.4.min.js (HybridShared/external/backbone/
フォルダにある) を追加します。
• jQuery ( HybridShared/external/jquery/ フォルダにある) をまだ追加していない場合は、追加し
ます。
• AppDelegate を更新して、AppDelegate.h および AppDelegate.m ファイルを新しい設計パターンに適
合します。AppDelegate クラスに変更を一切加えていない場合は、新しいテンプレートアプリケーション
の AppDelegate.h および AppDelegate.m ファイルを古いファイルにコピーするだけで十分です。次の
重要なポイントを参考にしてください。
– AppDelegate.h でのインストール手順は、次のとおりです。
• AppDelegate は SFContainerAppDelegate を継承しなくなりました。
• SFHybridViewController には新しい viewController プロパティがあります。
355
以前のリリースからの移行
バージョン 1.5 からバージョン 2.0 への移行
– AppDelegate.m では、ブートストラップと認証フローの移動を AppDelegate で主に行うことが前提
となりました。これには、ユーザがログアウトしたりログインホストを切り替えたりするときの境界イ
ベントの処理も含まれます。
356
第 13 章
リファレンス
トピック:
リファレンスドキュメントは、GitHub で提供されています。
•
REST API リソース
•
iOS アーキテクチャ
• iOS: http://forcedotcom.github.com/SalesforceMobileSDK-iOS/
Documentation/SalesforceSDK/index.html
•
Android アーキテク
チャ
•
Files API リファレン
ス
•
forceios パラメータ
•
forcedroid パラメー
タ
• Android: http://forcedotcom.github.com/SalesforceMobileSDK-Android/index.html
357
リファレンス
REST API リソース
REST API リソース
Salesforce Mobile SDK を使用すると、ラッパーを作成することによって REST API の使用が簡略化されます。メソッ
ドをコールし、正しいパラメータを指定するだけで十分です。残りの処理は自動的に行われます。次の表に、
使用可能なリソースとその用途を示します。詳細は、Force.comのREST APIリソースページを参照してください。
リソー
ス名
URI
説明
Versions
/
バージョン、表示ラベル、および各バージョ
ンのルートへのリンクなど、現在使用可能な
各 Salesforce バージョンの概要情報をリストし
ます。
Resources /vXX.X/
by Version
リソース名および URI を含む、指定された API
バージョンで使用可能なリソースをリストし
ます。
Describe
Global
/vXX.X/sobjects/
組織のデータで使用可能なオブジェクトとそ
のメタデータをリストします。
sObject
/vXX.X/sobjects/SObject/
Basic
Information
指定されたオブジェクトの個別のメタデータ
を説明します。特定のオブジェクトの新規レ
コードの作成にも使用できます。
SObject
Describe
/vXX.X/sobjects/SObject/describe/
指定されたオブジェクトのすべてのレベル
で、個別のメタデータを完全に説明します。
sObject
Rows
/vXX.X/sobjects/SObject/id/
指定されたオブジェクト ID に基づいてレコー
ドにアクセスします。レコードを取得、更
新、または削除します。このリソースは、項
目値の取得にも使用できます。
sObject
Rows by
External
ID
/vXX.X/sobjects/SObjectName/fieldName/fieldValue 指定された外部 ID 項目の値に基づいて、新し
いレコードを作成するか、既存のレコードを
更新 (レコードを Upsert) します。
sObject
ユーザパスワードを設定またはリセットした
/vXX.X/sobjects/User/ユーザ ID/password
User
り、ユーザパスワードに関する情報を取得し
Password /vXX.X/sobjects/SelfServiceUser/セルフサー たりします。
ビスユーザ ID/password
Query
/vXX.X/query/?q=soql
指定された SOQL クエリを実行します。
Search
/vXX.X/search/?s=sosl
指定されたSOSL検索を実行します。検索文字
列は URL 符号化されている必要があります。
358
リファレンス
iOS アーキテクチャ
リソー
ス名
URI
説明
Search
Result
Layouts
/vXX.X/search/layout/?q=カンマ区切りのオブ
クエリ文字列に含まれるオブジェクトの検索
結果レイアウトに関する情報を返します。こ
のコールでは、検索結果ページに列として表
示される項目のリスト、最初のページに表示
される行数、および検索結果ページで使用さ
れるラベルがオブジェクトごとに返されま
す。
ジェクトリスト
Search
/vXX.X/search/scopeOrder
Scope
and Order
ログインユーザのデフォルトのグローバル検
索範囲内にあるオブジェクトの順序付きリス
トを返します。グローバル検索は、操作する
オブジェクトとそれらを操作する頻度を追跡
し、それに基づいて検索結果を編成します。
最もよく使用されるオブジェクトは、リスト
の最上部に表示されます。
iOS アーキテクチャ
ネイティブ SDK がコンシューマに提供する現在の機能の概要は、次のとおりです。
• OAuth 認証機能
• REST API 通信機能
• SmartStore によるアプリケーションデータの安全な保存と取得
メモ: SmartStore は現在、ネイティブテンプレートアプリケーションには公開されていませんが、バイ
ナリ配布には含まれています。
Salesforce ネイティブ SDK は基本的に 1 つのライブラリで、次のライブラリと連動関係があり、公開されていま
す。
• libSalesforceNetworkSDK.a — REST API コールを容易にするための基礎となるライブラリ。このライブ
ラリには、Mobile SDK GitHub リポジトリから使用できるサードパーティライブラリが必要です。「iOS プロ
ジェクトの設定」を参照してください。
• libSalesforceOAuth.a — OAuth 認証を管理するための基礎となるライブラリ。
• libsqlite3.dylib — SQLite 機能へのアクセスを提供するライブラリ。これも、標準 iOS 開発環境の一部
です。
• fmdb — SQLite に対する Objective—C ラッパー。
メモ: このラッパーは現在、ネイティブテンプレートアプリケーションには公開されていませんが、
バイナリ配布には含まれています。
359
リファレンス
ネイティブ iOS オブジェクト
ネイティブ iOS オブジェクト
次のオブジェクトを使用して、ネイティブアプリケーションで Salesforce データにアクセスします。
• SFRestAPI
• SFRestAPI (Blocks)
• SFRestRequest
• SFRestAPI (QueryBuilder)
SFRestAPI
SFRestAPI は、REST 要求を行うためのエントリポイントであり、通常、[SFRestAPI sharedInstance] を
介してシングルトンインスタンスとしてアクセスされます。
このオブジェクトから、次のような既定の多くの標準クエリを簡単に作成できます。
SFRestRequest* request = [[SFRestAPI sharedInstance]
requestForUpdateWithObjectType:@"Contact"
objectId:contactId
fields:updatedFields];
次のコマンドを使用して、要求を開始できます。
[[SFRestAPI sharedInstance] send:request delegate:self];
SFRestAPI (ブロック)
SFRestAPI クラスのこのカテゴリ拡張を使用して、ブロックをコールバックメカニズムとして指定します。
次に例を示します。
NSMutableDictionary *fields = [NSMutableDictionary dictionaryWithObjectsAndKeys:
@"John", @"FirstName",
@"Doe", @"LastName",
nil];
[[SFRestAPI sharedInstance] performCreateWithObjectType:@"Contact"
fields:fields
failBlock:^(NSError *e) {
NSLog(@"Error: %@", e);
}
completeBlock:^(NSDictionary *d) {
NSLog(@"ID value for object: %@", [d objectForKey:@"id"]);
}];
SFRestRequest
SFRestAPI で提供される標準 REST 要求だけでなく、直接 SFRestRequest メソッドを使用して独自の要求を
作成することもできます。
NSString *path = @"/v31.0";
SFRestRequest* request = [SFRestRequest requestWithMethod:SFRestMethodGET path:path
queryParams:nil];
360
リファレンス
Android アーキテクチャ
SFRestAPI (QueryBuilder)
このカテゴリ拡張には、SOQL および SOSL のクエリ文字列を作成するためのユーティリティメソッドが備えら
れています。例:
NSString *soqlQuery =
[SFRestAPI SOQLQueryWithFields:[NSArray arrayWithObjects:@"Id", @"Name", @"Company",
@"Status", nil]
sObject:@"Lead"
where:nil
limit:10];
NSString *soslQuery =
[SFRestAPI SOSLSearchWithSearchTerm:@"all of these will be escaped:~{]"
objectScope:[NSDictionary dictionaryWithObject:@"WHERE isactive=true ORDER BY
lastname
asc limit 5"
forKey:@"User"]];
Android アーキテクチャ
SalesforceSDK は、ライブラリプロジェクトとして提供されています。アプリケーションプロジェクトから
SalesforceSDK プロジェクトを参照する必要があります。Android の開発者向けドキュメントを参照してください。
Android パッケージおよびクラス
Android Mobile SDK の Java ソースファイルは、libs/SalesforceSDK/src にあります。
パッケージカタログ
パッケージ名
説明
com.salesforce.androidsdk.accounts ユーザアカウントを管理するためのクラス
com.salesforce.androidsdk.app すべての Mobile SDK アプリケーションのエントリポイントクラスであ
る SalesforceSDKManager が含まれています。このパッケージに
は、内部で使用するアプリケーションユーティリティクラスもありま
す。
com.salesforce.androidsdk.auth 内部的にのみ使用されます。ログイン、OAuth 認証、HTTP アクセスを
処理します。
com.salesforce.androidsdk.phonegap ネイティブコードと Javascript コード間のブリッジを作成するためにハ
イブリッドアプリケーションで使用される内部クラス。Mobile SDK
Javascript ライブラリを実装するプラグインが含まれています。SDK アプ
リケーション内に独自の Javascript プラグインを実装する場合、
ForcePlugin を拡張して、抽象 execute() 関数を実装します。
「ForcePlugin クラス」を参照してください。
361
リファレンス
パッケージ名
Android パッケージおよびクラス
説明
com.salesforce.androidsdk.push このパッケージのコンポーネントは、Salesforce 転送通知の対象となる
デバイスを登録および登録解除します。次に、これらのコンポーネン
トは、Google Cloud Messaging (GCM) を通じて Salesforce 接続アプリケーショ
ンから通知を受信します。「転送通知とMobile SDK」を参照してくださ
い。
com.salesforce.androidsdk.rest REST API アクティビティを処理するためのクラス。これらのクラスは
Salesforce インスタンスとの通信を管理し、REST 要求の HTTP プロトコル
を処理します。要求の送信に使用できる同期メソッドや非同期メソッ
ドについての詳細は、ClientManager および RestClient を参照し
てください。
com.salesforce.androidsdk.rest.files Files REST API の要求および応答を処理するためのクラス。
com.salesforce.androidsdk.security パスコードおよび暗号化を処理する内部クラス。独自のキーを提供し
ている場合、Encryptor クラスを使用してハッシュを生成できます。
Encryptor を参照してください。
com.salesforce.androidsdk.smartstore SmartStore クラスとサポートクラス。
com.salesforce.androidsdk.ui アクティビティ (ログインアクティビティなど)。
com.salesforce.androidsdk.ui.sfhybrid ハイブリッドアプリケーションのアクティビティの基本クラス。
com.salesforce.androidsdk.ui.sfnative ネイティブアプリケーションのアクティビティの基本クラス。
com.salesforce.androidsdk.util
ユーティリティおよびテストクラスが含まれています。これらのクラ
スの大部分は内部で使用されますが、いくつかの重要な例外もありま
す。
• EventObserver インターフェースを実装して、任意のイベントタ
イプを傍受できます。
• EventsListenerQueue クラスは、独自のテストを実装する場合
に便利です。
• EventsObservable のソースコードを参照して、サポートされて
いるすべてのイベントタイプのリストを確認できます。
com.salesforce.androidsdk.accounts
クラス
説明
UserAccount
Salesforce 組織に対して現在ログインしている単一の
ユーザアカウントを表します。
362
リファレンス
Android パッケージおよびクラス
クラス
説明
UserAccountManager
現在ログインしているユーザアカウントにアクセスし
たり、SmartStore を使用しないアプリケーションの新
しいアカウントを追加したりするために使用します。
UserAccountManagerWithSmartStore
現在ログインしているユーザアカウントにアクセスし
たり、SmartStore を使用するアプリケーションの新し
いアカウントを追加したりするために使用します。
com.salesforce.androidsdk.app
クラス
説明
SalesforceSDKManager
アプリケーションの抽象サブクラス。プロジェクトで
具象サブクラスを指定する必要があります。
UpgradeManager
アップグレード用のヘルパークラス
UUIDManager
UUID 生成用のヘルパークラス
com.salesforce.androidsdk.auth
クラス
説明
AuthenticatorService
認証を処理するサービス
HttpAccess
汎用的な HTTP アクセスレイヤ
LoginServerManager
ログインホストを管理
OAuth2
一般的な OAuth2 要求のヘルパークラス
com.salesforce.androidsdk.phonegap
クラス
説明
ForcePlugin
すべての Salesforce プラグインの抽象スーパークラス
JavaScriptPluginVersion
JavaScript コードから通知されたバージョンをカプセル
化するためのヘルパークラス
SalesforceOAuthPlugin
Salesforce OAuth の PhoneGap プラグイン
SDKInfoPlugin
SDK コンテナに関する情報を取得するための PhoneGap
プラグイン
363
リファレンス
Android パッケージおよびクラス
クラス
説明
SFAccountManagerPlugin
ユーザアカウントを処理するための PhoneGap プラグ
イン
TestRunnerPlugin
コンテナで JavaScript テストを実行するための PhoneGap
プラグイン
com.salesforce.androidsdk.push
クラス
説明
PushBroadcastReceiver
Google Cloud Messaging (GCM) からメッセージを受信する
クラス (内部使用)
PushMessaging
転送通知用のデバイスの登録/登録解除を処理し、登
録情報を保存および取得するクラス (内部使用)
PushNotificationInterface
転送通知を受信および処理するアプリケーションで実
装された公開インターフェース
PushService
Salesforce 組織から転送通知を受信するために Salesforce
接続アプリケーションでアプリケーションを登録/登
録解除するクラス (内部使用)
com.salesforce.androidsdk.rest
クラス
説明
AdminPrefsManager
接続アプリケーションの組織のシステム管理者によっ
て行われたカスタム設定を表します。
ApiVersionStrings
API バージョン情報をカプセル化します。
BootConfig
重要なアプリケーション設定値(コンシューマ鍵、コー
ルバック URI、OAuth 範囲、更新動作など) をカプセル
化します。
ClientManager
RestClient のファクトリ。必要に応じてログインフロー
を起動します。
RestClient
Force.com サーバとやり取りする認証クライアント
RestRequest
Force.com REST 要求ラッパー
RestResponse
REST 応答ラッパー
364
リファレンス
Android パッケージおよびクラス
com.salesforce.androidsdk.rest.files
クラス
説明
ApiRequests
REST 要求を作成するためのヘルパーメソッド
ConnectUriBuilder
ユーザ ID と省略可能なパラメータの特別な処理を行っ
て、Connect URI を作成します。
FileRequests
Connect API を使用する、ファイルの HTTP 要求を定義し
ます。
RenditionType
サーバでサポートされる変換タイプの列挙子
com.salesforce.androidsdk.security
Google の PRNG の最新の修正が含まれます。
クラス
説明
Encryptor
暗号化/復号化/ハッシュ計算用のヘルパークラス
PRNGFixes
非活動状態タイムアウトマネージャ。必要に応じてパ
スコード画面を起動します。
PasscodeManager
非活動状態タイムアウトマネージャ。必要に応じてパ
スコード画面を起動します。
com.salesforce.androidsdk.smartstore.app
このパッケージは、SmartStore ライブラリプロジェクトの一部です。
クラス
説明
SalesforceSDKManagerWithSmartStore
SmartStore を使用するすべての強制アプリケーション
のスーパークラス (SmartStore ライブラリプロジェクト
に存在する)
UpgradeManagerWithSmartStore
SmartStoreを使用するアプリケーションのアップグレー
ドマネージャ (SmartStore ライブラリプロジェクトに存
在する)
com.salesforce.androidsdk.smartstore.phonegap
このパッケージは、SmartStore ライブラリプロジェクトの一部です。
365
リファレンス
Android パッケージおよびクラス
クラス
説明
SmartStorePlugin
SmartStore の PhoneGap プラグイン
StoreCursor
クエリカーソルを表す
com.salesforce.androidsdk.smartstore.store
このパッケージは、SmartStore ライブラリプロジェクトの一部です。
クラス
説明
DBHelper
SmartStore の基盤となるデータベースにアクセスする
ヘルパークラス
DBOpenHelper
通常のデータベース作成とバージョン設定を行うため
のヘルパークラス
IndexSpec
インデックス指定を表す
QuerySpec
クエリ指定を表す
SmartSqlHelper
SmartSql の解析および実行用のヘルパークラス
SmartStore
JSON ドキュメントの検索可能で安全なストア
com.salesforce.androidsdk.ui
クラス
説明
AccountSwitcherActivity
認証されたアカウント間の切り替えや新しいアカウン
トの追加のためのカスタムダイアログ。このダイアロ
グは、アカウントが切り替わった後に、アクティビ
ティスタックから取り出されます。
CustomServerUrlEditor
異なるログインホストをユーザが選択できるカスタム
ダイアログ
LoginActivity
ログイン画面
ManageSpaceActivity
ユーザがユーザデータをクリアしたり、ログアウトし
たりできるようにする、上書き可能なアクティビ
ティ。
OAuthWebviewHelper
OAuth ログインプロセスを行う Web ビューインスタン
スを管理するためのヘルパークラス
PasscodeActivity
パスコード (PIN) 画面
366
リファレンス
Android パッケージおよびクラス
クラス
説明
SalesforceAccountRadioButton
Salesforceアカウントを表すカスタムラジオボタン。こ
のラジオボタンにテキストを表示するには、カスタム
setText() メソッドを使用します。
SalesforceR
SDK 外で定義されたリソースの参照を許可するクラス
SalesforceServerRadioButton
カスタムサーバエンドポイントを表すカスタムラジオ
ボタン。このラジオボタンにテキストを表示するに
は、カスタム setText() メソッドを使用します。
ServerPickerActivity
OAuth フロー中にログインサーバ URL を変更するため
のアクティビティ。ユーザはカスタムサーバを追加し
たり、サーバのリストから選択したりできます。
com.salesforce.androidsdk.ui.sfhybrid
クラス
説明
SalesforceDroidGapActivity
Cordova ベースのアプリケーションのメインアクティ
ビティを定義する
SalesforceGapViewClient
Cordova ベースのアプリケーションの Web ビュークラ
イアントを定義する
com.salesforce.androidsdk.ui.sfnative
重要: ネイティブ Mobile SDK アプリケーションの各アクティビティで、このパッケージのいずれかのクラ
スの機能を拡張または複製する必要があります。
クラス
説明
SalesforceActivity
Android Activity クラスに基づいたネイティブアプ
リケーションのメインアクティビティ。
SalesforceListActivity
Android ListActivity クラスに基づいたネイティブ
アプリケーションのメインアクティビティ。
SalesforceExpandableListActivity
Android ExpandableListActivity クラスに基づい
たネイティブアプリケーションのメインアクティビ
ティ。
367
リファレンス
ライブラリ
com.salesforce.androidsdk.util
クラス
説明
EventsListenerQueue
特定のイベントが発生するまでテストを待機できるよ
うにするため、キューを使用してアクティビティイベ
ントを追跡するクラス
EventsObservable
SDK で生成されたイベントの登録および取得に使用 (主
にテストで使用)
EventsObserver
SDK イベントのオブザーバー
ForceAppInstrumentationTestCase
Salesforce Mobile SDK を使用したアプリケーションのテ
スト用のスーパークラス
HybridInstrumentationTestCase
ハイブリッドアプリケーションのテスト用のスーパー
クラス
JSTestCase
JavaScript 内でテストを実行するためのスーパークラス
JUnitReportTestRunner
実行時間制限を使用してテストを実行するテストラン
ナー
LogUtil
ログ記録用のヘルパーメソッド
NativeInstrumentationTestCase
ネイティブアプリケーションのテスト用のスーパーク
ラス
TimeLimitedTestRunner
テスト実行の有効期間を制限するテストランナー
UriFragmentParser
クエリ文字列スタイルを使用してパラメータを渡す
URI フラグメントを解析します (foo=bar&bar=foo2
など)。
UserSwitchReceiver
ユーザの切り替えイベントのリスナー
ライブラリ
次のライブラリは /libs/SalesforceSDK/libs にあります。
ライブラリ名
説明
android-junit-report-1.5.8.jar
Ant JUnit タスクの XML フォーマッタによって作成されるレポー
トと同様の形式の XML テストレポートを作成する Android 用の
カスタム計測テストランナー
apache-mime4j-0.7.2.jar
Java ストリームに基づく MIME メッセージパーサー
guava-18.0.jar
sqlcipher に必要な Java ライブラリ
httpcore-4.3.2.jar
HTTP トランスポートコンポーネント
368
リファレンス
Android リソース
ライブラリ名
説明
httpmime-4.3.2.jar
MIME でコード化されたエンティティ
volley_android-4.4.2_r2.jar
Google の Android ネットワーキングライブラリ
次のライブラリは /external/sqlcipher/libs にあります。
ライブラリ名
説明
armeabi/*.so
ARM ベースのデバイスで sqlcipher に必要なネイティブライブラ
リ (**)
commons-code.jar, guava-18.0.jar
sqlcipher に必要な Java ライブラリ
sqlcipher.jar
データベースファイルの透過的な 256 ビット AES 暗号化を行う
SQLite のオープンソースの拡張機能 (**)
x86/*.so
Intel ベースのデバイスで sqlcipher に必要なネイティブライブラ
リ
(*) は、ハイブリッドアプリケーションに必要なファイルを示します。
(**) は、SmartStore に必要なファイルを示します。
Android リソース
リソースは /res にあります。
drawable-hdpi
ファイル
使用
sf__edit_icon.png
サーバピッカー画面
sf__highlight_glare.png
ログイン画面
sf__icon.png
ネイティブアプリケーションアイコン
drawable-ldpi
ファイル
使途
sf__icon.png
アプリケーションアイコン
369
リファレンス
Android リソース
drawable-mdpi
ファイル
使途
sf__edit_icon.png
サーバピッカー画面
sf__highlight_glare.png
ログイン画面
sf__ic_refresh_sync_anim0.png
アプリケーションアイコン
sf__icon.png
アプリケーションアイコン
drawable-xhdpi
ファイル
使途
sf__icon.png
ネイティブアプリケーションアイコン
drawable-xlarge
ファイル
使途
sf__header_bg.png
ログイン画面 (タブレット)
sf__header_drop_shadow.xml
ログイン画面 (タブレット)
sf__header_left_border.xml
ログイン画面 (タブレット)
sf__header_refresh.png
ログイン画面 (タブレット)
sf__header_refresh_press.png
ログイン画面 (タブレット)
sf__header_refresh_states.xml
ログイン画面 (タブレット)
sf__header_right_border.xml
ログイン画面 (タブレット)
sf__login_content_header.xml
ログイン画面 (タブレット)
sf__nav_shadow.png
ログイン画面 (タブレット)
sf__oauth_background.png
ログイン画面 (タブレット)
sf__oauth_container_dropshadow.9.png
ログイン画面 (タブレット)
sf__progress_spinner.xml
ログイン画面 (タブレット)
sf__refresh_loader.png
ログイン画面 (タブレット)
sf__toolbar_background.xml
ログイン画面 (タブレット)
370
リファレンス
Android リソース
drawable-xlarge-port
ファイル
使途
sf__oauth_background.png
ログイン画面 (タブレット)
drawable-xxhdpi
ファイル
使途
sf__hybrid__icon.png
ハイブリッドアプリケーションアイコン
sf__icon.png
ネイティブアプリケーションアイコン
drawable
ファイル
使途
sf__header_bg.png
ログイン画面
sf__progress_spinner.xml
ログイン画面
sf__toolbar_background.xml
ログイン画面
layout
ファイル
使途
sf__account_switcher.xml
アカウントの切り替え画面
sf__custom_server_url.xml
サーバピッカー画面
sf__login.xml
ログイン画面
sf__manage_space.xml
ユーザがアプリケーションデータをクリアしたり、ロ
グアウトしたりできる画面
sf__passcode.xml
PIN 画面
sf__server_picker.xml
サーバピッカー画面 (廃止)
sf__server_picker_list.xml
サーバピッカー画面
371
リファレンス
Files API リファレンス
menu
ファイル
使途
sf__clear_custom_url.xml
[接続を追加] ダイアログ
sf__login.xml
ログインメニュー (電話)
values
ファイル
使途
bootconfig.xml
接続アプリケーションの構成設定
sf__colors.xml
色
sf__dimens.xml
Dimensions
sf__strings.xml
SDK 文字列
sf__style.xml
スタイル
strings.xml
その他の文字列 (アプリケーション名)
xml
ファイル
使途
authenticator.xml
アプリケーションで使用するアカウントの設定
config.xml
PhoneGap のプラグイン設定ファイル。ハイブリッドに
必要です。
servers.xml
サーバ設定
Files API リファレンス
Files 機能の API アクセスは、Android、iOS、および各種ハイブリッドで使用できます。
FileRequests メソッド (Android)
すべての FileRequests メソッドは静的で、それぞれ RestRequest インスタンスを返します。
RestClient.sendAsync() または RestClient.sendSync() メソッドを使用して、RestRequest オブジェ
クトをサーバに送信します。「REST API の使用」を参照してください。
REST リクエストボディおよびレスポンスボディについての詳細は、「Chatter REST API リソース」の「Files リソー
ス」(http://www.salesforce.com/us/developer/docs/chatterapi) を参照してください。
372
リファレンス
FileRequests メソッド (Android)
ownedFilesList
指定されたユーザが所有するファイルのリストを取得する要求を生成します。結果の 1 ページを返します。
署名
public static RestRequest ownedFilesList(String userId, Integer pageNum);
パラメータ
名前
型
説明
userId
String
ユーザの ID。null の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
pageNum
Integer
取得する結果のページの開始値 0 のインデックス。null の
場合、最初のページを取得します。
例
RestRequest request = FileRequests.ownedFilesList(null, null);
filesInUsersGroups
指定されたユーザの所属グループが所有するファイルのリストを取得する要求を生成します。
署名
public static RestRequest filesInUsersGroups(String userId, Integer pageNum);
パラメータ
名前
データ型
説明
userId
String
ユーザの ID。null の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
pageNum
Integer
取得する結果のページの開始値 0 のインデックス。null の
場合、最初のページを取得します。
例
RestRequest request = FileRequests.filesInUsersGroups(null, null);
filesSharedWithUser
指定されたユーザと共有されたファイルのリストを取得する要求を生成します。
署名
public static RestRequest filesSharedWithUser(String userId, Integer pageNum);
373
リファレンス
FileRequests メソッド (Android)
パラメータ
名前
データ型
説明
userId
String
ユーザの ID。null の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
pageNum
Integer
取得する結果のページの開始値 0 のインデックス。null の
場合、最初のページを取得します。
例
RestRequest request = FileRequests.filesSharedWithUser(null, null);
fileDetails
特定のバージョンのファイルの詳細を取得できる要求を生成します。
署名
public static RestRequest fileDetails(String sfdcId, String version);
パラメータ
名前
データ型
説明
sfdcId
String
ファイルの ID。null の場合、IllegalArgumentException
が発生します。
version
String
取得するバージョン。null の場合、最新バージョンを取得
します。
例
String id = <some_file_id>;
RestRequest request = FileRequests.fileDetails(id, null);
batchFileDetails
複数のファイルの詳細を取得できる要求を生成します。
署名
public static RestRequest batchFileDetails(List sfdcIds);
374
リファレンス
FileRequests メソッド (Android)
パラメータ
名前
データ型
説明
sfdcIds
List
1 つ以上のファイルの ID のリスト。リストの ID がひとつ
でも null の場合、IllegalArgumentException が発生し
ます。
例
List<String> ids = Arrays.asList("id1", "id2", ...);
RestRequest request = FileRequests.batchFileDetails(ids);
fileRendition
指定されたファイルのページの表示されたプレビューを取得できる要求を生成します。
署名
public static RestRequest fileRendition(String sfdcId,
String version,
RenditionType renditionType,
Integer pageNum);
パラメータ
名前
データ型
説明
sfdcId
String
表示されるファイルの ID。null の場合、
IllegalArgumentException が発生します。
version
String
取得するバージョン。null の場合、最新バージョンを取得
します。
renditionType
RenditionType
返される変換の種別を指定します。使用できる値は次の
とおりです。
• PDF
• FLASH
• SLIDE
• THUMB120BY90
• THUMB240BY180
• THUMB720BY480
null の場合、THUMB120BY90 が使用されます。
pageNum
Integer
取得するページの開始値 0 のインデックス。null の場合、
最初のページを取得します。
375
リファレンス
FileRequests メソッド (Android)
例
String id = <some_file_id>;
RestRequest request = FileRequests.fileRendition(id, null, "PDF", 0);
fileContents
指定されたファイルのバイナリコンテンツを取得できる要求を生成します。
署名
public static RestRequest fileContents(String sfdcId, String version);
パラメータ
名前
データ型
説明
sfdcId
String
表示されるファイルの ID。null の場合、
IllegalArgumentException が発生します。
version
String
取得するバージョン。null の場合、最新バージョンを取得
します。
例
String id = <some_file_id>;
RestRequest request = FileRequests.fileContents(id, null);
fileShares
指定されたファイルを共有するエンティティのリストからページを取得できる要求を生成します。
署名
public static RestRequest fileShares(String sfdcId, Integer pageNum);
パラメータ
名前
データ型
説明
sfdcId
String
表示されるファイルの ID。null の場合、
IllegalArgumentException が発生します。
pageNum
Integer
取得する結果のページの開始値 0 のインデックス。null の
場合、最初のページを取得します。
例
String id = <some_file_id>;
RestRequest request = FileRequests.fileShares(id, null);
376
リファレンス
FileRequests メソッド (Android)
addFileShare
指定されたエンティティと指定のファイルを共有できる要求を生成します。
署名
public static RestRequest addFileShare(String fileId, String entityId,
String shareType);
パラメータ
名前
データ型
説明
fileId
String
共有されるファイルの ID。null の場合、
IllegalArgumentException が発生します。
entityID
String
ファイルを共有するユーザまたはグループの ID。null の場
合、IllegalArgumentException が発生します。
shareType
String
共有種別。有効な値は「V」(表示) と「C」(コラボレーショ
ン) です。
例
String idFile = <some_file_id>;
String idEntity = <some_user_or_group_id>;
RestRequest request = FileRequests.addFileShare(idFile, idEntity, "V");
deleteFileShare
指定されたファイル共有を削除できる要求を生成します。
署名
public static RestRequest deleteFileShare(String shareId);
パラメータ
名前
データ型
説明
shareId
String
削除されるファイル共有の ID。null の場合、
IllegalArgumentException が発生します。
例
String id = <some_fileShare_id>;
RestRequest request = FileRequests.deleteFileShare(id);
377
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
uploadFile
ローカルファイルをサーバにアップロードできる要求を生成します。この要求により、バージョン 1 のファイ
ルがサーバで作成されます。
署名
public static RestRequest uploadFile(File theFile,
String name, String description, String mimeType)
throws UnsupportedEncodingException;
パラメータ
名前
データ型
説明
theFile
File
サーバにアップロードされるローカルファイルのパス。
name
String
ファイルの名前。
description
String
ファイルの説明。
mimeType
String
ファイルの MIME タイプ (タイプがわかっている場合)。そ
れ以外の場合は null。
発生する例外
UnsupportedEncodingException
例
RestRequest request = FileRequests.uploadFile("/Users/JayVee/Documents/",
"mypic.png", "Profile pic", "image/png");
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
iOS ネイティブアプリケーションでは、SFRestAPI (Files) カテゴリがファイル要求メソッドを定義します。
要求メッセージを SFRestAPI シングルトンに送信します。
SFRestRequest *request = [[SFRestAPI sharedInstance] requestForOwnedFilesList:nil page:0];
各メソッドは SFRestRequest インスタンスを返します。SFRestAPI シングルトンを再度使用して、要求オ
ブジェクトをサーバに送信します。次の例では、コール元クラス (self) が代理オブジェクトですが、
SFRestDelegate を実装する他のオブジェクトを指定することもできます。
[[SFRestAPI sharedInstance] send:request delegate:self];
requestForOwnedFilesList:page:
指定されたユーザが所有するファイルのリストを取得する要求を生成します。結果の 1 ページを返します。
378
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
署名
- (SFRestRequest *)
requestForOwnedFilesList:(NSString *)userId
page:(NSUInteger)page;
パラメータ
名前
データ型
説明
userId
NSString *
ユーザの ID。nil の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
page
NSUInteger
取得するページの開始値 0 のインデックス。nil の場合、
最初のページを取得します。
例
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForOwnedFilesList:nil
page:0];
requestForFilesInUsersGroups:page:
指定されたユーザの所属グループが所有するファイルのリストを取得する要求を生成します。
署名
- (SFRestRequest *)
requestForFilesInUsersGroups:(NSString *)userId
page:(NSUInteger)page;
パラメータ
名前
データ型
説明
userId
NSString *
ユーザの ID。nil の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
page
NSUInteger
取得するページの開始値 0 のインデックス。nil の場合、
最初のページを取得します。
例
SFRestRequest *request = [[SFRestAPI sharedInstance]
requestForFilesInUsersGroups:nil
page:0];
379
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
requestForFilesSharedWithUser:page:
指定されたユーザと共有されたファイルのリストを取得する要求を生成します。
署名
- (SFRestRequest *)
requestForFilesSharedWithUser:(NSString *)userId
page:(NSUInteger)page;
パラメータ
名前
データ型
説明
userId
NSString *
ユーザの ID。nil の場合、コンテキスト (ログイン) ユーザ
の ID が使用されます。
page
NSUInteger
取得するページの開始値 0 のインデックス。nil の場合、
最初のページを取得します。
例
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForFilesSharedWithUser:nil
page:0];
requestForFileDetails:forVersion:
特定のバージョンのファイルの詳細を取得できる要求を生成します。
署名
- (SFRestRequest *)
requestForFileDetails:(NSString *)sfdcId
forVersion:(NSString *)version;
パラメータ
名前
データ型
説明
sfdcId
NSString *
ファイルの ID。nil の場合、要求が失敗します。
version
NSString *
取得するバージョン。nil の場合、最新バージョンを取得
します。
例
NSString *id = [NSString stringWithString:@"some_file_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForFileDetails:id
forVersion:nil];
380
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
requestForBatchFileDetails:
複数のファイルの詳細を取得できる要求を生成します。
署名
- (SFRestRequest *)
requestForBatchFileDetails:(NSArray *)sfdcIds;
パラメータ
名前
データ型
説明
sfdcIds
NSArray *
1 つ以上のファイルの ID の配列。ID は文字列として表され
ます。
例
NSArray *ids = [NSArray arrayWithObject:@"id1",@"id2",...,nil];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForBatchFileDetails:ids];
requestForFileRendition:version:renditionType:page:
指定されたファイルのページの表示されたプレビューを取得できる要求を生成します。
署名
- (SFRestRequest *)
requestForFileRendition:(NSString *)sfdcId
version:(NSString *)version
renditionType:(NSString *)renditionType
page:(NSUInteger)page;
パラメータ
名前
データ型
説明
sfdcId
NSString *
表示されるファイルの ID。nil の場合、要求が失敗します。
version
NSString *
取得するバージョン。nil の場合、最新バージョンを取得
します。
renditionType
NSString *
返される変換の種別を指定します。使用できる値は次の
とおりです。
• "PDF"
• "FLASH"
• "SLIDE"
• "THUMB120BY90"
• "THUMB240BY180"
• "THUMB720BY480"
381
リファレンス
名前
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
データ型
説明
nil の場合、THUMB120BY90 が使用されます。
page
NSUInteger
取得するページの開始値 0 のインデックス。nil の場合、
最初のページを取得します。
例
NSString *id = [NSString stringWithString:@"some_file_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForFileRendition:id
version:nil
renditionType:nil
page:nil];
requestForFileContents:version:
指定されたファイルのバイナリコンテンツを取得できる要求を生成します。
署名
- (SFRestRequest *)
requestForFileContents:(NSString *) sfdcId
version:(NSString*) version;
パラメータ
名前
データ型
説明
sfdcId
NSString *
表示されるファイルの ID。nil の場合、要求が失敗します。
version
NSString *
取得するバージョン。nil の場合、最新バージョンを取得
します。
例
NSString *id = [NSString stringWithString:@"some_file_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForFileContents:id
version:nil];
requestForFileShares:page:
指定されたファイルを共有するエンティティのリストからページを取得できる要求を生成します。
署名
- (SFRestRequest *)
requestForFileShares:(NSString *)sfdcId
page:(NSUInteger)page;
382
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
パラメータ
名前
データ型
説明
sfdcId
NSString *
表示されるファイルの ID。nil の場合、要求が失敗します。
page
NSUInteger
取得するページの開始値 0 のインデックス。nil の場合、
最初のページを取得します。
例
NSString *id = [NSString stringWithString:@"some_file_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForFileShares:id
page:nil];
requestForAddFileShare:entityId:shareType: メソッド
指定されたエンティティと指定のファイルを共有できる要求を生成します。
署名
- (SFRestRequest *)
requestForAddFileShare:(NSString *)fileId
entityId:(NSString *)entityId
shareType:(NSString*)shareType;
パラメータ
名前
データ型
説明
fileId
NSString *
共有されるファイルの ID。nil の場合、要求が失敗します。
entityId
NSString *
ファイルを共有するユーザまたはグループの ID。nil の場
合、要求が失敗します。
shareType
NSString *
共有種別。有効な値は「V」(表示) と「C」(コラボレーショ
ン) です。
例
NSString *id = [NSString stringWithString:@"some_file_id"];
NSString *entId = [NSString stringWithString:@"some_entity_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForAddFileShare:id
entityId:entId
shareType:@"V"];
383
リファレンス
SFRestAPI (Files) カテゴリ — 要求メソッド (iOS)
requestForDeleteFileShare:
指定されたファイル共有を削除できる要求を生成します。
署名
- (SFRestRequest *)
requestForDeleteFileShare:(NSString *)shareId;
パラメータ
名前
データ型
説明
shareId
NSString *
削除されるファイル共有の ID。nil の場合、要求が失敗し
ます。
例
NSString *id = [NSString stringWithString:@"some_fileshare_id"];
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForDeleteFileShare:id];
requestForUploadFile:name:description:mimeType: メソッド
ローカルファイルをサーバにアップロードできる要求を生成します。この要求により、バージョン 1 の新しい
ファイルがサーバで作成されます。
署名
- (SFRestRequest *)
requestForUploadFile:(NSData *)data
name:(NSString *)name
description:(NSString *)description
mimeType:(NSString *)mimeType;
パラメータ
名前
データ型
説明
data
NSData *
サーバにアップロードするデータ。
name
NSString *
ファイルの名前。
description
NSString *
ファイルの説明。
mimeType
NSString *
ファイルの MIME タイプ (タイプがわかっている場合)。そ
れ以外の場合は、nil。
例
NSData *data = [NSData dataWithContentsOfFile:@"/Users/JayVee/Documents/mypic.png"];
384
リファレンス
ハイブリッドアプリケーションの Files メソッド
SFRestRequest *request =
[[SFRestAPI sharedInstance] requestForUploadFile:data
name:@"mypic.png"
description:@"Profile pic"
mimeType:@"image/png"];
ハイブリッドアプリケーションの Files メソッド
Files API のハイブリッドメソッドは、forcetk.mobilesdk.js ライブラリにあります。次の参照トピックの例
では、次のようなローカル ftkclient 変数を宣言していることを前提としています。
var ftkclient = new forcetk.Client(creds.clientId, creds.loginUrl, creds.proxyUrl, reauth);
メモ: smartsync.js では、forcetk.Client オブジェクトは Force.forcetkClient としてラップさ
れます。SmartSync アプリケーションでは、いずれかのクライアントを自由に使用できます。ただし、
Force.forcetkClient でコールされる REST API メソッドは、JavaScript promise を返すという点でそれらの
forcetk.Client の類似カテゴリとは異なります。Force.forcetkClient を使用する場合、正常な
コールバックとエラーコールバックを必要とする例を次のように再度書式設定します。
Force.forcetkClient.ownedFilesList(null, null)
.done(function(response) {/* do something with the returned JSON data */})
.fail(function(error) { alert("Error!");});
ownedFilesList メソッド
指定されたユーザが所有するファイルのリストからページを返します。
署名
forcetk.Client.prototype.
ownedFilesList =
function(userId, page, callback, error)
パラメータ
名前
説明
userId
既存のユーザの ID。null の場合、コンテキスト (現在ログインしている) ユー
ザの ID が使用されます。
page
取得する結果のページの開始値 0 のインデックス。null の場合、最初のペー
ジを取得します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
385
リファレンス
ハイブリッドアプリケーションの Files メソッド
例
ftkclient.ownedFilesList(null, null,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
filesInUsersGroups メソッド
指定されたユーザの所属グループが所有するファイルのリストからページを返します。
署名
forcetk.Client.prototype.
filesInUsersGroups =
function(userId, page, callback, error)
パラメータ
名前
説明
userId
既存のユーザの ID。null の場合、コンテキスト (現在ログインしている) ユー
ザの ID が使用されます。
page
取得する結果のページの開始値 0 のインデックス。null の場合、最初のペー
ジを取得します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.filesInUsersGroups(null, null,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
filesSharedWithUser メソッド
指定されたユーザと共有されたファイルのリストからページを返します。
署名
forcetk.Client.prototype.
filesSharedWithUser =
function(userId, page, callback, error)
386
リファレンス
ハイブリッドアプリケーションの Files メソッド
パラメータ
名前
説明
userId
既存のユーザの ID。null の場合、コンテキスト (現在ログインしている) ユー
ザの ID が使用されます。
page
取得する結果のページの開始値 0 のインデックス。null の場合、最初のペー
ジを取得します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.filesSharedWithUser(null, null,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
fileDetails メソッド
特定のバージョンのファイルの詳細を取得できる要求を生成します。
署名
forcetk.Client.prototype.
fileDetails = function
(fileId, version, callback, error)
パラメータ
名前
説明
sfdcId
既存のファイルの ID。null の場合、エラーが返されます。
version
取得するバージョン。null の場合、最新バージョンを取得します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.fileDetails(id, null,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
387
リファレンス
ハイブリッドアプリケーションの Files メソッド
batchFileDetails メソッド
複数のファイルの詳細を返します。
署名
forcetk.Client.prototype.
batchFileDetails =
function(fileIds, callback, error)
パラメータ
名前
説明
fileIds
1 つ以上の既存のファイルの ID のリスト。リストの ID がひとつでも null の場
合、エラーが返されます。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.batchFileDetails(ids,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
fileRenditionPath メソッド
service/data を基準とするファイル変換の相対パスを返します。HTML (img タグなど) では、代わりにベア
ラートークン URL を使用します。
署名
forcetk.Client.prototype.
fileRenditionPath =
function(fileId, version, renditionType,
page)
パラメータ
名前
説明
fileId
表示される既存のファイルの ID。null の場合、エラーが返されます。
version
取得するバージョン。null の場合、最新バージョンを取得します。
renditionType
返される変換の種別を指定します。使用できる値は次のとおりです。
• PDF
• FLASH
• SLIDE
388
リファレンス
名前
ハイブリッドアプリケーションの Files メソッド
説明
• THUMB120BY90
• THUMB240BY180
• THUMB720BY480
null の場合、THUMB120BY90 が使用されます。
page
取得するページの開始値 0 のインデックス。null の場合、最初のページを取
得します。
例
ftkclient.fileRenditionPath(id, null, "THUMB240BY180", null);
fileContentsPath メソッド
service/data を基準とするファイルコンテンツの相対パスを返します。html (img タグなど) では、代わりに
ベアラートークン URL を使用します。
署名
forcetk.Client.prototype.
fileContentsPath =
function(fileId, version)
パラメータ
名前
説明
fileId
表示される既存のファイルの ID。null の場合、エラーが返されます。
version
取得するバージョン。null の場合、最新バージョンを取得します。
例
ftkclient.fileContentsPath(id, null);
fileShares メソッド
このファイルを共有するエンティティのリストからページを返します。
署名
forcetk.Client.prototype.
fileShares = function
(fileId, page, callback, error)
389
リファレンス
ハイブリッドアプリケーションの Files メソッド
パラメータ
名前
説明
fileId
表示される既存のファイルの ID。null の場合、エラーが返されます。
page
取得する結果のページの開始値 0 のインデックス。null の場合、最初のペー
ジを取得します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.fileShares(id, null,
function(response){ /* do something with the returned JSON data */},
function(error){ alert("Error!");}
);
addFileShare メソッド
指定されたファイル ID のファイル共有を指定されたエンティティ ID に追加します。
署名
forcetk.Client.prototype.
addFileShare = function
(fileId, entityId, shareType, callback, error)
パラメータ
名前
説明
fileId
共有される既存のファイルの ID。null の場合、IllegalArgumentException
が発生します。
entityID
ファイルを共有する既存のユーザまたはグループの ID。null の場合、
IllegalArgumentException が発生します。
shareType
共有種別。有効な値は「V」(表示) と「C」(コラボレーション) です。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.addFileShare(id, null, "V",
function(response){ /* do something with the returned JSON data */},
390
リファレンス
forceios パラメータ
function(error){ alert("Error!");}
);
deleteFileShare メソッド
指定されたファイル共有を削除します。
署名
forcetk.Client.prototype.
deleteFileShare =
function(sharedId, callback, error)
パラメータ
名前
説明
shareId
削除される既存のファイル共有の ID。null の場合、
IllegalArgumentException が発生します。
callback
サーバ応答を非同期で受信して処理する関数。
error
サーバエラーを処理する関数。
例
ftkclient.deleteFileShare(id,
function(response){
/* do something with the returned JSON data */
},
function(error){ alert("Error!");}
);
forceios パラメータ
forceios コマンドパラメータの説明を次に示します。
パラメータ名
説明
--apptype
次のいずれかになります。
• 「native」
• 「hybrid_remote」(VisualForce を使用するサーバ側ハ
イブリッドアプリケーション)
• 「hybrid_local」(VisualForce を使用しないクライアン
ト側ハイブリッドアプリケーション)
391
リファレンス
forcedroid パラメータ
パラメータ名
説明
--appname
アプリケーションの名前。
--companyid
会社の一意の識別子。この値とアプリケーション名が
連結されて、アプリケーションを App Store に公開する
ための一意のアプリケーション識別子が作成されま
す。 たとえば、「com.myCompany.apps」のようになり
ます。
--organization
会社の正式名称。たとえば、「Acme Widgets, Inc.」など
です。
--startpage
(ハイブリッドリモートアプリケーションのみ) リモー
ト開始ページへのサーバパス。 たとえ
ば、/apex/MyAppStartPage のように入力します。
--outputdir
(省略可能) プロジェクトを作成するフォルダ。フォル
ダが存在していない場合は、スクリプトで作成されま
す。デフォルトは現在の作業ディレクトリです。
--appid
(省略可能) 接続アプリケーションのコンシューマ鍵。
デフォルトはサンプルアプリケーションのコンシュー
マ鍵です。
メモ: ここで値を指定しない場合は、App Store に
公開する前に値を変更する必要があります。
(省略可能) 接続アプリケーションのコールバック URL。
デフォルトはサンプルアプリケーションのコールバッ
ク URL です。
--callbackuri
メモ:
• ここで値を指定しない場合は、App Store に公
開する前に値を変更する必要があります。
• --appid のデフォルト値を受け入れる場合、
--callbackuri のデフォルト値も受け入れ
てください。
forcedroid パラメータ
次の表に、forcedroid コマンドパラメータを示します。
392
リファレンス
forcedroid パラメータ
パラメータ名
説明
--apptype
次のいずれかになります。
• 「native」
• 「hybrid_remote」(VisualForce を使用するサーバ側ハ
イブリッドアプリケーション)
• 「hybrid_local」(VisualForce を使用しないクライアン
ト側ハイブリッドアプリケーション)
--appname
アプリケーションの名前。
--targetdir
プロジェクトを作成するフォルダ。フォルダが存在し
ていない場合は、スクリプトで作成されます。
--packagename
アプリケーションのパッケージ識別子
(「com.acme.app」など)。
--apexpage
(ハイブリッドリモートアプリケーションのみ) Apex の
開始ページへのサーバパス。 たとえ
ば、/apex/MyAppStartPage のように入力します。
--usesmartstore=yes
(省略可能) オフラインデータにSmartStore、および必要
に応じて SmartSync を使用する場合にのみ含めます。
指定されていない場合、デフォルトの no に設定され
ます。
393