SlideShare a Scribd company logo
勉強会force#2
HTML5によるモバイルアプリ開発

        ISV Architect 中嶋一樹
Safe Harbor
Safe harbor statement under the Private Securities Litigation Reform Act of 1995:

This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such
uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ
materially from the results expressed or implied by the forward-looking statements we make. All statements other than
statements of historical fact could be deemed forward-looking, including any projections of product or service availability,
subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of
management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or
technology developments and customer contracts or use of our services.

The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and
delivering new functionality for our service, new products and services, our new business model, our past operating losses,
possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our
security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and
acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain,
and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our
limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further
information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report
on Form 10-Q for the most recent fiscal quarter ended April 30, 2011. This documents and others containing important
disclosures are available on the SEC Filings section of the Investor Information section of our Web site.

Any unreleased services or features referenced in this or other presentations, press releases or public statements are not
currently available and may not be delivered on time or at all. Customers who purchase our services should make the
purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does
not intend to update these forward-looking statements.
アーキテクチャ
3タイプのアプリケーション

Native
•   オンラインストアからインストール
•   モバイル端末のH/W機能を活用
•   リッチなユーザエクスペリエンス
•   特殊な開発能力が必要
3タイプのアプリケーション

Web
•   ブラウザからアクセス
•   端末を問わないシングルコードベース
•   限定的なH/Wアクセス
•   非互換なイベント
•   開発者を確保し易いWebベースの開発
3タイプのアプリケーション

Web + HTML5
•   ブラウザからアクセス
•   端末を問わないシングルコードベース
•   限定的なH/Wアクセス
•   Nativeのようなモバイル用UI
•   開発者を確保し易いWebベースの開発
3タイプのアプリケーション

Hybrid
•   オンラインストアからインストール
•   モバイル端末のH/Wを活用
•   リッチなユーザエクスペリエンス
•   開発者を確保し易いWebベースの開発
Force.comでのWeb + HTML5アプリ提供形態

        Database

          Apex

        Visualforce               js / css

                      Force.com   3rd Party


          HTML5
Database.comでのWeb + HTML5アプリ提供形態

  Database
    Apex
    API

                Open Web Platform   js / css

 Database.com                       3rd Party


                     HTML5
サンプルアプリ
User: mobile@sugoisurvey21.dev

Password: force0202
User Interface
Visualforce PageにjQuery Mobileをロード
<apex:page sidebar="false" showHeader="false" standardStylesheets="false"
standardController="Session__c" extensions="sugoiSurvey" contentType="text/html" doctype="HTML-5.0">
<apex:stylesheet value="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<apex:includescript value="http://code.jquery.com/jquery-1.7.1.min.js" />
<apex:includescript value="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js" />
<head>
    <title>{!$label.sugoiSurvey}</title>
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <script type="text/javascript">
    j$ = jQuery.noConflict();
    </script>




• <apex:stylesheet>,<apex:includescript>でライブラリ(jQuery, jQuery Mobile)をロード
• <meta name="viewport">で表示サイズをモバイル端末画面に最適化
• jQuery.noConfilict();で$を変更
jQuery Mobileでのページ構造
<div id="session_list" data-role="page">
	    <div data-role="header">
	    </div>
	    <div data-role="content">
          <a href="#session_detail">Session 1</a>
	    </div>
	    <div data-role="footer">
	    </div>
</div>

<div id="session_detail" data-role="page" data-add-back-btn="true">
	    <div data-role="header">
	    </div>
	    <div data-role="content">
	    </div>
	    <div data-role="footer">
	    </div>
</div>


