Google Map 上に表示する位置偽装トラッキングアニメーション

Android アプリ受託案件で表題の要件がありました。まずは表示まで。

ローカルホストかSSLじゃ無いと駄目らしく上手く行かないのを開発環境上で確認。余談ですが WebView 内の利用については未確認です。

index.html:25 [Deprecation] getCurrentPosition() and watchPosition() no longer work on insecure origins. To use this feature, you should consider switching your application to a secure origin, such as HTTPS. See https://goo.gl/rStTGz for more details.

これで現在地にマーカーを置くことに成功しました。
javascript – Geolocation: moving only google maps marker without reload the map – Stack Overflow

解決したコードで最後に参照したのがこちら。
Animate route on Google Maps – Stack Overflow

もちろんハイブリッド型なので iOS の WKWebview に埋め込んだり PWA で使う事も可です。

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

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

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

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

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

参考

読了『ハイ・コンセプト「新しいこと」を考え出す人の時代』

最近話題の「積読」ではないですが、Amazonの欲しいものリストに寝かせておいたものの中から電子書籍化されていない、あるいは中古で©驚安のものを選んで読むという事をたまにやるので、今回は表題にある作品を選んで購入しました。

Kindle にはハイライト機能があって後で見返すのがとても便利なのですが、印刷された本を読む時には気になる部分をコンピュータのテキスト(近年では iOS のメモ)に手打ちして残していくという事をやっていました。そこで、古いとは言え名著だと思ったので、こちらに印象に残った引用を残して置こうと思います。

ソフトウェアは思考のフォークリフトである。P.91

ゴールドマンとヘイグループが共同で行った調査結果によると、組織内で最も優れたリーダーとされる人たちには「おもしろい人物」が多いという(「愉快で楽しい人」という意味であって「変わった人」ではない)。「おもしろい」リーダーたちは、普通の管理職と比べて、三倍もよく笑うらしい(ユーモアというのは非常に右脳寄りの活動なのだ)。 P. 115

国が豊かになり、人々が快適な生活を送れるようになるかどうかは、学校で芸術家を育てていけるかどうかにかかっている。物があふれ、オートメーション化とホワイトカラーの仕事のアウトソーシングによって混乱している現代社会においては、職種を問わず、誰もが芸術的感覚を養う必要がある。みんながダリやドガになれるわけではない。だが、私たちは皆、デザイナーにならなければならないのだ。 P. 128

デザインは、古典的な全体思考能力だ。へスケットの言葉を借りれば、「実用性」と「優位性」の組み合わせである。 P. 129

熱帯雨林に暮らしていたら、さまざまな葉の見分け方を学ぶでしょう。それと同じで、私たちはいろいろな書体を見分けられる能力を身につけた訳です。 (バージニア・ポストレル)P. 138

ビジネスに携わる人がデザインをよく理解する必要などない。彼ら自身がデザイナーになる必要があるのだから。 (ロットマン・マネジメント・スクール学長、ロジャー・マーティン)P. 143

生活とデザインに関する指針

  • 1 専門的になるな。
  • 5 ものを作り出す前に、そのアイデアやコンセ6プトがオリジナルのものなのか、それには本当に価値があるのかどうかを自問してみること。
  • 6 自分が経験してきた仕事についてすべて理解し、その上で何か新しいものをデザインするときには、前のものは全部忘れてしまうこと。
  • 7 「やれたはずなんだけど」とは決して言わない。それは、やらなかったことだからだ。
  • 24 モノではなく、「経験すること」 にお金を使え。
  • 33 「普通」というのはいいことではない。
  • 38 世の中には三種類の人間がいる。文化の創造者、文化の消費者、文化など意に介さない人。最初の二種類の人間のどちらかになるようにする。
  • 40 一つのことにこだわらず、広く物事を考える。
  • 43 生活で最も重要なのは「経験」である。そして、アイデアの交換や他人との触れ合いこそ、本来の人間のありかただ。場所や対象物によって、経験の印象が強まったり、台無しになったりすることがある。
  • 50 今この場が、私たちにとってすべてである。

P. 159 http://karimrashid.com

日々の生活の中で、使用に耐え、かつ楽しくなるものを選ぶようにしよう。クラシックなデザインの衣類は、流行に左右されることがない。家具は長く使うほど趣を添えていくものだ。他人の注意を引くためではなく、自分が喜びを感じられるものを選ぶこと。家族や友人、そして自分の心以上に「もの」に重きを置くことは絶対にいけない。 P. 162 http://animatrix.com/

