Swift block compiler
Nativeblocks provides compiler to connect any codes with its core SDK
The Nativeblocks compiler is a tool that generates server-driven blocks and actions based on Swift code. It produces JSON and Swift files for each block and action, preparing them for upload to Nativeblocks servers.
How it works
If your project uses its own 'Package.swift' file, you can add NativeblocksCompiler as a dependency there. Add NativeblocksCompiler to your dependencies list
dependencies: [
.package(
url: "https://github.com/nativeblocks/nativeblocks-compiler-ios.git",
.upToNextMajor(from: "1.1.0")
),
],
Any targets in your application that will use NativeblocksCompiler need to have a dependency on the Nativeblocks product.
.target(
name: "MyApp",
dependencies: [
.product(name: "NativeblocksCompiler", package: "nativeblocks-compiler-ios")
]
)
Usage
Blocks are composable functions that can be visually edited and configured within a Nativeblocks Studio. These annotations provide metadata and define configurable properties, slots, and events for your composable, making them usable as building blocks in a visual editor.
@NativeBlock
Purpose: Marks a composable function as a block.
Parameters:
- name: The display name of the block in the visual editor.
- keyType: A unique key used to identify the block type.
- description: A brief description of the block's functionality.
Example:
@NativeBlock(name : "Custom button", keyType : "CUSTOM_BUTTON", description : "This is a button")
@NativeBlockProp
Purpose: Defines a configurable property for the block.
Parameters:
- description: (Optional) A description of the property.
- valuePicker: (Optional) Specifies the type of UI element used to edit the property (e.g., dropdown, text field).
- valuePickerGroup: (Optional) Specifies the group name of the property to group all related properties.
- valuePickerOptions: (Optional) Provides options for dropdown value pickers.
Example:
@NativeBlockProp(
description : "Button size",
valuePicker : NativeBlockValuePicker.DROPDOWN,
valuePickerOptions : [
NativeBlockValuePickerOption(" S", "Small"),
NativeBlockValuePickerOption(" M", "Medium"),
NativeBlockValuePickerOption(" L", "Large")
]
)
@NativeBlockData
Purpose: Marks a parameter as a data input for the block. This data can be provided directly from frame screen's variables.
Parameters:
- description: (Optional) A description of the data input.
Example:
@NativeBlockData(description : "Button text")
@NativeBlockSlot
Purpose: Defines a slot where other blocks can be inserted.This enables nesting and composition of blocks.
Parameters:
- description: (Optional) A description of the slot.
Example:
@NativeBlockSlot(description : "Button leading icon")
@NativeBlockEvent
Purpose: Defines an event that the block can trigger, such as a click or value change.
Parameters:
- description: (Optional) A description of the event.
Example:
@NativeBlockEvent(description : "Button on click")
This example demonstrates a simple button block with configurable properties, slots for icons, and a click event.
@NativeBlock(
name: "Custom button",
keyType: "CUSTOM_BUTTON",
description: "This is a button"
)
struct CustomButton: View {
@NativeBlockData(description: "Button text")
var text: String
@NativeBlockProp(valuePicker: NativeBlockValuePicker.COLOR_PICKER)
var background: String = "#ffffffff"
@NativeBlockProp(
description: "Button size",
valuePicker: NativeBlockValuePicker.DROPDOWN,
valuePickerOptions: [
NativeBlockValuePickerOption("S", "Small"),
NativeBlockValuePickerOption("M", "Medium"),
NativeBlockValuePickerOption("L", "Large"),
]
)
var size: String = "S"
@NativeBlockSlot(description: "Button leading icon")
var onLeadingIcon: () -> AnyView
@NativeBlockSlot(description: "Button trailing icon")
var onTrailingIcon: (() -> AnyView)? = nil
@NativeBlockEvent(description: "Button on click")
var onClick: (() -> Void)?
var body: some View {
Button(action: {
onClick?()
}) {
HStack(spacing: 8) {
onLeadingIcon()
Text(text)
.font(.system(size: textSize))
.padding(padding)
if let trailingIcon = onTrailingIcon {
trailingIcon()
}
}
}
.buttonStyle(PlainButtonStyle())
.background(Color(hex: background))
.cornerRadius(24)
}
private var padding: EdgeInsets {
switch size {
case "M":
return EdgeInsets(top: 12, leading: 12, bottom: 12, trailing: 12)
case "L":
return EdgeInsets(top: 16, leading: 16, bottom: 16, trailing: 16)
default: // "S"
return EdgeInsets(top: 4, leading: 4, bottom: 4, trailing: 4)
}
}
private var textSize: CGFloat {
switch size {
case "M":
return 22
case "L":
return 32
default: // "S"
return 16
}
}
}
Generated files
After providing annotations for blocks and actions, you can use the 'GenerateProvider' plugin to generate Swift code. These can then be initialized in App or via dependency injection
Note: The prefix for the provider name comes from the target name that was selected. In this case, since we provided "MyApp," the compiler generates with the "MyApp" prefix.
MyAppBlockProvider.provideBlocks()