The Anatomy of a macOS App

2025/12/07 21:31

The Anatomy of a macOS App

RSS: https://news.ycombinator.com/rss

要約

Japanese Translation:

改訂サマリー

この記事は、Classic Mac OS のリソース・フォーク方式(UI アセットが別のフォークに存在した)から NeXTSTEP のバンドルアーキテクチャへ進化した macOS の歴史を追っています。NeXTSTEP ではコード、リソース、およびメタデータをひとつのフォルダーに統合するバンドル構造が採用されました。各アプリケーションバンドル(

*.app
)には、以下のようなサブフォルダを含む
Contents
ディレクトリがあります。

  • MacOS – 実行可能バイナリ
  • Resources – アイコン、GUI アセットなど
  • Frameworks – バンドルされた動的ライブラリ
  • XPCServices, Plugins, Extensions – オプションのサービスコンポーネント

バンドルには必須の

Info.plist
が含まれ、実行ファイル名・アイコン・最小 macOS バージョン・ドキュメントタイプなどを指定します。さらに型/作成者情報を持つ
PkgInfo
ファイルがあればそれも格納できます。起動は二通りの経路があります:コマンドラインツールは launchd を使用し、アプリケーションは LaunchServices(および RunningBoard)によって plist のデータを元に起動されます。

OS X 10.5 以降、Apple は

_CodeSignature/CodeResources
にコード署名(CDHashes)を追加し、整合性の検証を行っています。App‑Store アプリはさらに
_MASReceipt
ディレクトリに購入領収書を含み、2018 年以降は notarization が
CodeResources
内にチケットを埋め込みます。ユニバーサルバイナリは同一ファイル内に Intel と Apple‑silicon の Mach‑O スライスを両方埋め込み、それぞれが独自の署名を持ちます。

すべてのコンポーネントをバンドル内に集中させることで、インストール・更新・削除が簡素化され、リソース不足によるエラーが減少し、署名・notarization・領収書検証によってセキュリティが強化されます。開発者はクロスアーキテクチャバイナリをサポートする標準化されたパッケージモデルの恩恵を受け、ユーザーはより滑らかなインストールと少ないリソース問題を享受できます。この傾向は、バンドル整合性への継続的な重視と階層内での拡張機能やサービスのさらなる統合を示唆しています。

本文

ウィンドウ環境で動作するプログラム―従来のコマンドラインから実行されるアプリケーションよりも複雑な要件を持つ―は、必要とするリソース(ウィンドウやメニューなど)をすべて1ファイルに埋め込む代わりに、Mac OS はそれらをアプリの「リソースフォーク」に格納し、新しい手法を確立しました。

以下は、2000年頃に登場した QuarkXPress 4.11 の例です。ResEdit(リソースエディタ)で表示されるリソースを確認すると、実行コードも

CODE
リソースとして格納されており、各ファイルには Finder が作り出す「見せかけ」をサポートするタイプとクリエイター情報が付与されています。


Mac OS X

Mac OS X の設計時に NeXTSTEP から継承したバンドル構造へ移行しました。従来の多数のリソースを一元化せず、実行コードとそれ以前は Mac OS がサポートしていたリソースが格納されたディレクトリ階層でアプリを構成します。このバンドルは以下の標準形態に従います。

  • 拡張子
    .app
    のバンドル名を持ち、1つだけ
    Contents
    ディレクトリがあります。
    • Contents/MacOS
      に実行コードが置かれます。ここには GUI アプリのメイン実行ファイルと、必要に応じて同梱されたコマンドラインツールが含まれます。
    • 別ディレクトリ
      Resources
      はアプリ専用アイコンや GUI コンポーネントを保持します。
      一部のアプリではさらに
      Frameworks
      ディレクトリに dylib(ライブラリ)を置くことがあります。
  • 重要ファイル 2 つ が存在します:
    Info.plist
    PkgInfo
    • PkgInfo
      は Classic Mac OS から継承されたタイプとクリエイター情報を保持し、必須ではないようですがほぼ普遍的です。
    • Info.plist
      (インフォプロパティリスト)は必須であり、実行ファイル名・アイコンファイル名(
      Resources
      内)、必要最低 macOS バージョン、アプリのドキュメントタイプ宣言、バージョン番号などを指定します。

macOS でコマンドツールを起動すると、その Mach‑O 実行ファイルは

