SkillAgentSearch skills...

IndieBuilderKit

A simple iOS toolkit for indie developers. Start your app faster with essential components, subscriptions, and analytics.

Install / Use

/learn @gokhanamal/IndieBuilderKit

README

<img src="Images/cover.png" alt="IndieBuilderKit - iOS toolkit showcase featuring paywall, settings, rating, notifications, typography, and UI components" width="100%">

Swift Platform License SPM

A simple iOS toolkit for indie developers. Start your app faster with essential components, subscriptions, and analytics.

Quick Start

Installation

Add to your project with Swift Package Manager:

dependencies: [
    .package(url: "https://github.com/gokhanamal/IndieBuilderKit", from: "1.0.0")
]

Basic Setup

import IndieBuilderKit
import SwiftUI

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
                .task {
                    // Register custom fonts
                    IndieBuilderKit.registerCustomFonts()
                }
        }
    }
}

Why IndieBuilderKit?

Building an iOS app as an indie developer means handling subscriptions, analytics, UI components, and notifications—all before writing your core features. IndieBuilderKit gives you these essential building blocks so you can focus on what makes your app unique.

Key Benefits:

  • 🚀 Ship faster - Pre-built components save weeks of development
  • 💰 Revenue ready - Complete subscription system with RevenueCat integration
  • 🎨 Native feel - SwiftUI components that follow iOS design guidelines
  • 🔧 Flexible - Use what you need, customize everything else
  • 📱 Modern - Built with Swift 6, async/await, and @Observable

Demo App

Check out the demo app in Demo/IndieBuilderKitDemo.xcworkspace to see all components in action.

Feature Overview

| Component | Description | Key Features | |-----------|-------------|--------------| | 💳 PaywallView | Beautiful subscription paywall | Custom images, localization, RevenueCat integration | | 📊 Analytics | Clean analytics abstraction | Multi-provider support, consistent API | | 🎨 UI Components | Ready-to-use SwiftUI views | Onboarding, settings, loading states, beautiful buttons | | 🔔 Permissions | Notification permission handling | User-friendly prompts, status tracking | | ⭐ RatingView | App Store review requests | Customizable benefits, native integration | | 🌐 NetworkService | Modern HTTP networking | Swift Concurrency, comprehensive error handling | | ⚙️ Utilities | Essential app services | Contact handling, fonts, app ratings |

Features & Usage

✨ Paywall & Subscriptions

Beautiful subscription paywall with complete subscription management. One service handles everything from UI state to purchases.

<img src="Images/paywall.png" width="300" alt="Paywall View with subscription options">
// Simple paywall with mock service (for testing/prototyping)
PaywallView()

// With custom configuration
PaywallView(configuration: PaywallConfiguration(
    title: "Unlock Premium",
    subtitle: "Get access to all features",
    image: .crown, // Use built-in crown icon
    features: [
        PaywallFeature(iconName: "checkmark.circle.fill", title: "Unlimited exports"),
        PaywallFeature(iconName: "cloud.fill", title: "Cloud sync"),
        PaywallFeature(iconName: "star.fill", title: "Premium templates"),
        PaywallFeature(iconName: "bell.slash.fill", title: "No ads")
    ]
))

// With system icon (SF Symbols)
PaywallView(configuration: PaywallConfiguration(
    title: "Go Premium",
    image: .systemIcon("star.fill")
))

// With bundle image
PaywallView(configuration: PaywallConfiguration(
    title: "Unlock Features",
    image: .bundleImage("app-logo")
))

// With custom image
PaywallView(configuration: PaywallConfiguration(
    title: "Premium Access",
    image: .customImage(Image("custom-paywall-hero"))
))

// With localized strings (supports NSLocalizedString)
PaywallView(configuration: PaywallConfiguration.localized(
    title: NSLocalizedString("unlock_premium", value: "Unlock Premium", comment: ""),
    subtitle: NSLocalizedString("premium_subtitle", value: "Get access to all features", comment: ""),
    strings: PaywallStrings.localized(
        continueText: NSLocalizedString("continue_button", value: "Continue", comment: ""),
        termsURL: "https://yourapp.com/terms",
        privacyPolicyURL: "https://yourapp.com/privacy"
    )
))

// Custom strings for branding
PaywallView(configuration: PaywallConfiguration(
    title: "Go Pro",
    strings: PaywallStrings(
        processingText: "Please wait...",
        selectPlanText: "Choose Your Plan",
        startFreeTrialText: "Try Free for 7 Days",
        continueText: "Subscribe Now",
        savingsText: "BEST VALUE",
        termsURL: "https://myapp.com/terms",
        privacyPolicyURL: "https://myapp.com/privacy"
    )
))

// Use RevenueCat (recommended for production)
let revenueCatService = RevenueCatSubscriptionService()
Task {
    await revenueCatService.configure(apiKey: "your-revenuecat-api-key")
}
PaywallView(service: revenueCatService)