•   <div data-role="page">で1つの画面を表示
•   1htmlファイルに複数の画面を記述可能。デフォルトでは最初のpageを表示。
•   ページ内リンク<a href="#{ID}">にて画面遷移。各<div>にid="{ID}"を設定しておく
•   data-add-back-btn="true"でヘッダにbackボタンを自動表示可能
リスト
<div id="session_list" data-role="page" >
	    <div data-role="header"><h1>セッションリスト</h1></div>
	    <div data-role="content">
	    	    <ul data-role="listview" data-inset="true" data-filter="true">
	    	    	    <li><a href="#session1">Session 1</a></li>
	    	    	    <li><a href="#session2">Session 2</a></li>
	    	    	    <li><a href="#session3">Session 3</a></li>
	    	    </ul>
	    </div>
</div>
<div id="session1" data-role="page" data-add-back-btn="true">
	    <div data-role="header"><h1>セッション詳細</h1></div>
	   <div   data-role="content">
	   	      <ul data-role="listview">
	   	      	    <li data-role="list-divider">Session 1</li>
	   	      	    <li>セッション 1の詳細</li>
	    	    </ul>
	    </div>
</div>


• <ul data-role=”listview”>でTouchに適したリストを表示
• <ul data-filter=”true”>でリスト絞り込み用サーチボックスを表示
• <li data-role=”list-divider”>でリストの見出を設定
サンプルアプリのトップページ
<div id="session_list" data-role="page" data-theme="d">
    <div data-role="header">
        <h1>{!$label.sessionList}</h1>
        <a href="#create_session" class="ui-btn-right" data-icon="plus" data-transition="slideup">{!$label.new}</a>
    </div>
    <div data-role="content">
        <ul data-role="listview" data-inset="true" data-divider-theme="d" data-filter="true" data-split-icon="gear">
            <apex:repeat var="session" value="{!sessions}">
                <li class="session">
                      <a href="/apex/sugoiSurveyM_detail?id={!session.id}" data-ajax="false">
                           <h3>{!session.name}</h3>
                           <p>
                        	 {!session.presenter__r.company__c} {!session.presenter__r.title__c} {!
session.presenter__r.name}<br />
                        	 {!YEAR(session.Date__c)}.{!MONTH(session.Date__c)}.{!DAY(session.Date__c)} #{!
session.hash_tag__c}
                             </p>
                        	    <span class="ui-li-count">{!session.rate_avg__c}pt</span>
                       </a>
                       <a href="/apex/sugoiSurveyM_edit?id={!session.id}" data-ajax="false"></a>
                </li>
            </apex:repeat>
        </ul>
    </div>
</div>
データベース操作
JavaScript RemotingでApexを実行
Apex
@RemoteAction
public static void submitSurveyJs(id session, string rate){
    survey__c survey = new survey__c(session__c = session, rate__c = rate);
    insert survey;
}

• @RemoteActionアノテーションを対応Methodに付加
• global/publicかつstaticのMethodを定義
Visulaforce Page
j$('#submit_survey').tap(function(){
    var rate = j$('input:radio:checked').val();
    sugoiSurvey.submitSurveyJs(
        "{!session__c.id}",
        rate,
        function(result, event){
            alert(event.message);
        },
        {escape:true}
    );
});

• sugoiSurvey.submitSurveyJs() => {Class名}.{Method名}()で対応するApexを実行
• resultでクラスからの返り値を参照
• eventでApexからの実行結果を参照
Database.com
認証
OAuth (PHP + REST)
OAuth Toolkit for PHPをドキュメントルートに設置
https://github.com/nkjm/Force.com-OAuth-Toolkit-for-PHP


認証下に置くphpファイルの先頭
<?php
session_start();
if (!isset($_SESSION['access_token']) || !isset($_SESSION['instance_url'])) {
    $_SESSION['oauth_return'] = $_SERVER['PHP_SELF'] . '?' . htmlspecialchars(SID);
    header( 'Location: /oauth/oauth.php?' . htmlspecialchars(SID));
}



• 認証されているセッションは常に$_SESSION[‘access_token’]にTokenを保持
• Tokenがなければ、
    1.ローカルのOAuthライブラリにリダイレクト。
    2.Salesforceの認証サーバにリダイレクトされ、認証 => 「コード」取得。
    3.ローカルのOAuthライブラリにリダイレクト。SalesforceのTokenサーバからTokenを取得。
    4.$_SESSION[‘access_token’]にTokenを保存し認証下のコンテンツにリダイレクト。
