読者です 読者をやめる 読者になる 読者になる

アプリカンブログ

HTML5でiOS/Androidアプリが開発できるプラットフォーム、アプリカンのブログです。

アプリカンを使ってスマートフォンアプリを作ってみよう(位置情報検索アプリ)

前回はコンパスを作ってみましたが、今回はネットワークも使う位置情報検索アプリを作ってみたいと思います。ネットワークを使う場合、その内容がJavaScriptだけの場合とアプリカンを使った場合で多少異なります。

ドメイン制限

フロントエンドエンジニアの方であればご存じですが、Webアプリケーションの場合はJSONデータを取得する場合、同一ドメインまたはJSONPを使う必要があります。対してアプリカンの場合アプリという枠組みになりますのでデータは自由に取得ができるようになっています。セキュリティ上制限を行う場合は applican-config.xml を使って制限を行います。

そのため開発中はJSONPで取得するのですが、アプリにする場合はアプリカンの applican.http.get を使う形になります。このあたりは環境によって使うメソッドを分けるようにした方が良さそうです。

HTMLファイルの準備

では早速HTMLファイルを用意します。完成品ですが、次のようになります。

<html ng-app="ionicApp">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
    <title>Ionic List Directive</title>
    <link href="lib/ionic/css/ionic.css" rel="stylesheet">
    <script src="lib/ionic/js/ionic.bundle.js"></script>
    <script src="lib/applican.js"></script>
  </head>
  <body ng-controller="MyCtrl">
    <ion-header-bar class="bar-positive">
      <h1 class="title">アプリカンマップ</h1>
      </div>
    </ion-header-bar>
    <ion-content>
      <!-- The list directive is great, but be sure to also checkout the collection repeat directive when scrolling through large lists -->
      <ion-list ng-controller="MyCtrl"
        can-swipe="listCanSwipe">
        <ion-item ng-repeat="item in items"
          class="item-thumbnail-left">
          <img ng-src="{{item.img}}">
          <h2 ng-click="openPopover($event, item)">{{item.title}}</h2>
        </ion-item>
      </ion-list>
    </ion-content>
    <script id="my-popover.html" type="text/ng-template">
      <ion-popover-view>
        <ion-header-bar>
          <h1 class="title">{{item.title}}</h1>
        </ion-header-bar>
        <ion-content>
          <img src="http://maps.googleapis.com/maps/api/staticmap?center={{item.lat}},{{item.lng}}&zoom=18&size=200x200&sensor=false">
        </ion-content>
      </ion-popover-view>
    </script>
   <script src="js/app.js"></script>
  </body>
</html>

今回もフレームワークとしてIonicを使っています。そのため基本的な書き方はAngularJSに従っています。

現在位置情報を使って近くのベニュー情報を取得

今回の最初の流れとしては、

  1. 現在位置の取得
  2. Foursquareを使ってベニュー検索
  3. リストに表示

になります。

まず現在位置の取得は、 applican.geolocation.getCurrentPosition を使います。リファレンスはこちらにあります。

angular.module("ionicApp", ["ionic"]).factory('GeoSearchService', function($q, $timeout) {
  return {
    getCurrentPosition: function() {
      var deferred, options;
      deferred = $q.defer();
      options = {
        maximumAge: 10000,
        timeout: 30000,
        enableHighAccuracy: false
      };
      // アプリカンの処理部分
      applican.geolocation.getCurrentPosition(function(res) {
        return deferred.resolve(res);
      }, function(res) {
        return deferred.reject(res);
      }, options);
      return deferred.promise;
    }
  };
}).controller("MyCtrl", function($scope, $ionicPopover, GeoSearchService, FoursqureService) {
  :
  GeoSearchService.getCurrentPosition().then(function(res) {
    var c;
    c = res.coords; // 位置情報が返ってきます。
  });
  :
});

今回はAngularJSのファクトリーに追加してあります。 GeoSearchService.getCurrentPosition を実行すると、現在位置が返ってきます。

次にこの位置情報を使ってFoursquareを検索します。別途Foursquareのクライアントキーとシークレットキーが必要なので用意してください。

こちらの処理もまたファクトリー化します。