観念的に言えば、人間は論理を理解するようにできていない。人間は物語を理解するようにできているのだ。(認知科学者、ロジャー・C・シャンク) P. 169

技術面での行き詰まりが、技術者でない人によって解消されることはよくある。そのような場合には、IQよりも全体像をとらえる力のほうが重要だからである。思考を大きく飛躍させられる能力は、画期的アイデアの発案者に共通して見られる特徴だ。非常に広いバックグラウンドと総合的な知力を持ち、幅広く多様な経験を積んできた人に、このような能力の持ち主が多い (MIT ニコラス・ネグロポンテ)P. 215

クリエイティブで才能豊かな女性はそうでない女性よりも支配的でタフであり、クリエイティブな男性は、他の男性に比べて繊細で攻撃性が低い P. 215

精神面が中性的な人は、事実上対応のレパートリーが倍になるので、より豊かな視点で世間の人々と交流ができ、多様なチャンスを手に入れることができるのだ (チクセントミハイ)P. 216

自力で成功して億万長者になった人は、一般の人より四倍も失読症である比率が高いという。 P. 224

卓越したリーダーたちは、「『もし〜ならば〜だ』式の推論に頼ることが少なく」、調和力の特徴でもある直感的で文脈に依存した推論を重視するらしい。 (ダニエル・ゴールマン)P. 225

『詩人をマネージャーにしなさい』と言うんだ。詩人というのは独創的なシステム思考ができる人だからね。彼らは自分たちの住む世界を観察し、その意味を読み取る義務を感じている。それから、世界の動きを読者が理解できる言葉で表現する。意外なシステム思考者である詩人たちこそ、真のデジタル思考のできる人材なのだ。彼らの中から、明日の新たなビジネスリーダーが現れると、私は信じている。 (シドニー・ハーマン)P. 226

優れた交響曲

  • ベートーベン『交響曲第九番』
  • モーツァルト『交響曲第35番ハフナー』
  • マーラー『交響曲第4番ト長調』
  • チャイコフスキー『祝典序曲1812年』
  • ハイドン『交響曲第94番ト長調 驚愕』

P. 231

「共感」と「同情」は違う。同情とは他人を気の毒に思うことだ。だが、共感とは、他人と「ともに」かんじ、その人だったらどんな気持ちがするだろうかと感じ取ることである。 P. 242

リーダーシップとは共感するということだ。人々の人生にインスピレーションと力を与えるために、人と結びつきを持ち、心を通わせる力を持つことなのだ。(オプラ・ウィンフリー)P. 245

論理や哲学や理性的説明ばかり寄りかかっている人は、精神のもっとも優れた部分を餓死させることになるだろう。 (ウィリアム・バトラー・イェイツ)P. 251

幸せは条件を伴うが、喜びに条件はない。P. 299

精神的(または非物質的)な不公正は、現在、物質的な不公正と同じくらい、あるいはそれ以上に重大な問題である (ロバート・ウィリアム・フォーゲル)P. 315

物質的欲望から意味的欲望への移行は、何億人もの人々を巻き込み、歴史上類を見ないほどの大きなスケールで進行しており、最終的に私たちの時代で最も重要な文化的発展と見なされることだろう (グレッグ・イースターブルック)P. 316

幸福の要因となるものには、満足のいく仕事に従事すること、ネガティブな出来事や気分を避けること、結婚、豊かな社会的ネットワークを築くことなどがある、とセリグマンは言う。また、感謝の気持ち、許すこと、楽観主義なども同様に重要だ。(一方、大して重要でないと思われるのは、お金を得ること、高い教育を受けること、快適な気候の中で暮らすことだという結果が出ている)。P. 328

働く理由の第一は物質的利益にあったが、それも近いうちに、仕事の結果を楽しむことに取って代わられるだろうと、私は予測している (マーティン・E・P・セリグマン博士)P. 328

現在でも題名で検索をすると粗筋や感想文を多く目にすることができますが、大意を掴むのに分かりやすかったのが “A not only B” で示されるこの図でした。

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

紹介されているリンクの八割はドメインが売りに出されていたりして閲覧ができなかったのが残念でしたが、当時のブログブームに乗ってなのか右脳左脳やEQ判定の話題について、妻でさえも勤務先から仕入れて熱心に話していたのをよく覚えています。

