Real-time Apps the SwiftUI way

What's New



Swift Package Manager Twitter: @nerdsupremacist


Sync is a proof of concept for expanding on the Magic of ObservableObject, and making it work over the network. This let's you create real-time Apps in which your Observable Objects are in sync across multiple devices. This has a lot of applications just as:

  • IoT Apps
  • Multi-Player Mini Games
  • etc.

As of right now Sync works out of the box using WebSockets, however, it's not limited to web sockets and it allows for multiple kinds of connections. Some possible connections could be:

  • Bluetooth
  • Multi-Peer
  • MQTT
  • etc.

The sky is the limit!

Warning: This is only a proof of concept that I'm using for exeprimentation. I assume there's lots and lots of bugs in there...


Swift Package Manager

You can install Sync via Swift Package Manager by adding the following line to your Package.swift:

import PackageDescription

let package = Package(
    dependencies: [
        .package(url: "", from: "0.1.0")


If you have ever used Observable Object, then Sync will be extremely easy to use. For this example we will create an app with a Switch that everyone can flip on or off as they like. We will build this using SwiftUI, WebSockets and a Vapor Server.


For this we will need a few additional packages:

Let's start by building our shared ViewModel. This is easy, instead of using ObservableObject we use SyncedObject. And instead of Published we use Synced:

class ViewModel: SyncedObject {
    var toggle: Bool = false

    init() { }

This ViewModel needs to be both on your App codebase as well as on the Server codebase. I recommend putting it in a shared Swift Package, if you're feeling fancy.

Next stop is to create our server. In this example every client will be using the exact same ViewModel. So we're creating a Vapor application, and using syncObjectOverWebSocket to provide the object:

import Vapor
import SyncWebSocketVapor

let app = Application(try .detect())

let viewModel = ViewModel()
app.syncObjectOverWebSocket("view_model") { _ in
    return viewModel


For our SwiftUI App, we need to use two things:

  • @SyncedObservedObject: Like ObservedObject, but for Synced Objects. It's a property wrapper that will dynamically tell SwiftUI when to update the UI
  • Sync: A little wrapper view to start the remote session

Our actual view then uses SyncedObservedObject with our ViewModel

struct ContentView: View {
    var viewModel: ViewModel

    var body: some View {
        Toggle("A toggle", isOn: $viewModel.toggle)
            .animation(.easeIn, value: viewModel.toggle)

And in order to display it we use Sync, and pass along the Web Socket Connection:

struct RootView: View {
    var body: some View {
        Sync(ViewModel.self, using: WebSocketClientConnection(url: url)) { viewModel in
            ContentView(viewModel: viewModel)


Contributions are welcome and encouraged!


Sync is available under the MIT license. See the LICENSE file for more info.


  • Swift Tools 5.5.0
View More Packages from this Author


  • None
Last updated: Wed Feb 01 2023 21:32:32 GMT-0500 (GMT-05:00)