Skip to content

Commit 4a11b64

Browse files
authored
refactor: Realtime V2 (#214)
* feat: add EventType to Realtime Message * refactor: rename Message to RealtimeMessage * feat: add callback manager * feat: implement onMessage handler * refactor realtime based on Kotlin library * wip * Fix Realtime connection * Add Sendable conformances and make classes thread safe * Rename v2 types * Fix Realtime tests * Fix leaks * add _Presence type * block task until subscribed * wip * Make Realtime and Channel Actors * wip slack clone example * Fix tests * Rename Realtime to RealtimeClientV2 * fix: pending heartbeat check * Remove AuthTokenProvider * wip * Remove Combine * Remove OSLog as it doesn't support non-Apple platform * Import FoundationNetworking * Integrate SupabaseLogger * Fix Realtime access token and improve slack clone example * wip * Test * test: realtime connect and subscribe * Import Dispatch * Remove NSEC_PER_SEC since non-Darwin don't have it * Trying to fix build on Linux * ci: use Xcode 15.2 * Comment out failing test * Add local supabase instance for SlackClone * Add visionOS support for SlackClone example * Add migration guide
1 parent 7288685 commit 4a11b64

File tree

67 files changed

+4358
-527
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

67 files changed

+4358
-527
lines changed

Dockerfile

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# Use an official Swift runtime as a base image
2+
FROM swift:latest
3+
4+
# Set the working directory to /app
5+
WORKDIR /app
6+
7+
# Copy the entire content of the local directory to the container
8+
COPY . .
9+
10+
# Build the Swift package
11+
RUN swift build
12+
13+
# Run tests
14+
CMD ["swift", "test"]
15+

Examples/Examples.xcodeproj/project.pbxproj

Lines changed: 212 additions & 160 deletions
Large diffs are not rendered by default.
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
LastUpgradeVersion = "1520"
4+
version = "1.7">
5+
<BuildAction
6+
parallelizeBuildables = "YES"
7+
buildImplicitDependencies = "YES">
8+
<BuildActionEntries>
9+
<BuildActionEntry
10+
buildForTesting = "YES"
11+
buildForRunning = "YES"
12+
buildForProfiling = "YES"
13+
buildForArchiving = "YES"
14+
buildForAnalyzing = "YES">
15+
<BuildableReference
16+
BuildableIdentifier = "primary"
17+
BlueprintIdentifier = "79D884C62B3C18830009EA4A"
18+
BuildableName = "SlackClone.app"
19+
BlueprintName = "SlackClone"
20+
ReferencedContainer = "container:Examples.xcodeproj">
21+
</BuildableReference>
22+
</BuildActionEntry>
23+
</BuildActionEntries>
24+
</BuildAction>
25+
<TestAction
26+
buildConfiguration = "Debug"
27+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
28+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
29+
shouldUseLaunchSchemeArgsEnv = "YES"
30+
shouldAutocreateTestPlan = "YES">
31+
</TestAction>
32+
<LaunchAction
33+
buildConfiguration = "Debug"
34+
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
35+
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
36+
launchStyle = "0"
37+
useCustomWorkingDirectory = "NO"
38+
ignoresPersistentStateOnLaunch = "NO"
39+
debugDocumentVersioning = "YES"
40+
debugServiceExtension = "internal"
41+
allowLocationSimulation = "YES">
42+
<BuildableProductRunnable
43+
runnableDebuggingMode = "0">
44+
<BuildableReference
45+
BuildableIdentifier = "primary"
46+
BlueprintIdentifier = "79D884C62B3C18830009EA4A"
47+
BuildableName = "SlackClone.app"
48+
BlueprintName = "SlackClone"
49+
ReferencedContainer = "container:Examples.xcodeproj">
50+
</BuildableReference>
51+
</BuildableProductRunnable>
52+
</LaunchAction>
53+
<ProfileAction
54+
buildConfiguration = "Release"
55+
shouldUseLaunchSchemeArgsEnv = "YES"
56+
savedToolIdentifier = ""
57+
useCustomWorkingDirectory = "NO"
58+
debugDocumentVersioning = "YES">
59+
<BuildableProductRunnable
60+
runnableDebuggingMode = "0">
61+
<BuildableReference
62+
BuildableIdentifier = "primary"
63+
BlueprintIdentifier = "79D884C62B3C18830009EA4A"
64+
BuildableName = "SlackClone.app"
65+
BlueprintName = "SlackClone"
66+
ReferencedContainer = "container:Examples.xcodeproj">
67+
</BuildableReference>
68+
</BuildableProductRunnable>
69+
</ProfileAction>
70+
<AnalyzeAction
71+
buildConfiguration = "Debug">
72+
</AnalyzeAction>
73+
<ArchiveAction
74+
buildConfiguration = "Release"
75+
revealArchiveInOrganizer = "YES">
76+
</ArchiveAction>
77+
</Scheme>

Examples/RealtimeSample/ContentView.swift

Lines changed: 0 additions & 127 deletions
This file was deleted.

Examples/RealtimeSample/RealtimeSampleApp.swift

Lines changed: 0 additions & 27 deletions
This file was deleted.

Examples/SlackClone/AppView.swift

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
//
2+
// AppView.swift
3+
// SlackClone
4+
//
5+
// Created by Guilherme Souza on 27/12/23.
6+
//
7+
8+
import Supabase
9+
import SwiftUI
10+
11+
@Observable
12+
@MainActor
13+
final class AppViewModel {
14+
var session: Session?
15+
var selectedChannel: Channel?
16+
17+
init() {
18+
Task { [weak self] in
19+
for await (event, session) in await supabase.auth.authStateChanges {
20+
guard [.signedIn, .signedOut, .initialSession].contains(event) else { return }
21+
self?.session = session
22+
23+
if session == nil {
24+
for subscription in await supabase.realtimeV2.subscriptions.values {
25+
await subscription.unsubscribe()
26+
}
27+
}
28+
}
29+
}
30+
}
31+
}
32+
33+
@MainActor
34+
struct AppView: View {
35+
@Bindable var model: AppViewModel
36+
37+
@ViewBuilder
38+
var body: some View {
39+
if model.session != nil {
40+
NavigationSplitView {
41+
ChannelListView(channel: $model.selectedChannel)
42+
} detail: {
43+
if let channel = model.selectedChannel {
44+
MessagesView(channel: channel).id(channel.id)
45+
}
46+
}
47+
} else {
48+
AuthView()
49+
}
50+
}
51+
}
52+
53+
#Preview {
54+
AppView(model: AppViewModel())
55+
}