この本の前に「ファスト&スロー」を読んでいたので始めは少し不安になりましたが、脳科学ネタを引っ張ることなく時代背景から今後の展望へとうまく論を繋いでいてあっという間に読むことができました。

その脳科学ネタは最後の章で、このブログで過去に紹介したことのある仏教の話に繋がっていて、また時代の断片的なものを感じることができる内容でした。

ただ当時と違うのは自分に小学生になる子供がいるということで、彼の周りでは中学受験のための塾通いなんかが話題になっていたりしますが、例えば勉強だけをしてきた地方の学生が都心の賢い大学に入って個人の文化的差異に衝撃を受ける、というようなことを実際にも聞いたりする訳です。

プログラミングの授業が新たに小学校で始まったりする中で、このようなアンチパターンを避けるべく子供の進路についての指針として読むことができたというのは単なるビジネス書としてではなくてなかなか良かったような気がします。

ドアラッチの故障

一週間前くらいからガタガタと言い出していたドアラッチが、ノブ制御不能になり作業部屋へ入る事ができなくなってしまいました。参考動画でドアラッチ自体を薄く硬いもので押せば引っ込むのが分かったので、針金ハンガーを折って向かうと、

枠に返しがあり直接アクセスできないので、仕方なくドアノブ修理の検索で掛かった業者に来て見積をお願いしました。赤枠部分を切断する必要があり料金は交換混みで3万超えの作業費で、少し業者さんと話したところ次のようなことが判明したので、自分で解決してみようと思いました。

  1. 木枠を削ればドアラッチが見えるので開けることは簡単
  2. ドアラッチの高さは片方づつ異なっており、押して開く側の方が低い

賃貸物件のため(1)は管理会社と相談する必要があります。外から部屋を見ると窓の鍵が開いて管理会社で梯子を借りてということも思いついたので一旦メール連絡を入れつつ、(2)によって力を加える方向が分かったので差し込む物を材質から検討しました。

  • 子供のコロコロのおまけについているカードゲームの少し硬めの厚紙
  • ツナ缶の蓋
  • 針金ハンガー
  • スーパーのパイナップル用プラスチック容器

3分ほど押し引きしていると開きました。

コツは強く押し少し引きながらラッチがあるであろう写真四角グレーがある中心まで動かして行くことです。実際に下から上への方向で開いた気がします。

参考

様々な大きさの円を重ならないように描く

あるテレビ撮影現場で解像度1920×1080のスクリーンに700個程の円を敷き詰めて描き動かすという要件があり JavaScript の Canvas を使ったのですが、円の座標を取得する際にブラウザの応答がなくなってしまう問題を避けるために注意した点を二つ書き留めておきます。

この画面を避ける

一つ目は重なり判定に Math.sqrtMath.pow を使わないことです。二つの円が重なる条件を言語化すると「中心点からの距離が、半径の合計よりも小さい」となって、直訳すると Math.sqrt(Math.pow(x2 - x1, 2) + Math.pow(y2 - y1, 2)) < r2 + r1 と表すことができるのですが、三平方の定理を平素に解釈し関数を使わず (x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1) < (r2 + r1) * (r2 + r1) とした方が処理が速くなります。

参考

二つ目は Web Workers の利用です。表示する円座標を格納しておく配列の数が上限数に到達するまで繰り返す部分 while(circles.length < circlesMax){...} を丸ごと worker.jsself.addEventListener('message', (e) => {...}); に記述しました。座標計算が終わるまで「読み込み中…」を表示をするのは UI としても良いし、処理時間の計測をしておき長い場合に中断しやり直すということも可能になり便利なこと極まりありません。

const worker = new Worker('./worker.js');
 
worker.addEventListener('message', (e) => {
  circles = e.data;
  circles.forEach(function(circle){
    drawCircle.call(this, circle.x, circle.y, circle.r);
  });
});
 
worker.postMessage({
  radiusMax: /*最大半径*/,
  radiusMin: /*最小半径*/,
  circlesMax: /*最大表示円数*/
});

これに関連して注意したのは、動作実機はウェブサーバがなくデスクトップ等に置いたファイルを実行する状況から同一生成元ポリシーによるエラーになってしまうので、Chrome にオプションを付けて起動することを予め伝えておく必要があります。

参考

実際には円同士を線で結んだり円や線の増減アニメーションがあったりで、今回初めて書いた Web Workers は参考したコードにもある Promise との併用がとても効果的になる場面が増えてくるのではないかと思いました。

