2015年10月5日月曜日

MacOSX El Capitanの問題

1台のMacにEl Capitanを入れてみた。基本的にはYosemiteと外見も似てて使い勝手の面では問題というか慣れが必要な部分は少なそうなのだけど、1つ大きな問題を見つけた。

・ディスクユーティリティーでNTFSのディスクの修復ができなくなった。

NTFSのドライブに対してはFirstAidのボタンが有効にならない。
今までは、BOOTCAMPでWindowsをインストールしている場合、Mac側のディスクユーティリティで、Windows上のSCANDISKでは復旧できない問題を修復できたのだが、できなくなってしまった。NTFSはディスク内容をしょっちゅう破壊するダメダメフォーマットなのでこの機能がとても重要だったのだ。

ということで、一旦入れたけどYosemiteに戻した。AppleにしてみればNTFSのサポートなんてしなくても問題じゃないというところなんだろうけど、こんな重要な機能削らないで。

2015年9月28日月曜日

iOS9の変化点

iOS9で変わった点を記録していく。

(1)フォントサイズが変わった
X-BASIC'では同じフォントを使っていても表示サイズが異なる結果になる。iOS9のほうが一回り小さい。
アップルのフォントは小さすぎて、高齢者に優しくない。

(2)バックグラウンドでreallocできなくなった
実行時に
「This application is modifying the autolayout engine from a background thread, which can lead to engine corruption and weird crashes.  This will cause an exception in a future release.」
が発生する。一応警告(とダンプ)だけで今は動いているようだが、将来的には落ちると書いてあるので対策したほうが良さそう。一番単純な対策はその部分をメインスレッドで行うようにすればいいのだが、reallocだけメインに持っていくのは無理。全体の動作の見直しが必要。

realloc以外でも発生する可能性はある。


(3)Autoresizeの結果がviewWillAppear時点で得られなくなった。
 こんなん仕様変更とは言わない。大バグ。
 仕様変更なら変更で仕様書に書け。書かれても許さないけど。

2015年9月19日土曜日

NSDataの内容をC的に変更する方法

NSDataは基本的には一度初期化するとその内容を変更することはできない。変更する場合はNSMutableDataを使うと。少なくともメソッドを使った方法ではその通りなのだが、C的に変更するなら方法がある。

NSMutableData *mdata〜
char *p=(char  *)[mdata mutableBytes];  

NSData *data=〜
char *p=(char  *)[data bytes];

とすると、内容を示すポインターを得られる。
ここでpのアドレスからに改変を加えるとNS(Mutable)Dataの内容が変わる。Mutableでなくてもいける。

NS(Mutable)Dataの中ではデータは連続した領域に保存されているようである。

ここ1つ注意すべきは、この方法で内容を更新するときは、絶対に元のデータの範囲を超えないこと。メソッドによるアクセスとは違い安全機構は働かないので確実にシステムが落ちる。

そしてもう1つ。この方法で書き換えても効果が出ないこともある。

AVAudioPlayerは内部でのデータの保持にNSDataを使っている。それは

AVAudioPlayer *av=[[AVAudioPlayer alloc]initWithContentsOfURL:url error:&error];
char *p=[av.data bytes];

でアクセスできるが、ここでpからの内容を書き換えても音は変化しない。おそらくは、元の音声データが.dataにあるが、実際に音声出力用データはinitWith時に別に複製が作られているのではないかと思う。

確保した音声データを直接書き換え音を変更しようと思った実験の結果。

2015年9月3日木曜日

iOSシミュレーターの仕様(Xcode6.4/7.0編)

Xcode6.4/7.0でのiOSシミュレーターの隠れた仕様を列記しておこうと思う。
主に自分の忘備録。

・AudioToolbox.frameworkのAudioServicesPlaySystemSound()はiOS7では音が出ない
iOS8では音が出る。またAVAudioPlayerはiOS7でも大丈夫。
音が出ないから散々調べたらこれだった。

・実機にしかないハードウェア機能は当然使えない
カメラ、モーションなど

・eMailはOK
・AirPrintもOK

・アプリの言語切替は、シミュレーター上の設定〜一般〜言語環境ではなくXcodeのEditScheme〜Application Languageで切り替える
ただしこれで切り替わるのはアプリケーションの言語だけなので、OSの設定の言語は元のまま。なので、SettingBundleでOSの設定に追加している時にその言語別表示を確認するには、OSの言語設定も別途変更する必要がある。

・AVAudioEngine/AVAudioPlayer系でエラーが発生すると、Macの他のアプリからも音が出なくなってしまう
例えばChromeでGyaoを見てて、シミュレーター上でそこでエラーが発生すると、しばらくすると(おそらく先行でバッファリングしていた分の再生が終わると)音が出なくなる。治すには、再度RUNすればいい。

・ProfileでAlloc/LeaksはiOS8でしか動かない
iOS7ではエラーが出てしまう。
AppleはiOS7外しにかかっているのがよくわかる。でも、それを開発者に強要するのはどういうものかと。

・キーボードの設定はHardware〜Keyboardにある

・[UIDevice currentDevice]model]が"iPad Simulator"または"iPhone Simulator"としか返してこない
シミュレートするデバイスを切り替えても一緒。
これを使うなら実機が必須ということ。機種別切り替えが必要なプログラムのデバッグにはシミュレーターが使えないってどういうこと?

