# Bluetooth Mesh Network Chat Interface for iOS

> By Lawrence Arya, Founder & CEO of VP0. Published 2026-06-18. 7 min read.
> Source: https://vp0.com/blogs/bluetooth-mesh-network-chat-interface-ios

How to build a Bluetooth mesh chat on iOS, from choosing MultipeerConnectivity to surfacing the presence, relay, and delivery states a server-backed app hides.

**TL;DR.** A Bluetooth mesh chat app lets phones message each other with no internet or cell service by relaying messages device to device. On iOS the practical transport is MultipeerConnectivity, which builds a local mesh over Bluetooth and peer-to-peer Wi-Fi for you, while raw Core Bluetooth is the lower-level option when you need custom GATT behavior or cross-platform reach. The chat interface is a normal SwiftUI message list, but the design must surface mesh realities: who is in range, relay and delivery state, and that there is no server history. Build the UI against those states from the start. The screen is fastest to start from a free VP0 design with Claude Code or Cursor.

A Bluetooth mesh chat app lets phones message each other with no internet and no cell service by relaying messages from device to device. On iOS the practical transport is MultipeerConnectivity, which builds a local mesh over Bluetooth and peer-to-peer Wi-Fi for you; raw Core Bluetooth is the lower-level path when you need custom behavior or cross-platform reach. The chat interface is a normal SwiftUI message list, but the design has to surface mesh realities a server-backed app hides: who is in range, whether a message relayed and was delivered, and that there is no cloud history. Build the UI against those states from the start. The screen is fastest to start from a free [VP0](/explore) design with Claude Code or Cursor.

## What mesh chat means on iOS

It means messaging that survives a dead network. Each phone is both a client and a relay, so a message can hop across intermediate devices to reach someone out of direct range. That makes it useful at crowded events where cell service collapses, while traveling without data, or anywhere infrastructure is missing. The tradeoff is that delivery is best-effort and bounded by who is physically nearby and online.

This is a different contract from a normal chat app, and the interface has to be honest about it. There is no guaranteed delivery, no server-side history, and no global presence, only the local picture each device can see.

## Picking the transport: Multipeer, Core Bluetooth, or a relay

For most iOS-to-iOS mesh chat, MultipeerConnectivity is the right tool. It discovers nearby peers and forms sessions over Bluetooth and peer-to-peer Wi-Fi without you writing the discovery and connection layer.

| Transport | Best for | Range and reach | Effort |
| --- | --- | --- | --- |
| MultipeerConnectivity | iOS-to-iOS local mesh | Bluetooth plus peer-to-peer Wi-Fi | Low |
| Core Bluetooth (GATT) | Custom protocol, cross-platform | Bluetooth LE | High |
| Internet relay fallback | When any device has connectivity | Global | Medium |

