見出し画像

macOS アプリを個人でリリースするまでにやったこと 〜 EXIF Extractor をつくった話

はじめに

写真を撮るのが好きで、撮影後に「このとき、どんな設定で撮ったんだろう?」と振り返ることがよくあります。

Sony のミラーレスカメラを使っているのですが、RAW 現像やリサイズが終わった写真を見返していると、「あれ、このボケ感はどの焦点距離だっけ」「ISO これで撮ったのか、思ったよりノイズ出てないな」といった感想が出てきます。そのたびに Finder でファイルの情報を開いたり、ターミナルでコマンドを打ったりしていたのですが、これが地味に手間です。

さらに、Instagram などに写真を投稿するとき、撮影設定をキャプションに添えることがあります。「Sony α7R V / FE 50-150mm F2 GM / 85mm f/2.8 ISO400 1/500s」みたいな感じです。
これまでは、ブラウザで同じようなことができるもの作って使っていましたが、毎回ファイルをアップロードするのが面倒になってきました。

「だったら自分で使いやすいツールを作ってしまおう」と思ったのが、今回の開発のきっかけです。

このメモは、そうして作った EXIF Extractor というアプリの機能紹介と、それを実際に配布できる状態にするまでに必要だった手続きについて書いたものです。特に Apple Developer プログラムへの登録から証明書の取得・公証・インストーラー作成まで、リリースにまつわる手続きの全体像を、できるだけわかりやすく説明しています。

「自作アプリを世に出したいが、どんな手続きが必要かわからない」「Mac アプリのリリースって敷居が高そう」と感じている方に、少しでも参考になれば嬉しいです。


つくったもの:EXIF Extractor

EXIF Extractor は、写真フォルダを開いて EXIF 情報(撮影データ)を手軽に確認・コピーできる macOS アプリです。

macOS 15.0(Sequoia)以降で動作します。ソースコードは GitHub で公開しており、インストーラー(.pkg ファイル)からワンクリックでインストールできます。



EXIF 情報とは何か

まず EXIF について簡単に説明しておきます。

EXIF(Exchangeable Image File Format) とは、デジタルカメラやスマートフォンで撮影した写真に自動的に埋め込まれるメタデータのことです。「写真についての情報」とも言えます。

具体的にはこんな内容が記録されています。

$$
\begin{array}{|l|l|}
\hline
\textbf{\textsf{カテゴリ}} & \textbf{\textsf{内容の例}} \\
\hline
\textsf{カメラ・レンズ} & \textsf{Sony ILCE-7CM2 / FE 50-150mm F2 GM} \\
\hline
\textsf{撮影設定} & \textsf{焦点距離 85mm / 絞り f/2.8 / ISO 400 / SS 1/500s} \\
\hline
\textsf{撮影日時} & \textsf{2026/03/07 16:24:24} \\
\hline
\textsf{ファイル情報} & \textsf{解像度 4898×3265 / JPG / 1 MB} \\
\hline
\textsf{GPS} & \textsf{緯度 35.681236 / 経度 139.767125(位置情報オン時のみ)} \\
\hline
\end{array}
$$

EXIF は写真ファイルの中に静かに存在しているデータで、普段は意識しませんが、活用できる場面は意外と多いです。

  • 「このときどんな設定で撮ったか」を見返して次の撮影に活かす

  • SNS に撮影情報を載せる

  • 複数の写真の設定を比べて傾向を分析する

  • フォルダ全体でどのカメラ・レンズを多く使ったか確認する


主な機能

フォルダブラウザ

まず左側のサイドバーに写真フォルダを追加します。追加すると写真枚数が表示され、クリックするとウィンドウ下部のサムネイル一覧に写真が並びます。

サムネイルをクリックするか、キーボードの 矢印キー(← →)で写真を切り替えながら、中央エリアに拡大表示できます。ファイルを開いて閉じて…という操作なしに、素早くブラウズできるのがポイントです。

