A SwiftUI app that identifies plants using AI vision APIs (OpenAI or Gemini) with Firebase Remote Config for dynamic configuration.
AIProxy provides a secure way to use AI APIs in mobile apps without exposing your API keys. It supports multiple providers including OpenAI and Gemini.
- Go to AIProxy Dashboard
- Create an account and log in
- Create a new project for your app
- In AIProxy dashboard, add OpenAI as a provider
- Enter your OpenAI API key
- Copy the generated:
- Partial Key (e.g.,
v2|xxxxxxxx|xxxxxxxxxxxxxx) - Service URL (e.g.,
https://api.aiproxy.com/xxxxx/xxxxx)
- Partial Key (e.g.,
- In AIProxy dashboard, add Gemini as a provider
- Enter your Google AI API key
- Copy the generated:
- Partial Key
- Service URL
For development and testing, you need to configure the device check bypass:
- In AIProxy dashboard, go to Project's Device Check
- Find DeviceCheck Bypass Token
- Copy your bypass token
- Add to your Xcode scheme environment variables:
AIPROXY_DEVICE_CHECK_BYPASS = your_bypass_token_here
How to add in Xcode:
- Select your target scheme β Edit Scheme
- Go to Run β Arguments β Environment Variables
- Add
AIPROXY_DEVICE_CHECK_BYPASSwith your token value
Firebase Remote Config allows you to dynamically change app behavior without releasing a new version. This project uses it to switch AI providers and models on the fly.
- Go to Firebase Console
- Click Add Project and follow the setup wizard
- Add an iOS app to your project
- Download
GoogleService-Info.plist
Navigate to Remote Config in your Firebase Console and add the following parameters:
| Parameter Key | Default Value | Description |
|---|---|---|
ai_provider |
openai |
Active AI provider (openai or gemini) |
openai_model_name |
gpt-4.1-mini |
OpenAI model to use |
gemini_model_name |
gemini-2.5-flash |
Gemini model to use |
system_prompt |
(see below) | System prompt for AI |
π‘ Tip: You can leave any Remote Config parameter blank in Firebase. The app will automatically use the default values defined in
RemoteConfigManager.swift. For example, you can leavesystem_promptempty, and the app will use the built-in default prompt.
Step-by-step:
- In Firebase Console, go to Remote Config
- Click Add Parameter
- Enter the parameter key (e.g.,
ai_provider) - Set the default value (e.g.,
openai) - Click Save
- Repeat for all parameters
- Click Publish Changes
To switch from OpenAI to Gemini:
- Go to Remote Config in Firebase Console
- Find the
ai_providerparameter - Change value from
openaitogemini - Click Save then Publish Changes
- The app will use Gemini on next launch or foreground
To change the OpenAI model:
- Find
openai_model_nameparameter - Change value (e.g.,
gpt-4oorgpt-4.1-nano) - Save and publish
Available models:
Check the official documentation for the latest supported models:
- OpenAI Models: platform.openai.com/docs/models
- Gemini Models: ai.google.dev/gemini-api/docs/models
- Download
GoogleService-Info.plistfrom your Firebase project - Delete the existing
GoogleService-Info.plistin your Xcode project - Drag and drop your new
GoogleService-Info.plistinto Xcode - Ensure "Copy items if needed" is checked
- Add to your app target
Open AIProxyService.swift and update the initialization with your AIProxy credentials:
// MARK: - Initialization
private init() {
// Replace with YOUR OpenAI AIProxy credentials
self.openAIClient = AIProxy.openAIService(
partialKey: "YOUR_OPENAI_PARTIAL_KEY", // e.g., "v2|xxxxxxxx|xxxxxxxxxxxxxx"
serviceURL: "YOUR_OPENAI_SERVICE_URL" // e.g., "https://api.aiproxy.com/xxxxx/xxxxx"
)
// Replace with YOUR Gemini AIProxy credentials
self.geminiClient = AIProxy.geminiService(
partialKey: "YOUR_GEMINI_PARTIAL_KEY", // e.g., "v2|xxxxxxxx|xxxxxxxxxxxxxx"
serviceURL: "YOUR_GEMINI_SERVICE_URL" // e.g., "https://api.aiproxy.com/xxxxx/xxxxx"
)
}Location in code:
PlantID/
βββ Services/
βββ AIProxyService.swift β Edit lines 76-84
Update RemoteConfigManager.swift to change the default system prompt for your use case:
static let defaultSystemPrompt: String = """
Your custom prompt here...
"""Modify PlantData.swift or create a new model that matches your AI response structure:
struct YourCustomResult: Codable {
let success: Bool
let data: YourDataResponse?
let error: String?
}
struct YourDataResponse: Codable {
// Your custom fields
}Run the app in DEBUG mode to see configuration logs in the Xcode console:
ββββββββββββββββββββββββββββββββββββββββ
π§ REMOTE CONFIG VALUES:
ββββββββββββββββββββββββββββββββββββββββ
π€ AI Provider: openai
π€ OpenAI Model: gpt-4.1-mini
π€ Gemini Model: gemini-2.5-flash
ββββββββββββββββββββββββββββββββββββββββ
- Launch the app
- Take or select a photo
- Verify the identification result appears
- Change
ai_providerin Firebase Console fromopenaitogemini - Publish the changes
- Background and foreground the app (or relaunch)
- Check console logs for updated provider
- Test identification again