[MultipeerConnectivity](https://developer.apple.com/documentation/multipeerconnectivity) handles the common case with the least code. Drop to [Core Bluetooth](https://developer.apple.com/documentation/corebluetooth) when you need a custom GATT service or to talk to Android, accepting that you now own discovery, chunking, and reconnection. A true many-hop mesh follows the [Bluetooth SIG mesh](https://www.bluetooth.com/specifications/specs/mesh-protocol/) model, which is worth reading even if you implement a simpler relay on top of Multipeer.

## What the chat UI must surface that a normal app hides

A mesh chat screen carries more state than an internet one. It should show who is currently in range, because that set changes as people move; a relay or hop indicator so a user understands a message traveled through others; and a per-message delivery state that can legitimately be not delivered because no one was in range. It should also make clear that history lives only on the device, since there is no server to sync from.

Identity is the subtle part. Without a server there is no account system, so the UI has to represent peers by a local name or key and signal when an identity is unverified. The [Bluetooth device pairing UI](/blogs/bluetooth-device-pairing-ui-swiftui/) covers the discovery-and-connect step that precedes the conversation.

## Building the message list in SwiftUI

The conversation view is a standard message list; the mesh lives behind it. Model a message, render a `List`, and update peers from the session state.

```swift
struct Message: Identifiable {
    let id = UUID()
    let sender: String
    let text: String
    var delivered: Bool
}

// MCSession delegate: append incoming data as Message,
// and publish an [MCPeerID] for the peers currently in range.
```

The familiar half of the work, bubbles, input bar, timestamps, mirrors any chat app, so the [chatbot UI with a Gifted Chat alternative](/blogs/chatbot-ui-react-native-gifted-chat-alternative-free-ios-template-vibe-coding-gu/) covers patterns you can reuse for the list itself. The unfamiliar half is binding presence and delivery to real session events.

## Designing for range and relay

People move, so peers appear and vanish. Show presence as a live, changing list rather than a static roster, and fade or mark peers who drop out instead of deleting them mid-conversation. Because a recipient may be briefly out of range, a store-and-forward step, holding a message and retrying as peers reconnect, makes delivery feel less brittle. Keep the user informed: a message waiting to relay is a normal state, not an error.

## Trust and safety in an open mesh

An open mesh has no gatekeeper, which has real consequences. Encrypt message content so relays cannot read what they forward, since intermediate devices carry traffic that is not theirs. Treat identities as unverified by default and make spoofing visible rather than assuming a name is genuine. MultipeerConnectivity also triggers the local network permission, so set a clear [local network usage description](https://developer.apple.com/documentation/bundleresources/information_property_list/nslocalnetworkusagedescription) and explain why the app needs it. Do not over-promise anonymity; a mesh hides you from the internet, not from the people physically around you.

## Common mistakes

The recurring errors come from treating mesh like a server app. Assuming guaranteed delivery leads to a UI that lies when no one is in range. Hiding the peer list leaves users with no idea who can receive a message. Forgetting the local network permission string gets the connection silently blocked. And shipping plaintext over relays exposes content to every device in the path. Design the empty and degraded states first, because in a mesh they are common, not rare.

## Building the screen fast

The transport is your work; the chat screen is a known layout worth starting from a design. [VP0](/explore) is a free, $0 iOS design library where each screen has a hidden source page an AI builder reads from a pasted link:

```text
Build this iOS mesh chat screen in SwiftUI.
Read the layout and tokens from this VP0 source page: <pasted VP0 link>.
Show a message list with delivery state, a live "peers in range" header, and a
"waiting to relay" state. Keep the transport abstract behind a session object;
I will wire MultipeerConnectivity. Surface an unverified-identity badge.
```

You get the conversation layout and presence header from the design and connect them to your session, keeping effort on the mesh logic.

## What to choose

For iOS-to-iOS mesh chat, use MultipeerConnectivity for the transport and a standard SwiftUI message list for the interface, then make the mesh visible: peers in range, relay and delivery state, device-only history, and unverified identities. Move to Core Bluetooth only for a custom protocol or Android interoperability, and add an internet relay fallback when any device has connectivity. Encrypt content, set the local network permission string, and design the degraded states first. Start the screen from a free VP0 design, generate it with Claude Code or Cursor, and test with at least three real devices, since a true mesh and its relay behavior do not show up with two phones or the simulator.

## Frequently asked questions

### How do I build a Bluetooth mesh network chat interface for iOS?

Use MultipeerConnectivity for the transport, which forms a local mesh over Bluetooth and peer-to-peer Wi-Fi, and build the conversation as a standard SwiftUI message list. The difference from a normal chat app is surfacing peers in range, relay and delivery state, and device-only history. Start the screen from a free VP0 design with Claude Code or Cursor and wire it to an MCSession.

### Should I use MultipeerConnectivity or Core Bluetooth for mesh chat?

Use MultipeerConnectivity for iOS-to-iOS chat, since it handles discovery and connections over Bluetooth and Wi-Fi with little code. Choose Core Bluetooth only when you need a custom GATT protocol or have to interoperate with Android, accepting that you then own discovery, chunking, and reconnection. Many apps start on Multipeer and add a relay layer on top.

### Does Bluetooth mesh chat work with no internet?

Yes, that is the point: messages relay device to device with no cell or Wi-Fi infrastructure. Delivery is best-effort and bounded by who is physically nearby and online, so the interface should show presence and a delivery state that can honestly be undelivered. A store-and-forward retry as peers reconnect makes it feel less brittle.

### Is an open Bluetooth mesh secure?

Not by default, so design for it. Encrypt message content so relays cannot read what they forward, treat peer identities as unverified and make spoofing visible, and set a clear local network usage description. A mesh hides traffic from the internet, not from the people around you, so do not promise anonymity you cannot deliver.

### Can VP0 give me a free template for the chat screen?

Yes. VP0 is a free iOS design library where each chat layout has an AI-readable source page, so you can copy the link and have Claude Code or Cursor build the message list and presence header in SwiftUI. You then connect it to MultipeerConnectivity or Core Bluetooth. The design provides the interface; the mesh transport is yours.

## Frequently asked questions

### How do I build a Bluetooth mesh network chat interface for iOS?

Use MultipeerConnectivity for the transport, which forms a local mesh over Bluetooth and peer-to-peer Wi-Fi, and build the conversation as a standard SwiftUI message list. The difference from a normal chat app is surfacing peers in range, relay and delivery state, and device-only history. Start the screen from a free VP0 design with Claude Code or Cursor and wire it to an MCSession.

### Should I use MultipeerConnectivity or Core Bluetooth for mesh chat?

Use MultipeerConnectivity for iOS-to-iOS chat, since it handles discovery and connections over Bluetooth and Wi-Fi with little code. Choose Core Bluetooth only when you need a custom GATT protocol or have to interoperate with Android, accepting that you then own discovery, chunking, and reconnection. Many apps start on Multipeer and add a relay layer on top.

### Does Bluetooth mesh chat work with no internet?

Yes, that is the point: messages relay device to device with no cell or Wi-Fi infrastructure. Delivery is best-effort and bounded by who is physically nearby and online, so the interface should show presence and a delivery state that can honestly be undelivered. A store-and-forward retry as peers reconnect makes it feel less brittle.

### Is an open Bluetooth mesh secure?

Not by default, so design for it. Encrypt message content so relays cannot read what they forward, treat peer identities as unverified and make spoofing visible, and set a clear local network usage description. A mesh hides traffic from the internet, not from the people around you, so do not promise anonymity you cannot deliver.

### Can VP0 give me a free template for the chat screen?

Yes. VP0 is a free iOS design library where each chat layout has an AI-readable source page, so you can copy the link and have Claude Code or Cursor build the message list and presence header in SwiftUI. You then connect it to MultipeerConnectivity or Core Bluetooth. The design provides the interface; the mesh transport is yours.

---
*Published on the [VP0 Journal](https://vp0.com/blogs). Free to read, index and cite with attribution.*
