Skip to content

Commit e565484

Browse files
authored
FORGE-1261-Better Docs and Demo App Fixes (#116)
* Documentation fixes first pass * Fixes for ios app * Android Demo app done
1 parent f049ae3 commit e565484

8 files changed

Lines changed: 401 additions & 72 deletions

File tree

README.md

Lines changed: 267 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -23,78 +23,301 @@
2323

2424
</div>
2525

26-
A suite of SDKs that provides UI components and data models to quickly build a
27-
peer-to-peer chat application using the Ditto Platform.
26+
# DittoChat Quickstart Guide
2827

29-
## Features
28+
This guide walks you through adding DittoChat to an iOS or Android app from scratch. By the end you'll have a working peer-to-peer chat experience that syncs over Bluetooth, Wi-Fi, and the cloud.
3029

31-
- Real-time, peer-to-peer chat
30+
---
3231

33-
- Group chat and private messaging
32+
## Prerequisites (Both Platforms)
3433

35-
- User presence and typing indicators
34+
Before you begin, make sure you have the following:
3635

37-
- Easy-to-integrate SwiftUI views
36+
1. **A Ditto account** — Sign up free at the [Ditto Portal](https://portal.ditto.live).
37+
2. **An App ID and Online Playground Token** — Create a new app in the portal and copy these credentials. You'll need them to initialize the SDK.
3838

39-
- Built on the Ditto Sync Platform
39+
---
4040

41-
## Requirements:
41+
## iOS Quickstart (Swift / SwiftUI)
4242

43-
### iOS
43+
### Step 1 — Create or Open Your Xcode Project
4444

45-
- iOS 18.0+
46-
- Xcode 15.6+
47-
- Swift 5.7+
48-
- A Ditto Account, AppId, and baseline knowledge of the [DittoSwift SDK](https://github.com/getditto/DittoSwiftPackage)
45+
Open an existing iOS project or create a new one in Xcode (**File → New → Project → App**). Select **SwiftUI** as the interface and **Swift** as the language.
4946

50-
### Android
47+
### Step 2 — Add the DittoChat Swift Package
5148

52-
- TBD
49+
1. In Xcode, go to **File → Add Package Dependencies…**
50+
2. In the search bar, paste the DittoChat repository URL:
5351

54-
### Web
52+
```
53+
https://github.com/getditto/DittoChat.git
54+
```
5555

56-
- Node.js 18.0+
57-
- React 18.0+ or 19.0+
58-
- TypeScript 4.5+
59-
- A Ditto Account, AppId, and baseline knowledge of the [Ditto JavaScript SDK](https://docs.ditto.live/sdk/latest/install-guides/js)
56+
3. Under **Dependency Rule**, choose **Up to Next Major Version** and set it to the latest release (check the [Releases page](https://github.com/getditto/DittoChat/releases) for the current version).
57+
4. Click **Add Package**.
58+
5. When prompted, select the DittoChat library product and add it to your app target.
6059

61-
#### Packages
60+
### Step 3 — Configure Permissions
6261

63-
The JavaScript implementation consists of two packages:
62+
Ditto uses Bluetooth LE and local networking for peer-to-peer sync. You need to declare usage descriptions so iOS can prompt the user for permission.
6463

65-
**[@dittolive/ditto-chat-core](./sdks/js/ditto-chat-core/README.md)** - Core data models and React hooks for real-time chat functionalities
64+
Add the following keys to your project's **Info.plist**:
6665

67-
```bash
68-
npm install @dittolive/ditto-chat-core
69-
# or
70-
yarn add @dittolive/ditto-chat-core
66+
```xml
67+
<key>NSBluetoothAlwaysUsageDescription</key>
68+
<string>Uses Bluetooth to connect and sync with nearby devices</string>
69+
70+
<key>NSBluetoothPeripheralUsageDescription</key>
71+
<string>Uses Bluetooth to connect and sync with nearby devices</string>
72+
73+
<key>NSLocalNetworkUsageDescription</key>
74+
<string>Uses WiFi to connect and sync with nearby devices</string>
75+
76+
<key>NSBonjourServices</key>
77+
<array>
78+
<string>_http-alt._tcp.</string>
79+
</array>
7180
```
7281

73-
**[@dittolive/ditto-chat-ui](./sdks/js/ditto-chat-ui/README.md)** - Ready-to-use React components for building chat UIs
82+
### Step 4 — Enable Background Modes (Optional but Recommended)
83+
84+
To keep chat syncing when your app is in the background:
85+
86+
1. Select your project in the navigator, then your app target.
87+
2. Go to **Signing & Capabilities → + Capability → Background Modes**.
88+
3. Enable the following:
89+
- **Uses Bluetooth LE accessories**
90+
- **Acts as a Bluetooth LE accessory**
91+
92+
### Step 5 — Initialize Ditto and Present the Chat UI
93+
94+
In your SwiftUI app entry point (e.g. `App.swift` or a root view), initialize a Ditto instance with your portal credentials and present the DittoChat view:
95+
96+
```swift
97+
import SwiftUI
98+
import DittoSwift
99+
import DittoChat
100+
101+
@main
102+
struct MyChatApp: App {
103+
@StateObject private var dittoInstance = DittoManager()
104+
105+
var body: some Scene {
106+
WindowGroup {
107+
// Replace with the DittoChat view provided by the SDK.
108+
// See the example app in the `apps/` directory for
109+
// a complete working implementation.
110+
ContentView()
111+
.environmentObject(dittoInstance)
112+
}
113+
}
114+
}
115+
116+
/// A simple singleton that owns the Ditto instance.
117+
class DittoManager: ObservableObject {
118+
let ditto: Ditto
119+
120+
init() {
121+
ditto = Ditto(
122+
identity: .onlinePlayground(
123+
appID: "YOUR_APP_ID",
124+
token: "YOUR_PLAYGROUND_TOKEN"
125+
)
126+
)
127+
128+
// Start syncing with nearby peers
129+
do {
130+
try ditto.startSync()
131+
} catch {
132+
print("Failed to start Ditto sync: \(error)")
133+
}
134+
}
135+
}
136+
```
137+
138+
> **Important:** Replace `YOUR_APP_ID` and `YOUR_PLAYGROUND_TOKEN` with the credentials from your Ditto Portal app. Never commit these values to source control — use environment variables or a configuration file excluded from Git.
139+
140+
### Step 6 — Build and Run
141+
142+
1. Connect a physical iOS device (Bluetooth is not available in the Simulator).
143+
2. Select your device as the run destination and press **⌘R**.
144+
3. Grant Bluetooth and local network permissions when prompted.
145+
4. Run the app on a second device to see peer-to-peer chat in action.
146+
147+
---
148+
149+
## Android Quickstart (Kotlin)
150+
151+
> **Note:** The DittoChat Android SDK is under active development. The steps below show how to integrate the Ditto SDK in a Kotlin Android project and prepare for the DittoChat library. Check the [Releases page](https://github.com/getditto/DittoChat/releases) and the `sdks/kotlin/` directory for the latest availability.
152+
153+
### Step 1 — Create or Open Your Android Studio Project
154+
155+
Open an existing project or create a new one in Android Studio (**File → New → New Project → Empty Activity**). Choose **Kotlin** as the language and set the minimum SDK to **API 23 (Android 6.0)** or higher.
74156

75-
```bash
76-
npm install @dittolive/ditto-chat-ui
77-
# or
78-
yarn add @dittolive/ditto-chat-ui
157+
### Step 2 — Add the Ditto SDK Dependency
158+
159+
1. In your **project-level** `build.gradle` (or `settings.gradle.kts`), make sure Maven Central is included:
160+
161+
```groovy
162+
// build.gradle (project-level)
163+
allprojects {
164+
repositories {
165+
mavenCentral()
166+
}
167+
}
168+
```
169+
170+
2. In your **app-level** `build.gradle`, add the Ditto SDK:
171+
172+
```groovy
173+
// build.gradle (app-level)
174+
dependencies {
175+
implementation "live.ditto:ditto:4.14.1" // Check docs.ditto.live for the latest version
176+
}
177+
```
178+
179+
3. Sync your project: **File → Sync Project with Gradle Files**.
180+
181+
> Once the DittoChat Android library is published, you will add it alongside the core Ditto SDK. Watch this repo for release announcements.
182+
183+
### Step 3 — Configure Permissions
184+
185+
The Ditto SDK's `AndroidManifest.xml` automatically merges the required Bluetooth and network permissions into your app. However, you should be aware of what's being added:
186+
187+
```xml
188+
<!-- These are automatically merged by the Ditto SDK -->
189+
<uses-permission android:name="android.permission.BLUETOOTH"
190+
android:maxSdkVersion="30" />
191+
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
192+
android:maxSdkVersion="30" />
193+
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE"
194+
tools:targetApi="s" />
195+
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT"
196+
tools:targetApi="s" />
197+
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"
198+
android:usesPermissionFlags="neverForLocation"
199+
tools:targetApi="s" />
200+
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"
201+
android:maxSdkVersion="32" />
202+
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"
203+
android:maxSdkVersion="30" />
204+
<uses-permission android:name="android.permission.INTERNET" />
205+
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
206+
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
207+
<uses-permission android:name="android.permission.NEARBY_WIFI_DEVICES" />
79208
```
80209

81-
## Publishing
210+
### Step 4 — Request Runtime Permissions
82211

83-
This monorepo uses [Changesets](https://github.com/changesets/changesets) for version management and publishing.
212+
Android requires that certain permissions (like Bluetooth and location) be requested from the user at runtime. Use the `DittoSyncPermissions` helper provided by the SDK:
213+
214+
```kotlin
215+
import live.ditto.transports.DittoSyncPermissions
216+
217+
// In your Activity's onCreate or a Composable's LaunchedEffect:
218+
fun requestPermissions() {
219+
val permissions = DittoSyncPermissions(this)
220+
val missing = permissions.missingPermissions()
221+
if (missing.isNotEmpty()) {
222+
this.requestPermissions(missing, 0)
223+
}
224+
}
225+
```
84226

85-
### For Contributors
227+
Call this early in your app's lifecycle — before starting Ditto sync — so the user sees the permission prompts right away.
86228

87-
When making changes to the packages, please create a changeset to document your changes:
229+
### Step 5 — Initialize Ditto
88230

89-
```bash
90-
npm run changeset
231+
Create a singleton `Application` class (or use your existing one) to initialize Ditto at app startup:
232+
233+
```kotlin
234+
import android.app.Application
235+
import android.util.Log
236+
import live.ditto.*
237+
import live.ditto.android.DefaultAndroidDittoDependencies
238+
239+
class MyChatApplication : Application() {
240+
241+
lateinit var ditto: Ditto
242+
243+
override fun onCreate() {
244+
super.onCreate()
245+
246+
try {
247+
DittoLogger.minimumLogLevel = DittoLogLevel.DEBUG
248+
249+
val androidDependencies = DefaultAndroidDittoDependencies(applicationContext)
250+
val identity = DittoIdentity.OnlinePlayground(
251+
androidDependencies,
252+
appId = "YOUR_APP_ID",
253+
token = "YOUR_PLAYGROUND_TOKEN"
254+
)
255+
256+
ditto = Ditto(androidDependencies, identity)
257+
ditto.startSync()
258+
} catch (e: DittoError) {
259+
Log.e("DittoChat", "Failed to start Ditto: ${e.message}")
260+
}
261+
}
262+
}
263+
```
264+
265+
Register the application class in your `AndroidManifest.xml`:
266+
267+
```xml
268+
<application
269+
android:name=".MyChatApplication"
270+
... >
91271
```
92272

93-
This will prompt you to select which packages are affected and describe your changes.
273+
> **Important:** Replace `YOUR_APP_ID` and `YOUR_PLAYGROUND_TOKEN` with your portal credentials. Store secrets securely — use `BuildConfig` fields or a `local.properties` file that is excluded from version control.
274+
275+
### Step 6 — Build and Run
276+
277+
1. Connect a physical Android device (Bluetooth is unavailable in the emulator).
278+
2. Run the app and grant all requested permissions.
279+
3. Deploy to a second device on the same network (or within Bluetooth range) to test peer-to-peer sync.
280+
281+
---
282+
283+
## Verifying Peer-to-Peer Sync
284+
285+
Once you have the app running on two or more devices:
286+
287+
1. Make sure both devices have **Bluetooth** and **Wi-Fi** enabled.
288+
2. Both apps must be configured with the **same App ID** from the Ditto Portal.
289+
3. Send a message on one device — it should appear on the other within seconds.
290+
4. To test offline sync, enable **Airplane Mode** on both devices (but keep Bluetooth on). Messages will still sync directly over Bluetooth LE.
291+
292+
---
293+
294+
## Troubleshooting
295+
296+
| Symptom | Possible Cause | Fix |
297+
|---|---|---|
298+
| Devices don't discover each other | Missing permissions | Verify all Bluetooth and network permissions are granted in device settings |
299+
| Sync works on Wi-Fi but not Bluetooth | Background Modes not enabled (iOS) | Enable BLE Background Modes in Xcode capabilities |
300+
| `DittoError` on startup | Invalid App ID or token | Double-check your credentials in the [Ditto Portal](https://portal.ditto.live) |
301+
| Messages appear only on one device | Different App IDs | Ensure both devices use the same App ID |
302+
| Permissions prompt doesn't appear (Android) | `requestPermissions` not called | Call `DittoSyncPermissions.missingPermissions()` before `startSync()` |
303+
| Build fails after adding package (iOS) | Xcode version too old | DittoChat requires Xcode 15.6+; update Xcode |
304+
305+
---
306+
307+
## Next Steps
308+
309+
- **Explore the example apps** in the [`apps/`](https://github.com/getditto/DittoChat/tree/main/apps) directory for complete, runnable implementations.
310+
- **Web integration?** See the [Web (React/TypeScript) section](./README.md#web-react--typescript) in the main README.
311+
- **Customize the UI** — DittoChat components are designed to be themed and extended. Check the platform-specific SDK READMEs in `sdks/` for API details.
312+
- **Go to production** — Replace `OnlinePlayground` authentication with `OnlineWithAuthentication` for production apps. See the [Ditto Cloud Authentication docs](https://docs.ditto.live/auth-and-authorization/cloud-authentication) for a full walkthrough.
313+
- **Learn more about Ditto** — Visit [docs.ditto.live](https://docs.ditto.live) for comprehensive platform documentation.
314+
315+
---
94316

95-
### Release Process
317+
## Support
96318

97-
Releases are automated via GitHub Actions:
319+
If you run into issues:
98320

99-
1. When changesets are merged to `main`, a "Version Packages" PR is automatically created
100-
2. Merging the "Version Packages" PR publishes the packages to NPM
321+
- **GitHub Issues:** [github.com/getditto/DittoChat/issues](https://github.com/getditto/DittoChat/issues)
322+
- **Ditto Support:** [support@ditto.live](mailto:support@ditto.live)
323+
- **Documentation:** [docs.ditto.live](https://docs.ditto.live)

apps/android/app/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ android {
3636
}
3737

3838
dependencies {
39-
implementation(project(":dittochat"))
4039

4140
val composeBom = platform(libs.compose.bom)
4241
implementation(composeBom)
@@ -71,4 +70,5 @@ dependencies {
7170
testImplementation(libs.junit)
7271
androidTestImplementation(libs.androidx.junit)
7372
androidTestImplementation(libs.androidx.espresso.core)
73+
implementation("com.ditto:dittochat:1.0.1")
7474
}

0 commit comments

Comments
 (0)