diff --git a/docs/REVENUECAT_INTEGRATION_GUIDE.md b/docs/REVENUECAT_INTEGRATION_GUIDE.md
index ae6aeec..2224d78 100644
--- a/docs/REVENUECAT_INTEGRATION_GUIDE.md
+++ b/docs/REVENUECAT_INTEGRATION_GUIDE.md
@@ -8,6 +8,9 @@ A comprehensive, reusable guide for integrating RevenueCat into iOS apps with Sw
2. [Prerequisites](#prerequisites)
3. [SDK Installation](#sdk-installation)
4. [Configuration Architecture](#configuration-architecture)
+ - [Option A: Swift Secrets File](#option-a-swift-secrets-file-simple)
+ - [Option B: Separate Debug/Release Keys](#option-b-separate-debugrelease-keys-swift-files)
+ - [Option C: xcconfig + Info.plist (Recommended)](#option-c-xcconfig--infoplist-recommended-for-xcode-15-projects)
5. [PremiumManager Implementation](#premiummanager-implementation)
6. [Paywall Implementation](#paywall-implementation)
7. [Event Handling](#event-handling)
@@ -123,7 +126,7 @@ Add to `.gitignore`:
**/Secrets.swift
```
-#### Option B: Separate Debug/Release Keys (Recommended for Production)
+#### Option B: Separate Debug/Release Keys (Swift Files)
Create two secrets files:
@@ -143,6 +146,228 @@ enum Secrets {
Use build configurations or compiler flags to include the correct file.
+#### Option C: xcconfig + Info.plist (Recommended for Xcode 15+ Projects)
+
+This approach is the most robust for modern Xcode projects, especially those using `fileSystemSynchronizedGroups` (automatic file sync). It keeps secrets in xcconfig files and injects them into Info.plist at build time.
+
+**Why use this approach:**
+- Secrets stay in gitignored xcconfig files
+- Build settings automatically switch between debug/release keys
+- Works with Xcode's auto-generated Info.plist replacement
+- No Swift code changes needed to switch keys
+
+##### Step 1: Create xcconfig Structure
+
+Create the following files in `YourApp/Configuration/`:
+
+**`Base.xcconfig`** (committed to git):
+```
+// Base.xcconfig - Source of truth for all identifiers
+
+COMPANY_IDENTIFIER = com.yourcompany
+BUNDLE_ID_NAME = YourApp
+PRODUCT_NAME = Your App
+DEVELOPMENT_TEAM = YOUR_TEAM_ID
+
+APP_BUNDLE_IDENTIFIER = $(COMPANY_IDENTIFIER).$(BUNDLE_ID_NAME)
+```
+
+**`Debug.xcconfig`** (committed to git):
+```
+// Debug.xcconfig
+#include "Base.xcconfig"
+#include "Secrets.debug.xcconfig"
+```
+
+**`Release.xcconfig`** (committed to git):
+```
+// Release.xcconfig
+#include "Base.xcconfig"
+#include "Secrets.release.xcconfig"
+```
+
+**`Secrets.debug.xcconfig`** (gitignored):
+```
+// Secrets.debug.xcconfig
+// ⚠️ DO NOT COMMIT THIS FILE
+
+// RevenueCat Test API Key (starts with "test_")
+REVENUECAT_API_KEY = test_your_test_key_here
+```
+
+**`Secrets.release.xcconfig`** (gitignored):
+```
+// Secrets.release.xcconfig
+// ⚠️ DO NOT COMMIT THIS FILE
+
+// RevenueCat Production API Key (starts with "appl_")
+REVENUECAT_API_KEY = appl_your_production_key_here
+```
+
+Add to `.gitignore`:
+```
+**/Secrets.debug.xcconfig
+**/Secrets.release.xcconfig
+```
+
+##### Step 2: Create Info.plist at Project Root
+
+**CRITICAL:** For projects using `fileSystemSynchronizedGroups`, the Info.plist MUST be placed at the **project root** (same level as the `.xcodeproj`), NOT inside the synced app folder. Otherwise Xcode will automatically add it to Copy Bundle Resources and cause build failures.
+
+Create `Info.plist` at the project root (e.g., `YourApp/Info.plist`, NOT `YourApp/YourApp/Info.plist`):
+
+```xml
+
+
+
+
+ CFBundleDevelopmentRegion
+ $(DEVELOPMENT_LANGUAGE)
+ CFBundleExecutable
+ $(EXECUTABLE_NAME)
+ CFBundleIdentifier
+ $(PRODUCT_BUNDLE_IDENTIFIER)
+ CFBundleInfoDictionaryVersion
+ 6.0
+ CFBundleName
+ $(PRODUCT_NAME)
+ CFBundlePackageType
+ $(PRODUCT_BUNDLE_PACKAGE_TYPE)
+ CFBundleShortVersionString
+ $(MARKETING_VERSION)
+ CFBundleVersion
+ $(CURRENT_PROJECT_VERSION)
+ CFBundleDisplayName
+ $(PRODUCT_NAME)
+ LSRequiresIPhoneOS
+
+ UILaunchStoryboardName
+ LaunchScreen
+ UIApplicationSceneManifest
+
+ UIApplicationSupportsMultipleScenes
+
+ UISceneConfigurations
+
+
+ UIApplicationSupportsIndirectInputEvents
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+
+
+ NSCameraUsageDescription
+ Your camera usage description
+
+
+ RevenueCatAPIKey
+ $(REVENUECAT_API_KEY)
+
+
+```
+
+##### Step 3: Configure Xcode Project
+
+1. **Set Build Configurations to use xcconfig files:**
+ - Project → Info → Configurations
+ - Set Debug to use `Debug.xcconfig`
+ - Set Release to use `Release.xcconfig`
+
+2. **Update Build Settings for the app target:**
+ - Set `GENERATE_INFOPLIST_FILE = NO`
+ - Set `INFOPLIST_FILE = Info.plist` (path relative to project root)
+
+##### Step 4: Update PremiumManager to Read from Info.plist
+
+```swift
+private static var apiKey: String {
+ let key = (Bundle.main.object(forInfoDictionaryKey: "RevenueCatAPIKey") as? String) ?? ""
+ let placeholders = [
+ "",
+ "YOUR_REVENUECAT_API_KEY_HERE",
+ "test_YOUR_TEST_KEY_HERE",
+ "appl_YOUR_PRODUCTION_KEY_HERE"
+ ]
+
+ #if DEBUG
+ let prefix = key.split(separator: "_").first.map(String.init) ?? "missing"
+ let keyStatus = key.isEmpty ? "empty" : "present"
+ print("ℹ️ [PremiumManager] RevenueCatAPIKey \(keyStatus), prefix=\(prefix)")
+ #endif
+
+ guard !placeholders.contains(key) else {
+ #if DEBUG
+ print("⚠️ [PremiumManager] RevenueCat API key not configured. Check Secrets.debug.xcconfig / Secrets.release.xcconfig")
+ #endif
+ return ""
+ }
+ return key
+}
+```
+
+##### Common Pitfalls
+
+**1. INFOPLIST_KEY_ prefix doesn't work for custom keys**
+
+The `INFOPLIST_KEY_` build setting prefix (e.g., `INFOPLIST_KEY_RevenueCatAPIKey`) only works for Apple's predefined Info.plist keys. Custom keys like `RevenueCatAPIKey` will NOT be added to the generated Info.plist.
+
+❌ **Does NOT work:**
+```
+// In xcconfig - custom keys are ignored
+INFOPLIST_KEY_RevenueCatAPIKey = $(REVENUECAT_API_KEY)
+```
+
+✅ **Works:** Use a custom Info.plist with build setting substitution:
+```xml
+RevenueCatAPIKey
+$(REVENUECAT_API_KEY)
+```
+
+**2. Info.plist in synced folder causes "Multiple commands produce Info.plist"**
+
+If your project uses `fileSystemSynchronizedGroups` (Xcode 15+ default for new projects), placing Info.plist inside the app folder causes Xcode to automatically add it to Copy Bundle Resources, resulting in a build error.
+
+❌ **Causes error:** `YourApp/YourApp/Info.plist`
+
+✅ **Correct location:** `YourApp/Info.plist` (at project root, outside the synced folder)
+
+**3. Wrong xcconfig include path**
+
+The `#include` path in xcconfig files is relative to the xcconfig file itself.
+
+❌ **Wrong (if files are in same directory):**
+```
+#include "YourApp/Configuration/Secrets.debug.xcconfig"
+```
+
+✅ **Correct:**
+```
+#include "Secrets.debug.xcconfig"
+```
+
+**4. Verify the key is in the built app**
+
+After building, verify the key was properly substituted:
+```bash
+plutil -p ~/Library/Developer/Xcode/DerivedData/YourApp-*/Build/Products/Debug-iphonesimulator/Your\ App.app/Info.plist | grep RevenueCat
+```
+
+Expected output:
+```
+"RevenueCatAPIKey" => "test_your_actual_key"
+```
+
---
## PremiumManager Implementation
@@ -970,6 +1195,66 @@ Use the test API key (`test_`):
2. Check bundle ID matches exactly
3. Wait 1-2 minutes for transactions to appear
+### API Key Shows in Build Settings But Not in App (xcconfig)
+
+**Symptom:** `xcodebuild -showBuildSettings` shows `REVENUECAT_API_KEY = test_...` but the app logs show "RevenueCatAPIKey empty".
+
+**Cause:** The `INFOPLIST_KEY_` prefix only works for Apple's predefined keys, not custom keys.
+
+**Solution:**
+1. Create a custom `Info.plist` file at the project root (NOT inside the synced app folder)
+2. Add the key with build setting substitution: `$(REVENUECAT_API_KEY)`
+3. Set `GENERATE_INFOPLIST_FILE = NO` in build settings
+4. Set `INFOPLIST_FILE = Info.plist`
+
+See [Option C: xcconfig + Info.plist](#option-c-xcconfig--infoplist-recommended-for-xcode-15-projects) for complete instructions.
+
+### "Multiple commands produce Info.plist" Build Error
+
+**Cause:** The Info.plist file is inside a `fileSystemSynchronizedGroups` folder (Xcode 15+ default), causing Xcode to automatically add it to Copy Bundle Resources.
+
+**Solution:** Move Info.plist to the project root directory (same level as `.xcodeproj`), NOT inside the app source folder.
+
+```
+YourProject/
+├── YourProject.xcodeproj
+├── Info.plist ← Correct location
+└── YourProject/
+ └── (source files) ← NOT here
+```
+
+### xcconfig Include Path Errors
+
+**Symptom:** Build settings show empty or placeholder values even though the Secrets xcconfig files exist.
+
+**Cause:** The `#include` path is relative to the xcconfig file itself, not the project root.
+
+**Fix:** If `Debug.xcconfig` and `Secrets.debug.xcconfig` are in the same directory:
+
+```
+// Wrong
+#include "YourApp/Configuration/Secrets.debug.xcconfig"
+
+// Correct
+#include "Secrets.debug.xcconfig"
+```
+
+### Verifying xcconfig Setup
+
+Run these commands to debug your xcconfig setup:
+
+```bash
+# Check if REVENUECAT_API_KEY is in build settings
+xcodebuild -showBuildSettings -scheme "YourScheme" -configuration Debug | grep REVENUECAT
+
+# Check if key is in the built Info.plist
+plutil -p ~/Library/Developer/Xcode/DerivedData/YourApp-*/Build/Products/Debug-iphonesimulator/Your\ App.app/Info.plist | grep -i revenue
+
+# Clean and rebuild after xcconfig changes
+rm -rf ~/Library/Developer/Xcode/DerivedData/YourApp-*
+xcodebuild clean build -scheme "YourScheme" -configuration Debug -destination "platform=iOS Simulator,name=iPhone 16 Pro"
+```
+
---
## Resources