launchd
によって実行されます。アプリを起動する場合も同様に
launchd
が実行ファイルを起動しますが、事前に LaunchServices と RunningBoard を経由して起動プロセスが開始され、
Info.plist
などから取得した情報を用いて処理が進められます。


macOS(継続)

この構造は 2007 年の Mac OS X 10.5 Leopard でコード署名が導入されるまで安定していました。署名に対応するため、

_CodeSignature
ディレクトリを追加し、その中に
CodeResources
ファイル(CDHashes を含む)を置きます。これによりアプリバンドルの整合性チェックが可能になります。

App Store で配布されるアプリはさらに

_MASReceipt
ディレクトリにストア領収書を格納します。2018 年以降、Apple が notarization(ノタリゼーション)を導入すると、Apple が発行する「ticket」を
CodeResources
ファイルとしてバンドルに「スタップル」できます。

過去には Library/Application Support フォルダなどにインストールされていた追加アイテムも、現在はアプリバンドル内に含まれるようになりました。代表的なディレクトリは次の通りです:

  • Library
    (以前はユーザー Home またはメイン Library に設置されていた
    LaunchDaemons
    LoginItems
    を保持)
  • XPCServices
    (アプリが提供する特定サービス用実行コードを格納)
  • Plugins
    (Appex 等の拡張機能)
  • Extensions
    (アプリ意図など他種の拡張機能)

Apple のアプリには

version.plist
など、その他多様なコンポーネントが存在することもあります。


メリット

バンドル内に全てを集約することで、以下の利点があります:

  1. 自己完結型:インストール・更新・削除が容易で、残留ファイルのリスクが低減。
  2. 欠落しにくい:コンポーネントがバンドル内にあるため、外部から消失することはほぼありません。
  3. セキュリティ強化:アプリ署名とノタリゼーションで保護されるため、不正改ざんの検出が容易。

図解(概要)

  • 淡黄色:必須または基本的に全アプリ共通のコンポーネント。
  • 緑色:App Store 経由で配布されるアプリに見られるコンポーネント。
  • 青色:ノタリゼーション票(スタップル)がある場合。
    (任意)

また、Automator ワークフローやスクリプトなど追加フォルダも含まれます。


Intel と Arm アーキテクチャの共通性

現在 Intel および Arm 用にビルドされたアプリは構造上差異がありません。

Contents/MacOS
(および
Frameworks
XPCServices
Plugins
など)のバイナリは単一 Mach‑O 実行ファイル内にプラットフォーム固有コードを持ちます。Universal アプリの場合、1つの「fat」コードファイルに両アーキテクチャ用のコードが含まれ、共通ファイル内に別々の署名も保持されます。

同じ日のほかのニュース

一覧に戻る →

2025/12/08 2:18

I failed to recreate the 1996 Space Jam website with Claude

## Japanese Translation: ## 要約 著者は、Claude AI を使って 1996 年の Warner Bros の「Space Jam」ランディングページをスクリーンショットとアセットフォルダから再構築しようとしました。元のサイトは 200 KB 未満の単一 HTML ファイルで、絶対位置決め、テーブルレイアウト、およびタイル状の星空 GIF 背景に依存しています。 **プロセスと所見** 1. **初期試行:** Claude は概算レイアウトを生成しましたが、惑星軌道を誤った位置に配置しました。軌道パターンは認識できたものの、それを再現することには失敗しました。 2. **構造化プロンプト:** 著者は Claude に「知覚分析」「空間解釈」「再構築計画」の各セクションで理由を説明させ、正確なピクセル座標を要求しましたが、Claude はそれらを提供できませんでした。 3. **カスタムツール:** 精度向上のために 50 px → 5 px のグリッドオーバーレイ、ラベル付き座標参照点、色差比較、スクリーンショットサイドバイサイドビューア、およびスクリーンショットを 6 区域に分割するスクリプトを構築しました。 4. **結果:** Claude の調整は目標から 5–10 px 内に留まりましたが、正しい軌道半径(約 350–400 px)には決して収束しませんでした。内部レイアウトが生成されると、その後のフィードバックは元のスクリーンショットではなく、この誤ったモデルに基づいて行われました。 5. **トークナイズ仮説:** 著者は Claude が 16×16 パッチで画像をトークナイズしているため、細かい視覚的粒度が欠如し、セマンティック理解はあるもののピクセル精度が低いと考えました。 6. **ズームインテスト:** 200 % に拡大したスクリーンショットを提供して、大きなパッチで解像度が向上するか確認しましたが、Claude は依然として比例スケーリング指示に従いませんでした。 **結論** このタスクは未解決のままです。実験は Claude の空間推論限界をベンチマークとし、ピクセル単位で正確な画像再構築におけるモデルの現在の制約を示しています。

