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:
-
Swift Component (
Extensions/MyComponent.swift)- The actual SwiftUI View struct
- Fully customizable after generation
- Supports both container and non-container components
-
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
-
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 contentparameter - Default behavior when using
sjui g converter
Non-Container Components
- Cannot have children
- Simpler implementation
- Use
--no-containerflag
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
- Update Package.swift:
dependencies: [
.package(url: "https://github.com/Tai-Kimura/SwiftJsonUI.git", from: "7.1.0")
]
-
No Breaking Changes: Existing code continues to work
-
Start Using Custom Components:
sjui g converter MyFirstComponent
🐛 Bug Fixes
- Removed unnecessary
isEnabledproperty 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
- Start Simple: Begin with non-container components
- Customize Swift Files: Modify generated
.swiftfiles for your needs - Keep Converters Clean: Complex logic belongs in Swift components
- Use Type-Safe Attributes: Define attributes with proper types
- 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
- Documentation: SwiftJsonUI Wiki
- Issues: GitHub Issues
- Examples: Custom Component Examples
SwiftJsonUI is developed and maintained by Tai Kimura