投稿

【Ionic(Cordova)】Telerik版WKWebViewのpluginでLocal Storageにデータを保存できるようにするには?

Ionic(Cordova)でWKWebViewを使う時にハマるのがLocal Storageの扱い。アプリを起動するたびにLocal Storageに保存したデータがリセットされるという問題だ。 公式のApache版 はこのように解決できる。 iPhoneアプリ開発メモ: WKWebViewでの環境構築がついに発表される iPhoneアプリ開発メモ: RPGツクールMVでiPhoenアプリビルド最新のcordovaでWKWebViewを使うセッティング 著者の方に感謝! Telerik版 は独自に解決した。Apache版が使えるようになった今となっては二度と使わない解決法だろうが、念の為に残しておこうと思う。 ポイントは ドキュメント にあるここだ。 0.5.1 Added support for config.xml property DisableLocalStorageSyncWithUIWebView (default false). Set it to true if you want to switch back to UIWebView and retain LS changes made while running WKWebView. つまり、デフォルトではUIWebViewのLSとWKWebViewのLSを同期するようになっていて、起動のたびにWKWebViewのLSが空のUIWebViewのLSで上書きされることが問題と考えられる。 この機能をOFFにするには (プロジェクト名)/config.xml に <preference name="DisableLocalStorageSyncWithUIWebView" value="true" /> と書く必要がある。もちろん保存した後、ionic prepare iosして設定を反映させる必要がある。 これで保存できるようになった。

AmazonのAppStoreで位置情報を使うアプリの対応端末を増やす方法

イメージ
最近AmazonのAppStoreはパーミッションに関する制約が厳しくなり、これまで何も言われなかったアプリが警告扱いになり、ついに非対応ということになってしまった。 問題のアプリは位置情報を扱うアプリなのだが、Amazonの端末はGPSを搭載している端末が少ないので、このままでは対応端末が非常に限られてしまう。 改善すべきはAndroidManifest.xmlに設定しているパーミッションの指定。現在、位置情報関連のパーミッションは次の2つ。 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> アプリの性質上、GPSほどの高い精度の位置情報は必要無いので、初めはACCESS_FINE_LOCATIONを消してみた。これでGPSを使わないようになるのではと考えたからだ。 これで対応端末は増えたが、ACCESS_COARSE_LOCATIONだけではキロ単位のズレが発生してしまうことが分かった。これはさすがにまずい^^; エラーの内容をよく見ると、「android.hardware.location.gps」がダメだと言っている。 ということは、「GPSは必須でない」という設定があるはず。ドキュメントを見ると <uses-feature> | Android Developers 「android.hardware.location.gps」というプロパティーがあった。そこで、このように指定することにした。 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <...

Swift2で二地点の緯度・経度からその距離を計算するには?

二地点の緯度・経度からその距離を計算する(日本は山だらけ〜) のJava版をSwift2に移植しました。数学は分かりません。理論も分かりません。でもSwiftとJavaは分かるので移植はできるのです(^^); オリジナルがMITライセンスなので、このコードもリスペクトを込めてMITライセンスとします。 // // GeoUtil.swift // import Foundation /** * 二地点の緯度・経度からその距離を計算する(日本は山だらけ〜) - http://yamadarake.jp/trdi/report000001.html */ @objc(GeoUtil) class GeoUtil: NSObject { static let BESSEL_A: Double = 6377397.155; static let BESSEL_E2: Double = 0.00667436061028297; static let BESSEL_MNUM: Double = 6334832.10663254; static let GRS80_A: Double = 6378137.000; static let GRS80_E2: Double = 0.00669438002301188; static let GRS80_MNUM: Double = 6335439.32708317; static let WGS84_A: Double = 6378137.000; static let WGS84_E2: Double = 0.00669437999019758; static let WGS84_MNUM: Double = 6335439.32729246; static let BESSEL: Int = 0; static let GRS80: Int = 1; static let WGS84: Int = 2; static func deg2rad(deg: Double) -> Double { return deg...

iOS9で位置情報を使う定期バックグラウンド処理をする場合のバッテリー消費を抑えるには?