フォルダはいくつでも追加でき、サブフォルダがある場合はツリー形式で表示されます。写真を読み込んだあとでフォルダ内のファイルが変わった場合はリロードボタンで更新できます。

EXIF メタデータパネル

写真を選択すると、右側のパネルに EXIF 情報が整理されて表示されます。セクションは以下の 5 つです。

  • File Info:ファイル名・サイズ・フォーマット

  • Camera Info:カメラメーカー・モデル名・レンズ・現像ソフト

  • Shooting Info:撮影日時・焦点距離・絞り・ISO・シャッタースピード・露出補正・ホワイトバランス・フラッシュ

  • Image Info:解像度・カラースペース

  • GPS:緯度・経度・高度

各フィールドの右端にはコピーボタンがあり、クリックするとその値だけをクリップボードにコピーできます。「レンズ名だけコピーしたい」「シャッタースピードだけ転記したい」といった操作が素早くできます。

コピーテンプレート

撮影情報を SNS に投稿する際、毎回「絞りは…ISO は…」と手動で組み合わせるのは面倒です。コピーテンプレート機能を使うと、あらかじめ決めた形式でまとめてコピーできます。

テンプレートは自由に作れます。たとえば Instagram 投稿用にこんなテンプレートを登録したとします。

{cameraName} {focalLength} {f} ISO{iso} {shutterSpeed}

写真を選んでこのテンプレートのコピーボタンを押すと、Sony ILCE-7CM2 85mm f/2.8 ISO400 1/500s という文字列がクリップボードに入ります。テンプレートはいくつでも登録でき、「カメラ名とレンズだけ」「ファイル情報だけ」など用途に合わせて使い分けられます。

テンプレートマネージャーでは、プレビューエリアで実際の写真データを使った出力を確認しながら編集できます。プレースホルダー({make} {lens} {iso} など)の一覧も表示されているので、覚えていなくても大丈夫です。

撮影統計

フォルダを選んだ状態でサイドバーの統計ボタンを押すと、そのフォルダ内の全写真を集計したグラフが表示されます。

表示されるのは以下のとおりです。

  • 分布グラフ:焦点距離 / 絞り値 / ISO 感度 / シャッタースピード

  • 使用ランキング:カメラ・レンズ別の枚数と割合

  • サマリー:総枚数・EXIF あり枚数・最初と最後の撮影日

「最近は ISO 1600 以上が増えてきたな」「このレンズは旅行のときしか使ってないのか」といった気づきが得られます。写真の撮り方の傾向を客観的に見るのに便利です。

環境設定

⌘,(Command + カンマ) で環境設定を開けます。

設定できる項目は 2 つです。

  • 言語:日本語 / English を切り替えられます。再起動不要で、切り替えた瞬間に全 UI の表示言語が変わります。

  • フォントサイズ:EXIF パネルやテンプレートエリアの文字サイズを 5 段階(XS / S / M / L / XL)で調整できます。細かい値を見たいときは小さめに、老眼気味のときは大きめに、など使い分けられます。

自動アップデート

アプリのアップデートがあった場合、起動時に通知されます。Sparkle というオープンソースのフレームワークを利用しており、通知ダイアログからそのままインストールできます。

「Updates」ページを自分で確認しにいく必要はなく、アプリが自動でチェックしてくれます。手動で確認したい場合は「EXIF Extractor」メニュー →「Check for Updates…」から実行できます。

ヘルプ

メニューバーの「Help」からヘルプウィンドウを開けます。キーボードショートカットや各機能の使い方がまとまっています。


個人でアプリを配布するために必要だったこと

コードを書いてアプリを作ること自体はできても、「他の人の Mac で安全に動かせるように配布する」となると、Apple のエコシステムが定めたいくつかの手続きが必要になります。最初はこのあたりが一番わかりにくく、調べながら進めるのに時間がかかりました。

全体の流れはこうなっています。

  1. Apple Developer プログラムに登録

  2. 証明書を取得(2 種類)

  3. アプリをビルド・署名

  4. Apple のサーバーで公証(ノータリゼーション)

  5. インストーラー(.pkg)を作成・署名・公証

  6. GitHub にリリースとして公開


