Block Factory

The recommended way to create blocks in Blockly is to use a block factory. A BlockFactory parses block definitions specified in JSON files in order to create Block instances.

The WorkbenchViewController holds a BlockFactory instance through its blockFactory property. WorkbenchViewController will automatically create one on instantiation, if one wasn't supplied to its initializer. This block factory instance should then be used for all future Block creation within this workbench as it's needed for things like the toolbox and undo-redo functionality to operate correctly.

JSON Definition Format

All three platforms of Blockly support the JSON block definition format. Click here for more details on this format.

Default JSON Files

Blockly is bundled with JSON files defining many default blocks. Every project will typically use a subset of these blocks as they represent fundamental programming concepts.

Here's an example of how to create two default blocks from a block factory:

Swift

let workbenchViewController = WorkbenchViewController(style: .defaultStyle)

// Load logic and text blocks into the workbench's block factory
let blockFactory = workbenchViewController.blockFactory
blockFactory.load(fromDefaultFiles: [.logicDefault, .textDefault])

do {
  // Make if block (from .LogicDefault)
  let ifBlock = try blockFactory.makeBlock(name: "controls_if")

  // Make text input block (from .TextDefault)
  let textBlock = try blockFactory.makeBlock(name: "text")

  // Do something with blocks...
} catch let error {
  print("Could not create blocks: \(error)")
}

Objective-C

BKYWorkbenchViewController *workbenchViewController =
    [[BKYWorkbenchViewController alloc] initWithStyle:BKYWorkbenchViewControllerStyleDefaultStyle];

// Load logic and text blocks into the workbench's block factory
NSError *error = nil;
BKYBlockFactory *blockFactory = workbenchViewController.blockFactory;
[blockFactory loadFromDefaultFiles:
  (BKYBlockJSONFileLogicDefault | BKYBlockJSONFileTextDefault)];

// Make if block (from .LogicDefault)
BKYBlock *ifBlock = [blockFactory makeBlockWithName: @"controls_if" error:&error];
if (error) {
  NSLog(@"Could not create `controls_if` block: %@", error);
  return;
}

// Make text input block (from .TextDefault)
BKYBlock *textBlock = [blockFactory makeBlockWithName: @"text" error:&error];
if (error) {
  NSLog(@"Could not create `text` block: %@", error);
  return;
}

Here is a complete list of default JSON block files:

JSON File Swift Parameter Objective-C Parameter
colour_blocks.json .colourDefault BKYBlockJSONFileColorDefault
list_blocks.json .listDefault BKYBlockJSONFileListDefault
logic_blocks.json .logicDefault BKYBlockJSONFileLogicDefault
loop_blocks.json .loopDefault BKYBlockJSONFileLoopDefault
math_blocks.json .mathDefault BKYBlockJSONFileMathDefault
text_blocks.json .textDefault BKYBlockJSONFileTextDefault
variable_blocks.json .variableDefault BKYBlockJSONFileVariableDefault
All Files .allDefault BKYBlockJSONFileAllDefault

To load a block factory with all default JSON files, call:

Swift

blockFactory.load(fromDefaultFiles: .allDefault)

Objective-C

[blockFactory loadFromDefaultFiles:BKYBlockJSONFileAllDefault];

Custom JSON Files

The following example shows how to load a custom JSON file into a block factory.

Suppose you define a blocks.json file in your project with the following block definition:

[
  {
    "type": "repeat_x_times",
    "message0": "repeat %1 times %2 %3",
    "args0": [
      {
        "type": "input_value",
        "name": "TIMES"
      },
      {
        "type": "input_dummy"
      },
      {
        "type": "input_statement",
        "name": "DO"
      }
    ],
    "previousStatement": null,
    "nextStatement": null,
    "colour": "#f44336",
    "inputsInline": true
  }
]

Here's the code to load that file into a block factory:

Swift

// Load the workbench's block factory with the "blocks.json" file
let blockFactory = workbenchViewController.blockFactory
do {
  try blockFactory.load(fromJSONPaths: ["blocks.json"])
} catch let error {
  print("Error loading 'blocks.json' into block factory: \(error)")
  return
}

Objective-C

// Load the workbench's block factory with the "blocks.json" file
NSError *blockFactoryError = nil;
BKYBlockFactory *blockFactory = workbenchViewController.blockFactory;
[blockFactory loadFromJSONPaths:@[@"blocks.json"] bundle:nil error:&blockFactoryError];

if (blockFactoryError) {
  NSLog(@"Error loading 'blocks.json' into block factory: %@", blockFactoryError);
  return;
}