This guide explains how to customize SwiftUI Indie Stack for your app.
-
Open
ios/Sources/UI/Assets.xcassets -
Add or modify the following color sets:
PrimaryGreen- Main action colorPrimaryBlue- Secondary colorAccentOrange- Accent/highlight colorTabHome,TabLibrary,TabSettings- Tab bar colors
-
Each color set should have both light and dark mode variants
Edit ios/Sources/UI/Theme/AppColors.swift:
struct AppColors {
// Change these hex values
static let primary = Color(hex: "#58CC02") // Your primary color
static let secondary = Color(hex: "#1CB0F6") // Your secondary color
static let accent = Color(hex: "#FF9600") // Your accent color
// ... other colors
}Edit ios/Sources/UI/Theme/AppFonts.swift to use custom fonts:
struct AppFonts {
static let title = Font.custom("YourFont-Bold", size: 28)
static let body = Font.custom("YourFont-Regular", size: 17)
// ...
}The template uses com.example.myapp as a placeholder. Simulator builds work without changes, but you must update the bundle identifier before running on a physical device.
- Open the Xcode project
- Select the project in the navigator
- Select the main app target → Signing & Capabilities
- Change "Bundle Identifier" to your own (e.g.,
com.yourcompany.yourapp) - Repeat for the widget extension target (
com.yourcompany.yourapp.widget) - Select your development team
- Update
CFBundleDisplayNameinInfo.plist - Update app name references in:
LoginView.swiftOnboardingView.swift
Search for and replace these placeholders:
YOUR_BUNDLE_ID → com.yourcompany.yourapp
YOUR_REVENUECAT_API_KEY → appl_xxxxxxxxxxxxx
YOUR_TELEMETRYDECK_APP_ID → XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX
https://yourapp.com → Your actual website
support@yourapp.com → Your support email
Skip this section if using Local Mode (useFirebase = false).
- Create a Firebase project at console.firebase.google.com
- Enable Authentication → Sign-in method → Apple + Google
- Enable Firestore Database (start in test mode, then add security rules)
- Download
GoogleService-Info.plistfrom Project Settings → Your Apps → iOS - Add
GoogleService-Info.plistto your Xcode project (drag intoios/Sources/folder, check "Copy items if needed") - Update
firebase-functions/.firebasercwith your project ID
The streak system is backend-driven:
- Frontend (iOS): Displays streak data from Firestore
- Backend (Firebase Functions): Calculates streaks, sends reminders
Edit firebase-functions/functions/src/index.ts:
// Default: 6 PM
export const checkStreaksAtRisk = functions.pubsub
.schedule("0 18 * * *") // Change this cron expression
.timeZone("America/New_York") // Change timezone// Default: Midnight
export const resetBrokenStreaks = functions.pubsub
.schedule("0 0 * * *") // Change this cron expressionTo count something toward the streak, log activity from your app:
// In your view or view model
FirestoreManager.shared.logActivity(type: "lesson_completed")The type parameter is flexible - use any string that describes the activity.
Edit ios/Sources/Streak/StreakBadgeView.swift:
private var flameColor: Color {
let streak = streakProvider.streakData.currentStreak
if streak >= 365 { return .purple } // Legendary
if streak >= 100 { return .blue } // Epic
if streak >= 30 { return .orange } // Hot
// Add more tiers...
}var isMilestone: Bool {
let milestones = [7, 30, 50, 100, 200, 365] // Customize milestones
return milestones.contains(streakData.currentStreak)
}- Create a new GitHub repository (can be public or private)
- Add
index.jsonat the root - Add markdown files in
articles/directory - Add images in
images/directory
Edit ios/Sources/Library/ViewModels/LibraryViewModel.swift:
private let indexURL = "https://raw.githubusercontent.com/YOUR_ORG/YOUR_REPO/main/index.json"Your index.json should follow this structure:
{
"version": "1.0",
"lastUpdated": "2025-01-01T00:00:00Z",
"articles": [
{
"id": "unique-article-id",
"title": "Article Title",
"summary": "Brief description shown in list",
"category": "category_slug",
"publishDate": "2025-01-01T00:00:00Z",
"expiryDate": null,
"contentURL": "https://raw.githubusercontent.com/.../article.md",
"imageURL": "https://raw.githubusercontent.com/.../image.jpg",
"featured": false,
"version": "1.0"
}
]
}Categories are auto-generated from article category fields. To customize colors:
Edit ios/Sources/Library/Models/LibraryModel.swift:
extension String {
var categoryColor: Color {
switch self.lowercased() {
case "tutorials": return .blue
case "tips": return .green
case "news": return .orange
// Add your categories...
default: return .gray
}
}
}The template uses RevenueCatUI for paywall display. Configure your paywall in the RevenueCat dashboard:
- Go to RevenueCat Dashboard → Your App → Paywalls
- Design your paywall using the visual editor
- The app will automatically use your configured paywall
// Show paywall manually
PaywallManager.shared.triggerPaywall()
// Show paywall if not subscribed
PaywallManager.shared.showPaywallIfNeeded()
// Check subscription status
let isSubscribed = await PaywallManager.shared.checkSubscriptionStatus()
// Check specific entitlement
let hasPremium = await PaywallManager.shared.hasEntitlement("premium")The default shows paywall when showPaywallIfNeeded() is called (on app launch). Customize the logic in PaywallManager.swift.
Edit ios/Sources/TabBar/MainTabView.swift:
HStack {
TabBarIcon(selectedTab: $selectedTab, assignedTab: 0,
systemIconName: "house.fill", tabName: "Home",
color: AppColors.tabHome)
// Add or remove tabs here
TabBarIcon(selectedTab: $selectedTab, assignedTab: 1,
systemIconName: "book.fill", tabName: "Library",
color: AppColors.tabLibrary)
}Update the switch statement in the body to handle new tabs:
switch selectedTab {
case 0: HomeView()
case 1: LibraryView()
case 2: YourNewView() // Add new view
case 3: SettingsView()
default: HomeView()
}Edit ios/Sources/Onboarding/OnboardingView.swift:
private let pages: [OnboardingPage] = [
OnboardingPage(
title: "Welcome",
description: "Your custom welcome message",
imageName: "hand.wave.fill",
imageColor: .orange
),
// Add more pages...
]- Open an issue on GitHub
- Check existing issues for common questions
Need help customizing this template for your app? Professional assistance is available:
- Website: pagescholar.com
- GitHub: @cliffordh
Services include:
- Custom feature development
- Firebase backend setup and configuration
- App Store submission assistance
- Code review and architecture consulting