PowerPC MacからApple Siliconまで、クラシックなMac体験を届けるアプリを配布しています。 なぜまだ使えるMacを捨てるのか。究極のエコは使い続けること。
Mac OS X 10.4 Tiger を搭載したPowerPC Mac (G3/G4/G5) 向けの、超軽量3ペイン型Webリーダーです。現代のWebページはJavaScript・広告・巨大な画像だらけで、2000年代半ばのハードウェアではまともに開けません。コダマはそれらを一切読み込まず、libxml2でHTMLを解析して「見出し・本文・画像リンク」だけを抽出し、OS標準のCocoaコンポーネントに直接描画します。JavaScriptもCSSも実行しないため、 G3 450MHz機でも軽快に動作することを目標にしています。
[ 画像N を表示 ]というリンクに置き換わり、クリックした時だけ読み込みます。Kodama.dmg をダウンロードして開きます。Kodama.app を、動かしたいPowerPC Macの/Applicationsなど好きな場所にドラッグします。| 動作環境 | PowerPC Mac / Mac OS X 10.4.11 (Tiger) |
|---|---|
| 動作確認機種 | iBook G4 |
個人の趣味プロジェクトにつき無保証、MITライセンスです。詳しいソースコードはGitHubをご覧ください。
コダマの中身は、libxml2でHTMLを構造化するだけの軽量パーサーです。WebKitは使わず、JavaScriptも CSSも一切実行しません。目標は最初からG3 450MHzでも実用的に動くこと。ここでは実装のポイントと、実際のサイトで踏んだ地雷を紹介します。
今どきのWebページはJS・広告・巨大な画像だらけで、G3世代のCPUではまともに描画できません。だからコダマは最初からWebKitを捨てて、libxml2でHTMLをパースし、見出し・本文・画像リンクだけを抜き出して Cocoaの標準部品に直接描画する設計にしました。JSもCSSも動かさないので、そもそも重くなりようがない、という考え方です。
最初のパーサー(HTMLParserEngine)を作った段階から、実機検証だけでいくつも古い環境特有の壁に当たりました。使っているlibxml2(2.6.16)にはHTML_PARSE_RECOVER定数が無い、Foundation(10.4)には componentsSeparatedByCharactersInSet:が無くてNSScannerベースで書き直す必要がある、といった具合です。一番厄介だったのはgcc 4.0.0のObjective-C文字列リテラル(@"...")で、日本語などのマルチバイト文字を含む@""リテラルが正しくエンコードされず文字化けするというバグ。何度も踏んだので、Cの生リテラル+stringWithUTF8String:経由で文字列を作るPWRJPStrというマクロを用意して、以降のUI文字列は全部これ経由にしました。
TigerにはGCDもblocksも無いので、curlを非同期で呼ぶだけでも一苦労でした。 NSTaskDidTerminateNotificationとNSFileHandleReadCompletionNotificationを両方待ち合わせる形で CurlTaskRunnerというクラスを実装し、結果はdelegateで通知する昔ながらの作りにしています。実機では Tigerbrew経由のポータブルcurl(7.58.0+OpenSSL 1.0.2l)でHTTPS取得に成功し、TLS1.2/1.3のハンドシェイク回避というこのアプリの核心部分を実証できました。
v0.2までのTigerbrew/MacPorts必須という要件は機能はしてたんですが、どちらも入ってない素のTiger環境だと
それだけで詰んでしまう問題がありました。実際にPower Mac G4にv0.2を入れた利用者がまさにこれに遭遇して
発覚しました。v0.2.1では、静的リンクしたPPC版curl 8.9.1(LibreSSL 3.8.4)と最新の
cacert.pemを、そのままKodama.app/Contents/Resourcesに同梱するようにしました。
CurlTaskRunnerのパス検出は、まずこの同梱版を最優先で探しに行き、無ければ従来通りの
探索順(/opt/local → /usr/local/bin → PATH上のポータブルcurl)に
フォールバックします。--cacertオプションは、実際に動いているのが同梱版のcurlの時だけ
渡すようにしていて、システムに入ってるcurlにフォールバックした場合は、そちらが元々信頼してるCAストアを
上書きせずそのまま尊重するようにしています。
右ペイン(画像プレビュー)は普段は幅0で隠れていて、画像リンクをクリックした時だけ広がる作りです。ところがTiger(10.4)のNSSplitViewにはsetPosition:ofDividerAtIndex:というメソッドが無く、今どきのやり方が使えません。splitView:resizeSubviewsWithOldSize:の中でサブビューのframeを自分で計算する、昔ながらのやり方で折りたたみ/展開を実装しています。
ここが一番時間を食ったところかもしれません。
フォーム未対応(検索ボックスなど)は、現状アドレスバーのDuckDuckGo検索フォールバックだけで凌いでいるので、ここは引き続き検討中です。
ソースコードはGitHubにあります。