ionic(cordova)にてtwitterログインを実装

やりたいことは、Twitterアカウントでのログインの実装。
前提としては、fabricへは登録済みであること。

やることは以下
・fabricからorganizationsを作成
twitterアプリを作成
twitter-connect-pluginプラグインの導入
・プログラム実装

fabricからorganizationsを作成

https://fabric.io/settings/organizations

作成したorganizationsの詳細画面へ行くと小さく「API Key」というのがあるのでコレをメモしておく。
ちなみに「Build Secret」というのもあるが今時点ではこちらは未使用。

twitterアプリを作成

https://apps.twitter.com/
作る際にハマったのが、今回は「Callback URL」使わないと思って未設定だったのだがこれが空だとなぜかうまくいかず。適当なURLをいれたらなぜかいけた。。
アプリを作ると「Consumer Key (API Key)」と「Consumer Secret (API Secret)」が確認できるのでこれをメモしておく。

twitter-connect-pluginプラグインの導入

ちょっと調べたらこのプラグインが1番ヒット気がしたので今回はこれで。

xxxxxの部分はfabricでメモした「API Key」

$ ionic plugin add twitter-connect-plugin --variable FABRIC_KEY=xxxxx

config.xml

・・・
  <preference name="TwitterConsumerKey" value="xxxxx" />
  <preference name="TwitterConsumerSecret" value="zzzzzz" />
</widget>

twitterアプリ作成時にメモしたConsumer KeyとConsumer Secretを設定