Xcodeプロジェクトを複製してホーム画面にアイコンを並べる

基本的な挙動は同じだけど、数パターンでアプリを提示しないといけないという状況があります。そんな時には元になるプロジェクトを複製してアプリ名称の末尾に数字等を添えてホーム画面に並べられるように AdHoc 形式で配布する事になるのですが、半年以上に一度くらいの頻度でやってくるこの作業の度に同じ Stack Overflow ページを参照しているのと、日本語で検索した結果の手法が若干回りくどいものが散見されたので書いておこうと思います。環境について、現在は Xcode Version 9.4.1 (9F2000) を使っていますが、参照している Stack Overflow の回答の日付から察するに Xcode 6くらいから同じ作業だった気がします。コマンドラインのみで行う方もいましたが、今回は GUI 操作を選びました。

Duplicate and rename Xcode project & associated folders – Stack Overflow

具体的な手順を簡易に訳すと、

  1. ファインダでプロジェクトフォルダを複製し名称変更
  2. Xcode の左パネルでプロジェクトを選んだ状態で右パネル Identity and Type の Name を変更
  3. Manage Schemes からスキーム名称を変更
  4. Targets > General > Bundle Identifier を変更
  5. ファインダで複製したプロジェクトフォルダ内直下のソースフォルダ名称を変更
  6. Xcode の左パネルのファイル名が赤色に変わるので、フォルダを選んだ状態で右パネル Identity and Type の Name を変更、更にその直下 Location にあるグレーのフォルダアイコンを押して該当するソースフォルダを選択
  7. Targets > Build Settings > Packaging > Info.plist File にあるパスを変更

覚えておくにはかなり面倒で、うる覚えで作業順序を間違えると方法も変わり試行錯誤の露頭に迷った結果、複製後のフォルダを削除してやり直しという厄介な作業になります。

日本語でググった結果上位5つくらいを確認してもっと簡単な方法があるなと思ったのは手順3のスキーム名称の変更のやり方で、左下の「+」や「-」ボタンで追加削除、右上の「Autocreate Schemes Now」ボタンを使う事なく、

表示されるスキーム名をクリックすると変更可能になるので、

名前を変えてリターンすると完了します。

もう一つは同様の手法を取る手順7で、

変更箇所の文字列をクリックすると、

簡単に変更ができます。

参考にしている Stack Overflow ページにも書いてあるのですが、検索窓に複製元のプロジェクト名を入れると外部ライブラリを使うプロジェクトの場合にも変更が容易になります。

参照

最終的に納品先の端末にはこのようにアプリ名がずらずらと並んでいく事なります。

最後に暴言を吐くと、Android と比較してク*面倒臭い事極まりないという感想になります。

Grade Sync Issues: (5 warnings) 回避

数ヶ月ぶりに Android アプリ案件をやったところ表題のようなエラーに出くわして回避したお話です。

内容はリンク先にもある通り、先方の都合で2018年末に使えなくなるから変更しろということで、 Gradle Script/build.gradle(Module:app) に記述のある “compile” 文字列を全て “implementation” に書き換えてから右上の Sync Now リンクを押します。具体的には、dependencies の中にある4箇所、compile fileTreeandroidTestCompilecompiletestCompile を implementation fileTreeandroidTestImplementation implementationtestImplementation とします。

解決前:

解決後:

参考:

ICSからTVPIDファイルを作る

先日作成したワールドカップ用のカレンダーファイルを利用して、EyeTV の予約に使う iEPG データを作りました。尚、このソニーが提唱した電子番組表の規格は終了する事になるようですが理由は不明です。

ICS ファイルの読み込みは公開されていたものを拝借して利用しましたが、2点変更を加えました。1つ目は、ics クラスで icsData 値を全て取得する際の explode の区切り文字列が \n になっていたのですが、作成した(というか元にしていた) ICS ファイルの改行コードが CRLF だったので次のようにしました。

$icsDatesMeta [$key] = explode ( "\n", str_replace(["\r\n", "\r"],  "\n", $value) );

また、このクラスから $icsEvents 取得後に TVPID ファイルを作る際に終了時間のタイムゾーンが設定されていなかったので次の1行を追加しました。

$endDt->setTimeZone ( new DateTimezone ( $timeZone ) );

更にこの追加行の直上に、決勝トーナメント以降の対戦は延長戦の可能性を考慮して終了時間に1時間を追加しました。

if($i > 47) {
  $endDt->add(new DateInterval('PT1H'));
}