データベース操作
OAuth (PHP + REST)
Tokenを用いたREST APIアクセス
$query = ‘select name from session__c’;
$url = $_SESSION[‘instance_url’] . “/services/data/" . VERSION . "/query?q=" . urlencode($query);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth “ . $_SESSION[‘access_token’]));
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ($status != 200) {
    if ($status == 401){
        $response = json_decode($json_response);
        if ($response[0]->errorCode == 'INVALID_SESSION_ID') {
            header( 'Location: oauth/oauth.php' );
        }
    }
    $curl_error = curl_error($curl);
    $curl_errno = curl_errno($curl);
    die("Status Code: $status <br/>Response: $json_response <br/> Curl Error: $curl_error <br/>Curl Errno:
$curl_errno");
}
curl_close($curl);
$response = json_decode($json_response, true);
return($response);
OAuth (PHP + JavaScript + REST)
Force.com JavaScript REST API Toolkit
https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit




                       forcetk.js
OAuth (PHP + JavaScript + REST)
Force.com JavaScript REST API Toolkitをドキュメントルートに設置
[root@server]# ls ${DOCUMENT_ROOT}/
forcetk.js
proxy.php
index.php
oauth/


HTMLから読み込み
<!DOCTYPE html>
<html>
<head>
    <title><?php echo LABEL_SUGOISURVEY; ?></title>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" rel="stylesheet" type="text/css" />
    <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script>
    <script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
    <script type="text/javascript" src="forcetk.js"></script>
</head>
OAuth (PHP + JavaScript + REST)
POSTでレコードを作成
<script type=”text/javascript”>
    $(document).ready(function(){
        var $client_id = "[あなたのConsumer ID]";
        var $proxy_url = "https://[あなたのWebサーバ]/proxy.php?mode=native";

        // REST APIアクセスを抽象化するWrapperを初期化
        var client = new forcetk.Client($client_id, null, $proxy_url);

        // セッション情報をセット
        client.setSessionToken('<?php echo $_SESSION["access_token"]; ?>', null, '<?php echo
$_SESSION["instance_url"]; ?>');

        $('#account_form :button').click(function(){
            var $account_name = $('#account_form :text').attr('value');

              // createメソッドでAccountレコードを作成。第一引数はオブジェクト名。第二引数はフィールド。第三引数は成功時のコールバック。
第四引数はエラー時のコールバック。
              client.create(
                  "Account",
                  {"Name":$account_name},
                  function(response){ alert('Success!'); },
                  function(jqXHR){ alert(jqXHR.responseText); }
              );
        });
    });
</script>

More Related Content

PPTX
適切な Azure AD 認証方式の選択の決め手
PPT
How to Tango with Salesforce & jQueryMobile for HTML5 Goodness
PDF
Visualforce + jQuery
PDF
Twitter連携chrome extension作り方
PDF
初めての Data API CMS どうでしょう - 仙台編 -
PDF
Summer '14開発者向け新機能Webinar
PPT
AppExchangeパートナー&デベロッパー第2部:20070523版
PDF
Webに今求められているレベル: HTML5 コントロールを利用した開発
適切な Azure AD 認証方式の選択の決め手
How to Tango with Salesforce & jQueryMobile for HTML5 Goodness
Visualforce + jQuery
Twitter連携chrome extension作り方
初めての Data API CMS どうでしょう - 仙台編 -
Summer '14開発者向け新機能Webinar
AppExchangeパートナー&デベロッパー第2部:20070523版
Webに今求められているレベル: HTML5 コントロールを利用した開発

Similar to 勉強会force#2 HTML5によるモバイルアプリ開発 (20)

PPT
20061125
PDF
Tech talk salesforce mobile sdk
PPTX
HTML5 on ASP.NET
PDF
jQuery と MVC で実践する標準志向 Web 開発
PPTX
html5j.orgがHTML5+JavaScriptで Metro Style アプリを作ってみた
PDF
初めての Data api cms どうでしょう - 大阪夏の陣
PPT
Apexコアデベロッパーセミナー070726 配布用
PDF
Data apiで実現 進化するwebの世界
PDF
勉強会force#3 iOSアプリ開発
PDF
Spring16 リリース開発者向け新機能Webセミナー
PDF
初めての Data api
PDF
SocialWeb Conference vol.5 OpenSocial Night #2
PDF
Jqm20120210
PDF
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
PDF
Lightning Experience 時代のプロセス開発
PDF
jQuery Mobile 最新情報 & Tips
PDF
XPagesDay2014 A-4 XPages with jQueryMobile BADプラクティスガイド
PDF
Webエンジニアがラクして企業向けモバイルアプリを作る方法 ~Salesforce1モバイルコンテナを使った開発手法~
PDF
Spring12新機能webinar
PDF
Progressive Framework Vue.js 2.0
20061125
Tech talk salesforce mobile sdk
HTML5 on ASP.NET
jQuery と MVC で実践する標準志向 Web 開発
html5j.orgがHTML5+JavaScriptで Metro Style アプリを作ってみた
初めての Data api cms どうでしょう - 大阪夏の陣
Apexコアデベロッパーセミナー070726 配布用
Data apiで実現 進化するwebの世界
勉強会force#3 iOSアプリ開発
Spring16 リリース開発者向け新機能Webセミナー
初めての Data api
SocialWeb Conference vol.5 OpenSocial Night #2
Jqm20120210
DBP-020_いざ無制限のデータの彼方へ! ~Azure Data Lake 開発の知識とベストプラクティス~
Lightning Experience 時代のプロセス開発
jQuery Mobile 最新情報 & Tips
XPagesDay2014 A-4 XPages with jQueryMobile BADプラクティスガイド
Webエンジニアがラクして企業向けモバイルアプリを作る方法 ~Salesforce1モバイルコンテナを使った開発手法~
Spring12新機能webinar
Progressive Framework Vue.js 2.0
Ad

More from Kazuki Nakajima (20)

PDF
ビーコンBotによるニュータイプな受付
PDF
Apexで作成したrest apiをしっかり保護する方法
PDF
Waterfall cafeで働くBot
PPTX
AIが入った栄養士Botのアーキテクチャー
PDF
AIを組み込んだ近未来のアプリケーションで感じる新しいサービスの新しい開発手法
PDF
畑と会話するニュータイプなIo tアプリで加熱中の技術トレンドを鷲掴みにする45分
PDF
無償のAPEXワークスペース取得方法
PDF
Oracle Cloudのjava実行環境
PDF
実はDatabase cloudだけで実現できる巷で噂の機械学習とは?
PDF
海外で人気沸騰中のIo tデバイスとdatabase cloudで構成するシンプルなiot構成を学ぶ
PDF
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
PDF
今さらきけない環境ハブ
PDF
Spring'15 ISV様向け新機能紹介
PDF
絶対使いたくなるAppexchangeアプリとそのアーキテクチャー
PDF
ビジネスアイデアを最速で形にできるApp exchange
PDF
キャンバス個人用アプリ 速習ガイド
PDF
活躍中のアプリケーションから紐解くForcecom
PDF
Upwardのご紹介
PDF
Salesforce1入門
PDF
Force.com canvas入門ガイド
ビーコンBotによるニュータイプな受付
Apexで作成したrest apiをしっかり保護する方法
Waterfall cafeで働くBot
AIが入った栄養士Botのアーキテクチャー
AIを組み込んだ近未来のアプリケーションで感じる新しいサービスの新しい開発手法
畑と会話するニュータイプなIo tアプリで加熱中の技術トレンドを鷲掴みにする45分
無償のAPEXワークスペース取得方法
Oracle Cloudのjava実行環境
実はDatabase cloudだけで実現できる巷で噂の機械学習とは?
海外で人気沸騰中のIo tデバイスとdatabase cloudで構成するシンプルなiot構成を学ぶ
鳥肌必至のニューラルネットワークによる近未来の画像認識技術を体験し、IoTの知られざるパワーを知る
今さらきけない環境ハブ
Spring'15 ISV様向け新機能紹介
絶対使いたくなるAppexchangeアプリとそのアーキテクチャー
ビジネスアイデアを最速で形にできるApp exchange
キャンバス個人用アプリ 速習ガイド
活躍中のアプリケーションから紐解くForcecom
Upwardのご紹介
Salesforce1入門
Force.com canvas入門ガイド
Ad

勉強会force#2 HTML5によるモバイルアプリ開発

  • 2. Safe Harbor Safe harbor statement under the Private Securities Litigation Reform Act of 1995: This presentation may contain forward-looking statements that involve risks, uncertainties, and assumptions. If any such uncertainties materialize or if any of the assumptions proves incorrect, the results of salesforce.com, inc. could differ materially from the results expressed or implied by the forward-looking statements we make. All statements other than statements of historical fact could be deemed forward-looking, including any projections of product or service availability, subscriber growth, earnings, revenues, or other financial items and any statements regarding strategies or plans of management for future operations, statements of belief, any statements concerning new, planned, or upgraded services or technology developments and customer contracts or use of our services. The risks and uncertainties referred to above include – but are not limited to – risks associated with developing and delivering new functionality for our service, new products and services, our new business model, our past operating losses, possible fluctuations in our operating results and rate of growth, interruptions or delays in our Web hosting, breach of our security measures, the outcome of intellectual property and other litigation, risks associated with possible mergers and acquisitions, the immature market in which we operate, our relatively limited operating history, our ability to expand, retain, and motivate our employees and manage our growth, new releases of our service and successful customer deployment, our limited history reselling non-salesforce.com products, and utilization and selling to larger enterprise customers. Further information on potential factors that could affect the financial results of salesforce.com, inc. is included in our annual report on Form 10-Q for the most recent fiscal quarter ended April 30, 2011. This documents and others containing important disclosures are available on the SEC Filings section of the Investor Information section of our Web site. Any unreleased services or features referenced in this or other presentations, press releases or public statements are not currently available and may not be delivered on time or at all. Customers who purchase our services should make the purchase decisions based upon features that are currently available. Salesforce.com, inc. assumes no obligation and does not intend to update these forward-looking statements.
  • 4. 3タイプのアプリケーション Native • オンラインストアからインストール • モバイル端末のH/W機能を活用 • リッチなユーザエクスペリエンス • 特殊な開発能力が必要
  • 5. 3タイプのアプリケーション Web • ブラウザからアクセス • 端末を問わないシングルコードベース • 限定的なH/Wアクセス • 非互換なイベント • 開発者を確保し易いWebベースの開発
  • 6. 3タイプのアプリケーション Web + HTML5 • ブラウザからアクセス • 端末を問わないシングルコードベース • 限定的なH/Wアクセス • Nativeのようなモバイル用UI • 開発者を確保し易いWebベースの開発
  • 7. 3タイプのアプリケーション Hybrid • オンラインストアからインストール • モバイル端末のH/Wを活用 • リッチなユーザエクスペリエンス • 開発者を確保し易いWebベースの開発
  • 8. Force.comでのWeb + HTML5アプリ提供形態 Database Apex Visualforce js / css Force.com 3rd Party HTML5
  • 9. Database.comでのWeb + HTML5アプリ提供形態 Database Apex API Open Web Platform js / css Database.com 3rd Party HTML5
  • 13. Visualforce PageにjQuery Mobileをロード <apex:page sidebar="false" showHeader="false" standardStylesheets="false" standardController="Session__c" extensions="sugoiSurvey" contentType="text/html" doctype="HTML-5.0"> <apex:stylesheet value="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" /> <apex:includescript value="http://code.jquery.com/jquery-1.7.1.min.js" /> <apex:includescript value="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js" /> <head> <title>{!$label.sugoiSurvey}</title> <meta name="viewport" content="width=device-width, initial-scale=1" /> <script type="text/javascript"> j$ = jQuery.noConflict(); </script> • <apex:stylesheet>,<apex:includescript>でライブラリ(jQuery, jQuery Mobile)をロード • <meta name="viewport">で表示サイズをモバイル端末画面に最適化 • jQuery.noConfilict();で$を変更
  • 14. jQuery Mobileでのページ構造 <div id="session_list" data-role="page"> <div data-role="header"> </div> <div data-role="content"> <a href="#session_detail">Session 1</a> </div> <div data-role="footer"> </div> </div> <div id="session_detail" data-role="page" data-add-back-btn="true"> <div data-role="header"> </div> <div data-role="content"> </div> <div data-role="footer"> </div> </div> • <div data-role="page">で1つの画面を表示 • 1htmlファイルに複数の画面を記述可能。デフォルトでは最初のpageを表示。 • ページ内リンク<a href="#{ID}">にて画面遷移。各<div>にid="{ID}"を設定しておく • data-add-back-btn="true"でヘッダにbackボタンを自動表示可能
  • 15. リスト <div id="session_list" data-role="page" > <div data-role="header"><h1>セッションリスト</h1></div> <div data-role="content"> <ul data-role="listview" data-inset="true" data-filter="true"> <li><a href="#session1">Session 1</a></li> <li><a href="#session2">Session 2</a></li> <li><a href="#session3">Session 3</a></li> </ul> </div> </div> <div id="session1" data-role="page" data-add-back-btn="true"> <div data-role="header"><h1>セッション詳細</h1></div> <div data-role="content"> <ul data-role="listview"> <li data-role="list-divider">Session 1</li> <li>セッション 1の詳細</li> </ul> </div> </div> • <ul data-role=”listview”>でTouchに適したリストを表示 • <ul data-filter=”true”>でリスト絞り込み用サーチボックスを表示 • <li data-role=”list-divider”>でリストの見出を設定
  • 16. サンプルアプリのトップページ <div id="session_list" data-role="page" data-theme="d"> <div data-role="header"> <h1>{!$label.sessionList}</h1> <a href="#create_session" class="ui-btn-right" data-icon="plus" data-transition="slideup">{!$label.new}</a> </div> <div data-role="content"> <ul data-role="listview" data-inset="true" data-divider-theme="d" data-filter="true" data-split-icon="gear"> <apex:repeat var="session" value="{!sessions}"> <li class="session"> <a href="/apex/sugoiSurveyM_detail?id={!session.id}" data-ajax="false"> <h3>{!session.name}</h3> <p> {!session.presenter__r.company__c} {!session.presenter__r.title__c} {! session.presenter__r.name}<br /> {!YEAR(session.Date__c)}.{!MONTH(session.Date__c)}.{!DAY(session.Date__c)} #{! session.hash_tag__c} </p> <span class="ui-li-count">{!session.rate_avg__c}pt</span> </a> <a href="/apex/sugoiSurveyM_edit?id={!session.id}" data-ajax="false"></a> </li> </apex:repeat> </ul> </div> </div>
  • 18. JavaScript RemotingでApexを実行 Apex @RemoteAction public static void submitSurveyJs(id session, string rate){ survey__c survey = new survey__c(session__c = session, rate__c = rate); insert survey; } • @RemoteActionアノテーションを対応Methodに付加 • global/publicかつstaticのMethodを定義 Visulaforce Page j$('#submit_survey').tap(function(){ var rate = j$('input:radio:checked').val(); sugoiSurvey.submitSurveyJs( "{!session__c.id}", rate, function(result, event){ alert(event.message); }, {escape:true} ); }); • sugoiSurvey.submitSurveyJs() => {Class名}.{Method名}()で対応するApexを実行 • resultでクラスからの返り値を参照 • eventでApexからの実行結果を参照
  • 21. OAuth (PHP + REST) OAuth Toolkit for PHPをドキュメントルートに設置 https://github.com/nkjm/Force.com-OAuth-Toolkit-for-PHP 認証下に置くphpファイルの先頭 <?php session_start(); if (!isset($_SESSION['access_token']) || !isset($_SESSION['instance_url'])) { $_SESSION['oauth_return'] = $_SERVER['PHP_SELF'] . '?' . htmlspecialchars(SID); header( 'Location: /oauth/oauth.php?' . htmlspecialchars(SID)); } • 認証されているセッションは常に$_SESSION[‘access_token’]にTokenを保持 • Tokenがなければ、 1.ローカルのOAuthライブラリにリダイレクト。 2.Salesforceの認証サーバにリダイレクトされ、認証 => 「コード」取得。 3.ローカルのOAuthライブラリにリダイレクト。SalesforceのTokenサーバからTokenを取得。 4.$_SESSION[‘access_token’]にTokenを保存し認証下のコンテンツにリダイレクト。
  • 23. OAuth (PHP + REST) Tokenを用いたREST APIアクセス $query = ‘select name from session__c’; $url = $_SESSION[‘instance_url’] . “/services/data/" . VERSION . "/query?q=" . urlencode($query); $curl = curl_init($url); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_HTTPHEADER, array("Authorization: OAuth “ . $_SESSION[‘access_token’])); $json_response = curl_exec($curl); $status = curl_getinfo($curl, CURLINFO_HTTP_CODE); if ($status != 200) { if ($status == 401){ $response = json_decode($json_response); if ($response[0]->errorCode == 'INVALID_SESSION_ID') { header( 'Location: oauth/oauth.php' ); } } $curl_error = curl_error($curl); $curl_errno = curl_errno($curl); die("Status Code: $status <br/>Response: $json_response <br/> Curl Error: $curl_error <br/>Curl Errno: $curl_errno"); } curl_close($curl); $response = json_decode($json_response, true); return($response);
  • 24. OAuth (PHP + JavaScript + REST) Force.com JavaScript REST API Toolkit https://github.com/developerforce/Force.com-JavaScript-REST-Toolkit forcetk.js
  • 25. OAuth (PHP + JavaScript + REST) Force.com JavaScript REST API Toolkitをドキュメントルートに設置 [root@server]# ls ${DOCUMENT_ROOT}/ forcetk.js proxy.php index.php oauth/ HTMLから読み込み <!DOCTYPE html> <html> <head> <title><?php echo LABEL_SUGOISURVEY; ?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" /> <link href="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="http://code.jquery.com/jquery-1.7.min.js"></script> <script type="text/javascript" src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script> <script type="text/javascript" src="forcetk.js"></script> </head>
  • 26. OAuth (PHP + JavaScript + REST) POSTでレコードを作成 <script type=”text/javascript”> $(document).ready(function(){ var $client_id = "[あなたのConsumer ID]"; var $proxy_url = "https://[あなたのWebサーバ]/proxy.php?mode=native"; // REST APIアクセスを抽象化するWrapperを初期化 var client = new forcetk.Client($client_id, null, $proxy_url); // セッション情報をセット client.setSessionToken('<?php echo $_SESSION["access_token"]; ?>', null, '<?php echo $_SESSION["instance_url"]; ?>'); $('#account_form :button').click(function(){ var $account_name = $('#account_form :text').attr('value'); // createメソッドでAccountレコードを作成。第一引数はオブジェクト名。第二引数はフィールド。第三引数は成功時のコールバック。 第四引数はエラー時のコールバック。 client.create( "Account", {"Name":$account_name}, function(response){ alert('Success!'); }, function(jqXHR){ alert(jqXHR.responseText); } ); }); }); </script>