プログラム実装
TwitterConnect.login(
  function(result) {
    // 成功
    console.log(result);
  }, function(error) {
    // 失敗
  }

前もfabricでの作業で完結するのか、twitterアプリをつくらなきゃならないのか。。てところで迷ってる気がする。両方って覚えておけばよいのかな。以上です。

ionic(cordova)にてGoogle+ログインを実装

簡単なものかと思ったらけっこう時間かかった。。

手順はざっくり以下
・ionicプロジェクトを作成
Googleコンソールからプロジェクトを作成
・作ったプロジェクトに認証情報を作成
・cordova-plugin-googleplusプラグインを導入
・プログラム実装

ionicプロジェクトを作成

まずはプロジェクト作って、androidを追加する。

$ ionic start google-login blank --v1
$ cd google-login
$ ionic platform add android
Googleコンソールからプロジェクトを作成

まずはここからプロジェクトを作成
https://console.developers.google.com/apis/dashboard

作ったプロジェクトに認証情報を作成

「認証情報を作成」から「OAuthクライアントID」を作成

ios
バンドルIDが必要

android
名証明書フィンガープリントとパッケージ名が必要

フィンガープリントは以下のコマンドで確認。SHA1の内容をコピーして貼り付ける

$ keytool -exportcert -list -v -alias androiddebugkey -keystore ~/.android/debug.keystore
$ キーストアのパスワードを入力してください:  android (パスワードはandroidぽい)
・・・
証明書のフィンガプリント:
         MD5:  ・・・
         SHA1: ・・・
         SHA256: ・・・
         署名アルゴリズム名: SHA256withRSA
         バージョン: 3
・・・

パッケージ名はiosのバンドルIDと同じ。

cordova-plugin-googleplusプラグインを導入

以下のコマンドでプラグイン導入。iOS の URL スキームは認証情報を作成する際に作られる。Googleコンソールの認証情報の画面から確認できる。

$ ionic plugin add cordova-plugin-googleplus --variable REVERSED_CLIENT_ID=[iOS の URL スキーム]
プログラム実装
・・・
  .controller("MainCtrl", function($scope, $timeout) {
    $timeout(function() {
      window.plugins.googleplus.login({ /* なくてもデフォルトの設定で動く */ }
      /* scopesを指定したい場合はスペースで複数指定可
      {
        'scopes': 'https://www.googleapis.com/auth/youtube.readonly https://www.googleapis.com/auth/userinfo.profile'
      }
      */
      , function (obj) {
        console.log(obj);
      }, function (msg) {
        alert('error: ' + msg);
      });
    }, 3000);
・・・

以上です

その他URLメモ
https://github.com/EddyVerbruggen/cordova-plugin-googleplus
https://developers.google.com/mobile/add?platform=ios&cntapi=signin
https://developers.google.com/mobile/add?platform=android&cntapi=signin

ionic(cordova)でiOSでのキーボード入力で完了ボタンを表示する

inputタグでキーボード表示したあとに何かたりないと思ったら、完了ボタンがなかった。
ionic startで作ったプロジェクトだとデフォルトで非表示に設定されてるぽい。

app.js

angular.module('starter', ['ionic'])
.run(function($ionicPlatform) {
  $ionicPlatform.ready(function() {
    if(window.cordova && window.cordova.plugins.Keyboard) {
      // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
      // for form inputs)

      // ★ここをfalseに変更
      //cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
      cordova.plugins.Keyboard.hideKeyboardAccessoryBar(false);

      // Don't remove this line unless you know what you are doing. It stops the viewport
      // from snapping when text inputs are focused. Ionic handles this internally for
      // a much nicer keyboard experience.
      cordova.plugins.Keyboard.disableScroll(true);
    }
    if(window.StatusBar) {
      StatusBar.styleDefault();
    }
  });
});

これだけですが、デフォルトで表示でも良い気が。。以上です

angularのhttpでレスポンスヘッダーを取得する

今回やりたかったことは以下。
angularの$http.getまたは$http.postでAPIへリクエストしたレスポンスヘッダーを取得するということ。
chromeの開発ツールからはレスポンスヘッダーを確認できたのだが、angularでは取り扱う場合にうまく取得できずに少しはまりました。

$http.get("path/to")
  .success(function(result, status, headers) {
    // headers()
  });

上記の形で取得できるはずなのだが、なぜか上手くいかなかった。
理由ははサーバー側で対応する必要があったみたい。

下記の形でレスポンスヘッダーを追加してやればすんなり取得できました。

Access-Control-Expose-Headers: <header-name>, <header-name>, ...

以上です

【ionic】collection-repeatで行の高さを動的にする

まだ調査中。無限スクロール実装するときにng-repeatよりcollection-repeatを使った方がパフォーマンスが良いらしい。とのことで。試していたら行の高さが1行目の高さに合わせられてしまうようで、高さを動的にする場合は高さを計算してやる必要がありそう。

テンプレート

<ion-content>
  <ion-list>
    <ion-item class="item-text-wrap item-remove-animate item-avatar item-icon-right"
              ng-repeat="item in items"
              item-height="getHeight(item)">
      <img ng-src="{{item.face}}">
      <h2>{{item.name}}</h2>
      <p>{{item.lastText}}</p>
    </ion-item>

    ・・・

  </ion-list>                                                                                                                                                                                                      

  <!-- 計算用に準備 -->
  <ion-item class="item-text-wrap item-remove-animate item-avatar item-icon-right"
            id="calculateItem">
    <img ng-src="">
    <h2></h2>
    <p></p>
  </ion-item>
</ion-content>

コントローラ

// 計算用DOM
var calculateItem = document.getElementById("calculateItem");

// 計算用DOMに値を入れて高さを計算して返す
$scope.getHeight = function(item) {
  var h2 = dummy.getElementsByTagName('h2')[0];
  var p = dummy.getElementsByTagName('p')[0];
  h2.textContent = item.name;
  p.textContent = item.lastText;
  return dummy.clientHeight;
};

とりあえずこれで動いた。collection-repeatの方がパフォーマンスが良いとかこのやりかたでパフォーマンスがよいかとかまではまだ調べられていない。以上です。

【Angularjs】PromiseでforEachで同期処理で順次実行する

こちらのコードを実行すると、testが1秒間隔で3回順次実行される。

var test = function() {
  var deffered = $q.defer();
  $timeout(function() {
    deffered.resolve();
  }, 1000);
  return deffered.promise;
};

var deffered = $q.defer();
var promise = deffered.promise;

promise
  .then(function() {
    var deffered = $q.defer();
    var promise = deffered.promise;
    for	(var i = 0; i < 3; i++) {
    // [1, 2, 3].forEach(function(v) { // forEachも一緒
      promise = promise.then(function() {
        return test();
      })
        .then(function() {
          var deffered = $q.defer();
          deffered.resolve();
          return deffered.promise;
	});
    });
    deffered.resolve();
    return promise;
  });
  deffered.resolve();

やりたかったのはこれだけ。以上です。

ionic(cordova)にて$ionicPopupをカスタマイズしてモーダルを作る

今回やりたかったのはこんな感じの画面。
初めはionicModalのサイズを変えてやろうとしていたのだが、モーダルのサイズを中のテキストとかにあわせてリサイズするのを自前で実装するのが手間でした。
で、少し調べたらionicPopupをカスタマイズしたら簡単にできたのでその手順をメモ。

f:id:yoppy0066:20170810130806g:plain:w250

ionic-close-popup をインストール

ポップアップの外をタップしたらポップアップを閉じるのを簡単に実現できるライブラリ。
https://github.com/mvidailhet/ionic-close-popup

インストール

$ bower install ionic-close-popup

index.htmlで読み込む

<script src="lib/ionic-close-popup/ionic-close-popup.js"></script>
ポップアップ画面を用意

ていっても今回はこれだけ

templates/custome_popup.html

Custom Popup!!
ポップアップを呼び出す

コントローラー

・・・
  .controller('DashCtrl', function(
    $scope,
    $ionicPopup,
    IonicClosePopupService
  ) {

    var popup = null;

    $scope.showPopup = function() {
      popup = $ionicPopup.alert({
        scope: $scope,
	cssClass: "custom-popup", // ★ 見た目をカスタマイズするためにCSSのクラスを追加
        templateUrl: "templates/custom_popup.html"
      });
      IonicClosePopupService.register(popup);
    };
  })
・・・

テンプレート

<ion-view view-title="Dashboard">
  <ion-content class="padding">
    <a ng-click="showPopup()">ポップアップOPEN</a>
  </ion-content>
  <style>                                                                                                                                                                                                          
  <!-- ポップアップサイズを指定することも可能 -->                                                                                                                                                                  
   .custom-popup .popup {
       width: 86%;
       height: 90%;
   }
   <!-- デフォルトで用意されているボタンとヘッダー部分を非表示に -->
   .custom-popup .popup-head,                                                                                                                                                                                      
   .custom-popup .popup-buttons {
       display:none;
   }
  </style>
</ion-view>

これだけでいけた。以上です