ページ

ラベル PhoneGap の投稿を表示しています。 すべての投稿を表示
ラベル PhoneGap の投稿を表示しています。 すべての投稿を表示

2016年11月6日日曜日

PhoneGapを使用する 5 - React Hot Reloading Templateを試す -


Phonegapの公式テンプレートで
react-hot-loaderがあります。(※筆者のPhonegapのバージョン:6.3.2)
$ phonegap template list
・・・省略・・・
react-hot-loader   Starter PhoneGap project using React.js, Babel, Webpack and Hot Reloading.
PhonegapでReact.jsを使えて、環境はBabel、WebpackでHot Reloadingする
という事なので早速試してみたいと思います。

プロジェクト作成


プロジェクトの作成は以下のコマンドでサクッと作成できます。
$ phonegap create [プロジェクト名] --template react-hot-loader
作成したプロジェクトの構成は次のようになっています。
.
├── config.js
├── config.xml
├── env.js
├── hooks
├── package.json
├── platforms
├── plugins
├── res
├── src
│   ├── components
│   │   ├── Hello.js
│   │   └── Message.js
│   ├── css
│   │   ├── hello.css
│   │   ├── index.css
│   │   └── message.css
│   └── index.js
├── webpack.config.js
└── www
    ├── icon.png
    └── index.html
ちゃんとwebpack.config.jsが用意されています。
.jsxが見当たらないですが、Hello.js、Message.jsで実装されてます。
次に依存パッケージをインストールします。
$ npm install
これで準備完了です。

ブラウザで実行&確認


それでは早速実行してみたいと思います。
まずはブラウザで確認。
$ npm start
起動完了後http://localhost:8080を見てみると
gif1
↑のような画面が表示されており。ボタンを押すと「Hello World」と表示され
しばらく経つと消えます。
次にHot Reloadが効いているか確認してみます。
gif2
ちょっと分かりにくいかもしれませんが、ボタンの文字を修正し
保存するとちゃんとブラウザ側のボタンに反映されています。

iOSシュミレータで確認


次はiOSのシュミレータで確認してみます。
まずはiOS用のプラットフォームを追加。
$ phonegap cordova platform add ios
次にシュミレータで動作する用にビルドしてやる必要があります。
ビルドせずに動かすと以下のエラーが発生します。
Failed to load webpage with error: Could not connect to the server.
また、Phonegapを使用している場合、package.jsonを以下のように修正します。
・・・省略・・・
"scripts": {
  "android": "phonegap cordova run android",
  "ios": "phonegap cordova run ios",
  "prepare": "node config && webpack && phonegap cordova prepare",
  "build": "node config && webpack && phonegap cordova build",
  "start": "node config && HOST=0.0.0.0 webpack-dev-server",
  "test": "echo \"No tests (yet!) -- submit a PR?\" && exit 0"
},
・・・省略・・・
あとは、
$ npm run build -- ios
$ npm run ios
で↓のようにシュミレータで動作できればOKです。
gif3

まとめ


Hot Reloadもできて、Babel, Webpackも揃っているので、
とても使いやすいのではないかと思います。
今後PhonegapでReact.jsを使う必要がある場合はオススメです。

2016年7月16日土曜日

Android MarshmallowのPermission問題をPluginで解決


Android 6.0(Marshmallow)からpermissionモデルが新しくなってます。

Android 6.0未満はインストール時に必要なpermissionsを一括で
同意し、アプリの実装も許可されているものとして実装してます。
が、
Android 6.0からはインストール後の初期状態は全て拒否されており、
アプリを起動して必要になった時にユーザーに同意を求めます。

PhoneGapを使ってる場合

Javaでネイティブでゴリゴリ実装〜という場合は素直にユーザーの同意が
必要になった場合に
if (checkSelfPermission(Manifest.permission.READ_CONTACTS)
        != PackageManager.PERMISSION_GRANTED) {
   // ユーザーに許可を求める
   ・・・・
}
といった具合に実装していかないといけませんが、PhoneGapなら
cordova-plugin-android-permissionsという便利なプラグインがっ!!

