iOSを再起動させるとdidEnterRegionが呼ばれなくなる

iOS7.1からはビーコンのモニタリングはアプリを終了しても、iOSを再起動しても継続するはずなのだが、iOSを再起動させるとdidEnterRegionが呼ばれなくなった。
例によって色々調べてみると、iOS起動後しばらくはCoreLocationがまだおねむな状態らしい。
少なくとも2分は待ってね、と書いてあるので、待ってからリージョンに入るとdidEnterRegionが呼ばれるようになった。


ただ、ビーコンを近くに置いてON/OFFを切り替えるのでは、didEnterRegionもdidExitRegionも呼ばれない(呼ばれることもある?)ようなので、遠くからビーコンに近づいたり離れたりする正規の手順でやったほうが良いようだ。
(再起動後に限らないけど)


http://stackoverflow.com/questions/28028382/ibeacon-monitoring-ranging-after-device-restarts

アプリを終了させるとビーコンのリージョンに入ってもdidEnterRegionが呼ばれない

ionic2でIBeaconクラス(cordova-plugin-ibeacon)を使用している。
アプリがフォアグラウンド、あるいはバックグラウンドにいるときはdidEnterRegionが呼ばれるのだが、終了させるとdidEnterRegionが呼ばれなくなる。
iOSは7.1からアプリを終了させてもモニタリングは継続してくれるはずだから、何かおかしい。


いつものように色々調べると、このアプリ終了後の挙動は、ビーコンのリージョンに入ったときに裏でアプリが起動され、そこでアプリのコードが実行される仕組みになっているということがわかった。
翻って自分のコードを見ると、アプリを起動して1画面遷移したところでdidEnterRegionをsubscribeしている。
これでは裏でアプリが起動されたときにsubscribeが行われない。


というわけで、最初の画面でdidEnterRegionをsubscribeするようにしたところ、アプリ終了後もdidEnterRegionが呼ばれるようになった。

VMイメージをコピーして使おうとしたらネットワークがこける

VMware Workstation 12 Playerで作成したVM(CentOS7)をマシンAからマシンBに移行しようとしたときのこと。


マシンBにVMware Workstation 12 Playerをインストールして、VMのイメージをvmxが入っているフォルダごとコピーすれば動くと思っていたのだけれど、実行してみるとネットワークがこけてしまう。
色々検索してみると、MACアドレスが変わってしまったのがまずいらしい。
解決策としては /etc/udev/rules.d/70-persistent-net.rules と /etc/sysconfig/network-scripts/ifcfg-* のMACアドレス修正が示されていたが、私の場合はそもそもこの両設定ファイルにはMACアドレスなどなかった。
前者のファイルに至っては設定は全部コメントアウトされていて実質空。
もちろん追加でMACアドレスを書き込んでみてもうまくいかない。
いったいどこでMACアドレスの設定がなされているのかわからず、調べてもさっぱり。


困り果ててうだうだ色々やっていると、VMwareのサイトにこんな記述が。

注:コピーしました オプションを選択すると、新しい UUID と MAC アドレスが生成されます。これにより、ネットワーク内での競合が発生しないことが保証されます。

そういえばVM起動時に「移動しました/コピーしました」の選択肢が出てきて、「コピーしました」の方を押した。
けど…これ、「移動しました」にしておけば良かったんじゃないだろうか。


というわけでVMをもう一度コピーし、「移動しました」を押したところ…何の問題もなくあっさりとネットワークが使えるようになった。

dockerでPostgreSQLのログをDataVolumeに吐きたい

postgresql.confでログを/var/log/pgsqlに吐くように設定する。
そして -v /var/log/pgsql:/var/log/pgsql でホストのディレクトリをマウントさせると、ログ出力でPermission deniedと言われてコンテナがこける。


調べてみるとマウントしたディレクトリはゲスト側では UID=1000, GID=1000 になり、UIDが1000のユーザかrootしか書き込めなくなるとのことだったが、今回の場合は所有者が root:root になっており、どうも話が違う。
色々悩んだ末に、ホスト側の所有者を root ではなく適当な一般ユーザーにしすると、ゲスト側で UID=1000, GID=1000 になることがわかった。


あとはpostgresのUID/GIDを1000にするようDockerfileに書いておけば、ログをDataVolumeに吐くことができる。
1つ注意が必要なのは、yumとかでPostgreSQLをインストールする前にユーザーとグループを作っておかなければならないこと。
インストール後に変更すると、usermod/groupmodでは既存のpostgres所有のファイルまではUID/GIDが変更されないため、また別のところでPermission deniedと言われてしまう。

AOTで画像のインポートをするとCannot find moduleと言われる

Cannot find module '../assets/images/icon.gif'.

だそうだ。
怒られているコードはこんな感じ。

import {Component} from '@angular/core'
import * as icon from '../assets/images/icon.gif'

requireに変えるとコンパイラの怒りが鎮まる。

import {Component} from '@angular/core'
const icon = require('../assets/images/icon.gif')


んーでも前AOTでrequire使ってたら怒られてた気がするんだけどなあ…。
コンポーネント定義中で使うのはだめだけど、それさえ静的に解決できてれば他では使っていいってことかな。

'Response' is not assignable to type 'Response'

Responseを参照する自作ライブラリを使用しようとしたら謎のエラーが。
調べてみたらこんな感じになってた。

my-application
└node_modules
  ├@angular
  └my-library
    └node_modules
      └@angular

my-library中のmode_modulesを削除したら解決。


my-libraryのpackage.jsonのdependenciesと、my-applicationのpackage.jsonのdependenciesに設定されている、共通する依存ライブラリのバージョンが違うとこうなるっぽい?


アプリケーション側でもdependenciesに書くライブラリの場合は依存関係はdevDependencies(とpeerDependencies)に書き、dependenciesには書かないのが良いっぽい?

Can't resolve all parameters for XXX

Angular2.1.1

src/app/services/XXX.service.ts

import {Injectable} from '@angular/core'
import {YYY} from './'

@Injectable()
export class XXX {
  constructor(private yyy: YYY) {}
}

src/app/services/YYY.service.ts

import {Injectable} from '@angular/core'

@Injectable()
export class YYY {
  constructor() {}
}

src/app/services/index.ts

export * from './XXX.service'
export * from './YYY.service'

こーすると↑こんな風に↓怒られるみたい。
循環参照の問題、らしい。

Can't resolve all parameters for XXX

こーやって↓index.tsを経由せずにインポートすると解決するみたい。

src/app/services/XXX.service.ts

import {Injectable} from '@angular/core'
import {YYY} from './YYY.service'

@Injectable()
export class XXX {
  constructor(private yyy: YYY) {}
}