この PHP ファイルと同階層に iepg というディレクトリを 777 権限で作成して実行すると、ブラウザ上では日付順の日程を表示しつつ、iepg-{n}.tvpi というファイルを64種作成します。装置は EyeTV 250 を UNIDEN 地上デジタルチューナー DTH11 からのコンポジット入力で使用しているので、station 値は固定し EyeTV 側の「録画ソース」には「100 コンポジットビデオ」となるようにしました。

Content-type: application/x-tv-program-info; charset=shift_jis
version: 1
station: コンポジットビデオ
year: 2018
month: 06
date: 15
start: 00:00
end: 02:00
program-title: FIFAWC2018 ロシア vs サウジアラビア - A組 第1節
genre: 1
subgenre: 2

iEPG ファイルの準備ができたら、重複を回避するために EyeTV の既存の予約をスタンバイ状態(チェックを外す)にし、全てのファイルをダウンロードフォルダにドロップすると予選リーグ第3節の重複を警告してきますので、それぞれどちらの対戦名を優先するか決定して読み込みが完了します。

スタンバイ状態にした既存の予約を有効にして行くと、重複した予約の対戦名をダイアログで警告してきますので、それらの予約をスタンバイにしながら最終的にどちらの予約を優先するか調整する事になるかと思います。

最後に今回作成した iEPG ファイルをこちらに置きましたので、PC 録画を予定されている方のお役に立てば幸いです。
WC2018IEPGs.zip

P.S. チューナーの方は面倒臭い…

参考:

Googleファミリーリンクで子供の端末を制御する

昨年、安価な子供の位置情報確認方法について書いたのですが、iOS のようなペアレンタルコントロール機能が Android には無いので、アプリを無効化しても Chrome ブラウザを使い際限なく Youtube 視聴をしてしまったり、子供の友人が勝手にロック画面からカメラを起動して街中で動画を撮影するといったような子供あるある問題が表面化してきたので対策を考えていたところ、Google が「ファミリーリンク」という制御アプリを日本向けにリリースしたので導入してみました。環境は前回同様、子供の端末に Huawei SIMフリースマートフォン P8 lite に 0 SIM を利用します。

まず現在年齢を詐称して登録していた子供の端末のアカウントのデータをバックアップしました。
$ adb backup -f backup_20180604.ab -all -nosystem -apk -obb

次にこの端末に親管理者となる自分のアカウントを追加し Google ファミリーリンクのアプリをインストールして進むのかと思いきや、別端末から管理する必要がある事が分かりました。公式の文書には「〜の端末」や「〜の Android」と言った記述がなく分かり難い事半端ありませんでした。

気を取り直して子供の端末を初期化し、自分の端末(iOS と Android 共)にも Google ファミリーリンクのアプリをインストールし、子供のアカウントを正しく再取得した後に2台並べて設定、Chrome のフィルタで youtube.com ドメインの追加、アプリ管理、位置情報、その他からフォト共有をオフにし、1日の利用上限とおやすみ時間を指定して無事完了しました。

次に上部スワイプからショートカットで Wi-Fi をオフにしてデータ通信での挙動を確認してみたのですが、先のアプリの管理で「端末管理」と「EMUI」をブロックすると「設定>データ通信量の管理」の項目が非表示になってしまう事が分かったので、一旦許可済みにして「ネットワーク通信を行うアプリ」と「1ヶ月の利用可能なデータ通信量」の設置を行いました。

そしてネットワーク通信を行うアプリを観測してみたところ、10085 というアプリが位置情報を取得する際に必要な事が判明したので「ネットワーク通信を行うアプリ>システムアプリ」でモバイルデータのチェックを入れてみたのですが、Google ファミリーリンクのアプリにある他の設定を変更する事ができませんでした。

もう一度設定画面を確認してみると、10085 前後に存在している 10008, 10012, 10014, 10017, 10026, 10029, 10031, 10032, 10045, 10050, 10058, 10064, 10070, 10074, 10080, 10081, そして 10086 という多数の怪しい名称のアプリが関係しているだろうと推測して全てにチェックを入れるとうまく動きました。

それぞれのアプリがどの設定に関連するのか調べるのは面倒だったので放置していますが、 10032 をオフにする際「モバイルデータ通信の無効化」というタイトルのダイアログを表示し「MMS メッセージの送受信」が不可能になる旨の警告をしていました。結構な数のアプリなので通信量が若干心配なのですが、幸運にも 6.0(Marshmallow)端末で対応できましたし、フィルタリングや時間制限など MacOS に近い制御が可能だという事で、iPhone SE2 が出たらどうなるか分からないところ、暫くこれで運用してみようと思います。