・Intervalが非常に短い間隔のNSTimerを発行すると正しい時間にならない。
1/10=0.1 秒くらいなら大丈夫そうだけど、1/1000秒を設定しても(実測で)約0.1秒になっている。iPad2を選択しているとうまく動 くのにiPad RetinaやAirを選んでいるとだめなので、それらだけのバグ。ちなみに、実機ではちゃんと動く。
→その後調べた結果、AppleのNSTimerのドキュメントに「the effective resolution of the time interval for a timer is limited to on the order of 50-100 milliseconds.」とあった。要するに0.05s〜0.1sより大きな数値でないと動作は保証しないということで、それ以下なら動いて御の字と言える。これでは音楽ドライバが作れない!!
→実験の結果、repeat:NOなら1ms(0.001s)単位でもほぼ正確にかかってる。実機、シミュレーターとも。repeat:YESでも30ms位ならほぼ大丈夫だけど極稀にダメみたい。
 X-BASIC'では画面更新とキーリピートが引っかかる。・・・

それはそうと、Xcode6.4/7はブレークポイントがおかしいと思うのだけど。
設定した場所で止まらない。
一見設定した場所で止まっているようで、実はぜんぜん違う場所で止まっていることが多発している。7.1でも直ってない。
このバグのせいでブレーポイントを使ったデバッグがまともにできない状態。
細かくNSLog()を入れて、チェックするしかない。
アップルはもっとデバッグして。

2015年8月31日月曜日

GRANDIA II for PCをPS3コントローラーで操作する方法(修正版)

DreamCastの名作PRG、GRANDIA IIのPC版が出た。とはいっても英語版の、しかもリメイク版。
たまたま知ってやり始めたのだけど、キーボードでの操作ではまともにゲームにならない。
このゲームは3Dで表示されるため画面回転というかカメラ視点を変えないと見えない物が多く、また移動の際も歩きから走りまでを無断階で調整でき、かつ同時に回転も出来ないといけない。キーボードではこれが出来ないからだめ。

ではあったが、PS3のコントローラーをWindowsに接続したら格段に操作性が良くなった。その接続とGRANDIA IIからの正しい認識にはちょっと苦労があった。それを箇条書きにしておく。
  1. PS3コントローラーをUSBケーブルでWindowsに接続する。すると標準のドライバーで認識される。これはすごいことだが、そのドライバーではGRANDIA IIには不足なので、SONY提供のドライバーに差し替える。
  2. ここからコントローラーのドライバーをダウンロードし、展開しておく。
  3. 以下Windows7での手順。コントロールパネル~デバイスとプリンター~PLAYSTATION3コントローラーで右クリック~プロパティ。
  4. ハードウエアのタグからプロパティ
  5. ドライバーのタグを開き、削除を押す。これで標準ドライバを外す。
  6. ドライバの更新から先ほどドライバを展開したフォルダを指定する。これで新しいドライバがインストールされる。認識までにはちょっと時間がかかるかもしれない。一旦抜き差しして見る必要もあるかも。

    もし標準でドライバが入ってしまい上記方法でうまくいかない場合は4の次から以下の通り。
    ・「USB入力デバイス」のプロパティ
    ・ハードウエア~ドライバー~ドライバの更新
    ・「コンピューターを参照してドライバーソフトウエアを更新します」の次の場所でフォルダを指定する。サブフォルダもチェック。
  7. 以下Windows10での手順。デバイスとプリンターで標準で認識されたPS3コントローラーを削除する。
  8. ドライバーを展開したフォルダ内にある sixaxis.infで右クリック、インストールを選択する。
  9. デバイスをインストールしますか?と聞いてくるので、インストールを選ぶ。
  10. これで一応GRANDIA IIが操作できるようになるが、そのままのボタン配置では非常に使いにくいので変更する。GRANDIA IIにはボタン配置を変更する画面があるが、このPS3コントローラーに対しては全く効かない。なので、ドライバ側で変更をかける。
  11. 展開したドライバのフォルダの中にあるsixaxistool.exeをダブルクリックする。画面上何も起こらないように見えるが、タスクバーの中にアイコンで入っているので、右クリックから設定編集を選ぶ。
  12. ドライバ設定をクリック、空きのどれかを選ぶ
  13. ボタンアサインを変更する:ボタン0→○、ボタン1→×、ボタン2,3→無し、ボタン4→L1,ボタン5→R1、ボタン7→△、
  14. 設定保存を押して名前をつけて保存する(GRANDIA IIとか)
  15. 適用アプリケーションにgrandia2.exeを設定する(上の画像は入れる前)
  16. 設定画面を閉じる
  17. もう一度タスクバーから右クリック、先ほど付けた名前が出ているので、それを選択(重要)
これで、PS3コントローラーで操作できるようになる。ただし、起動時の「PUSH START BUTTON」だけはボタンが効かないので、キーボードを押す。

Windowsを再起動または休止明けの時にはコントローラーが認識されなくなるので、一度ケーブルを抜いて再接続が必要。

なお、Blutoothでの接続ができるかどうかは不明。可能そうな気もするけど、必要がないもので試してない。
→上記ドライバではそもそも無理な上に、他のを使ってもBlutoothのポートを1つ占有してしまうようで、実用的ではない。PS3コントローラー用ドライバーを用意しているBluetoothアダプタも売れている。でもそれくらいするなら、USB接続のままでいいや。


PS3コントローラーをWindowsに接続するドライバーにはmotioninjoyというのもあるが、やたら広告が出てきて非常に見づらい上に、うちの環境ではインストールすら出来なかった。このSONY純正で十分なので、これはおすすめしない(大元のHPも閉じられているようだし)。

これで大体DreamCastと同じ操作ができる。左スティックで歩くから走るの無段階切り替え移動、L1/R1で回転、○で選択、×でキャンセル、三角でメニューとなる。本当に格段に操作性が良くなり、ようやくゲームになる。

それは良かったのだが、いかんせんゲームのシステム的出来が悪い。
とにかく引っかかりが多すぎる。音が出るたび一旦停止、時々敵のキャラクターが消えるし、画面は波打ってる。音楽はループする前に一旦途切れるからおかしい。DreamCast版を知っていると「この程度で製品にする?」と思えるくらい。PS2版も出来は良くなかったが、それ以下。いくら高解像度でもなぁ、と思う。

まあ、買ったからには最後までやるけど。

・・・追記
ゲームの起動は以下の画面から行う。複数の場所から起動ができそうなのだけど、他の場所から起動しようとするとエラーが出て起動できない。
 他にも色々とバグがいそう。アップデートが時々発表されているから、自動アップデートはONにするのが良いかと。本当にアップデートされているか確認する方法がないけど(ファイル日付から判断するにされてない気もする)。
→次回起動時に更新されると判明。V1.03でだいぶ設定項目が増えたけど、前の設定が消えてしまうようで、設定し直しが必要。急に画面幅が変わってるし、英語音声になったので驚いた。
なお、バージョンは設定画面の右下に表示されている。

2015年9月17日追記
V1.04では標準でPS3コントローラーがサポートされた。コントローラーのところにその表示が出てる。でもうまく設定できないので私は上記ドライバーで動かしている。
頻繁にバージョンアップされるのはありがたいんだけど、その都度設定が初期化されるのが難点。
少なくともフルスクリーン起動をデフォルトにするのだけはやめてほしい。終了するのにものすごく苦労するから。

2015年8月28日金曜日

花子で作るUIToolbarアイコン

UIToolBarのアイコンはPNGのアルファチャンネルというものを使って描かなければならない。
この画像は特殊なので、一般的なグラフィックツールでは作成できない。

Photoshopが一般的らしいが有償である。無償ではgimpやinkscapeを使うらしいが共に英語版で、
しかも操作が直感でわからない(と思う)上に、gimpは非常に重いので過去に断念している。

Windows上で、なんとか花子や花子フォトレタッチという手慣れたツールで出来ないか調べた結果、出来た。以下にその方法をまとめる。
  1. グレースケールのPNG画像を作る。私は花子2013と花子フォトレタッチを使った。花子フォトレタッチでは、保存時にグレースケール、透過はなしを指定する。
  2. そのグレースケール画像を読み込み、花子フォトレタッチでネガ・ポジ変換をかける(画像>色>ネガ・ポジ変換)。これが意外と重要。
  3. ここからNetPBMのWindows版を入手する。グラフィック加工ツール群である。
  4. アーカイブの中からbinフォルダの下を適当な場所に展開、libの下も同フォルダに展開する。
  5. コマンドプロンプトを起動。set RGBDEF=./rgb.txtを実行。
  6. グレイスケール画像を透過マスクPNGに変換する方法に従って各ツールを実行していく。
これで作成した画像をiOSに読み込ませたらうまく行った。

各ツールの実行をバッチファイルにしてみた。これをツールと同じフォルダにal.batという名前(適当で構わない)で保存した場合、

  al pngファイル名 x幅 y幅

で、PNGファイル名は拡張子を付けず指定、その画像幅を後に指定する。
例えば64*32のicon.pngというファイルを 変換する場合、

 al icon 64 32

とすると、変換結果としてiconA.pngというファイルが出来る。これをUIToolbarに入れればよい。

これが出来たので、ようやくUIToolbarのアイコンが自作できるようになった。いや、今までも作ったことはあるけど、白黒の2値画像しか作れなかったので。その成果はX-BASIC'にて。

---↓ここからバッチファイル---

@echo off
if "%1"=="" goto ERR
if "%2"=="" goto ERR
if "%3"=="" goto ERR
set RGBDEF=./rgb.txt
pngtopnm %1.png > %1.pgm
ppmmake black %2 %3 > black.pgm
pnmtopng -alpha=%1.pgm black.pgm > %1A.png
del black.pgm
del %1.pgm
goto END
:ERR
echo al pngファイル名(拡張子は不要) x幅 y幅
:end
 
---↑ここまでバッチファイル---


おまけ。
iOSでPNGの透過を有効にするときは、256色にするか、インデックスカラーというものにしなければならない。普通にフルカラーで透過色を設定しても透過しない。
インデックスカラーへの変換は、フリーのgimpかPhotoshopで出来る。

gimpの場合は、画像>モード>インデックスカラー>255色で変換し、ファイル>エクスポートでPNGで出力し直す。



2015年8月3日月曜日

Windows7が休止から勝手に復帰するときの対処法

なんか昨日あたりから、Windows7(Pro 64ビット)が、休止から勝手に復帰する現象が発生していた。「スリープ」ではなく「休止」。

スリープはマウスやキーボードの押下で復帰するが、休止はそんなことはない。基本的には電源ボタンの再押下しか復帰方法はないはず・・・だと思っていた。

しかし、休止させてから10分ほどすると勝手に復帰している。電気の無駄でもあるし、そうでなくてもこの糞暑い時に暖房器具にも近いPCが起動しているのは宜しくない。
ということで調査を開始。

スリープからの復帰を止める方法はいくらでも情報があるが、さすがに休止からについては殆ど無い。あったとしても、ほとんどは休止とスリープを混同してる。

念のためキーボード、マウス、Bluetoothのプロパティーからスリープからの復帰も禁止してみたが、変わらず。

考えられる可能性として、有線ネットワークからWakeupLANを受信して再起動している事が考えられた。念のため調べてみたが、それもONになってなかった。

とあるサイトに、「電源オプション」の詳細設定でスリープの「次の時間が経過後休止状態にするを有効にしていると、休止にならずに復帰することがある」という情報があった。調べてみたが、うちでは「なし」になっている。しかしその下に今まで見たこともない設定があった。

それが「スリープ解除タイマーの許可」で、「有効」になっていた。まさかと思ってこれを「無効」にしてみたら直った。