cordova-plugin-android-permissions


Android6.0未満の場合はpermissionチェックで全て許可済みになります。
今後の為に入れておいて損は無いかな〜と。
Install
$ phonegap cordova plugin add cordova-plugin-android-permissions
例)カメラのパーミッションが必要な場合
var permissions = cordova.plugins.permissions;
permissions.hasPermission(permissions.CAMERA, checkPermissionCallback, null);

function checkPermissionCallback(status) {
  if(!status.hasPermission) {
    var errorCallback = function() {
      console.warn('Camera permission is not turned on');
    }

    permissions.requestPermission(
      permissions.CAMERA,
      function(status) {
        if(!status.hasPermission) errorCallback();
      },
      errorCallback);
  }
}
指定できるpermission一覧はここで確認できます。

2016年5月8日日曜日

PhoneGapを使用する 4 - SwiftでPlugin作成 Camera実装 -


前回の続きをやっていきたいと思います。
前回はプラグインを経由してコンソールに文字を出力するだけでしたが、
今回はカメラの撮影画面を表示させてみたいと思います。
ちなみに現時点のプラグインのディレクトリ構成は、
├── custom-plugin-camera
│   ├── plugin.xml
│   ├── src
│   │   └── ios
│   │       └── CustomCamera.swift
│   └── www
│       └── CustomCamera.js
上のようになっています。

カメラ用のカスタムUIViewController作成


カメラ撮影用の画面を表示するカスタムUIViewControllerを作成します。
名前はCustomCameraViewController.swiftとし、
plugins/custom-plugin-camera
├── plugin.xml
├── src
│   └── ios
│       ├── CustomCamera.swift
│       └── CustomCameraViewController.swift ☆
└── www
    └── CustomCamera.js
src/ios配下に作成します。またplugin.xml
<source-file src="src/ios/CustomCameraViewController.swift" />
を追加します。
次にCustomCameraViewController.swiftを実装します。
import UIKit
import AVFoundation

class CustomCameraViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // セッションの作成.
        let session = AVCaptureSession()

        // デバイス一覧の取得.
        let devices = AVCaptureDevice.devices()

        // バックカメラをmyDeviceに格納.
        var device : AVCaptureDevice!
        for d in devices{
            if(d.position == AVCaptureDevicePosition.Back){
                device = d as! AVCaptureDevice
            }
        }

        let videoInput: AVCaptureInput!
        // バックカメラからVideoInputを取得.
        do {
            videoInput = try AVCaptureDeviceInput.init(device: device)
        } catch {
            videoInput = nil
        }

        // セッションに追加.
        session.addInput(videoInput)

        // 出力先を生成.
        let imageOutput = AVCaptureStillImageOutput()

        // セッションに追加.
        session.addOutput(imageOutput)

        // 画像を表示するレイヤーを生成.
        let videoLayer : AVCaptureVideoPreviewLayer = AVCaptureVideoPreviewLayer.init(session: session)
        videoLayer.frame = self.view.bounds
        videoLayer.videoGravity = AVLayerVideoGravityResizeAspectFill

        // Viewに追加.
        self.view.layer.addSublayer(videoLayer)

        // セッション開始.
        session.startRunning()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}
UIViewControllerクラスを継承したカスタムクラスを作成し、
画面が表示されたタイミングで実機の背面カメラの撮影画面を表示しています。
次にCustomCamera.swiftから呼ぶようにします。
import Foundation

@objc(CustomCamera) class CustomCamera : CDVPlugin {

    func start(command: CDVInvokedUrlCommand) {        
        let v : CustomCameraViewController = CustomCameraViewController()
        self.viewController.addChildViewController(v)
        self.viewController.view.addSubview(v.view)
    }
}
CDVPluginを継承しているのでself.viewController経由で
ViewControllerの追加、Viewの追加を行っています。

検証


