はじめに
この記事では、JUCEフレームワークを使ってGoogle Drive APIと連携するクロスプラットフォームアプリケーションの実装方法を解説します。よくテレビ用のアプリで見るコードを入力してアクティベートするタイプのCXです。
対応プラットフォーム:
- 🍎 macOS - ネイティブで快適な動作
- 🪟 Windows - Visual Studio 2022対応
- 🥧 Raspberry Pi - ARMアーキテクチャでも完全動作
特徴
- ✅ 完全クロスプラットフォーム - Mac、Windows、Raspberry Piで同一コード
- ✅ OAuth2認証 - セキュアなGoogle Drive接続
- ✅ ファイル同期 - ローカルストレージとクラウドの切り替え
- ✅ モダンなUI - JUCEによる美しいネイティブインターフェース
- ✅ プラグイン対応 - VST/AU/AUv3対応のオーディオプラグインとしても動作
アーキテクチャ概要
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────┐
│ Main App │ │ Cloud Manager │ │ Storage Provider│
│ │◄──►│ │◄──►│ │
│ - UI Components │ │ - Service Switch │ │ - Google Drive │
│ - User Input │ │ - Auth Manager │ │ - Local Storage │
└─────────────────┘ └──────────────────┘ └─────────────────┘
│
▼
┌──────────────────┐
│ Auth Component │
│ │
│ - OAuth2 Flow │
│ - Web Browser │
└──────────────────┘
実装の核心部分
1. クラウドマネージャー(R2CloudManager)
全体の制御を行うメインクラスです。
class R2CloudManager
{
public:
enum class ServiceType
{
Local,
GoogleDrive
// 今後追加予定: iCloud, Dropbox, OneDrive
};
enum class AuthStatus
{
NotAuthenticated,
Authenticating,
Authenticated,
Error
};
// シンプルなファイル操作API
void saveFile(const juce::String& filename, const juce::String& content,
FileOperationCallback callback = nullptr);
void loadFile(const juce::String& filename, FileContentCallback callback);
// 認証関連
void showAuthenticationUI(juce::Component* parentComponent);
void selectService(ServiceType serviceType);
2. Google Drive認証(OAuth2実装)
デバイスフローを使用したセキュアな認証を実装しています。
void R2CloudAuthComponent::startAuthentication()
{
// 1. デバイスコードをリクエスト
requestDeviceCode();
}
void R2CloudAuthComponent::requestDeviceCode()
{
juce::String postData = "client_id=" + googleClientId;
postData += "&scope=https://www.googleapis.com/auth/drive.file";
makeHttpRequest("https://oauth2.googleapis.com/device/code", postData,
[this](bool success, juce::String response, int statusCode) {
parseDeviceCodeResponse(response);
});
}
3. クロスプラットフォーム対応のポイント
WebBrowserComponentを使用してOAuth認証画面を表示:
// JUCE 8の新しいAPIを使用
juce::WebBrowserComponent::Options options;
options = options.withNativeIntegrationEnabled(true);
// JavaScript関数を登録して認証完了を検知
options = options.withNativeFunction("authComplete",
[this](const juce::Array<juce::var>& args, auto completion) {
handleAuthSuccess(args[0].toString());
completion(juce::var());
});
webBrowser = std::make_unique<juce::WebBrowserComponent>(options);
セットアップ手順
1. プロジェクトのクローンと認証情報設定
# プロジェクトをクローン
git clone https://github.com/your-repo/r2juce-clouddoc.git
cd r2juce-clouddoc
# 認証情報ファイルを準備
cp Source/Credentials_template.h Source/Credentials.h
2. Google Cloud Console設定
2-1. プロジェクト作成
- Google Cloud Consoleにアクセス
- 新しいプロジェクトを作成
- Google Drive APIを有効化
2-2. OAuth同意画面の設定
APIs & Services > OAuth consent screen
├── User Type: External
├── App name: CloudDoc Desktop Client
├── User support email: your-email@example.com
└── Test users: 自分のアカウントを追加
2-3. OAuth 2.0認証情報の作成
APIs & Services > Credentials > Create Credentials > OAuth 2.0 Client ID
├── Application type: Desktop application
├── Name: CloudDoc Desktop Client
└── Download JSON (後で使用)
3. 認証情報をコードに設定
生成されたClient IDとClient SecretをCredentials.h
に設定:
// Source/Credentials.h
#define GOOGLE_CLIENT_ID "123456789012-abcdefg...xyz.apps.googleusercontent.com"
#define GOOGLE_CLIENT_SECRET "GOCSPX-AbCdEfGhIjKlMnOpQrSt..."
📝 認証情報の取得例
Google Cloud Consoleで生成された認証情報は以下のような形式です:
{
"client_id": "123456789012-abcdefghijklmnopqrstuvwxyz123456.apps.googleusercontent.com",
"client_secret": "GOCSPX-AbCdEfGhIjKlMnOpQrStUvWxYz123"
}
これをCredentials.h
の対応する箇所に貼り付けてください。
⚠️ 重要:
Credentials.h
は.gitignore
に含まれており、リポジトリにコミットされません。各開発者が個別に設定する必要があります。
ビルドと実行
事前準備
- JUCE Frameworkをインストール(バージョン7.0以上推奨)
- 各プラットフォームの開発環境を準備
macOS
cd Builds/MacOSX
# Xcodeプロジェクトをビルド
xcodebuild -project CloudDoc.xcodeproj -configuration Release
# または、Xcodeで直接開いてビルド
open CloudDoc.xcodeproj
Windows (Visual Studio 2022)
cd Builds\VisualStudio2022
# コマンドラインでビルド
MSBuild CloudDoc.sln /p:Configuration=Release /p:Platform=x64
# または、Visual Studioで直接開いてビルド
Raspberry Pi (Linux)
cd Builds/LinuxMakefile
# 依存関係のインストール(Debian/Ubuntu)
sudo apt-get update
sudo apt-get install build-essential libasound2-dev libjack-jackd2-dev \
ladspa-sdk libcurl4-openssl-dev libfreetype6-dev libx11-dev \
libxcomposite-dev libxcursor-dev libxext-dev libxinerama-dev \
libxrandr-dev libxrender-dev libwebkit2gtk-4.0-dev libglu1-mesa-dev
# ビルド実行
make CONFIG=Release
ビルドが成功すると...
-
macOS:
Builds/MacOSX/build/Release/CloudDoc.app
-
Windows:
Builds/VisualStudio2022/x64/Release/App/CloudDoc.exe
-
Raspberry Pi:
Builds/LinuxMakefile/build/CloudDoc
使用方法
1. 基本的な使い方
// CloudManagerの初期化
cloudManager = std::make_unique<r2juce::R2CloudManager>();
cloudManager->setGoogleCredentials(CLIENT_ID, CLIENT_SECRET);
// コールバック設定
cloudManager->onAuthStatusChanged = [this](auto status) {
handleAuthStatusChanged(status);
};
// Google Driveサービスを選択
cloudManager->selectService(r2juce::R2CloudManager::ServiceType::GoogleDrive);
// 認証が必要な場合は認証UIを表示
if (cloudManager->needsAuthentication()) {
cloudManager->showAuthenticationUI(this);
}
2. ファイル操作
// ファイル保存
cloudManager->saveFile("document.txt", "Hello World!",
[](bool success, juce::String error) {
if (success) {
DBG("File saved successfully!");
}
});
// ファイル読み込み
cloudManager->loadFile("document.txt",
[](bool success, juce::String content, juce::String error) {
if (success) {
DBG("File content: " + content);
}
});
技術的なハイライト
1. プロバイダーパターン
ローカルストレージとクラウドストレージを統一インターフェースで操作:
class R2CloudStorageProvider {
public:
virtual void uploadFile(const juce::String& fileName,
const juce::MemoryBlock& data,
const juce::String& folderId,
FileOperationCallback callback) = 0;
// ...
};
2. 非同期処理
すべてのネットワーク操作は非同期で実行し、UIをブロックしません:
juce::Thread::launch([this, url, callback]() {
auto stream = url.createInputStream(options);
auto response = stream->readEntireStreamAsString();
juce::MessageManager::callAsync([callback, response]() {
callback(true, response);
});
});
3. トークン管理
アクセストークンとリフレッシュトークンを安全に保存・管理:
void R2GoogleDriveProvider::saveTokens() {
auto tokenFile = getTokenFile();
juce::DynamicObject::Ptr tokenData = new juce::DynamicObject();
tokenData->setProperty("access_token", accessToken);
tokenData->setProperty("refresh_token", refreshToken);
tokenData->setProperty("token_expiry", tokenExpiry.toMilliseconds());
auto json = juce::JSON::toString(juce::var(tokenData.get()));
tokenFile.replaceWithText(json);
}
ライブラリ構成
本実装は再利用可能なライブラリとして設計されています:
r2juce/
├── R2CloudManager.h/.cpp # メイン管理クラス
├── R2CloudStorageProvider.h # 抽象基底クラス
├── R2GoogleDriveProvider.h/.cpp # Google Drive実装
├── R2LocalStorageProvider.h/.cpp # ローカルストレージ実装
├── R2CloudAuthComponent.h/.cpp # 認証UI
└── R2TextEditor.h/.cpp # カスタムテキストエディタ
今後の拡張予定
- 🔄 Dropbox API対応
- ☁️ OneDrive API対応
- 🍎 iCloud Drive対応
- 📁 フォルダ階層サポート
- 🔍 ファイル検索機能
- 📊 同期状態の可視化
まとめ
JUCEフレームワークを使用することで、一つのコードベースでMac、Windows、Raspberry Piすべてで動作するGoogle Drive連携アプリが実現できました。
🎯 特に注目すべきポイント:
- 完全なクロスプラットフォーム対応 - ビルド設定を変えるだけで各OSのネイティブアプリに
- モダンなOAuth2実装 - セキュリティベストプラクティスに準拠
- プラグイン対応 - VST/AUプラグインとしても動作可能
- 拡張性の高い設計 - 新しいクラウドサービスの追加が容易
🚀 ぜひお試しください!
完全なソースコードはGitHubリポジトリで公開中です。
🚀 クイックスタート
# 1. リポジトリをクローン
git clone https://github.com/masanaohayashi/R2JUCE.git
cd R2JUCE/examples/CloudDoc
# 2. 認証情報を設定
cp Source/Credentials_template.h Source/Credentials.h
# Credentials.hを編集してGoogle認証情報を設定
# 3. Dockerを使ってRaspberry Pi用にビルド
cd Docker/raspi
./build.sh Release