/SwiftFlatbuffer

Unofficial Flatbuffer Swift library and code generator for Flatbuffer

Primary LanguageC++Apache License 2.0Apache-2.0

Swift For Flatbuffer

Unofficial Swift library and code generator for Flatbuffer

Usage

Build Flatbuffer From source

In the current source of flatbuffer, I have included the binary executable which was build under MacOS Sierra 10.12.3. If you're running flatbuffer on other platform you can recompile the code follow the official instruction on Flatbuffer site https://google.github.io/flatbuffers/flatbuffers_guide_building.html

Generate Code from the schema

The sample of the schema was included in the XCode Project under FlatbufferUnitTest. If you wanna create your own schema, please visit Flatbuffer official site how to write Flatbuffer schema https://google.github.io/flatbuffers/flatbuffers_guide_writing_schema.html

To generate the code, run the following command

flatc --swift monster_test.fbs

To generate mutable code, run the following command

flatc --gen-mutable --swift monster_test.fbs

Reading Flatbuffer data

In the current source code of Unit Test there is a binary file name "monsterdata_test.mon". You can include this file to your project.

Note that, you need to add swift file from Xcode project under sources (https://github.com/cmidt-veasna/SwiftFlatbuffer/tree/master/XCodeFlatbuffer/FlatbufferSwift/Sources). If you only attempted to read the Flatbuffer data then you can exclude the file "builder.swift" and "writer.swift"

Read data from the binary file

Initial Data object pointing to Flatbuffer binary file. This code is suppose run on MacOS, if you're running this code on iOS please adjust it accordingly.

let bundle = Bundle(for: type(of: self))
        let path = bundle.path(forResource: "monsterdata_test", ofType: "mon")!
var data = try? Data(contentsOf: URL(fileURLWithPath: path), options: Data.ReadingOptions.alwaysMapped)

Access to Flatbuffer binary data

let monster = Monster.getRootAsMonster(withData: &data)
print(monster.hp)
print(monster.mana)
print(monster.name)
// accesss unsigned byte vector
for i in 0..<monster.inventoryCount {
    print(monster.inventory[i])
}

Access to Flatbuffer data with Object cache initialization. Note, this only prevent object from being create every time you access nested table or vector

every time the below code executed, it always create a new Instant of "Vec3" Struct

let pos = monster.pos

To reuse the Instant of "Vec3" Struct, use the below code

let pos = Vec3()
_ = monster.getPos(vec3: pos)
...
_ = monster1.getPos(vec3: pos)

As for vector, it's implemented with subscript which will be a little different, see the below code:

let monster1 = monster.testnestedflatbuffer[0]
let monster2 = monster.testnestedflatbuffer[1]

The monster1 and monster2 will be initialization as two different object but sharing the same data. To reuse the monster object and prevent initialization every time we access "testnestedflatbuffer", use the code below

let xmonster = Monster()
_ = monster.testnestedflatbuffer[0, xmonster]
...
_ = monster.testnestedflatbuffer[1, xmonster]
...

Mutable options

As describe by Flatbuffer, we can only update the value to existing Flatbuffer with Scalar type field. It's a bit different from other language as the code using properties setter which mean the setter will silence if the update was failed. This might be because of the properties does not exist in the binary buffer. Read more about forcing default from the following page https://google.github.io/flatbuffers/flatbuffers_guide_tutorial.html

monster.hp = 200

Build Flatbuffer binary data

The current code of Flatbuffer compiler for Swift did not provide any additional code wrapper to help simplify build the binary data. The code generator only provide a common behavior code to build the binary data (Similar to other language generated by flatc command). See below code

let strOffset = try! builder.createString(with: "MyMonster")
_ = try? Monster.startMonster(builder)
try? Monster.addHp(builder, hp: 80)
try? Monster.addName(builder, nameOffset: strOffset)
let monsterOffset = try! Monster.endMonster(builder)
try? Monster.finishBuffer(builder, offset: monsterOffset)
// get final binary data
builder.getData()

Xcode Test

To test Flatbuffer, open Xcode project, Set the active schema to "FlatbufferUnitTest" then hit Command + U

Unsupported Feature

  • Namespace

Swift does not support multiple namespace in a module or project.

  • Reflection (&Resizing)

This feature is support in C++.

  • JSON Parser