① Apple Developer プログラムへの登録

macOS(や iOS)向けのアプリを配布するためには、Apple Developer Program への加入が必要です。

登録に必要なもの

  • Apple ID

  • クレジットカード(または PayPal)

  • 年間 12,800 円(2026 年現在)

登録先は developer.apple.com です。手順としては、Apple ID でサインインして「Enroll」ボタンから申し込みを進めます。個人として登録する場合、法人番号などは不要です。

審査があり、承認されるまで数日かかることもあります(私の場合は 2 日でした)。承認されると Apple Developer のポータルサイトにアクセスでき、証明書の発行などができるようになります。

年間費用を支払い続ける必要があるため、「とりあえず試したいだけ」という場合は、署名なしで自分の Mac だけで動かす形にするか、費用対効果をよく考えてから登録するのがよいと思います。


② 証明書の取得

Apple Developer に登録したら、次は 証明書(Certificate) を取得します。証明書は「このアプリはこの開発者が作ったものです」という身元証明のようなものです。

macOS アプリの配布では、以下の 2 種類の証明書が必要です。

Developer ID Application 証明書

アプリ本体(.app ファイル)に署名するための証明書です。

この証明書で署名されたアプリは、Mac App Store を経由せずに配布しても、macOS の Gatekeeper(セキュリティ機能)に「信頼できる開発者のアプリ」として認識されます。

Developer ID Installer 証明書

インストーラーパッケージ(.pkg ファイル)に署名するための証明書です。

アプリ本体とは別の証明書が必要な点が最初わかりにくかったです。「アプリに署名したのに、なぜパッケージにも別の証明書が必要なの?」と思いますが、.pkg ファイルは macOS のインストール機構(macOS Installer)が扱うもので、アプリ署名とは別の体系で管理されているためです。

証明書の取得方法

証明書の取得は、Xcode(Apple の開発ツール)から行います。

  1. Xcode を開いて「Preferences(設定)」→「Accounts」タブに進む

  2. Apple ID でサインインする

  3. 「Manage Certificates」ボタンから証明書の種類を選んで「+」ボタンで作成

Xcode が秘密鍵の生成から Apple のサーバーへの申請・インストールまで自動でやってくれるので、手作業で CSR(証明書署名要求)ファイルを作る必要はありません。証明書は Mac のキーチェーン(パスワード管理の仕組み)に保存されます。

取得した証明書は、後述する GitHub Actions での自動リリース時に使うため、Base64 形式でエクスポートして GitHub のシークレットに登録しておきます。


③ コード署名(Code Signing)

証明書が手に入ったら、ビルドしたアプリに署名します。

コード署名とは、アプリのバイナリ(実行ファイル)に電子的な印鑑を押す行為です。「このアプリは確かにこの開発者が作ったもので、配布後に改ざんされていない」ことを証明します。

macOS では、Gatekeeper という機能がアプリの署名を確認しています。署名がなかったり、信頼されていない開発者の署名だったりすると、初回起動時に「開発元を確認できないため開けません」という警告が出てしまいます。

Xcode でビルドするときにプロジェクト設定で証明書を指定しておけば、ビルドと同時に署名が行われます。コマンドラインでビルドする場合は xcodebuild コマンドにオプションを付けて署名できます。

署名が正しくできているかは codesign -dv --verbose=4 アプリのパス というコマンドで確認できます。


④ 公証(Notarization)

コード署名が済んだら、次は 公証(ノータリゼーション)です。

公証とは、署名済みのアプリを Apple のサーバーに送って自動スキャンを受け、問題がなければ「公証済み」のチケットを発行してもらう手続きです。macOS Catalina(10.15)以降、公証を受けていないアプリは Gatekeeper によって起動がブロックされるようになりました。

公証の流れ

  1. xcrun notarytool submit コマンドでアプリのパッケージを Apple に送信

  2. Apple のサーバーが自動でセキュリティスキャンを実施

  3. 問題がなければ「Accepted」の結果が返ってくる(通常数秒〜数分)

  4. xcrun stapler staple コマンドで公証チケットをアプリに埋め込む(ステープル)