.factory('FoursqureService', function($q, $http, $timeout) {
  return {
    getVenues: function(lat, lon) {
      var client_id, deferred, options, secret;
      deferred = $q.defer();
      client_id = "FOURSQUARE_CLIENT_KEY";
      secret    = "FOURSQUARE_SECRET_KEY";
      options = {
        timeout: 10000,
        headers: {},
        verboseoutput: true
      };
      applican.http.get("https://api.foursquare.com/v2/venues/search?ll=" + lat + "," + lon + "&client_id=" + client_id + "&client_secret=" + secret + "&v=20140715&limit=50", options, function(res) {
        res = JSON.parse(res);
        return deferred.resolve(res.response);
      }, function(res) {
        console.log(res);
        return deferred.reject(res);
      });
      return deferred.promise;
    }
  };
})

ここで注意して欲しいのが外部リソースの取得部分になります。 applican.http.get というメソッドを使っています。この場合、JSONデータがそのまま取得できるようになりますが、取得される値はJSONでパースされていません。そのため JSON.parse を使ってJSONオブジェクトに変換する必要があります。

後は取得されたベニューデータを一覧表示すれば初期画面の完了です。

f:id:moongift:20141127213036p:plain

タップして地図を表示

これはアプリカンではなくAngularJSの実装だけになりますが、単純に表示して終わりよりは良いと思いますので紹介します。一覧表示の際に、

<h2 ng-click="openPopover($event, item)">{{item.title}}</h2>

とすることでイベントを呼び出しています。

$ionicPopover.fromTemplateUrl("my-popover.html", {
  scope: $scope
}).then(function(popover) {
  $scope.popover = popover;
});
$scope.openPopover = function($event, item) {
  $scope.item = item;
  $scope.popover.show($event);
};

こちらがその表示処理部分で、受け取ったitemでポップオーバーを描画しています。そうすると次の画像のようにGoogleマップ(静的画像版)を表示するという仕組みです。

f:id:moongift:20141127213054p:plain

その他必要なファイルのダウンロード

アプリカンのアプリを開発する際に必要なファイルをダウンロードします。web.zipをダウンロードして、解凍します。そして以下のファイルを開発しているプロジェクトに配置しましょう。

f:id:moongift:20141127213111p:plain

applican-config.xml : アプリカンの基本設定ファイルです。

applican.js : アプリカンAPIを利用するために必要な制御ファイルです。

whitelist.xml : アプリケーションからURL・ファイルのアクセス制御をする際に必要なファイルです。

最終的に次のようなファイル構成になります。これで開発が完了です。

f:id:moongift:20141127213126p:plain

圧縮してアップロード

開発したプロジェクトを web というディレクトリ名にしてZip圧縮します。次のようなコマンドで可能です。

$ rm -R web.zip web # 古いのは消す
$ cp -r compass web # 今回のプロジェクトをコピー
$ zip -r web.zip web # 圧縮

※ 今回のプロジェクトがcompassというフォルダであった場合です。webというディレクトリで作っている場合は古いものを削除する必要はありません。

アップロードはアプリカンの管理画面、アップロードメニューから行います。

f:id:moongift:20141127213142p:plain

コンテンツのアップロードフォームで先ほど作成したweb.zipを指定します。

f:id:moongift:20141127213156p:plain

これで完了です。

アプリカンシミュレータで確認する

アップロードが終わったらアプリカンシミュレータを起動します。Android版iOS版がありますのでそれぞれ入手してください。

アプリを起動し、アプリカンのユーザIDとパスワードでログインすると、登録しているプロジェクトが一覧で確認できます。その中から先ほど作成したプロジェクトをタップします。

プロジェクトが開いた後、少し待つと近隣のベニューが一覧表示されます。

f:id:moongift:20141127213211p:plain

その中から好きなものをタップすると、小さな地図が表示されます。

f:id:moongift:20141127213225p:plain

今回は以上になります。


位置情報を取得するのはとても簡単なので、後はそれを使ってどう表示するか(大抵は地図か位置情報検索に利用されると思います)が大事になるのではないでしょうか。アプリカンを使った位置情報アプリを作られる際にはぜひ参考にしてください。

今回のソースコードはGitHubにアップロードしてあります。動かないといった時には参考にしてください。