diff --git a/Examples/Examples.xcodeproj/project.pbxproj b/Examples/Examples.xcodeproj/project.pbxproj index cd986255..aeef716b 100644 --- a/Examples/Examples.xcodeproj/project.pbxproj +++ b/Examples/Examples.xcodeproj/project.pbxproj @@ -7,11 +7,11 @@ objects = { /* Begin PBXBuildFile section */ + 790132E02B0C29080051B356 /* Supabase in Frameworks */ = {isa = PBXBuildFile; productRef = 790132DF2B0C29080051B356 /* Supabase */; }; 790308E92AEE7B4D003C4A98 /* RealtimeSampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790308E82AEE7B4D003C4A98 /* RealtimeSampleApp.swift */; }; 790308EB2AEE7B4D003C4A98 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 790308EA2AEE7B4D003C4A98 /* ContentView.swift */; }; 790308ED2AEE7B4E003C4A98 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 790308EC2AEE7B4E003C4A98 /* Assets.xcassets */; }; 790308F02AEE7B4E003C4A98 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 790308EF2AEE7B4E003C4A98 /* Preview Assets.xcassets */; }; - 790308F62AEE7B5B003C4A98 /* Realtime in Frameworks */ = {isa = PBXBuildFile; productRef = 790308F52AEE7B5B003C4A98 /* Realtime */; }; 793895CA2954ABFF0044F2B8 /* ExamplesApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793895C92954ABFF0044F2B8 /* ExamplesApp.swift */; }; 793895CC2954ABFF0044F2B8 /* RootView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 793895CB2954ABFF0044F2B8 /* RootView.swift */; }; 793895CE2954AC000044F2B8 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 793895CD2954AC000044F2B8 /* Assets.xcassets */; }; @@ -85,7 +85,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 790308F62AEE7B5B003C4A98 /* Realtime in Frameworks */, + 790132E02B0C29080051B356 /* Supabase in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -233,7 +233,7 @@ ); name = RealtimeSample; packageProductDependencies = ( - 790308F52AEE7B5B003C4A98 /* Realtime */, + 790132DF2B0C29080051B356 /* Supabase */, ); productName = RealtimeSample; productReference = 790308E62AEE7B4D003C4A98 /* RealtimeSample.app */; @@ -800,9 +800,9 @@ /* End XCRemoteSwiftPackageReference section */ /* Begin XCSwiftPackageProductDependency section */ - 790308F52AEE7B5B003C4A98 /* Realtime */ = { + 790132DF2B0C29080051B356 /* Supabase */ = { isa = XCSwiftPackageProductDependency; - productName = Realtime; + productName = Supabase; }; 7956406C2955B3500088A06F /* SwiftUINavigation */ = { isa = XCSwiftPackageProductDependency; diff --git a/Examples/RealtimeSample/ContentView.swift b/Examples/RealtimeSample/ContentView.swift index caf67033..4504e6b6 100644 --- a/Examples/RealtimeSample/ContentView.swift +++ b/Examples/RealtimeSample/ContentView.swift @@ -53,22 +53,13 @@ struct ContentView: View { } .onAppear { createSubscription() - - socket.connect() - socket.onOpen { - socketStatus = "OPEN" - } - socket.onClose { - socketStatus = "CLOSE" - } - socket.onError { error, _ in - socketStatus = "ERROR: \(error.localizedDescription)" - } } } func createSubscription() { - publicSchema = socket.channel("public") + supabase.realtime.connect() + + publicSchema = supabase.realtime.channel("public") .on("postgres_changes", filter: ChannelFilter(event: "INSERT", schema: "public")) { inserts.append($0) } @@ -94,6 +85,17 @@ struct ContentView: View { channelStatus = "ERROR" } } + + supabase.realtime.connect() + supabase.realtime.onOpen { + socketStatus = "OPEN" + } + supabase.realtime.onClose { + socketStatus = "CLOSE" + } + supabase.realtime.onError { error, _ in + socketStatus = "ERROR: \(error.localizedDescription)" + } } func toggleSubscription() { diff --git a/Examples/RealtimeSample/RealtimeSampleApp.swift b/Examples/RealtimeSample/RealtimeSampleApp.swift index 382fe9e4..e8f4f489 100644 --- a/Examples/RealtimeSample/RealtimeSampleApp.swift +++ b/Examples/RealtimeSample/RealtimeSampleApp.swift @@ -5,7 +5,7 @@ // Created by Guilherme Souza on 29/10/23. // -import Realtime +import Supabase import SwiftUI @main @@ -17,13 +17,11 @@ struct RealtimeSampleApp: App { } } -let socket: RealtimeClient = { - let client = RealtimeClient( - "https://PROJECT_ID.supabase.co/realtime/v1", - params: [ - "apikey": "SUPABASE_ANON_KEY", - ] +let supabase: SupabaseClient = { + let client = SupabaseClient( + supabaseURL: "https://project-id.supabase.co", + supabaseKey: "anon key" ) - client.logger = { print($0) } + client.realtime.logger = { print($0) } return client }() diff --git a/Examples/UserManagement/Supabase.swift b/Examples/UserManagement/Supabase.swift index c76a5509..266901cf 100644 --- a/Examples/UserManagement/Supabase.swift +++ b/Examples/UserManagement/Supabase.swift @@ -9,6 +9,6 @@ import Foundation import Supabase let supabase = SupabaseClient( - supabaseURL: URL(string: "https://PROJECT_ID.supabase.co")!, + supabaseURL: "https://PROJECT_ID.supabase.co", supabaseKey: "YOUR_SUPABASE_ANON_KEY" ) diff --git a/Sources/Supabase/SupabaseClient.swift b/Sources/Supabase/SupabaseClient.swift index 3e48c530..cc0fcdbb 100644 --- a/Sources/Supabase/SupabaseClient.swift +++ b/Sources/Supabase/SupabaseClient.swift @@ -16,7 +16,6 @@ public final class SupabaseClient: @unchecked Sendable { let supabaseKey: String let storageURL: URL let databaseURL: URL - let realtimeURL: URL let functionsURL: URL /// Supabase Auth allows you to create and manage user sessions for access to data that is secured @@ -41,11 +40,7 @@ public final class SupabaseClient: @unchecked Sendable { ) /// Realtime client for Supabase - public private(set) lazy var realtime = RealtimeClient( - realtimeURL.absoluteString, - headers: defaultHeaders, - params: defaultHeaders - ) + public let realtime: RealtimeClient /// Supabase Functions allows you to deploy and invoke edge functions. public private(set) lazy var functions = FunctionsClient( @@ -69,17 +64,20 @@ public final class SupabaseClient: @unchecked Sendable { /// your project dashboard. /// - options: Custom options to configure client's behavior. public init( - supabaseURL: URL, + supabaseURL: String, supabaseKey: String, options: SupabaseClientOptions = .init() ) { + guard let supabaseURL = URL(string: supabaseURL) else { + fatalError("Invalid supabaseURL: \(supabaseURL)") + } + self.supabaseURL = supabaseURL self.supabaseKey = supabaseKey self.options = options storageURL = supabaseURL.appendingPathComponent("/storage/v1") databaseURL = supabaseURL.appendingPathComponent("/rest/v1") - realtimeURL = supabaseURL.appendingPathComponent("/realtime/v1") functionsURL = supabaseURL.appendingPathComponent("/functions/v1") defaultHeaders = [ @@ -99,6 +97,12 @@ public final class SupabaseClient: @unchecked Sendable { } ) + realtime = RealtimeClient( + supabaseURL.appendingPathComponent("/realtime/v1").absoluteString, + headers: defaultHeaders, + params: defaultHeaders + ) + listenForAuthEvents() } diff --git a/Tests/SupabaseTests/SupabaseClientTests.swift b/Tests/SupabaseTests/SupabaseClientTests.swift index 85ec0209..2d0e9cd7 100644 --- a/Tests/SupabaseTests/SupabaseClientTests.swift +++ b/Tests/SupabaseTests/SupabaseClientTests.swift @@ -20,7 +20,7 @@ final class SupabaseClientTests: XCTestCase { let customHeaders = ["header_field": "header_value"] let client = SupabaseClient( - supabaseURL: URL(string: "https://project-ref.supabase.co")!, + supabaseURL: "https://project-ref.supabase.co", supabaseKey: "ANON_KEY", options: SupabaseClientOptions( db: SupabaseClientOptions.DatabaseOptions(schema: customSchema), @@ -34,10 +34,8 @@ final class SupabaseClientTests: XCTestCase { XCTAssertEqual(client.supabaseURL.absoluteString, "https://project-ref.supabase.co") XCTAssertEqual(client.supabaseKey, "ANON_KEY") - // XCTAssertEqual(client.authURL.absoluteString, "https://project-ref.supabase.co/auth/v1") XCTAssertEqual(client.storageURL.absoluteString, "https://project-ref.supabase.co/storage/v1") XCTAssertEqual(client.databaseURL.absoluteString, "https://project-ref.supabase.co/rest/v1") - XCTAssertEqual(client.realtimeURL.absoluteString, "https://project-ref.supabase.co/realtime/v1") XCTAssertEqual( client.functionsURL.absoluteString, "https://project-ref.supabase.co/functions/v1"