参考:

サポート対象外のMacでNight Shiftを使う

昨年内部ディスクを SSD に換装して快適さを取り戻した開発機で使っている iMac Mid-2011 ですが、リビング用に購入した MacBook と比較してみるとスマホでは一般的な機能になっている Night Shift の設定が欠けている事に気が付きました。調べてみると、iMac に関しては2012年型から使える機能なようで、ブルーライトで失明してしまったお婆さんの体験談を近所にお住いの方から伺った事もあって、ソフトウェア側から何かできないものかともう少し追いかけると、MacRumors のフォーラムに相当する内容が書かれていました。

参考:

インストーラがあったので簡単に済ませようとしたのが運の何とかではありませんが、再起動後の起動画面で無線キーボードとトラックパッドを認識しなくなると言う問題に直面、内容をよく読むと macOS 10.13.2 は検証中だと…。背面の電源ボタンで強制終了し、コマンド+Rキーで内蔵の macOS 復元システムを立ち上げ、クソ長いクリーンインストールと Time Machine バックアップからの復元か〜と思っていた矢先、SSD にした恩恵に与る事ができました。

気を取り直し原典に当たる事にして、日本語の説明も参考にしつつも、その手順の内容が箸折ってあったのと途中で問題があったので経過を書いておこうと思います。

まず CoreBrightness.framework のバックアップは、デスクトップ等にドラッグしたり直接副クリックからの圧縮をしてデスクトップに移動させるのでも良いのですが、パーミッションが {User}:staff に変更されてしまうため戻すことの手間や後述する手順の作業内容を考えるとゴミ箱にぶち込むと言う手もありそちらの方法を選択しました。

次にエディタアプリで CoreBrightness.framework を開く場合、このフレームワークの置いてある場所 /System/Library/PrivateFrameworks/ で書き込み権限が無いため、一旦デスクトップ等の場所に複製したものを編集しました。編集アプリには iHex を利用しました。

そして、CoreBrightness.framework の ModelMinVersionBLR と言うシンボル名のアドレスを拾います。
$ nm /S*/L*/PrivateFrameworks/CoreBrightness.framework/CoreBrightness|grep _ModelMinVersion
0000000000035000 S _ModelMinVersionBLR

更に16進数ダンプを表示して編集箇所の目星を付け、編集アプリでファイル内検索を利用し実際の編集箇所を見つけます。
$ xxd -s 0x35000 -l 28 /S*/L*/PrivateFrameworks/CoreBrightness.framework/CoreBrightness
00035000: 0900 0000 0100 0000 0d00 0000 0600 0000 ................
00035010: 0500 0000 0600 0000 0800 0000 ............

今回は iMac12,1 に対応させるべく 0d000c00 に書き換え、保存した CoreBrightness.framework を /System/Library/PrivateFrameworks/ へ戻し、$ sudo chown -R root:wheel /System/Library/PrivateFrameworks/CoreBrightness.framework と権限を元に戻しました。

これで最後と思った codesign コマンドでエラーが返ってきました。
$ sudo codesign -f -s - /S*/L*/PrivateFrameworks/CoreBrightness.framework/Versions/Current/CoreBrightness
/System/Library/PrivateFrameworks/CoreBrightness.framework/Versions/Current/CoreBrightness: replacing existing signature
codesign_allocate: error: unable to locate xcodebuild, please make sure the path to the Xcode folder is set correctly!
codesign_allocate: error: You can set the path to the Xcode folder using /usr/bin/xcode-select -switch
/System/Library/PrivateFrameworks/CoreBrightness.framework/Versions/Current/CoreBrightness: the codesign_allocate helper tool cannot be found or used

2つ目のエラーに書いてある sudo xcode-select --switch /Applications/Xcode.app を試しても、Xcode の「環境設定>Locations>Command Line Tools」を確認するも問題がなく、結局1つ目のエラーにあるように .bash_profile ファイルへ export PATH=${PATH}:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/ とパスを記述し再読み込みして解決しました。

$ vi .bash_profile
$ source .bash_profile

ここまでやっておいて何なんですが、OS の更新毎に作業が発生する事や、子供が産まれてからは17時以降の作業はやらないようにしているのであまり必要がなかったのかもしれません。

参考: