iOSのヘッドフォンモードを解除する

どうも Siri からのフィードバック音声がスピーカーから聞こえないなあと iPhone の音量ボタンを押すとアイコンと共に「ヘッドフォン」の文字があったのでググってみるとヘッドフォンモードが解除できなくなる問題というのがあるそうで、日本語で検索すると、再起動、イヤフォンジャックの物理的な掃除、ストアに持ち込む、の三点セットな記事が多く、イヤフォンによる音量調節やスピーカーフォンでの通話、サウンド環境設定のボタンで変更の動作も問題が無いのでソフトウェアの解決方法を更に調べたところ、公式フォーラムで見つけた解決方法が役に立ちました。

http://hkitago.tumblr.com/post/179840974976

具体的な操作は簡単で、設定>一般>アクセシビリティ>通話オーディオルーティングと遷移し、初期状態では未選択の「Bluetoothヘッドセット」と「スピーカー」の選択項目を適当に選んで音量ボタンを押して表示を確認していくと、音量アイコン上部の文字が「ヘッドフォン」から「着信/通知音量」となって解決しました。

原因は恐らく、複数台の macOS と iOS 端末とペアリングし頻繁に切り替えて使っている AirPods にあると思うのですが定かではありません。参考にしたフォーラム内には機内モードにして解決したという報告もあるので、イヤフォンジャックに綿棒を突っ込む前に目を通してみると良いかと思います。

参考

iPhone5sをアンロックする

受託案件が増えたのでアンドロイド端末を一台持たねばと購入した HUAWEI P8lite だったのですが、イングレスで使うには GPS がブレたり大きな画面でグリフハックがやり辛いことなどから、開発用途としてソフトバンク契約が切れて Wi-Fi のみで利用していた iPhone5s をアンロックして DMM の SIM を使ってみようと思いました。今回はジェイルブレイク(脱獄)せず、SIM アダプター(下駄)も使わず、単純に IMEI アンロック(ファクトリーアンロック)をすることを目的としています。

まず “iphone unlock softbank” 程度の検索語で出てきたサイトですが、格安だったのでサイト名に “scam” キーワードを付けてみたところ見事に詐欺サイトだと判明しました。Fb ではかなりの評判だったのがあわや騙されるところで、体験談を読むと明示されている19ユーロというのは前金で、これを支払った後に60ユーロの請求が届き、更にこれを支払った後に音沙汰がなかったり、未だ時間が掛かると自動返信でトンズラするそうです。(具体的には英国のオフィシャルアイポンXXXXXXユーケーというサービスです、ご注意ください)

次に MacRumors のフォーラム経由で見つけたのが、UnlockBase という米国のサービスで、複数の情報源から信頼できると判断しこちらを利用することにしました。実際に申し込む前に確認すべきことは次の3つです。

  • IMEI 番号の確認:
    電話アプリのキーパッドで *#06# と押し、メモアプリなどに控えておきます。設定>一般>情報>IMEI からだと番号を長押しでコピペできます。
  • アップルのサイトでアクティベーションロックの状態を確認
    対象機種の「iPhone を探す」機能がオフになっているかどうかを確認できます。
  • IMEI Database Lookup で iPhone のシムロックの確認
    キャリアとの契約状態や盗難品かどうかを確認できます。

理想的なのは国内のキャリアで購入し契約の切れた iPhone があると良いのですが、秋葉原やヤフオクなどで中古端末を入手している場合は少し注意が必要です。これらの確認が終わったら、UnlockBase のトップページ上部に見える iPhone の GET STARTED からメーカーと機種を選択し “UNLOCK NOW” ボタンを押して進みます。次のページでは、IMEI 番号、メールアドレスを入力し、国名、契約中のキャリア名を選び “PROCEED TO CHECKOUT NOW” ボタンを押して支払い方法を選びます。今回は Paypal を選択し、待つこと13営業日で無事に作業が完了したという旨のメールを受け取りました。早速メールにリンク先のある “How to Unlock the Apple iPhone 5S” を読み(緊急通話のみのソフトバンク SIM を使い USB を経由し iTunes で認識させてから抜き、10秒待ってから再接続再認識させるだけ) DMM のプロファイルをダウンロードし SIM を交換してみたところ見事に「ドコモ 24.2」のキャリアを掴みました。

またこの待ち時間を利用して内臓バッテリーの交換を試みました。

手順は若干多様性があるようでしたが、iFixit を主な参考にしてパネルを外さない方法を選択しました。バッテリ自体は強力な糊付けだったのですが、AirMac の底面などで分解経験のあるヘアドライヤで外しました。
IMG_0816

最初に届いたものは充電ができない不良品でしたが、返品して再度購入し無事新品のような状態になりました。

IMG_2492

電池交換後に計測に使用していたアプリを一旦削除しないと測定値をリセットしないという問題も発見しました(この間にサイクルが1増えてた笑)が、無料なので開発側には報告しませんでした。

IMG_2507

ということで、中古の端末が多く流通しているということや円高傾向もあり、SE の購入に悩んでいたり(Android 端末のアンロックも可能らしい)、月額の出費を抑えるのに格安 SIM に移行したい、夏休みに向けて子供の GPS トラッキング用途、サブ機などにいかがでしょうか。

参考:

iPhone 4SのWi-Fi強度

iPhone 4 を妻に譲って iPhone 4S にしてから寝室において Time Capsule (MB765J/A) との Wi-Fi 接続が途切れることが多くなったので、ルーターの設定や内蔵されている Wi-Fi 部品の種類、室内の構造などから検証した。

まず室内の構造と端末の配置について、寝室から階下のルーターまで直線距離にすると4メートルくらいで(石膏ボードかな?)壁が2枚ある。

iPhone の AirMac ユーティリティで確認するとワイアレスクライアントの接続状況は iPhone 4S が「良い」iPhone 4 が「非常に良い」と表示される。具体的な接続状況は、データレートと強度を表す RSSI (Received Signal Strength Indication) 値がそれぞれ、52MB/秒と-72dBm、58MB/秒と-62dBmと表示される。上述した接続状況はこの RSSI 値を読んでいると予測できる。

そこで Lion の AirMac ユーティリティを使って自動設定にしていた ワイアレス>ワイアレスオプションの「無線モード」「2.4GHz チャンネル」「5GHz チャンネル」を全て手動設定にした。(iPhone の AirMac ユーティリティを使うと 5GHz ネットワークがオフになってしまうバグがあるの注意。Pismo があるけどほぼ使ってないので無視。)

そうするとデータレートが改善され途切れることが無くなった。それでも RSSI 値が変わらないので(たぶん Time Machine バックアップが始まった時とかに)画像の読み込みに失敗することが多々ある。これはマクドナルドなんかに設定されているソフトバンクの mobilepoint で体験するイライラ感に近いものがあると言えば伝わるだろうか。

Wi-Fi の部品については iPhone 4S で使われているものが新しい iPad と同等だというので試してみると、やはり結果は同じようなものだった。ただ、プロセッサが幾分高速なことと IEEE802.11n で且つ 5GHz は安定していることもあるのか iPhone 4S を使っている時のようなストレスを感じることはない。

と、ここまでくると最終的には Apple が公表することのない Time Capsule のハードウェア仕様に起因するのかもしれないけれど、旧型の iPhone 4 よりも 4S の電波の方が弱くなってしまうというのは端末側の Wi-Fi チップにも問題があるだろうと思わざるを得ない。最安値を付けていた Amazon でMD032J/A モデルをポチってみたので後日再検証することにしよう。

参考:

iPhoneアプリレビュー

日本バックギャモン協会のウェブサイトに「バックギャモンスコアボード」と「バックギャモンポジションカード」が Learningカテゴリ内「iPhone アプリレビュー」として紹介されました。

望月プロの辛口レビューがとても参考になります。

iOS用お絵描きソフト

iPad の Safari で動作するマルチタッチ対応お絵描きソフトを作ってみた” からコードを拝借し、フルスクリーンで起動するように次のタグを追加してローカル上にある Mac OS のサイトディレクトリに配置した。

"apple-touch-icon"を指定しない場合のホームアイコンはページのスクリーンショットになるので、何か描いた後に “ホーム画面に追加” ボタンを実行すると良い。

デモ (リンクは予告無く削除する事があります)

フルスクリーン表示ではアドレスバーの表示が無いので、白紙に戻す時に使う “再読み込み” は “ホーム>アイコン” とタップ数が多くなってしまう事に注意。

P.S. 子供に遊ばせてみる事にする。

更新: "apple-touch-icon"を指定したウェブアプリは iOS4 のマルチタスクに対応する様だ。

更新2(7/22):子供とお絵描きをして遊んだ。彼は飽きたらホームボタンを押すので同時にスリープボタンを押してキャプチャを撮る事に成功。

iCalとiPhoneでW杯の予定を管理

更新:ロシアW杯のデータはこちら
照会カレンダーを作る – hkitago software development

あと21日と迫ったサッカーのW杯南アフリカ大会の予定が Google カレンダー上で公開されているらしいので過去の投稿に習って iCal と iPhone で閲覧できるようにした。

  1. Google カレンダーに登録する
    World Cup 2010 Google Calendar » The Artesea” に掲載されている Google カレンダー右下のボタンをクリックしてマイカレンダーに “World Cup 2010″ を登録し、”マイカレンダー>カレンダー設定” を選ぶ。
  2. カレンダーのリンクをコピーする
    “カレンダーのアドレス>iCal” ボタン上で右クリック、 “リンクをコピー” する。


    注意:iPhone から iCal ボタンを押してみたところうまくいかなかったので、デスクトップ環境と同様にコピーする必要がある。
  3. 照会する
    iCal を起動して “カレンダー>照会” を選んだ後に URL を貼付ける。左側に照会カレンダーから編集も可能。決勝トーナメントの事を考えると自動更新を毎日に変更した方が良いと思う。iPhone からはメールで URL を自分宛に送るだけ。詳しくは “iPhoneに祝日を自動登録” を参照のこと。

iPhone の Spotlight 検索が使えるのも良い。

(・∀・)イイ!

P.S. 実は iPhone対応「2010World Cup Schedule」(無料)を使ってみたのだけど、あまりに重たくて…

更新(5/24):iPhone から iCal のリンクボタンを押してみた結果を2に追加。

更新(6/25):大会も半ばにして照会していたICSファイルが接続できなくなったので “こちら” の webcal 形式のものに変更した。

SQLiteデータベースにカラムを追加する

以前 “SQLiteデータベースのバージョンを変更する“という記事を書いたが、結局実機でもうまく動作しなかった(Safari ブラウザやシミュレータと同じ結果だった)ので、データベースのバージョンによる管理を諦めて単純にカラムを追加することにした。

try {
 if (window.openDatabase) {
  db = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000); /* 現行バージョンのまま */
  if (!db) {
   alert("Failed to open the database on disk.");
   /* 初期化 */
  } else {
   db.transaction(function (tx) { /* 新しいカラムがなければ追加する */
    tx.executeSql("SELECT crawford, star FROM BGPositions;", [],
     function(tx, result) { },
     function(tx, error) {
      tx.executeSql("ALTER TABLE BGPositions ADD COLUMN crawford INTEGER default 0; VACUUM;");
      tx.executeSql("ALTER TABLE BGPositions ADD COLUMN star INTEGER default 0; VACUUM;");
    });
   });
   /* 全行読み込み */
   return;
  }
 } else {
 alert("Couldn't open or support the database. Please try to contact with author.");
  /* 初期化 */
 }
} catch(e) {
 /* former changeVerion.js (前回はここにバージョンを変える関数をいれていた) */
}

Webkit のバグが解消されない限りはこの方法が良いと思う。

さてこのコードを埋めたアップデートファイルが、驚愕のわずか12時間程度で承認され公開(Backgammon Position Cards for iPhone, iPod touch, and iPad on the …)されている。また以前の投稿 “iPhone アプリのアップデートで課金する” で話していた様に価格も元の Tier5 に戻した。

更新(2010年5月11日): 一年間十分食べさせて頂いたのと世界的な不況ということを考慮してTier4に値下げした。:-)

SQLiteデータベースのバージョンを変更する

iPhone アプリで利用している SQLite のスキーマを変更する必要に迫られ開発中に予期せぬ出来事があった。具体的にはテーブルに一列追加する changeVersion という関数を利用する際に必ずバージョンがマッチしないというエラーを出力するというものだ。

success callback である第五引数内でもoj.versionがoldVersionを返すのが気になります、、、。リロードするとようやくnewVersionに変わるんですけれど、これで良いのかなぁ。