全く用途不明だが、スリープを指定時間で解除するタイマーがあるようだ。しかもそれがスリープだけでなく休止に対しても効いてしまっていると。そりゃバグだろう。

ということでまとめ。
(1)コントロールパネル~電源オプションを開く
(2)省電力(他のプランでも可)を選択し、プラン設定の変更をクリック。もしくは左のリストから「電源プランの作成」をクリックして新規にプランを作成する(上のはそれで「カスタムプラン1」というのを作った時のもの)。


(3)詳細な電源設定の変更をクリック
(4)すると上記の電源オプションの詳細設定が出てくるので、スリープ~スリープ解除タイマーの許可を開く
(5)設定を「無効」にする
他の設定も必要に応じて変更すればいい。

ちょうどWindows10が公開された辺りからだったので、もしかしたら、それを通知するプログラム(GWX.EXE)が悪さしているのではとも疑ったが、そうではなかった。ウイルスも疑ったが、ウイルスバスターの検査では引っかかるものはなかった。

しかし、こんな設定変更した覚えはない。Windows7(XP以降全て)のファイルシステムNTFSは、しょっちゅうファイルが破壊される、極めて弱いファイルシステムなので、何かの拍子に関連情報ファイルが破壊されたのかもしれない。

ス リープ解除の時間をどこで設定するのかはわからない。ここではない。これが有効になっていてもそのスリープ解除タイマーの設定さえなければ自動復帰しない はずで、何かのプログラムがそれを指定したのかもしれない。それがGWXではないという保証はない。いずれにせよ、解除タイマーを無効にすれば勝手に復帰 はしなくなる。

もし同様のことでお悩みの方がいらっしゃれば、お試しを。

2016/02/08追記:
Windows10ではこれをしてもまだ勝手に休止から明けてしまうことがある。とりあえずの可能性の回避方法を別ネタへ。

2015年7月15日水曜日

しまなみ海道全線走破に必須・または必要そうな物紹介

しまなみ海道全線走破の話はこちら
そこにはアフリエイトが貼れないので、こちらに集約。


リュックは「ドイターフューチュラ28」



GPSは「GARMIN etrex20 中国語版」



液晶フィルタは一応これを上げておくけど、文字がにじむのでいまいちかもしれない。



おしりの痛み防止にはこれが良さそう。見つけただけで使ってはいないから、評価はお預け。


もう少し高級品はこちら。

2015年6月24日水曜日

Objective-CやiOSの隠れた仕様

X-BASIC for iOS v3.00の開発では、Objective-C、というかそのコンパイラの隠れた仕様に悩まされた部分があった。それを記録しておく。

(1)Objective-Cでの %ld の l判定はlong という宣言文字列と比較されているので実質ではない
何が言いたいのかというと、64ビットでlong != intで弾かれるのはいいとして、
32bitで実質 int == longでも「異なる」と判定されるということ。
X-BASICでは32ビット環境ではLong = longと定義していたのを、64ビット環境でLong = intと変更した。(LLong=long long;64bit)。32ビットのままでなければならない処理が山のようにあるからだ。ところが上記の仕様のため、従来%ldでいけたところをすべて%dにしなければいけなくなった。ところが%dにすると今度は32ビット環境下で警告を食らうハメになる。というわけで、結局都度(int)で型キャストするという手をとった。