ステープルをしておくと、オフライン環境でもアプリが公証済みと判断されます。ネットにつながっていない状態でも Gatekeeper の確認が通るため、ユーザー体験が向上します。

公証が通らない原因としてよくあるのは、「ハード化されたランタイム(Hardened Runtime)が有効になっていない」「特定のエンタイトルメント(権限設定)が足りない」といったケースです。エラーメッセージを読んで対処するか、Apple のドキュメントを参照することになります。


⑤ インストーラー(.pkg ファイル)の作成

アプリを配布する方法は主に 3 つあります。

$$
\begin{array}{|l|l|}
\hline
\textbf{\textsf{方法}} & \textbf{\textsf{特徴}} \\
\hline
\textsf{.app をそのまま配布(ZIP 形式など)} & \textsf{最も簡単。手動で Applications フォルダにドラッグ} \\
\hline
\textsf{.dmg(ディスクイメージ)で配布} & \textsf{ドラッグ&ドロップのレイアウトを設定できる} \\
\hline
\textsf{.pkg(インストーラーパッケージ)で配布} & \textsf{ウィザード形式。スクリプトも実行できる} \\
\hline
\end{array}
$$

今回は .pkg 形式を選びました。ユーザーがダブルクリックして「続ける」を押していけば自動的に /Applications にインストールされ、迷いにくいからです。

.pkg ファイルの作成には pkgbuildproductbuild という 2 つのコマンドラインツールを使います。まず pkgbuild でアプリ本体を .pkg にパッケージ化し、次に productbuild で最終的なインストーラーとして組み立てます。このとき --sign オプションで Developer ID Installer 証明書を指定することで、.pkg ファイルへの署名が同時に行われます。署名後、アプリ本体と同様に公証を受けます。


⑥ 自動リリースの仕組み(GitHub Actions)

ここまでの手順を毎回手動でやるのは、ミスも起きやすく非常に大変です。今回は GitHub Actions を使って、バージョンを付けてコードを push するだけで自動でリリースが完了する仕組みを作りました。

自動化している内容

今回設定した自動リリースの流れはこうです。

  1. バージョンタグを push(例: v/v1.0.0)

  2. GitHub Actions が起動

  3. アプリをビルド

  4. Developer ID Application 証明書でコード署名

  5. Apple サーバーへ公証を依頼 → 完了後にステープル

  6. .pkg インストーラーを作成

  7. Developer ID Installer 証明書で .pkg に署名

  8. .pkg を公証

  9. GitHub Releases に .pkg を添付してリリースを公開

これらすべてが自動で実行されます。手動でやっていたら小一時間かかる作業が、タグを push するだけで 10 分ほどで終わります。

GitHub Secrets の活用

証明書や App Store Connect の API キーなどの機密情報は、リポジトリに直接含めるわけにはいきません。GitHub には Secrets(シークレット)という機能があり、外部から見えない形で機密情報を保存できます。ワークフロー(自動化の定義ファイル)の中で環境変数として参照する形で使います。

今回登録した主なシークレットはこのようなものです。

  • 証明書ファイル(Base64 エンコード済み)

  • 証明書のパスワード

  • App Store Connect の API キー(公証に使用)

  • Sparkle の更新署名に使う秘密鍵

バージョン管理の自動化

さらに、tagpr というツールも使っています。tagpr は GitHub Actions 上で動くツールで、main ブランチにマージされるたびに自動でバージョンアップの Pull Request を作ってくれます。PR にラベルを付けることで「マイナーバージョンアップ」「パッチ」などを指定でき、マージするとタグが自動で付いてリリースが走る、という流れができています。


コーディングについて

このアプリは Claude Code(Anthropic の AI コーディングエージェント)を使いながら開発しました。

Claude Code は、ターミナルやエディタと連携して動く AI エージェントで、「こういう機能を作りたい」「このエラーを直したい」と話しかけると、実際にコードを書いて・修正して・実行して、結果を確認しながら作業を進めてくれます。