引用元: JavaScript++かも日記: 【iPhone】iPhone用 JavaScriptデータベースプログラミング入門 (6).

Safari の JavaScript のデバッガでこの問題を確認し回避策を模索していたところ、Apple の文書に次のような回答を見つけた。

Unfortunately, the only way for your code to see the new version number is by closing the browser window. If you get an error code 2 (see “Error Codes”) and the database version you passed in for the old version matches the version in db.version, you should either assume that the version change already happened or display an alert instructing the user to close and reopen the browser window.

引用元: Safari Dev Center: Safari Client-Side Storage and Offline Applications Programming Guide: Using the JavaScript Database.

結局のところ挙動は問題ないのだけど、ブラウザを閉じるか再読み込みしないと利用者に反映されないということで、次のようなコードにして iPhone の UIWebView 用に移植する前段階として一旦作業を終えることにした。

try {
  if (window.openDatabase) {
  // db = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000); /* 現行バージョンの記述 */
  db = openDatabase("BackgammonPositionsDB", "2.0", "Backgammon Positions DB", 200000);2.0バージョンは開けずエラーをキャッチするので通常の処理は省略)
} catch(e) {
  if (e.code == DOMException.INVALID_STATE_ERR) { // Version number mismatch.
    var prevdb = openDatabase("BackgammonPositionsDB", "1.0", "Backgammon Positions DB", 200000);
    prevdb.changeVersion("1.0","2.0", 
      function(tx){
        tx.executeSql('ALTER TABLE BGPositions ADD COLUMN crawford INTEGER default 0;VACUUM;');}, 
        function(error){ /* SQLエラー処理 */ }, 
        function(){ /* 成功後初期化処理 */ });
    return;
  }
  alert("Unknown error " + e + ".");
}

またこの検証作業に関して SQLite のバージョンを戻す(1.0 に下げる)必要があり、前述した Apple の文書にもある ~/Library/Safari/Databases/ にあるファイルを削除して Safari を再起動するという若干面倒な手続きを取るしか方法がないので、Rails のような管理手法を Automator や AppleScript で作ることが望ましい気がした。

実際の iPhone 上の UIWevView ではどのような挙動になるのか、悩ましいことになるようであれば追って報告しようと思う。

XcodeでJavaScriptを外部ファイルとして扱う

UIWebView を使い iPhone のウェブアプリケーションをネイティブアプリケーションとして構築していると、Canvas 描画やタグ出力、Sqlite の扱い等、膨大なコード量になる JavaScript は次の様にしておくとプロジェクトの管理が楽になるのはウェブ開発者であれば誰もが思うところだが、そのままビルドすると Xcode は JavaScript をコンパイルしてしまい外部ファイルとして認識しないという問題がある。

<script src="xxx.js" type="text/javascript"><!--mce:0--></script>

そこで Developer Forums を覗いてみると、次のような回避策が紹介されていたので試してみた。

So you need to do two things – select the .js file in your project, and turn off the checkbox that indicates that it is compiled (the “bullseye” column).  If you don’t do this, you’ll get a warning in your build log about being unable to compile the file (which should be your first warning – always try to figure out and and correct any and all warning that appear in your build).

Then drag it and drop it in the target’s “Copy Bundle Resources”.

引用元: Developer Forums Beta: UIWebView and JavaScript ….

  1. 外部ファイルとして HTML に読み込みたい JS ファイルを選択し、表示メニューから詳細コマンドを選択する。(この詳細表示とエディタの間にあるハンドルをマウスで下方へドラッグしても良い。)
  2. ターゲットのチェックボックスを外す。ターゲットのチェックボックスを外す
  3. グループとファイルのターゲットからアプリケーション名ツリーの中にあるバンドルリソースをコピーに対し対象となる JS ファイルをドロップする。JS ファイルをドロップする

これで Safari ブラウザ等のデバッガと連携する JavaScript プログラムの管理や分業がより容易なものになり、加えて jQuery 等のライブラリも自由に扱える事で開発の効率が上がるのは間違いない(はず)。

更新:Xcode 3.2で検証した結果、チェックボックスのチェックが自動的に復活しているにも関わらず動作しているので手順1と2は不要かもしれない結論に至った。単にバンドルリソースとすれば良いらしい。