iOSでのバックグラウンド処理の制限 iOSでのバックグラウンド処理は非常に制限されているが、いくつか方法はある。しかし、「定期的にバックグラウンド処理をする」という条件になるとかなり限られる。 どのような方法を選択できるかはアプリのタイプや目的によるが、アプリによらず選択できるであろう方法は少なくとも2つある。 Background fetch iOSがアプリの利用頻度などから「非定期に」バックグラウンド処理を動作させるので使えない。 Remote Notifications サーバーからのNotificationが届くタイミングでバックグラウンド処理を起動する方法だが、サーバーサイドの実装が必要な上、Notificationが届くタイミングはまちまちで、最悪の場合は届かないこともあるので、苦労の割に確実性に欠ける。 AndroidのAlarmManagerの代替は無いのか? 調べた限り、iOSではAndroidでいうところのAlarmManagerのようなバックグランド処理はできない。 iOSで言うところの「バックグラウンド」とは、タスクマネージャーにプロセスが残っている状態のこと である。つまり、ユーザーがタスクマネージャーからアプリを終了させたらバックグラウンド処理はできない。 位置情報の更新を利用した定期バックグラウンド処理を採用 幸い今回開発中のアプリは位置情報を利用するタイプのアプリなので、「Location updates」のcapabilityを利用して定期的にバックグラウンド処理をさせることができた。 位置情報の更新によるバッテリー消費を抑えるために考えた2つのこと(失敗) しかし、ここで気になるのは、バックグラウンドで位置情報を更新し続けることによるバッテリーの消費がどれだけのものなのかということ。 そこで、このあたりを参考にした。 Energy Efficiency Guide for iOS Apps: Reduce Location Accuracy and Duration 一番始めに考えたのは、iOS9から導入された requestLocation() を利用することだった。タイマーで必要な時だけrequestLocation()を使って位置情報を取得すればバッテリーの...

SwiftでCordova(ionic)のpluginを開発するには?

イメージ
Swiftでcordovaのプラグインを開発することはできるのだろうか? このあたりを見ると開発できそうだ。 Chris Dell - Software Developer :: Writing an iOS Cordova plugin in pure Swift How to write Cordova plugin in Swift? - Stack Overflow やってみよう。 今回はChrisさんのコードを参考に、HTMLからネイティブに小文字のメッセージを送って大文字変換されたメッセージを受信するというサンプルを作る。これが完成形。 ビルドシステムはionicを使うが、プラグイン部分の開発はcordovaでも通用するはず。 まずはblankプロジェクトを作ろう。 $ ionic start CDVEchoPlugin blank CDVEchoPlugin/www/index.htmlをこのように編集する。 <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="initial-scale=1, maximum-scale=1, user-scalable=no, width=device-width"> <title>CDVEchoPlugin</title> <link href="lib/ionic/css/ionic.css" rel="stylesheet"> <link href="css/style.css" rel="stylesheet"> <!-- IF using Sass (run gulp sass first), then uncomment below and remove the CSS includes above <link href="...

これがAngularJSの$apply()や$digest()が低速な理由のひとつか?

イメージ
昨日書いた記事 「 琴線探査: Dr. GlebのAngularアプリ最適化TIPSまとめ 」 に、try-catchがあるとV8では最適化されないため処理が遅くなると書いた。 今日は自分で書いたアプリをプロファイルしてみた。このように、$apply()や$digest()に相当な時間がかかっていることが分かった。 これは予想通りだったが、驚いたのは$apply()や$digest()でtry-catchを使っているらしいことだ。 「Not optimized: TryCatch Statement」とツールチップが出ている。ひょっとすると、これが$apply()や$digest()が低速な理由のひとつなのかもしれない。 だとすると、かなり根本的なレベルで高速化できていないことになる…内部的にtry-catchを使わないようにできないのかなぁ(´・ω・`)

Dr. GlebのAngularアプリ最適化TIPSまとめ

Dr. Glebのブログ記事 Improving Angular web app performance example. | Better world by better software を簡単にまとめておこうと思う。 try-catchはできるだけ使わない V8ではtry-catchを使った処理は最適化されないので、特にループ処理ではできるだけ使わないようにする。Primesの例ではtry-catchを無くしただけで全体の処理は2倍以上、メソッド単体では200倍近く高速化している。 追記15.08.26 :$apply()や$digest()でtry-catchが使われていることが判明(ノ∀`) 琴線探査: これがAngularJSの$apply()や$digest()が低速な理由のひとつか? ダイジェストサイクルをできるだけ速くする $scope.$apply()した時のあれ。ダイジェストサイクルはフレームレートと同じで、長くなるほどUIが固まってしまうことになる。短くする方法は色々ある。 バインドさせる変数をできるだけ少なくする ng-modelとか$scope.valueとか。バインドさせる変数の数だけダイジェストサイクルは遅くなる。 filterはできるだけ使わない filterはダイジェストサイクルを遅くさせる。「{{ "index" | lowercase }}」的な無駄なフィルターはもってのほか。 one-time-bindingを使う サーバーから持ってくるデータは大抵の場合は大量だ。これをページにレンダリングするために2wayバインディングを使ってしまうとダイジェストサイクルが大幅に遅くなる。 そこでAngular1.3から導入されたone-time-bindingを使う。これを使えば、始めだけはバインディングするのでダイジェストサイクルに影響するが、その後は影響が無くなる。 例えば「{{name}}」としている所を「{{::name}}」とするだけでone-time-bindingになる。 AngularJS: Developer Guide: Expressions React的なレンダリング方法に変更する 特にtableの中身などの反復...