Examples/RealtimeSample/Assets.xcassets/AppIcon.appiconset/Contents.json renamed to Examples/SlackClone/Assets.xcassets/AppIcon.appiconset/Contents.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
{
22
"images" : [
3+
{
4+
"idiom" : "universal",
5+
"platform" : "ios",
6+
"size" : "1024x1024"
7+
},
38
{
49
"idiom" : "mac",
510
"scale" : "1x",

Examples/SlackClone/AuthView.swift

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
//
2+
// AuthView.swift
3+
// SlackClone
4+
//
5+
// Created by Guilherme Souza on 27/12/23.
6+
//
7+
8+
import SwiftUI
9+
10+
@Observable
11+
@MainActor
12+
final class AuthViewModel {
13+
var email = ""
14+
var toast: ToastState?
15+
16+
func signInButtonTapped() {
17+
Task {
18+
do {
19+
try await supabase.auth.signInWithOTP(
20+
email: email,
21+
redirectTo: URL(string: "slackclone://sign-in")
22+
)
23+
toast = ToastState(status: .success, title: "Check your inbox.")
24+
} catch {
25+
toast = ToastState(status: .error, title: "Error", description: error.localizedDescription)
26+
}
27+
}
28+
}
29+
30+
func handle(_ url: URL) {
31+
Task {
32+
do {
33+
try await supabase.auth.session(from: url)
34+
} catch {
35+
toast = ToastState(status: .error, title: "Error", description: error.localizedDescription)
36+
}
37+
}
38+
}
39+
}
40+
41+
@MainActor
42+
struct AuthView: View {
43+
@Bindable var model = AuthViewModel()
44+
45+
var body: some View {
46+
VStack {
47+
VStack {
48+
TextField("Email", text: $model.email)
49+
#if os(iOS)
50+
.textInputAutocapitalization(.never)
51+
.keyboardType(.emailAddress)
52+
#endif
53+
.textContentType(.emailAddress)
54+
.autocorrectionDisabled()
55+
}
56+
Button("Sign in with Magic Link") {
57+
model.signInButtonTapped()
58+
}
59+
}
60+
.padding()
61+
.toast(state: $model.toast)
62+
.onOpenURL { model.handle($0) }
63+
}
64+
}
65+
66+
#Preview {
67+
AuthView()
68+
}

0 commit comments

Comments
 (0)