ここまで出来たら早速動かしてみたいと思いますが、、
その前に・・プラグインを更新した場合、phonegap cordova buildしても
プラグインが反映されない場合があるので、
$ phonegap cordova platform rm ios
$ phonegap cordova platform add ios
上のように一度iosのプロジェクトを削除し、再度作成することでキレイに反映されます。
※他にもしかしたらいい方法があるのかもしれませんが・・
今回はカメラを使うので、実機で確認します。
platforms/ios/XXXX.xcodeprojを開き、Deviceに実機を選択し実行します。
※ Xcode7以上でないと実機でデバッグはできません。

また、実行時には設定が必要な場合があります。iphoneの場合、
設定 > 一般 > プロファイルとデバイス管理でデベロッパAPPを選択し認証します。
 
実行して画面全体に背面カメラの撮影画面が表示されていれば成功です^^

2016年5月4日水曜日

PhoneGapを使用する 3 - SwiftでPlugin作成 -


今回はPhoneGapの特徴であるPluginをSwiftで作成してみたいと思います。
とりあえず今回はiOSをターゲットにしたPluginを作成します。
Pluginとは?
PhoneGapのプラグインでは、WebViewからネイティブの機能を使えるようにしたものです。

Goal


プラグインを経由して、ネイティブ側でカメラを起動する所までやってみたいと思います。
今回はPlugin経由でネイティブ内で実行する所を確認し、次回カメラ起動をやってみたいと思います。

ディレクトリとファイルを作成


まずはカスタムプラグイン用のディレクトリを作成します。
$ mkdir plugins/custom-plugin-camera
次にplugin.xmlsrc/ios/CustomCamera.swiftwww/CustomCamera.jsを作成します。
ここまでのディレクトリ構成は
plugins
│
.
.
.
├── custom-plugin-camera
│   ├── plugin.xml
│   ├── src
│   │   └── ios
│   │       └── CustomCamera.swift
│   └── www
│       └── CustomCamera.js
│
├── android.json
├── fetch.json
└── ios.json
こんな感じです。

プラグイン実装


次にplugin.xmlを以下のように修正します。
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
    id="custom-plugin-camera"
    version="0.1.0">
    <name>CustomCamera</name>
    <description>Custom Camera Plugin</description>
    <license>Apache 2.0</license>
    <keywords>camera</keywords>

    <!-- ① -->
    <js-module src="www/CustomCamera.js" name="CustomCamera">
        <clobbers target="CustomCamera" />
    </js-module>

    <!-- ② -->
    <platform name="ios">
        <config-file target="config.xml" parent="/*">
            <feature name="CustomCamera">
                <param name="ios-package" value="CustomCamera" />
            </feature>
        </config-file>

        <js-module src="www/CustomCamera.js" name="CustomCamera">
            <clobbers target="CustomCamera" />
        </js-module>

        <source-file src="src/ios/CustomCamera.swift" />
    </platform>
</plugin>
① 
ここではプラグインを使う時に呼ばれるjsのモジュールを定義します。
ちなみに<clobbers target="CustomCamera" />は、プラグインを使う際に
CustomCameraでアクセスができるようにする為のものです。
例えば、プラグインでecho()メソッドが定義されていた場合、
CustomCamera.echo();
でメソッドが実行できます。
② 
ここではiosプラットフォームに関するプラグインの設定になります。
CustomCamera.jsを以下のように実装します。
var exec = require('cordova/exec');

var CustomCamera = {

  start: function() {
    exec(null, null, 'CustomCamera', 'start', []);
  }
};
module.exports = CustomCamera;
次にCustomCamera.swiftを実装します。
import Foundation

@objc(CustomCamera) class CustomCamera : CDVPlugin {

    func start(command: CDVInvokedUrlCommand) {
        print("exec from plugin")
    }
}
今回はただネイティブ側でprintするだけの実装です。
最後にplugins/ios.jsonに作成したプラグインを追加します。
    .
    .
    .
    "cordova-plugin-whitelist": {
        "PACKAGE_NAME": "xxxxxxxxx"
    },
    "custom-plugin-camera": {
        "PACKAGE_NAME": "xxxxxxxxx"
    }