実装の大半は Claude Code との会話の中で進んでいきました。GitHub Actions の設定や公証の自動化など、普段あまり触れない領域の作業も、相談しながら進めることでスムーズに実装できました。

個人的に感じたのは、「やりたいことは明確なのに、調べて試して失敗して…を繰り返す時間が大幅に短くなった」ということです。特に今回のような Apple のエコシステム特有の手続き(証明書・公証など)は、情報が散らばっていて調べるだけでも時間がかかりますが、一緒に考えてくれる相手がいることで大分楽になりました。


苦労したこと・ハマったポイント

スムーズにいかなかった部分もいくつかあるので、メモとして残しておきます。

証明書の種類が多くて最初は混乱した

「アプリ署名用」「インストーラー署名用」があり、さらに開発中だけで使う「Development 証明書」と配布用の「Developer ID 証明書」がある、という整理が最初わかりにくかったです。最終的には、Mac App Store 外で配布するなら Developer ID Application と Developer ID Installer の 2 つが必要、とシンプルに覚えることにしました。

公証のエラーメッセージが難解

公証に失敗したとき、エラーコードとメッセージが返ってきますが、最初は何を意味するのかよくわかりませんでした。「Hardened Runtime が有効になっていない」「特定のエンタイトルメントが必要」といった原因が多く、Apple のドキュメントを読んだり、エラー内容を調べながら対処しました。

アプリ名にスペースを入れたかった

アプリの表示名を「EXIF Extractor」(スペースあり)にしたかったのですが、Xcode のターゲット名(内部的な識別子)はスペースが使えません。ターゲット名を変えずに、ビルド設定の PRODUCT_NAME という項目だけを「EXIF Extractor」に変更することで解決しました。こういった細かいところで詰まることがありました。

GitHub Actions でのリリースの説明文が二重になる問題

リリースの説明文(変更履歴)が 2 回繰り返される問題がありました。tagpr が自動生成した本文と、リリース時のアクションが追加する本文が重なっていたためで、一方の設定を削除することで解消しました。


かかった費用

参考までに、アプリをリリースするまでにかかった費用をまとめます。

$$
\begin{array}{|l|l|}
\hline
\textbf{\textsf{項目}} & \textbf{\textsf{費用}} \\
\hline
\textsf{Apple Developer プログラム(年間)} & \textsf{12,800 円} \\
\hline
\textsf{GitHub(ソースコード管理・Actions)} & \textsf{無料(個人利用の範囲内)} \\
\hline
\textsf{Claude Code(AI コーディングエージェント)} & \textsf{使用量による} \\
\hline
\end{array}
$$

Apple Developer プログラムは毎年更新が必要です。更新しないと証明書が失効し、公証済みアプリの配布ができなくなります(既にインストール済みのアプリには影響なし)。


配布先・インストール方法

GitHub のリリースページから .pkg ファイルをダウンロードして実行するだけです。

インストーラーは署名・公証済みなので、「開発元を確認できません」という警告は出ません。macOS 15.0(Sequoia)以降の Mac であれば動作します。

ソースコードも同じリポジトリで公開しているので、Xcode があれば自分でビルドして使うこともできます。


まとめ

「SNS に投稿するとき撮影設定をコピーするのが面倒」という個人的な不満からはじまり、ひとつの macOS アプリをリリースするところまで経験できました。

アプリをつくること自体はコードと AI の助けで進められましたが、配布するための手続き——Apple Developer プログラムへの登録、2 種類の証明書の取得、公証、インストーラーの作成——はコードとは別の学習コストがかかりました。特に最初は「何が必要で、何をすればいいのか」の全体像がつかみにくかったです。

この記事がその全体像を理解するための参考になれば嬉しいです。同じように「作ったはいいけど配布どうすればいい?」という方がいたら、ぜひ一歩踏み出してみてください。

よければ使ってみてください 📷

いいなと思ったら応援しよう!