// Or implement your own complete subscription service
@Observable
class MySubscriptionService: SubscriptionServiceProtocol {
    // Configuration
    var isConfigured = false
    
    // Subscription Management  
    var subscriptionStatus: SubscriptionStatus = .inactive
    
    // Paywall UI State
    var availablePlans: [SubscriptionPlan] = [/* your plans */]
    var selectedPlan: SubscriptionPlan?
    
    func configure(apiKey: String) async {
        // Setup your subscription backend
        isConfigured = true
    }
    
    func refreshSubscriptionStatus() async {
        // Check current subscription status
    }
    
    func hasEntitlement(_ entitlementId: String) -> Bool {
        return subscriptionStatus.isActive
    }
    
    func selectPlan(_ plan: SubscriptionPlan) {
        selectedPlan = plan
    }
    
    func purchaseSelectedPlan() async throws {
        // Your purchase logic (StoreKit, RevenueCat, etc.)
        // Throw SubscriptionServiceError.purchaseCancelled if cancelled
        // Throw SubscriptionServiceError.purchaseFailed(_) if failed
    }
    
    func restorePurchases() async throws {
        // Your restore logic
        // Throw SubscriptionServiceError.restoreFailed(_) if failed
    }
    
    func setUserId(_ userId: String?) { /* User management */ }
    func logOut() { /* Logout logic */ }
}

PaywallView(service: MySubscriptionService())

📊 Analytics Wrapper

Clean abstraction for analytics that works with any provider. Track events consistently without vendor lock-in.

// Setup with your analytics provider
let analytics = AnalyticsWrapper(providers: [
    FirebaseAnalyticsProvider(),
    AmplitudeProvider(),
    MockAnalyticsProvider() // For testing
])

// Track events
analytics.track(.screenView(name: "HomeScreen"))
analytics.track(.purchase(transactionId: "tx_123", value: 9.99))
analytics.track(.custom(name: "feature_used", parameters: ["feature": "export"]))

// User properties
analytics.setUserId("user_123")
analytics.setUserProperty("premium", forName: "subscription_status")

🎨 UI Components

Ready-to-use SwiftUI components for common app patterns. All follow modern iOS design guidelines with a comprehensive design system.

<table> <tr> <td><img src="Images/onboarding.png" width="200" alt="Onboarding flow"></td> <td><img src="Images/settings.png" width="200" alt="Settings screen"></td> </tr> <tr> <td><img src="Images/buttons.png" width="200" alt="Button component library"></td> <td><img src="Images/ui-components.png" width="200" alt="UI components showcase"></td> </tr> </table>
// Loading states
StateView(state: .loading) {
    // Your content here
}

// Settings screen with social links
SettingsView(
    socialLinks: [
        SocialLink(platform: .twitter, handle: "gokhanamal"),
        SocialLink(platform: .github, handle: "gokhanamal")
    ]
)

// Onboarding flow
OnboardingView(pages: [
    OnboardingPage(title: "Welcome", description: "Get started with our app")
])

// Error handling
ErrorView(
    title: "Something went wrong",
    message: "Please try again later",
    retryAction: { /* retry logic */ }
)

// Beautiful Button Components
PrimaryButton("Get Started") {
    // Action
}

PrimaryButton("Loading...", isLoading: true) { }

SecondaryButton("Learn More") {
    // Action
}

// Icon buttons
IconButton(icon: "heart.fill", title: "Like") { }
IconButton(icon: "share", style: .prominent) { }

// Floating action button
FloatingActionButton(icon: "plus") {
    // Add new item
}

// Chip buttons for filters/tags
HStack {
    ChipButton("All", isSelected: true) { }
    ChipButton("Favorites") { }
    ChipButton("Recent") { }
}

// Link buttons
LinkButton("Terms of Service", style: .underlined) { }

🔔 Notification Permissions & App Reviews

Handle notification permissions gracefully with user-friendly prompts and beautiful rating request views.

<table> <tr> <td><img src="Images/notification-permission.png" width="200" alt="Notification permission request"></td> <td><img src="Images/rating.png" width="200" alt="Rating request view"></td> <td><img src="Images/network.png" width="200" alt="Network demo"></td> </tr> </table>
// Notification Permissions
let permissionManager = PermissionManager.shared

// Check notification permission status
if permissionManager.notificationStatus == .authorized {
    // Send notifications
}

// Request notification permission
await permissionManager.requestPermission(for: .notifications)

// Use in SwiftUI
@Environment(\.permissions) private var permissions

// Check if notifications are granted
if permissions.arePermissionsGranted([.notifications]) {
    // Handle n

Related Skills

View on GitHub
GitHub Stars125
CategoryData
Updated6h ago
Forks9

Languages

Swift

Security Score

100/100

Audited on Apr 9, 2026

No findings