iOSプラットフォームを追加し、作成されたxcodeprojファイルを開きます。
$ phonegap cordova platform add ios
$ open platforms/ios/XXXX.xcodeproj
Xcode上で実行し、コンソールにexec from pluginが表示されていれば成功です。


2016年4月29日金曜日

PhoneGapを使用する 2 - PhoneGap + Grunt で自動化 -


最近仕事でお世話になっているPhoneGap
タイトルがPhoneGapを使用する 2 となってますが、
実は随分前にPhoneGapを触っていた事があります。
その時から全然触ってなかったら、npmのバージョンが
$ npm -v
1.4.28
古い・・・古いすぎる!!
早速バージョンアップ
$ npm update -g npm
$ npm -v
3.8.7
すごいバージョンの差 ^^;
そんなこんなで今回はPhoneGapをタスクツールのGruntと
組み合わせてやってみたいと思います。

ちなみに・・・

PhoneGapと並んでよく出てくるワードでCordovaというのがあります
両者の違いですが、公式のFAQでは
PhoneGap is an open source distribution of Cordova. Think about Cordova’s relationship to PhoneGap like WebKit’s relationship to Safari or Chrome.
となっています。
CordovaをWebkitに例えるならば、PhoneGapはWebKitから派生したSafariやChromeみたいなもので、PhoneGapはCordovaを内包してるようなイメージです。
実際、PhoneGapはCordovaの全ての機能が使えます。

環境セットアップ

※ ここではPhoneGapのコマンドラインツールであるPhoneGap CLIを使用します!!
↑のnpmのアップデートをやりましたが、最初からセットアップする場合、
Node.jsのインストールが必要です。
次に最新のPhoneGap CLIをインストールします。
$ npm install -g phonegap@latest
プロジェクト作成から実行まで

次にプロジェクト作成〜実行まで一気にやりたいと思います。
# プロジェクトの作成
$ phonegap create <path> --id <id> --name <projectname>
# プラットフォームの追加(ios や androidなど)
$ phonegap cordova platform add <ios/android> --save
# ビルド
$ phonegap cordova build <ios/android>
# 実行
$ phonegap cordova run <ios/android>
※ と思ったらphonegapコマンドで以下のようなエラーが・・・
module.js:340
    throw err;
          ^
Error: Cannot find module 'phonegap-build-api'
    at Function.Module._resolveFilename (module.js:338:15)
    at Function.Module._load (module.js:280:25)
    at Module.require (module.js:364:17)
    at require (module.js:380:17)
    at Object.<anonymous> (/usr/local/lib/node_modules/phonegap/node_modules/phonegap-build/lib/phonegap-build/login.js:6:14)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    at Module.load (module.js:356:32)
    at Function.Module._load (module.js:312:12)
    at Module.require (module.js:364:17)
やっぱりアップデートが極端だったから?
色々試してもダメだったので、phonegapを再インストールしてみ他ところエラーがなくなりました。
$ sudo npm uninstall -g phonegap
$ npm install -g phonegap
エラーがなくなった所でビルドと実行をGruntのタスク化にしてみたいと思います。
タスク化するにあたりgruntgrunt-execをインストールします。
$ npm install -g grunt-cli
$ npm install grunt --save-dev
$ npm install grunt-exec --save-dev
プロジェクトのビルドと実行をタスク化してみたいと思います。
module.exports = function(grunt) {
  grunt.loadNpmTasks('grunt-exec');

  grunt.initConfig({
   exec: {
      build: {
         command: 'phonegap cordova build'
      },
      run: {
         command: 'phonegap cordova run'
      }
   }
  });

  grunt.registerTask('default', ['exec:build', 'exec:run']);
};
これで
$ grunt
とするとビルドと実行が可能になりました^^。