2025/12/08 7:18

How I block all online ads

## Japanese Translation: > **概要:** > 著者は、ウェブブラウザとモバイルアプリの両方で広告を排除するために長期的かつ多層的なアプローチを説明しています。彼は **Firefox + uBlock Origin** と最小限のフィルタリスト(組み込みのuBlockフィルタ、EasyList、AdGuard – Ads)と「広告でない不快要素」のためのカスタム非広告フィルタを使用します。 > DNS フィルタリングには **Pi‑hole(または AdGuard Home)** を Docker 上で $5 の DigitalOcean ドロップレットに稼働させ、WireGuard VPN の DNS サーバとして設定しています。トラフィックは **クラウドベースの VPN**(DigitalOcean、Hetzner、Azure、Google Cloud、または AWS)を経由し、プラットフォームが公的クラウド IP を検知して広告配信を減らします。 > この設定では **Cloudflare のキャプチャや HTTP エラー** が発生する場合があるため、著者は該当サイトで VPN を無効化しています。また、**Consent‑O‑Matic**(クッキーポップアップ)、**Buster**(キャプチャ)、**SponsorBlock**(動画広告)などのブラウザ拡張機能を推奨します。iOS では **Background App Refresh** をオフにするとデータ収集が減少し、Android では **ReVanced がアプリをパッチできますが、セキュリティリスクがあります** と指摘しています。 > 著者はこの統合戦略を 3 年以上使用しており、現在ほとんど広告を見ることはありません。プラットフォーム別の効果は異なります:YouTube は uBlock Origin + VPN(1週間〜1か月)が必要;Instagram は uBlock Origin のみで十分;Twitch は主に VPN に依存し、数日で効果が現れます;TikTok は両方のツールを使用しますが、数時間だけです。**AdMob** を利用するアプリも DNS ブロックの恩恵を受けます。 > 広告配信ネットワークは数日から数週間でパターンを観察し調整する可能性があるため、継続的な監視が必要です。著者は **Firebog** をブロックリストの良い情報源として引用し、正当なサイトを壊さないように許可リスト(allowlist)を維持する重要性を強調しています。

2025/12/07 23:37

Dollar-stores overcharge cash-strapped customers while promising low prices

## Japanese Translation: ドルジェネラルとファミリードラーは、棚に貼られたタグの価格よりも高い価格で顧客を頻繁に請求し、低所得層の買い物客に不釣り合いな過剰課金が広く発生しています。州検査と独立調査では、一部店舗でエラー率が88%に達するケースや、両チェーン全体で価格設定失敗が一貫して報告されています。 主な例としては、ノースカロライナ州ウィンザーのファミリードラーで23%のスキャンアイテムが過剰請求(同店の4回連続失敗)、オハイオ州ハミルトンのドルジェネラルで76%のエラー率(2022年10月)、ニュージャージー州バウンドブルックのファミリードラーで68%の不一致(2023年2月)があります。2022年1月以降、ドルジェネラルは4,300件以上、ファミリードラーは2,100件以上の価格失敗事例を記録しています。 アリゾナ州(60万ドル)、コロラド州(40万ドル)、ニュージャージー州・バーモント州・ウィスコンシン州・オハイオ州(最大100万ドル)など複数の州がチェーンと訴訟を和解し、連邦および州の司法長官は追加訴訟を提起しています。株主訴訟では、経営陣がシステム的問題を認識していたと主張されています。ニュージャージー州の連邦裁判所は、モバイルアプリ利用に関連する仲裁条項を理由にドルジェネラルに対する集団訴訟を停止し、消費者の救済手段を制限しました。 規制当局は現在の1検査あたり5,000ドル上限を超えるより厳格な執行や高い罰則を課すことができ、さらに州が調査を進めるにつれて追加の和解が生じる可能性があります。影響としては顧客信頼の低下、チェーンへの潜在的財務損失、評判へのダメージ、およびドルストア業界全体での価格設定と人員管理の強化への動きが挙げられます。