|
| 1 | +--- |
| 2 | +id: data-sync-cpp-getting-started |
| 3 | +title: "Get Started with Syncing Data in C++" |
| 4 | +sidebar_label: "Data Sync C++" |
| 5 | +description: "Learn how to use ObjectBox Sync in a C++ app: get the sync library, mark entities for sync, and connect to a server." |
| 6 | +slug: /data-sync/cpp-getting-started |
| 7 | +keywords: [ObjectBox, Data Sync, C++, sync client, offline-first, data synchronization] |
| 8 | +image: /img/social/data-sync-cpp-getting-started.jpg |
| 9 | +author: Dr. Vivien Dollinger |
| 10 | +author_url: https://www.linkedin.com/in/vivien-dollinger/ |
| 11 | +--- |
| 12 | + |
| 13 | +# Get Started with Syncing Data in C++ <!-- ObjectBox Sync overview: https://sync.objectbox.io/sync-client --> |
| 14 | +This guide shows how to use ObjectBox **Sync** in a C++ app (get the sync library, mark entities for sync, connect to a server). <!-- Overview + minimal setup incl. C++: https://sync.objectbox.io/sync-client --> |
| 15 | + |
| 16 | +## 1) Get ObjectBox Sync <!-- Install docs, CMake linking, sync variant: https://cpp.objectbox.io/installation/ --> |
| 17 | +To use Sync you must link your app against the **`objectbox-sync`** library (instead of `objectbox`). <!-- Installation page shows `target_link_libraries(... objectbox-sync)`: https://cpp.objectbox.io/installation/#objectbox-library --> |
| 18 | + |
| 19 | +> We’ll use the officially documented CMake **FetchContent** setup and then switch the link target to `objectbox-sync`. <!-- Recommended approach per docs: https://cpp.objectbox.io/installation/#objectbox-library --> |
| 20 | + |
| 21 | +### CMakeLists.txt <!-- CMake + FetchContent: https://cpp.objectbox.io/installation/#objectbox-library --> |
| 22 | +```cmake |
| 23 | +cmake_minimum_required(VERSION 3.14) # per docs 3.14+ example <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 24 | +project(myapp) # example name <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 25 | +set(CMAKE_CXX_STANDARD 11) # C++11 or higher <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 26 | + |
| 27 | +include(FetchContent) # use FetchContent <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 28 | +FetchContent_Declare( # declare OBX dependency <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 29 | + objectbox |
| 30 | + GIT_REPOSITORY https://github.com/objectbox/objectbox-c.git # official repo <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 31 | + GIT_TAG v4.1.0 # example tag <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 32 | +) |
| 33 | +FetchContent_MakeAvailable(objectbox) # fetch headers & libs <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 34 | + |
| 35 | +add_executable(myapp src/main.cpp) # your target <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 36 | + |
| 37 | +# Link against the Sync variant instead of the core library: |
| 38 | +target_link_libraries(myapp PRIVATE objectbox-sync) # sync-enabled <!-- https://cpp.objectbox.io/installation/#objectbox-library --> |
| 39 | +``` |
| 40 | + |
| 41 | +By linking **`objectbox-sync`**, the Sync client API (from `objectbox-sync.hpp`) is available to your app. <!-- Sync C++ API reference header & classes: https://objectbox.io/docfiles/c/current/objectbox-sync_8hpp.html --> |
| 42 | + |
| 43 | +## 2) Define Your Data Model for Sync <!-- Entity annotations: https://cpp.objectbox.io/entity-annotations/ --> |
| 44 | +Enable sync per entity by adding an ObjectBox annotation comment to your FlatBuffers schema (`.fbs`). <!-- Annotation mechanism (comments): https://cpp.objectbox.io/entity-annotations/ --> |
| 45 | + |
| 46 | +Use `/// objectbox: sync` immediately before the `table` you want to sync. <!-- Sync annotation: https://cpp.objectbox.io/entity-annotations/#supported-annotations --> |
| 47 | + |
| 48 | +### `schema.fbs` <!-- Annotated schema example shows `objectbox:sync`: https://cpp.objectbox.io/entity-annotations/#annotated-schema-example --> |
| 49 | +```fbs |
| 50 | +/// objectbox: sync // enable sync for this entity <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations --> |
| 51 | +table Task { // FlatBuffers table = OBX entity <!-- https://cpp.objectbox.io/entity-annotations/ --> |
| 52 | + id: ulong (id); // ObjectBox ID annotation <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations --> |
| 53 | + text: string; // regular property <!-- https://cpp.objectbox.io/entity-annotations/ --> |
| 54 | + date_created: ulong (date); // timestamp (ms since epoch) <!-- https://cpp.objectbox.io/entity-annotations/#supported-annotations --> |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +> Note: `root_type` is a general FlatBuffers concept and **not required by ObjectBox**; you can omit it here. <!-- FlatBuffers schema docs (root_type is generic, not needed by OBX): https://flatbuffers.dev/schema/ --> |
| 59 | + |
| 60 | +After editing the schema, run the **ObjectBox Generator** again so the `.obx.hpp/.obx.cpp` and `objectbox-model.json` are updated with the sync flag. <!-- Generator outputs incl. objectbox-model.json: https://cpp.objectbox.io/generator/ --> |
| 61 | + |
| 62 | +## 3) Start the Sync Client <!-- Sync client start (C++ snippet): https://sync.objectbox.io/sync-client --> |
| 63 | +Create your `Store`, create a `SyncClient` for it, and `start()` the client. <!-- Minimal C++ example + start(): https://sync.objectbox.io/sync-client --> |
| 64 | + |
| 65 | +### `main.cpp` <!-- Core/Sync headers, Options/Store, Sync client: official C++ API pages --> |
| 66 | +```cpp |
| 67 | +#include "objectbox.hpp" // core C++ API <!-- C++ header ref: https://objectbox.io/docfiles/c/current/objectbox_8hpp.html --> |
| 68 | +#include "objectbox-sync.hpp" // sync API & classes <!-- Sync header ref: https://objectbox.io/docfiles/c/current/objectbox-sync_8hpp.html --> |
| 69 | +#include "schema.obx.hpp" // generated model code <!-- Generator outputs: https://cpp.objectbox.io/generator/ --> |
| 70 | + |
| 71 | +int main() { |
| 72 | + // Build Store with the generated model: |
| 73 | + obx::Options opt; // Options API <!-- Options class: https://objectbox.io/docfiles/c/current/classobx_1_1Options.html --> |
| 74 | + opt.model(create_obx_model()); // set model on Options<!-- Options::model(...): https://objectbox.io/docfiles/c/current/classobx_1_1Options.html --> |
| 75 | + obx::Store store(opt); // open Store <!-- Store class: https://objectbox.io/docfiles/c/current/classobx_1_1Store.html --> |
| 76 | + |
| 77 | + // Server URL: use ws:// for unencrypted, wss:// for TLS. |
| 78 | + // Using localhost (same machine): |
| 79 | + std::string server_url = "ws://127.0.0.1:9999"; // example endpoint <!-- Sync client docs use ws://127.0.0.1:9999: https://sync.objectbox.io/sync-client --> |
| 80 | + |
| 81 | + // If using the Android Emulator, 10.0.2.2 reaches the host machine: |
| 82 | + // std::string server_url = "ws://10.0.2.2:9999"; // emulator host map <!-- Mentioned in Sync docs with link to Android docs: https://sync.objectbox.io/sync-client#start-the-sync-client (see "Using Android emulator?" note) --> |
| 83 | + |
| 84 | + // Create the Sync client (keep it in a shared_ptr as advised by the API docs): |
| 85 | + std::shared_ptr<obx::SyncClient> syncClient = obx::Sync::client( // builder <!-- C++ minimal example: https://sync.objectbox.io/sync-client#start-the-sync-client --> |
| 86 | + store, // Store <!-- Same as above --> |
| 87 | + server_url, // URL <!-- Same as above --> |
| 88 | + obx::SyncCredentials::none() // creds <!-- Credentials factory methods incl. none(): https://objectbox.io/docfiles/c/current/classobx_1_1SyncCredentials-members.html --> |
| 89 | + ); // shared_ptr<!-- SyncClient API is in objectbox-sync.hpp: https://objectbox.io/docfiles/c/current/classobx_1_1SyncClient.html --> |
| 90 | + |
| 91 | + // Start background syncing: |
| 92 | + syncClient->start(); // non-blocking<!-- start(): background + reconnect behavior described: https://sync.objectbox.io/sync-client --> |
| 93 | + |
| 94 | + // Your normal ObjectBox usage continues, synced entities will propagate: |
| 95 | + obx::Box<Task> box(store); // Box API <!-- Box<> class: https://objectbox.io/docfiles/c/current/classobx_1_1Box.html --> |
| 96 | + box.put({0, "My first C++ task", 1730716800000}); // put object <!-- Box operations documented in C++ API: https://objectbox.io/docfiles/c/current/classobx_1_1Box.html --> |
| 97 | + |
| 98 | + // Keep the app running while syncing (start() is async). Also, close sync before closing the Store: |
| 99 | + // The sync client runs asynchronously, auto-reconnects; always stop/close it before closing Store. |
| 100 | + // Guidance covered in Sync docs ("All of this happens asynchronously" + "Always close the client before closing the store."): |
| 101 | + // https://sync.objectbox.io/sync-client |
| 102 | + std::cout << "Press ENTER to exit.\n"; |
| 103 | + std::cin.get(); |
| 104 | + |
| 105 | + syncClient->stop(); // stop client <!-- stop/close lifecycle on SyncClient: https://objectbox.io/docfiles/c/current/classobx_1_1SyncClient.html --> |
| 106 | + return 0; |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +**Production note:** instead of `none()`, use real credentials such as `sharedSecret(...)` or JWT as recommended. <!-- Credentials options + JWT recommendation: https://sync.objectbox.io/sync-server/configuration and https://objectbox.io/docfiles/c/current/classobx_1_1SyncCredentials-members.html --> |
| 111 | + |
| 112 | +## 4) Connect to the Sync Server <!-- Sync Server docs: https://sync.objectbox.io/sync-server --> |
| 113 | +Run the **Sync Server** configured with the same model you generated (point it at your `objectbox-model.json`). <!-- Model file option (CLI `-m/--model` and JSON `modelFile`): https://sync.objectbox.io/sync-server/configuration --> |
| 114 | + |
| 115 | +### Example (Linux/macOS) <!-- CLI options incl. --model & --unsecured-no-authentication: https://sync.objectbox.io/sync-server/configuration --> |
| 116 | +```bash |
| 117 | +# Bind locally on port 9999 & load your model JSON: |
| 118 | +sync-server --bind=ws://127.0.0.1:9999 \ # bind address/port <!-- bind option doc: https://sync.objectbox.io/sync-server/configuration --> |
| 119 | + --model=path/to/build/objectbox-model.json \ # model file (JSON) <!-- --model/-m and JSON modelFile: https://sync.objectbox.io/sync-server/configuration --> |
| 120 | + --unsecured-no-authentication # dev-only, no auth <!-- dev option documented (not for production): https://sync.objectbox.io/sync-server/configuration --> |
| 121 | +``` |
| 122 | + |
| 123 | +You should see log output from the server on startup and when clients connect. <!-- Server CLI help & logging examples on the configuration page: https://sync.objectbox.io/sync-server/configuration --> |
| 124 | + |
| 125 | +> For long-term setups, prefer a JSON config file (`sync-server-config.json`) and use proper authentication (JWT recommended). <!-- Config file & auth guidance: https://sync.objectbox.io/sync-server/configuration --> |
| 126 | + |
| 127 | +## Next Steps <!-- Further reading / features --> |
| 128 | +- Try the **Sync Client** page for more options (listeners, request update modes, filter variables). <!-- Event listeners & options: https://sync.objectbox.io/sync-client --> |
| 129 | +- Use **credentials** like `SyncCredentials::sharedSecret(...)` or **JWT tokens** for production. <!-- Credentials list: https://objectbox.io/docfiles/c/current/classobx_1_1SyncCredentials-members.html ; JWT production note: https://sync.objectbox.io/sync-server/configuration --> |
| 130 | +- Review **entity relations & constraints** for sync: only relations between either all-synced or all-non-synced entities. <!-- Relationship rule: https://sync.objectbox.io/sync-client (section around annotations & relations) --> |
0 commit comments