SwiftJsonUI 7.1.0 Release Notes - Tai-Kimura/SwiftJsonUI GitHub Wiki

SwiftJsonUI 7.1.0 Release Notes

Release Date

August 26, 2025

Overview

SwiftJsonUI 7.1.0 introduces Custom Component Support for SwiftUI - a powerful new feature that allows developers to create reusable, custom components that work seamlessly in both Static and Dynamic modes.

✨ Major New Feature

Custom Components for SwiftUI

What's New

For the first time in SwiftUI mode, you can now:

  • Create custom, reusable components using sjui g converter
  • Use custom components in both Static and Dynamic modes
  • Modify generated Static converters to customize behavior
  • Enjoy full hot reload support for custom components in Dynamic mode

The Complete Solution

The sjui g converter command generates three essential files:

  1. Swift Component (Extensions/MyComponent.swift)

    • The actual SwiftUI View struct
    • Fully customizable after generation
    • Supports both container and non-container components
  2. Ruby Converter (sjui_tools/lib/swiftui/views/extensions/my_component_converter.rb)

    • Converts JSON to Swift code for Static mode
    • Can be customized to handle special attributes
    • Automatically registered in converter mappings
  3. Dynamic Adapter (Extensions/Adapters/MyComponentAdapter.swift)

    • Enables Dynamic mode support with hot reload
    • Accesses all JSON properties via rawData
    • Only compiled in DEBUG builds for optimal performance

How to Use

1. Generate a Custom Component

# Basic component
sjui g converter MyCard

# With attributes
sjui g converter MyCard --attributes "title:String,subtitle:String,elevation:Double"

# Container component (can have children)
sjui g converter MyContainer --container

# Non-container component (no children)
sjui g converter MyBadge --no-container

2. The Generated Files

Swift Component (Extensions/MyCard.swift):

struct MyCard<Content: View>: View {
    let title: String
    let subtitle: String
    let elevation: Double
    let content: Content?
    
    init(title: String, subtitle: String, elevation: Double, 
         @ViewBuilder content: () -> Content = { EmptyView() }) {
        self.title = title
        self.subtitle = subtitle
        self.elevation = elevation
        self.content = content()
    }
    
    var body: some View {
        // Customize your component here
        VStack {
            Text(title).font(.headline)
            Text(subtitle).font(.subheadline)
            if let content = content {
                content
            }
        }
        .shadow(radius: elevation)
    }
}

Ruby Converter (for Static mode):

class MyCardConverter < BaseViewConverter
  def convert
    # Handles JSON to Swift conversion
    # Can be customized for special attribute handling
  end
end

Dynamic Adapter (for Dynamic mode with hot reload):

#if DEBUG
struct MyCardAdapter: CustomComponentAdapter {
    func buildView(component: DynamicComponent, ...) -> AnyView {
        // Access all JSON properties
        let title = component.rawData["title"] as? String ?? ""
        let subtitle = component.rawData["subtitle"] as? String ?? ""
        let elevation = component.rawData["elevation"] as? Double ?? 0
        
        // Build and return the view
        return AnyView(MyCard(...))
    }
}
#endif

3. Use in JSON

{
  "type": "MyCard",
  "title": "Welcome",
  "subtitle": "Custom Component Example",
  "elevation": 4.0,
  "child": [
    {
      "type": "Label",
      "text": "This is the card content"
    }
  ]
}

Key Benefits

  • Full SwiftUI Support: First-time support for custom components in SwiftUI mode
  • 🛠️ Complete Customization: All generated files can be modified
  • 🔥 Hot Reload: Works with Dynamic mode for rapid development
  • 📦 Automatic Registration: Components are automatically registered
  • 🎯 Type Safety: Static mode provides compile-time checking
  • 🚀 Performance: Dynamic adapters only compile in DEBUG builds

Component Types

Container Components

  • Can have child components
  • Use @ViewBuilder content parameter
  • Default behavior when using sjui g converter

Non-Container Components

  • Cannot have children
  • Simpler implementation
  • Use --no-container flag

Configuration

Add to sjui.config.json:

{
  "extension_directory": "Extensions",
  "adapter_directory": "Extensions/Adapters"
}

🔧 Technical Details

File Structure

YourApp/
├── Extensions/
│   ├── MyCard.swift              # Swift component
│   └── Adapters/
│       ├── MyCardAdapter.swift   # Dynamic adapter
│       └── CustomComponentRegistration.swift
├── sjui_tools/
│   └── lib/
│       └── swiftui/
│           └── views/
│               └── extensions/
│                   ├── my_card_converter.rb
│                   └── converter_mappings.rb

Registration

Automatic Registration in App Startup:

#if DEBUG
// In your App.swift or AppDelegate
CustomComponentRegistration.registerAll()
#endif

🔄 Migration Guide

Upgrading from 7.0.x

  1. Update Package.swift:
dependencies: [
    .package(url: "https://github.com/Tai-Kimura/SwiftJsonUI.git", from: "7.1.0")
]
  1. No Breaking Changes: Existing code continues to work

  2. Start Using Custom Components:

sjui g converter MyFirstComponent

🐛 Bug Fixes

  • Removed unnecessary isEnabled property from DynamicComponent
  • Fixed rawData to properly capture all JSON properties
  • Improved converter code generation for SwiftUI
  • Better string interpolation in generated converters

💡 Tips & Best Practices

  1. Start Simple: Begin with non-container components
  2. Customize Swift Files: Modify generated .swift files for your needs
  3. Keep Converters Clean: Complex logic belongs in Swift components
  4. Use Type-Safe Attributes: Define attributes with proper types
  5. Test Both Modes: Ensure components work in Static and Dynamic modes

📚 Documentation

New Documentation

  • Custom Component Generator guide
  • Converter system architecture
  • Adapter pattern explanation

Command Reference

# Generate a component
sjui g converter ComponentName

# With attributes
sjui g converter ComponentName --attributes "prop1:Type1,prop2:Type2"

# Container component
sjui g converter ComponentName --container

# Non-container component  
sjui g converter ComponentName --no-container

# Overwrite existing
sjui g converter ComponentName --force

🚀 Performance

  • Zero overhead in Release builds: Adapters are DEBUG-only
  • Optimized Static mode: Direct Swift code generation
  • Efficient Dynamic mode: Minimal adapter layer

📬 Support


SwiftJsonUI is developed and maintained by Tai Kimura