(2)Objective-CのC型文字列の"~"はchar *であってsigned char *ではない。
これも警告で引っかかった。
確かにcharはコンパイルオプションでunsigned にもできるけど、でもそうでない設定の時はchar = signed charだろう?これはCの規約違反だと思うのだが。

 (3)定義済み定数__FUNCTION__ は char [n]と定義されるため、”%s”,__FUNCTION__では受けられるけど、func(char *mes)に対してfunc(__FUNCTION__)にすると警告が出る
 わけわからんかもしれないけど、やってみるとわかる。

 (4)NSUserDefaultで、setBoolしたものはintegerForKeyで読める
    [defaults setBool:NO        forKey:@"BOOL"];

    BOOL       ynb=[defaults    boolForKey:@"BOOL"];
    NSInteger yni=[defaults    integerForKey:@"BOOL”];
   どちらでも読めている。

まあ、普通はしないけど、バージョンアップで記録内容をBOOL範囲からNSInteger範囲にしなければならなかったので。

(5)array=[@"A\nB\n" componentsSeparatedByString:@"\x0a"]の結果は
[0]=@"A\n",[1]=@"B\n",[2]=@""となる。
最後に@""が入った要素ができるのが味噌。countで得られる値-1が行数である。

(6)Objective-C(というかそのライブラリ)の%sは日本語に対応できてない。
    NSString *mes=@"English日本語";
    char *cmes=[mes UTF8String];
    NSLog(@"元文字列=%@,char*=%s",mes,cmes);
    NSString *mes2=[NSString stringWithCString:cmes encoding:NSUTF8StringEncoding]; // もしくはmes2=@(cmes)だけでもOK
    NSLog(@"逆文字列=%@",mes2);

を実行すると、
元文字列=English日本語,char*=EnglishÊó•Êú¨Ë™û
逆文字列=English日本語
となる。要するに%sの表示だけがおかしい。NSLog()だけじゃなくてprintf()でも同じ。
日本語を含む文字列の表示には%sを使ってはいけないということ。
バグに近い仕様。

(7)NSStringのlength,substring*のメソッドはサロゲートペア文字を考慮していない
 サロゲートペア文字は常に2文字分の扱いをしないといけない
 サロゲートペアは見た目1文字だけど、内部では2文字の扱いになっているということ。
   length=2だし、substringのrangeもlength=2単位にしないといけない。
X-BASICではV3.10でNSStringをサロゲートペア対応にするためのカテゴリを作って対応した。


(8)NSLog(@"%@",文字列)の時、その文字列がサロゲートペアの最初の半分だった時、表示が全く出ない
これは(7)と絡むのだが、サロゲートペア文字は内部では2文字なので、その最初の1文字だけを持ってNSLog()で表示しようとすると、そのNSLog()すべてが表示されない。
NSLog(@"str=%@",[@"サロゲートペア文字" substringToIndex:1])とかすると、文字だけでなくstr=も含めて表示が出ない。
NSLog()入れてるはずなのに表示が出ないという時はこの可能性がある。

(9)これはObjective-Cではないけど、Zipアーカイブ内のファイル名は、それが作られた環境によって文字コードが異なる様子。
WindowsではSHIFT-JISで格納されている。ZipArchiveというライブラリではUTF8にしか対応していないため、Windows環境下で作られた日本語名ファイル含むZipを展開しようとすると、日本語名ファイルのみ抜けてしまう。
X-BASICではライブラリを修正して利用している。

(10)PNGファイルをiOSのリソースに入れると、ファイルが改変される。
ヘッダーの中にも情報が追加されてる。しかもその追加され方がPNGのフォーマット(規約)に合致していないので、たぶん、そのファイルを抜き出して画像ソフトに読ませても表示できない。
X-BASIC V3.10まででpngHeader()関数を内部にある画像に対して使うと正しい情報が得られないのはこのせい。

(11)iOSでPNGの透過を有効にするときは、256色にするか、インデックスカラーというものにしなければならない。普通にフルカラーで透過色を付けても透過しない。
インデックスカラーへの変換は、フリーのgimpかPhotoshopで出来る。

(12) NSTimerを実行させるにはNSRunLoopへ追加しなければならないが、これはメインスレッドで行わなければならない
NSTimer *tickTimer=[NSTimer timerWithTimeInterval:(NSTimeInterval)MML_1TICK_TIME
  target:self
selector:@selector(tickCountDown)
userInfo:nil
repeats:YES // 繰り返し
  ];

// 次がRunLoopへの追加だが、これはメインスレッドで実行しなければ有効にならない。

[[NSRunLoop currentRunLoop] addTimer:tickTimer forMode:NSDefaultRunLoopMode];

テストでは動いていたものが本番ではどうしても動かないので調べてみたらこれだった。
(X-BASIC'の言語処理は実はバックグラウンドで動いているのです。)
このメソッドはエラーを返さないのでわからなかった。

(13)複数の処理を並行動作させたいときはメインスレッドは使えない
メインスレッドは1つしかないから考えたらあたりまえのことなんだけど、

複数同時に走らせたい処理を
 [self performSelectorInBackground:@selector(fetch_main) withObject:nil];

[self performSelectorOnMainThread:@selector(fetch_main) withObject:nil waitUntilDone:NO];
に変更したらうまく動かなくなった(上記を複数回発行して複数本同時に走らせる)
バックグラウンドは同時に何本でも設定できる=並行動作するが、メインスレッドは1つしかないからである。メインスレッドでは、追加された順にキューに記録され、1つが終わると次のが走る。

iOS8とXcode6.3.2(一部7)のバグ

X-BASIC for iOS v3.00の開発に際して、iOS8のバグとかiOS7との挙動の違いをいくつか見つけたので記録しておく。Xcode6.3.2のバグも。

巷で情報がないもの。

(1)iOS8で、UITextViewでズームを繰り返すとシステムが反応しなくなることがある
iOS7.1では問題ない。なので、iOS8.1では頻発、8.2以上では頻度は減ったけどやはり出る。
UIScrollView上にUIImageViewを載せた場合は問題なさそう。
 回避策なし。


(2)iOS8.xで、UITextViewでズームした時、画面外に出た部分を表示できない
表示及びスクロール可能範囲が拡大前のそれと同じであり、またスクロールもできないし、表示も欠ける。
iOS7では問題ないが、iOS8は全てのバージョンで不可。他の設定が必要になったのかと思ったが、それらしいものはなかった。
 回避策なし。

UIScrollView上にUIImageViewを載せた場合は問題ない。
(1)(2)のせいで、X-BASICではテキストのズーム表示をiOS8上禁止した。iOS7では動く。


(3)UITextViewのscrollRangeToVisible:selectRangeで指定範囲までスクロールしようとした時、iOS8ではその設定のあとそれを発行するtextViewの内容を変更してもその場所に飛ぶが、iOS7では無効になる。

「例」
[txView  scrollRangeToVisible:selectRange];
txView.attributedText=〜
iOS8では修正後テキストの指定位置に移動するが、iOS7では移動しない。

先に修正すればOK。
txView.attributedText=〜
[txView  scrollRangeToVisible:selectRange];

 iOS7の動作もおかしいとはいえないが、なまじiOS8で動いてしまうだけにiOS7上での隠れバグになりそう。


(4)iOS8/iOS7とも、UITextView.contentOffsetに値を設定してもそこに飛ばないことがある。
 txView.contentOffset=offset
 としてもだめで、
 [txView setContentOffset:offset animated:YES];
とするといける。=offsetの後にsetNeedDisplayを発行しても、RunLoopに戻すようにしてもダメ。
animatedにすると時分割でoffsetを与え続けてくれるので動くのだと思う。
ということは、contentOffsetへの設定が無視されるタイミングがあるのだろう。

(5)contentSizeの値が正しくない
これはiOS7で散々騒がれて回避ロジックも編み出されたけど、iOS8でも治ってなかった。

ちなみに、UITextView内で行を追加した時、各行の表示位置はsizeWithAttributesで求められる文字列描画高さの累積に一致しない。このため、各行の表示位置を正確に知る方法がない(それがX-BASICでスクロール同期がうまくいかない理由)。


(6)Xcode6.3.2のバグ;IB上でのUndo
以下の手順で操作すると、おかしくなる。
1. IB上で何かUI要素を乗せて実行して動作を見る。
 IBActionでの接続もしてたらよりわかりやすい
2. その要素を削除して実行
3. Undoで要素を戻す
 IBActionでの接続も戻っている
これで元(1.の段階のもの)に戻るように思うが、実際には戻らない。UI要素が表示されない。表面上どこにも問題ないのに戻らないのでしばらく調査したが、どうもXcodeのバグ臭い。要素を一旦削除し、再度乗せたらうまく行った。
IB上で、実行を挟んだUndoは気をつけろ、ということ。

(7)Xcodeのバグ;iPhone6シミュレーターで日本語にならない
ここに情報があった
簡単になったのかそうでないのかわからないところ。でもシミュレーター上でも切り替えられるようにするのが筋。

(8)Xcodeのバグ;Breakポイントが違う場所に付く
 break文にBreakポイントをつけると、実行時にはbreakして飛んだ先に設定されてしまう。
 breakを通過したあとで止まるならいいが、breakを通らない時も止まってしまうので、デバッグがしにくくなる。
「例」
switch (n) {
 case 1:
   break; <- ここにBreakポイントを設定しても
}
<-ここで止まってしまう。n=1でなくても。

Xcode7でも治っていない。Xcodeでブレイクポイントはあまり使いものにならない状態。
バックグラウンドで動くタスクの場合だけかもしれないが。

(9)シミュレーター上で、Intervalが非常に短い間隔のNSTimerを発行すると正しい時間にならない。
1/10=0.1秒くらいなら大丈夫そうだけど、1/1000秒になると1秒以上(正確には計ってない)に1回くらいになってしまう。iPad2を選択しているとうまく動くのにiPad RetinaやAirを選んでいるとだめなので、それらのバグ。ちなみに、実機ではちゃんと動く。

(10)Xcode7で、ツールバーが表示されないことがある。2つ以上のプロジェクトを同時に開いた場合、2つ目以降にてこうなる模様。表示を選択しても表示されない。また、一旦閉じるとツールバーの表示状態がリセットされてしまう。極めて面倒。

UITextViewはiOS7で大問題を起こしたけど、iOS8でも別のバグを入れ込んでいる体たらく。アップルはもっと開発者の声を聞いて、大量の人員を導入してバグ取りすべき。iOS9なんて出している場合じゃない。

余談:
UITextViewで、画面上に表示されている範囲を知る方法が欲しいのだけど、実装してくれないかなぁ。

2015年5月15日金曜日

Firefox/Chrome/IEでまともに見られないページに出会った時の対処方法

Windows7の再インストールした時、Firefox/Chrome/IEで発生していた各種問題を一気に解決した。それを記録にとどめておく。

・・・

1. Chromeでバンダイチャンネルが見られない
アドオンのAdblockが悪さをしていたと判明。
ホワイトリストでhttp://www.b-ch.comを通すことで解決。

2. Firefoxでバンダイチャンネルが見られない
自動的にhttpsで接続するアドオン(名前は失念)が悪さをしていた様子。外したらいけた。
ついでにこちらもAdblockを外すように設定。


3. FirefoxでGyaoが正常に見られない(テキストのみ表示になってしまう)
これもAdblockが原因。Gyaoを始め、Yahoo系のサイトはAdBlockを有効にしているとまともに表示されない事が多い(Yahoo知恵袋とか)。広告収入が主なサイトは、あえてAdblock対策してあるのかも。



4. FirefoxでSilverlightが正常に動かない
Yahooのルートラボとか。
これもAdBlockで対象ページを通せばOKだった。



とにかく動画系にはAdblockを入れているとおかしくなるサイトが多い。広告を外してくれるありがたいアドオンだが、副作用もあるので、表示がおかしい時はまず疑ったほうがいいかも。


 5.  NTTの速度測定ができない
http://www.flets-west.jp/speed/

5-1. 「必要なプラグインがインストールされてない」と出る場合
32bit-Javaのインストールが必要。
Javaのダウンロードサイトはアクセスしたブラウザのビット数でダウンロードできるJavaのビット数が自動的に切り替わってしまう。64bit Chrome使ってJavaダウンロードしたら64bit Javaが入ってた。
IE11やFirefoxは32ビットなので、それを使ってJavaをダウンロード&インストールすること。


5-2. 「エラーが発生する」
セキュリティーでブロックされてる。
コントロールパネル~Java(32ビット)~Javaコントロールパネルからセキュリティ~サイトリストの編集で追加として、速度計測サイトのアドレスを登録する。http://[~:~:~:~::~]/bench.jspで、~の部分はつなぐ先によって異なると思う。
登録すると、実行確認が出てくるので、「実行」を押すと実行される。


6. Silverlightを再インストールしようとするとWindowsが完全ハングアップする
これが一番厄介。Silverlightはアンインストール時にレジストリにゴミを残す。そしてそのごみがあると再インストール時にハングアップする。多分80%~95%までの間で。完全に固まってしまい、キーもマウスも何も効かないので強制電源OFFしかない。

解決法は、そのレジストリのゴミを取り除くこと。
Windows再起動後、regeditを起動、検索で「Silverlight」を探し、それを含むエントリを全て削除する。200個以上あるので地道にやるしかない(ひょっとしたら一部だけでいいかもしれないけど)。他のを削除しないように。
全部削除したらregeditを終了し(再起動は必要ない)、Silverlightを再インストールするとうまくいく。


7. ChromeでSilverlightが有効にならない
Chrome自体が外部プラグインを認めない方針になったことによるらしい。
以下の手順で有効にできる。

(1)URL欄に「chrome://flags/#enable-npapi」と入力
(2)出てくる設定一覧の中で、NPAPI を有効にする
(3)Chromeを再起動(先の画面の一番下にボタンが有る)
(4)URL欄に「chrome://plugins/」と入力
(5)Silverlightで「常に実行を許可する」をチェック

先のルートラボをChromeで閲覧する場合がこれが必須となる。
また、他の外部プラグインも同様に有効にできる。

2015年4月11日土曜日

GARMIN etreck20(台湾版)の使い方;随時追記

GARMIN社のGPS、etreck 20を購入した。日本語版もあるのだがかなり高い。
日本語版で下位機種のetreck10の値段で、海外版では上位機種であるこの20が買えてしまうほどだった
しかも、調べてみると海外版を日本語化出来るそうなので、海外版を購入した。


~~



~~

これ、実際には台湾版(中国語版)である。Amazonの写真は赤の筐体が写っているが、台湾版は黄色である。この台湾版は英語版に比べ日本語化がしやすい。なので、「中国語がちょっとでも表示されるのは絶対嫌だ」というのがないなら、英語版を買うよりこの台湾版を入手した方がいい。

ちなみに、2015/4/10現在では円高も進んだこともあって、Amazon.comから英語版を購入しても、この台湾版と余り変わらない値段となってしまう。もっとも、この台湾版も日によって大幅に価格が変わることがあるようだが。

~~~準備~~~

届いたらまず、PCにGARMIN Expressと言うアプリを導入する。インターネットで検索して探す。
このアプリ自体は日本語化されている。 今回はWindows版を導入したが、Mac版も存在するようだ。
ファームのアップデートもこの上から行えるようであるが、台湾版は2015年4月11日現在V2.80が最新のようで、アップデートは出来ない。英語版にはV4.20まであるようだが、台湾版にはどうやっても導入出来なかった。


台湾版なので、付属取説は全く読めなかった。しかし、GARMIN Express上から英語の取説を開くことが出来る。英語の取説もわかりやすいとは思わないし、上位機種の30と共用なので20には存在しない機能についても書かれていたりする。なお、英語版向けの日本語簡易取説はここにある。機械翻訳らしく一部に間違いがあるけど。


実のところ、GARMIN Expressは余り使いようがない。ログの取り出しもこれでは出来ない。じゃあなんで導入するかといえば、念のため。

ちなみに、GARMIN Expressは、起動毎にスタートメニューのルートにGarminというフォルダを作る。きわめていらんお節介。



~~~日本語化~~~

台湾版の日本語化の手順は、
  1. メニューの日本語化
  2. 日本地図の導入
の順になる。

~~~メニューの日本語化~~~

これはとても簡単。
Setup~System~LanguageでJapaneseを選ぶだけ。
台湾版にはすでに日本語フォントと日本語メニューデータが入っているからこれだけで済む。
英語版だとフォントの導入から行わなければならないのでかなり面倒そう。

ただ、標準で入っている日本語メニューデータは、翻訳がおかしいと言うかわかりにくい部分があるので、私は独自に編集して使っている。まだ全ての表示を確認出来ていないので公開はしない(文字列長の問題があるかも知れないので)。
変更したい人は、本体を記録デバイスとして認識させて、\Garmin\Text\Japanese.gttを編集すればよい。UTF-8のテキストである。

なお、日本語を選んでも一部のメニューや文言は英語のままになる。どうもファームに直接書かれていて変更出来ない部分があるようだ。

~~~日本地図の導入~~~

この台湾版の最大の問題がこれで、標準では日本が全く表示されない。日本の座標を入れても海のど真ん中になってしまう。なので、日本で使うには日本地図の導入が必須である。

地図は市販のものもあるようだが、無料で手に入れることも出来る。その方法を紹介する。
なお、日本語地図の導入にはマイクロSDカードが必要である。一時的にではなく恒久的に。

~~

~~
日本語地図の導入には最低1GB必要だが、今時そんな小容量はないので問題ない。でも、このSDカードにはログデータも記録されるので、過去のログを本体内に長くとどめておきたいならそれ相応の容量が必要となる。


海外版etreck対応の日本地図はここ↓にある。時々更新されている。
OpenStreetMap for Garmin

これを台湾版GARMINで使う場合、ダウンロードすべきは英語版である。日本語版をダウンロードしてはいけない。英語版は英語(ローマ字)表記ではなく英語モデル用に文字コードUTF-8で作られているという意味だった(日本語版は日本モデル=etreck20J用にSHIFT-JISで作られていると思われる)。
誤解を招きやすい書き方をされているので要注意。

2016/02/17更新:
サイトが更新されデータが変わっている。ダウンロードすべきは日本~UTF8のもの。等高線の有り無しは好みで。

で、導入仕方。
  1. 上記サイトから日本~英語版をダウンロードしてくる。等高線の有り無しは好みで。両者を同時に使うことは出来ないようである。Mega Limitedと言うサイトからダウンロードすることになるのだが、Google ChromeにAdBlockを導入しているとはじかれてしまいダウンロード出来ない。設定を変更して通るようにするか、他のブラウザを使うこと。
  2. ZIPを展開する。gmapsupp.imgというのが地図データである。
  3. マイクロSDに書き込む
    まずGarminと言うフォルダを作り、その下に入れる。
    \Garmin\gmapsupp.imgと言うファイルがあれば正解。
  4. GARMINの電池ぶたを開け、電池を外し、その下にあるSDスロットにカードを入れる。
    写真は下参照(Google Bloggerの制約でここに写真が貼れないので)。
    このスロットはカードを差し込むのではなく置くタイプなので、注意。
  5. 電池を入れ直して再起動。
  6. 設定>地図>地図選択でOSM MAPS Familyを有効に設定する
    これをしないとせっかく導入した地図が表示されない。
    同じファイル名でも内容が異なれば再度この設定が必要。
  7. 同、China BasemapおよびDigital Globeを無効にする
[写真]
SDカードスロットのカバーを上げた状態

    SDカードを挿して蓋を閉めた状態

    先にSDカードを入れて、USBで認識させて書き込めばいいと思うかもしれないが、USB経由のGARMIN内SDへの書き込みはかなり遅い(多分USB1.1だと思う)ので、特に大容量の地図データではしない方がよい。

    これを導入すると、地図上の表記が漢字になるほか、検索も漢字で行える。ただし、OpenStreetMapの性格上、抜けや間違いがある。それに対して文句を言うのは筋違いである。気になるなら、自分で入力して貢献しよう。

    日本語フォントを導入していない海外版でも使えるようにローマ字表記で表示する地図もある。ただ、台湾版は日本語フォントがあるのでわざわざこちらを導入する必要はない。ローマ字変換がおかしい部分もあるし。

    ~~~製品感想~~~

    しばらく使った上での感想などをいくつか。
    • GPS衛星補足能力はかなり高い。また、一端見失っても再捕捉が早い。
      →ではあるが、時々長時間再補足出来ないことがある。特に電源投入直後の捕捉は、高速移動中だとかなりかかる。新幹線の中で電源を切ったり、電池切れに気がついて交換した後に判明(全く別の日に両方やってしまった)。長時間捕捉失敗後も同様の傾向がある様子。
      →低速移動中でもできないと判明。基本的に、初期のGPS補足は停止中にしなければならない(その割には電源ボタンが押しやすすぎ)。
    • 精度は今まで使ったGPSの中でもトップクラス。さすが高いだけのことはある。平均的な誤差は2~3メートルという感じ。
      ただ、GPSの原理上、低速移動時の誤差は大きくなってしまう。これは他のGPSも同様。
    • 電池の保ちはかなり良いと思う。エネループ2本で21時間くらい保つ感じ(標準のログ記録間隔で)。でも、電池が減っても気がつきにくいので、毎日交換するのが吉かと。
    • 重い。電池を抜いてもそう思う。 
    • 電源スイッチを間違って押してしまうこと多数回。 押し易す過ぎる。これは要改良点。スライドスイッチだったらよかったのに。うちではボタン上にホットメルトでぽっちを作って手触りでわかるようにしている。(電源以外も押されてしまいやすいけど、ほかの動作モードに入ってもログ記録は途切れないので致命的ではない。)
    • 全体的に操作はわかりにくい。本体だけでは事実上出来ないこともある。それについてここで書いていこうかと。「トリップメーターどうやって使うんだ!?」
       
    GPS衛星を捕捉しにくい場所
    • 室内;木造でも
    • 地下鉄、トンネル内;携帯電話が通じてもGPSは無理
    • JR223系新快速車両;なぜか窓際でも補足できなかった(京都→大阪間で体験)。
    • 新幹線700系の通路側
    鋼鉄製の普通車両、新幹線N700AやJR四国 8000系は問題なしだった。

    ~~~ログの取り出し方法(日本語地図導入時)~~~
    ログは、日本語地図導入時=SDカード挿入時はSDカード上に記録される。
    なので、GARMINをUSBでつないで SDカード上のGarmin\TRK内のgpxファイルを取り出せばよい。GoogleEarthやカシミール3Dで表示させることができる。
    (カシミールはひたすら重いので、編集でもしない限り使わないけど。)


    ~~~ショートカットの使い方~~~
    ショートカットとは、 機能の中で良く使い物をbackボタンを押すだけで呼び出せる様にする機能である。ショートカットに登録した物は、backを押す度に切り替わって表示(いわゆるトグル表示)される。

    しかしこいつには問題があって、ショートカットに登録された機能は普通のメニューからは表示されなくなる

    最初機能が表示されなくなって故障したかと思ったが、そういう仕様だった。
    メニューからは常に全て表示させておいて欲しいものだ。

    実際の所、ショートカットに登録したところで、メニューから選択するのとさほど操作手順は短縮されないと思うので、使い道は少ないと思う。


    ~~~液晶保護は必要か~~~
    etrex20の液晶画面は傷はつきにくいと思う。自転車移動中にだいぶガチガチ当ててしまい、時には擦ってしまったかと思ったこともあったが無事だった。
    傷よりむしろ手などの油の付着のほうが気になった。

    ということで、一応液晶フィルムも購入してみた。屋外では反射して見にくかったので無反射タイプを選択。

    でもこのフィルム、低反射はいいけど、字がボケる。かなり。
    ということで、諸手を挙げてのおすすめは出来ない。

    ~~~ルート設定~~~
    etrex20には、外部で作ったコースデータを入れて、それにそって案内するという機能もある。
    案内と言ってもカーナビのように音声ガイドしてくれるわけではないが、人によっては重要かもしれない。
    (私は基本軌跡をとれればいいので、重視してない)。

    で、問題はそのルートデータの作成仕方。etrex20本体でも、過去の軌跡から設定できるのかもしれないが、いかんせん取説がないのでわからない。現在わかっているコースデータの作り方はYahooのルートラボを使う方法である。

    細かい使い方はサイトのヘルプを見てもらうとして、このサイトで地図上にルートを描き、出力したものをetrex20のSDに入れて表示させる。

    このサイトでは自分の作ったコースデータを公開したり、逆に他の人の公開データを見ることも出来る。

    なおこのルートラボ、silverlightを使うのだが、silverlightはマイクロソフト自体が開発終了を宣言しているので、いつまで使えるのかはわからない。


    ・・・今後追加予定の項目・・・

    ~~~メニューのカスタマイズ~~~
    ~~~表示項目のカスタマイズ~~~
    など