chore: official supabase-swift (#22678)

* chore: remove community badge from supabase-swift

* chore: update realtime swift reference

* fix typo

* chore: update swift references

* chore: fix misspelling of behavior
This commit is contained in:
Guilherme Souza authored and GitHub committed 2024-04-16 00:01:01 +10:00
1 parent 03c85fb6ba
commit c7217582ab
13 files changed
+490 -274

No files matched your search

+9 -9
View File
@@ -111,6 +111,15 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td><a href="https://github.com/supabase/storage-dart" target="_blank" rel="noopener noreferrer">storage-dart</a></td>
<td><a href="https://github.com/supabase/functions-dart" target="_blank" rel="noopener noreferrer">functions-dart</a></td>
</tr>
<tr>
<td>Swift</td>
<td><a href="https://github.com/supabase/supabase-swift" target="_blank" rel="noopener noreferrer">supabase-swift</a></td>
<td><a href="https://github.com/supabase/supabase-swift/tree/main/Sources/PostgREST" target="_blank" rel="noopener noreferrer">postgrest-swift</a></td>
<td><a href="https://github.com/supabase/supabase-swift/tree/main/Sources/Auth" target="_blank" rel="noopener noreferrer">auth-swift</a></td>
<td><a href="https://github.com/supabase/supabase-swift/tree/main/Sources/Realtime" target="_blank" rel="noopener noreferrer">realtime-swift</a></td>
<td><a href="https://github.com/supabase/supabase-swift/tree/main/Sources/Storage" target="_blank" rel="noopener noreferrer">storage-swift</a></td>
<td><a href="https://github.com/supabase/supabase-swift/tree/main/Sources/Functions" target="_blank" rel="noopener noreferrer">functions-swift</a></td>
</tr>
<!-- /notranslate -->
<th colspan="7">💚 Community 💚</th>
<!-- notranslate -->
@@ -177,15 +186,6 @@ Our approach for client libraries is modular. Each sub-library is a standalone i
<td>-</td>
<td>-</td>
</tr>
<tr>
<td>Swift</td>
<td><a href="https://github.com/supabase-community/supabase-swift" target="_blank" rel="noopener noreferrer">supabase-swift</a></td>
<td><a href="https://github.com/supabase-community/postgrest-swift" target="_blank" rel="noopener noreferrer">postgrest-swift</a></td>
<td><a href="https://github.com/supabase-community/gotrue-swift" target="_blank" rel="noopener noreferrer">gotrue-swift</a></td>
<td><a href="https://github.com/supabase-community/realtime-swift" target="_blank" rel="noopener noreferrer">realtime-swift</a></td>
<td><a href="https://github.com/supabase-community/storage-swift" target="_blank" rel="noopener noreferrer">storage-swift</a></td>
<td><a href="https://github.com/supabase-community/functions-swift" target="_blank" rel="noopener noreferrer">functions-swift</a></td>
</tr>
<tr>
<td>Godot Engine (GDScript)</td>
<td><a href="https://github.com/supabase-community/godot-engine.supabase" target="_blank" rel="noopener noreferrer">supabase-gdscript</a></td>
@@ -112,6 +112,12 @@ export const HOMEPAGE_MENU_ITEMS: HomepageMenuItems = [
href: '/reference/dart/introduction',
level: 'reference_dart',
},
{
label: 'Swift',
icon: 'reference-swift',
href: '/reference/swift/introduction',
level: 'reference_swift',
},
{
label: 'Python',
icon: 'reference-python',
@@ -126,13 +132,6 @@ export const HOMEPAGE_MENU_ITEMS: HomepageMenuItems = [
level: 'reference_csharp',
community: true,
},
{
label: 'Swift',
icon: 'reference-swift',
href: '/reference/swift/introduction',
level: 'reference_swift',
community: true,
},
{
label: 'Kotlin',
icon: 'reference-kotlin',
@@ -13,6 +13,7 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
| --------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Javascript/Typescript | [supabase-js](https://github.com/supabase/supabase-js) | [Docs](https://supabase.com/docs/reference/javascript/introduction) |
| Dart/Flutter | [supabase-flutter](https://github.com/supabase/supabase-flutter/tree/main/packages/supabase_flutter) | [Docs](https://supabase.com/docs/reference/dart/introduction) |
| Swift | [supabase-swift](https://github.com/supabase/supabase-swift) | [Docs](https://supabase.com/docs/reference/swift/introduction) |
## Community libraries
@@ -23,5 +24,4 @@ Supabase provides client libraries for the REST and Realtime APIs. Some librarie
| Kotlin | [supabase-kt](https://github.com/supabase-community/supabase-kt) | [Docs](https://supabase.com/docs/reference/kotlin/introduction) |
| Python | [supabase-py](https://github.com/supabase-community/supabase-py) | [Docs](https://supabase.com/docs/reference/python/initializing) |
| Ruby | [supabase-rb](https://github.com/supabase-community/supabase-rb) | |
| Swift | [supabase-swift](https://github.com/supabase-community/supabase-swift) | [Docs](https://supabase.com/docs/reference/swift/introduction) |
| Godot Engine (GDScript) | [supabase-gdscript](https://github.com/supabase-community/godot-engine.supabase) | |
@@ -23,9 +23,9 @@ Let's start building the SwiftUI app from scratch.
Open Xcode and create a new SwiftUI project.
Add the [supabase-swift](https://github.com/supabase-community/supabase-swift) dependency.
Add the [supabase-swift](https://github.com/supabase/supabase-swift) dependency.
Add the `https://github.com/supabase-community/supabase-swift` package to your app. For instructions, see the [Apple tutorial on adding package dependencies](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app).
Add the `https://github.com/supabase/supabase-swift` package to your app. For instructions, see the [Apple tutorial on adding package dependencies](https://developer.apple.com/documentation/xcode/adding-package-dependencies-to-your-app).
Create a helper file to initialize the Supabase client.
You need the API URL and the `anon` key that you copied [earlier](#get-the-api-keys).
+63
View File
@@ -0,0 +1,63 @@
---
id: installing
title: 'Installing'
slug: installing
custom_edit_url: https://github.com/supabase/supabase/edit/master/web/spec/supabase.yml
---
### Install using Swift Package Manager
<RefSubLayout.EducationRow>
<RefSubLayout.Details>
You can install Supabase package using Swift Package Manager.
The package exposes multiple libraries, you can choose between adding all of them using Supabase, or some of:
- `Auth`
- `Realtime`
- `Postgrest`
- `Functions`
- `Storage`
</RefSubLayout.Details>
<RefSubLayout.Examples>
<Tabs
size="small"
type="underlined"
defaultActiveId="swift"
queryGroup="framework"
>
<TabPanel id="swift" label="Package.swift">
```swift
let package = Package(
...
dependencies: [
...
.package(
url: "https://github.com/supabase/supabase-swift.git",
from: "2.0.0"
),
],
targets: [
.target(
name: "YourTargetName",
dependencies: [
.product(
name: "Supabase", // Auth, Realtime, Postgrest, Functions, or Storage
package: "supabase-swift"
),
]
)
]
)
```
</TabPanel>
</Tabs>
</RefSubLayout.Examples>
</RefSubLayout.EducationRow>
+2 -14
View File
@@ -8,25 +8,13 @@ hideTitle: true
<IconMenuSwift width={35} height={35} />
<div className="flex flex-col gap-2">
<h1 className="text-3xl text-foreground m-0">Swift Client Library</h1>
<h2 className="text-base font-mono text-foreground-light">
@supabase-community/supabase-swift
</h2>
<h2 className="text-base font-mono text-foreground-light">@supabase/supabase-swift</h2>
</div>
</div>
{/* prettier-ignore */}
<div className="max-w-xl">
This reference documents every object and method available in Supabase's Swift library, [supabase-swift](https://github.com/supabase-community/supabase-swift). You can use supabase-swift to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
We also provide a [supabase](https://pub.dev/packages/supabase) package for non-Swift projects.
</div>
{/* prettier-ignore */}
<div className="max-w-xl bg-slate-300 px-4 py-2 rounded-md">
The Swift client library is created and maintained by the Supabase community, and is not an official library. Please be tolerant of areas where the library is still being developed, and — as with all the libraries — feel free to contribute wherever you find issues.
Huge thanks to official maintainers, [Guilherme](https://github.com/grdsdev) and [Maail](https://github.com/maail).
This reference documents every object and method available in Supabase's Swift library, [supabase-swift](https://github.com/supabase/supabase-swift). You can use supabase-swift to interact with your Postgres database, listen to database changes, invoke Deno Edge Functions, build login and user management functionality, and manage large files.
</div>
@@ -33,6 +33,7 @@
"reference_python_v2",
"reference_csharp_v0",
"reference_swift_v1",
"reference_swift_v2",
"reference_kotlin_v1",
"reference_kotlin_v2"
]
@@ -48,6 +49,7 @@
"reference_python_v2",
"reference_csharp_v0",
"reference_swift_v1",
"reference_swift_v2",
"reference_kotlin_v1",
"reference_kotlin_v2"
]
@@ -986,6 +988,7 @@
"reference_python_v2",
"reference_csharp_v0",
"reference_swift_v1",
"reference_swift_v2",
"reference_kotlin_v1",
"reference_kotlin_v2"
],
+398 -235
View File
@@ -92,7 +92,7 @@ functions:
- To fetch the currently logged-in user, refer to [`getUser()`](/docs/reference/swift/get-user).
examples:
- id: sign-up
name: Sign up
name: Sign up with email and password
isSpotlight: true
code: |
```swift
@@ -101,6 +101,30 @@ functions:
password: "example-password"
)
```
- id: sign-up-phone
name: Sign up with a phone number and password (SMS)
isSpotlight: true
code: |
```swift
try await supabase.auth.signUp(
phone: "123456789",
password: "example-password",
channel: "sms"
)
```
- id: sign-up-phone-whatsapp
name: Sign up with a phone number and password (whatsapp)
isSpotlight: true
description: |
The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature.
code: |
```swift
try await supabase.auth.signUp(
phone: "123456789",
password: "example-password",
channel: "whatsapp"
)
```
- id: sign-up-with-additional-user-metadata
name: Sign up with additional user metadata
isSpotlight: false
@@ -120,6 +144,7 @@ functions:
- id: sign-up-with-redirect
name: Sign up with a redirect URL
description: |
- You can provide a default redirect URL when initializing the client.
- See [redirect URLs and wildcards](/docs/guides/auth/overview#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
code: |
```swift
@@ -129,6 +154,69 @@ functions:
redirectTo: URL(string: "https://example.com/welcome")!
)
```
- id: on-auth-state-change
title: "onAuthStateChange()"
notes: |
- Subscribes to important events occurring on the user's session.
- Emitted events:
- `INITIAL_SESSION`
- Emitted right after the Supabase client is constructed and the initial session from storage is loaded.
- `SIGNED_IN`
- Emitted each time a user session is confirmed or re-established, including on user sign in.
- Avoid making assumptions as to when this event is fired, this may occur even when the user is already signed in. Instead, check the user object attached to the event to see if a new user has signed in and update your application's UI.
- `SIGNED_OUT`
- Emitted when the user signs out. This can be after:
- A call to `supabase.auth.signOut()`.
- After the user's session has expired for any reason:
- User has signed out on another device.
- The session has reached its timebox limit or inactivity timeout.
- User has signed in on another device with single session per user enabled.
- Check the [User Sessions](/docs/guides/auth/sessions) docs for more information.
- Use this to clean up any local storage your application has associated with the user.
- `TOKEN_REFRESHED`
- Emitted each time a new access and refresh token are fetched for the signed in user.
- It's best practice and highly recommended to extract the access token (JWT) and store it in memory for further use in your application.
- Avoid frequent calls to `supabase.auth.session` for the same purpose.
- There is a background process that keeps track of when the session should be refreshed so you will always receive valid tokens by listening to this event.
- The frequency of this event is related to the JWT expiry limit configured on your project.
- `USER_UPDATED`
- Emitted each time the `supabase.auth.update(user:)` method finishes successfully. Listen to it to update your application's UI based on new profile information.
- `PASSWORD_RECOVERY`
- Emitted instead of the `SIGNED_IN` event when the user lands on a page that includes a password recovery link in the URL.
- Use it to show a UI to the user where they can [reset their password](/docs/guides/auth/passwords#resetting-a-users-password-forgot-password).
examples:
- id: listen-to-auth-changes
name: Listen to auth changes
isSpotlight: true
code: |
```swift
// Using AsyncStream
for await (event, session) in await supabase.auth.authStateChanges {
print(event, session)
}
// Using Closure
let subscription = await supabase.auth.onAuthStateChange { event, session in
print(event, session)
}
// call remove() to remove subscription
subscription.remove()
```
description: |
- When using closure based, remember to call `remove()` on the returned subscription.
- When using AsyncStream, it automatically removes the subscription when AsyncStream is canceled, or finishes.
- id: list-to-a-specific-event
name: Listen to a specific event
code: |
```swift
for await (_, session) in await supabase.auth.authStateChanges
.filter({ $0.event == .signedIn }) {
// handle signIn event.
}
```
- id: sign-in-anonymously
title: "signInAnonymously()"
notes: |
@@ -187,14 +275,14 @@ functions:
- id: sign-in-with-otp
title: "signInWithOTP()"
notes: |
- Requires either an email or phone number.
- This method is used for passwordless sign-ins where a OTP is sent to the user's email or phone number.
- If the user doesn't exist, `signInWithOTP()` will signup the user instead. To restrict this behavior, you can set `shouldCreateUser` to `false`.
- If the user doesn't exist, `signInWithOTP()` will signup the user instead. To restrict this behavior, you can set `shouldCreateUser` to `false``.
- If you're using an email, you can configure whether you want the user to receive a magiclink or a OTP.
- If you're using phone, you can configure whether you want the user to receive a OTP.
- The magic link's destination URL is determined by the [`SITE_URL`](/docs/guides/auth/concepts/redirect-urls).
- See [redirect URLs and wildcards](/docs/guides/auth#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
- Magic links and OTPs share the same implementation. To send users a one-time code instead of a magic link, [modify the magic link email template](/dashboard/project/_/auth/templates) to include `{{ .Token }}` instead of `{{ .ConfirmationURL }}`.
- When using magic links, specify a `redirectTo` that matches a configured url scheme in your iOS app, so Supabase can correctly redirect back to your app.
- See our [Twilio Phone Auth Guide](/docs/guides/auth/phone-login/twilio) for details about configuring WhatsApp sign in.
examples:
- id: sign-in-with-email
@@ -216,13 +304,55 @@ functions:
```swift
try await supabase.auth.signInWithOTP(phone: "+13334445555")
```
- id: sign-in-with-whatsapp-otp
name: Sign in with WhatsApp OTP
isSpotlight: false
description: The user will be sent a WhatsApp message which contains a OTP. By default, a given user can only request a OTP once every 60 seconds. Note that a user will need to have a valid WhatsApp account that is linked to Twilio in order to use this feature.
code: |
```swift
try await supabase.auth.signInWithOTP(
phone: "+13334445555",
channel: "whatsapp"
)
```
- id: sign-in-with-oauth
title: "getOAuthSignInURL()"
title: "signInWithOAuth()"
notes: |
- This method is used for signing in using a third-party provider.
- Supabase supports many different [third-party providers](https://supabase.com/docs/guides/auth#providers).
examples:
- id: sign-in-using-a-third-party-provider
- id: sign-in-using-ASWebAuthenticationSession
name: Sign in with OAuth using ASWebAuthenticationSession
isSpotlight: true
description: |
- Use `configure` parameter to customize the `ASWebAuthenticationSession`
code: |
```swift
let session = try await supabase.auth.signInWithOAuth(
provider: .github
) { (session: ASWebAuthenticationSession) in
// customize session
}
```
- id: sign-in-using-generic-flow
name: Sign in with OAuth and customize flow
isSpotlight: true
description: |
- Use `launchFlow` parameter to customize the flow.
code: |
```swift
let session = try await supabase.auth.signInWithOAuth(
provider: .github
) { url in
// use url to start OAuth flow
// and return a result url that contains the OAuth token.
// ...
return resultURL
}
```
- id: sign-in-using-manual-implementation
name: Sign in using a third-party provider
isSpotlight: true
description: |
@@ -231,7 +361,7 @@ functions:
- When using `ASWebAuthenticationSession` or any other implementation, use the returning URL as input to `session(from:)` method.
code: |
```swift
let url = try await supabase.auth.getOAuthSignInURL(provider: .github)
let url = try await supabase.auth.getOAuthSignInURL(provider: .github, redirectTo: URL(string: "my-app-scheme://"))
let session = ASWebAuthenticationSession(url: url, callbackURLScheme: "my-app-scheme") { url, error in
guard let url else { return }
@@ -246,21 +376,6 @@ functions:
session.start()
```
- id: sign-in-using-a-third-party-provider-with-redirect
name: Sign in using a third-party provider with redirect
isSpotlight: false
description: |
- When the third-party provider successfully authenticates the user, the provider redirects the user to the URL specified in the `redirectTo` parameter. This parameter defaults to the [`SITE_URL`](/docs/guides/auth/concepts/redirect-urls). It does not redirect the user immediately after invoking this method.
- See [redirect URLs and wildcards](/docs/guides/auth/overview#redirect-urls-and-wildcards) to add additional redirect URLs to your project.
- getOAuthSignInURL() provides the URL which needs to be opened in a SFSafariViewController instance.
- The redirectTo URL needs to be setup correctly in your project under Authentication -> URL Configuration -> Redirect URLs.
code: |
```swift
let url = try await supabase.auth.getOAuthSignInURL(
provider: .google,
redirectTo: URL(string: "https://example.com/welcome")!
)
```
- id: sign-in-with-scopes
name: Sign in with scopes
isSpotlight: false
@@ -269,7 +384,7 @@ functions:
You may also need to specify the scopes in the provider's OAuth app settings, depending on the provider. The list of scopes will be documented by the third-party provider you are using and specifying scopes will enable you to use the OAuth provider token to call additional APIs supported by the third-party provider to get more information.
code: |
```swift
let url = try await supabase.auth.getOAuthSignInURL(
let url = try await supabase.auth.signInWithOAuth(
provider: .github,
scopes: "repo gist notifications"
)
@@ -290,6 +405,45 @@ functions:
)
)
```
- id: sign-in-with-sso
title: 'signInWithSSO()'
notes: |
- Before you can call this method you need to [establish a connection](/docs/guides/auth/sso/auth-sso-saml#managing-saml-20-connections) to an identity provider. Use the [CLI commands](/docs/reference/cli/supabase-sso) to do this.
- If you've associated an email domain to the identity provider, you can use the `domain` property to start a sign-in flow.
- In case you need to use a different way to start the authentication flow with an identity provider, you can use the `providerId` property. For example:
- Mapping specific user email addresses with an identity provider.
- Using different hints to identity the identity provider to be used by the user, like a company-specific page, IP address or other tracking information.
examples:
- id: sign-in-with-domain
name: Sign in with email domain
isSpotlight: true
code: |
```swift
// You can extract the user's email domain and use it to trigger the
// authentication flow with the correct identity provider.
let url = try await await supabase.auth.signInWithSSO{
domain: "company.com"
}
// Open the URL using your preferred method to complete sign-in process.
UIApplication.shared.open(url)
```
- id: sign-in-with-provider-uuid
name: Sign in with provider UUID
isSpotlight: true
code: |
```swift
// Useful when you need to map a user's sign in request according
// to different rules that can't use email domains.
let url = try await supabase.auth.signInWithSSO{
providerId: "21648a9d-8d5a-4555-a9d1-d6375dc14e92"
}
// Open the URL using your preferred method to complete sign-in process.
UIApplication.shared.open(url)
```
- id: sign-out
title: "signOut()"
notes: |
@@ -410,6 +564,30 @@ functions:
```swift
let identities = try await supabase.auth.userIdentities()
```
- id: unlink-identity
title: 'unlinkIdentity()'
notes: |
- The **Enable Manual Linking** option must be enabled from your [project's authentication settings](/dashboard/project/_/settings/auth).
- The user needs to be signed in to call `unlinkIdentity()`.
- The user must have at least 2 identities in order to unlink an identity.
- The identity to be unlinked must belong to the user.
examples:
- id: unlink-identity
name: Unlink an identity
isSpotlight: true
code: |
```swift
// retrieve all identites linked to a user
let identities = try await supabase.auth.userIdentities()
// find the google identity
let googleIdentity = identities.first {
$0.provider == .google
}
// unlink the google identity
try await supabase.auth.unlinkIdentity(googleIdentity)
```
- id: send-password-reauthentication
title: "reauthenticate()"
notes: |
@@ -512,29 +690,7 @@ functions:
```swift
let session = try await supabase.auth.refreshSession(refreshToken: "custom-refresh-token")
```
- id: on-auth-state-change
title: "authStateChanges"
notes: |
- Types of auth events: `INITIAL_SESSION`, `SIGNED_IN`, `SIGNED_OUT`, `TOKEN_REFRESHED`, `USER_UPDATED`, `PASSWORD_RECOVERY`, `MFA_CHALLENGE_VERIFIED`
- The `INITIAL_SESSION` can be used to allow you to invoke the callback function when `authStateChanges` is first called.
examples:
- id: listen-to-auth-changes
name: Listen to auth changes
isSpotlight: true
code: |
```swift
for await (event, session) in await supabase.auth.authStateChanges {
print(event, session)
}
```
- id: list-to-a-specific-event
name: Listen to a specific event
code: |
```swift
for await (_, session) in await supabase.auth.authStateChanges.filter({ $0.event == .signedIn }) {
// handle signIn event.
}
```
- id: exchange-code-for-session
title: "exchangeCodeForSession()"
notes: |
@@ -679,6 +835,41 @@ functions:
```swift
let factors = try await supabase.auth.mfa.listFactors()
```
- id: admin-api
title: 'Overview'
notes: |
- Any method under the `supabase.auth.admin` namespace requires a `service_role` key.
- These methods are considered admin methods and should be called on a trusted server. Never expose your `service_role` key in the browser.
examples:
- id: create-auth-admin-client
name: Create server-side auth client
isSpotlight: true
code: |
```swift
import Supabase
let supabase = SupabaseClient(
supabaseURL: supabaseURL,
supabaseKey: serviceRoleKey
)
// Access auth admin api
let adminAuthClient = supabase.auth.admin
```
- id: delete-user
title: 'deleteUser()'
notes: |
- The `deleteUser()` method requires the user's ID, which maps to the `auth.users.id` column.
examples:
- id: removes-a-user
name: Removes a user
isSpotlight: true
code: |
```swift
try await supabase.auth.admin.deleteUser(
id: "715ed5db-f090-4b8c-a067-640ecee36aa0"
)
```
- id: select
title: "Fetch data: select()"
notes: |
@@ -2899,133 +3090,140 @@ functions:
isSpotlight: true
code: |
```swift
let channel = supabase
.realtime
.channel("room1")
let channel = await supabase.channel("room1")
channel
.on("broadcast", filter: ChannelFilter(event: "cursor-pos")) { message in
print("Cursor position received!", message.payload)
}
.subscribe { status, error in
if status == .subscribed {
Task {
await channel.send(
type: .broadcast,
event: "cursor-pos",
payload: ["x": Double.random(in: 0...1), "y": Double.random(in: 0...1)]
)
}
}
let broadcastStream = await channel.broadcastStream(event: "cursor-pos")
await channel.subscribe()
Task {
for await message in broadcastMessage {
print("Cursor position received", message.payload)
}
}
Task {
await channel.broadcast(
event: "cursor-pos",
message: [
"x": .double(.random(in: 0...1)),
"y": .double(.random(in: 0...1))
]
)
}
```
- id: listen-to-presence-sync
name: Listen to presence sync
isSpotlight: true
- id: listen-to-presence-updates
name: Listen to presence updates
code: |
```swift
let channel = supabase.realtime.channel("room1")
channel
.on("presence", filter: ChannelFilter(event: "sync")) { _ in
print("Synced presence state: ", channel.presenceState())
struct PresenceState: Codable {
let username: String
}
let channel = await supabase.channel("channelId")
let presenceChange = await channel.presenceChange()
await channel.subscribe()
Task {
for await presence in presenceChange {
let joins = try presence.decodeJoins(as: PresenceState.self)
let leaves = try presence.decodeLeaves(as: PresenceState.self)
}
.subscribe { status, error in
if status == .subscribed {
Task {
await channel.track(["online_at": Date().ISO8601Format()])
}
}
}
```
- id: listen-to-presence-join
name: Listen to presence join
isSpotlight: true
code: |
```swift
let channel = supabase.realtime.channel("room1")
channel
.on("presence", filter: ChannelFilter(event: "join")) { message in
print("Newly joined presences: ", message.payload)
}
.subscribe { status, error in
if status == .subscribed {
Task {
await channel.track(["online_at": Date().ISO8601Format()])
}
}
}
```
- id: listen-to-presence-leave
name: Listen to presence leave
isSpotlight: true
code: |
```swift
let channel = supabase.realtime.channel("room1")
channel
.on("presence", filter: ChannelFilter(event: "leave")) { message in
print("Newly left presences: ", message.payload)
}
.subscribe { status, error in
if status == .subscribed {
Task {
await channel.track(["online_at": Date().ISO8601Format()])
await channel.untrack()
}
}
}
```
}
// Send your own state
Task {
try await channel.track(PresenceState(username: "John"))
}
- id: listen-to-all-database-changes
name: Listen to all database changes
isSpotlight: true
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "*", schema: "*")) { message in
print("Change received!", message.payload)
let channel = await supabase.channel("channelId")
let changeStream = await channel.postgresChange(AnyAction.self, schema: "public")
await channel.subscribe()
for await change in changeStream {
switch change {
case .delete(let action): print("Deleted: \(action.oldRecord)")
case .insert(let action): print("Inserted: \(action.record)")
case .select(let action): print("Selected: \(action.record)")
case .update(let action): print("Updated": \(action.oldRecord) with \(action.record)")
}
.subscribe()
}
```
- id: listen-to-a-specific-table
name: Listen to a specific table
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "*", schema: "public", table: "countries")) { message in
print("Change received!", message.payload)
let channel = await supabase.channel("channelId")
let changeStream = await channel.postgresChange(
AnyAction.self,
schema: "public",
table: "users"
)
await channel.subscribe()
for await change in changeStream {
switch change {
case .delete(let action): print("Deleted: \(action.oldRecord)")
case .insert(let action): print("Inserted: \(action.record)")
case .select(let action): print("Selected: \(action.record)")
case .update(let action): print("Updated": \(action.oldRecord) with \(action.record)")
}
.subscribe()
}
```
- id: listen-to-inserts
name: Listen to inserts
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "INSERT", schema: "public", table: "countries")) { message in
print("Change received!", message.payload)
}
.subscribe()
let channel = await supabase.channel("channelId")
let insertions = await channel.postgresChange(
InsertAction.self,
schema: "public",
table: "users"
)
await channel.subscribe()
for await insert in insertions {
print("Inserted: \(insert.record)")
}
```
- id: listen-to-updates
name: Listen to updates
description: |
By default, Supabase will send only the updated record. If you want to receive the previous values as well you can
enable full replication for the table you are listening to:
enable full replication for the table you are listening too:
```sql
alter table "your_table" replica identity full;
```
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "UPDATE", schema: "public", table: "countries")) { message in
print("Change received!", message.payload)
}
.subscribe()
```
let channel = await supabase.channel("channelId")
let updates = await channel.postgresChange(
UpdateAction.self,
schema: "public",
table: "users"
)
await channel.subscribe()
for await update in updates {
print("Updated: \(update.oldRecord) with \(update.record)")
}
```
- id: listen-to-deletes
name: Listen to deletes
description: |
@@ -3037,131 +3235,96 @@ functions:
```
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "DELETE", schema: "public", table: "countries")) { message in
print("Change received!", message.payload)
}
.subscribe()
```
- id: listen-to-multiple-events
name: Listen to multiple events
description: You can chain listeners if you want to listen to multiple events for each table.
code: |
```swift
supabase.realtime
.channel("room1")
.on("postgres_changes", filter: ChannelFilter(event: "INSERT", schema: "public", table: "countries"), handler: handleRecordInserted)
.on("postgres_changes", filter: ChannelFilter(event: "DELETE", schema: "public", table: "countries"), handler: handleRecordDeleted)
.subscribe()
let channel = await supabase.channel("channelId")
func handleRecordInserted(_ message: Message) {
// handle message
}
let deletions = await channel.postgresChange(
DeleteAction.self,
schema: "public",
table: "users"
)
func handleRecordDeleted(_ message: Message) {
// handle message
await channel.subscribe()
for await deletion in deletions {
print("Deleted: \(deletion.oldRecord)")
}
```
- id: listening-to-row-level-changes
name: Listen to row level changes
description: You can listen to individual rows using the format `{table}:{col}=eq.{val}` - where `{col}` is the column name, and `{val}` is the value which you want to match.
notes: |
- ``eq`` filter works with all database types as under the hood, it's casting both the filter value and the database value to the correct type and then comparing them.
code: |
```swift
supabase.realtime
.channel("room1")
.on(
"postgres_changes",
filter: ChannelFilter(
event: "INSERT",
schema: "public",
table: "countries",
filter: "id=eq.200"
),
handler: handleRecordInserted
)
.subscribe()
let channel = await supabase.channel("channelId")
func handleRecordInserted(_ message: Message) {
// handle message
}
```
- id: broadcast-message
title: broadcastMessage()
description: |
Broadcast a message to all connected clients to a channel.
notes: |
- When using REST you don't need to subscribe to the channel
examples:
- id: send-a-message
name: Send a message via websocket
isSpotlight: true
code: |
```swift
supabase.realtime
.channel("room1")
.subscribe { status, error in
if status == .subscribed {
Task {
await channel.send(
type: "broadcast",
event: "cursor-pos",
payload: ["x": Double.random(in: 0...1), "y": Double.random(in: 0...1)]
)
}
}
}
```
- id: send-a-message-via-rest
name: Send a message via REST
isSpotlight: true
code: |
```swift
await supabase.realtime
.channel("room1")
.send(
type: "broadcast",
event: "cursor-pos",
payload: ["x": Double.random(in: 0...1), "y": Double.random(in: 0...1)]
)
```
- id: get-channels
title: channels
examples:
- id: get-all-channels
name: Get all channels
isSpotlight: true
code: |
```swift
let channels = supabase.realtime.channels
let deletions = await channel.postgresChange(
DeleteAction.self,
schema: "public",
table: "users",
filter: "id=eq.1"
)
await channel.subscribe()
for await deletion in deletions {
print("Deleted: \(deletion.oldRecord)")
}
```
- id: remove-channel
title: removeChannel()
description: |
Unsubscribes and removes Realtime channel from Realtime client.
title: "removeChannel()"
notes: |
- Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
- Removing a channel is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes.
- Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
- If you removed all channels, the client automatically disconnects from the Realtime websocket. This can be disabled in the Realtime config by setting `disconnectOnNoSubscriptions` to false.
examples:
- id: removes-a-channel
name: Removes a channel
name: Remove a channel
isSpotlight: true
code: |
```swift
supabase.realtime.remove(myChannel)
```
let channel = await supabase.channel("channelId")
//...
await supabase.removeChannel(channel)
```
- id: unsubscribe-channel
name: Unsubscribe from a channel
isSpotlight: true
code: |
```swift
let channel = await supabase.channel("channelId")
//...
await channel.unsubscribe()
```
- id: remove-all-channels
title: removeAllChannels()
$ref: "@supabase/supabase-js.index.SupabaseClient.removeAllChannels"
notes: |
Unsubscribes and removes all Realtime channels from Realtime client.
- Removing channels is a great way to maintain the performance of your project's Realtime service as well as your database if you're listening to Postgres changes. Supabase will automatically handle cleanup 30 seconds after a client is disconnected, but unused channels may cause degradation as more clients are simultaneously subscribed.
- If you removed all channels, the client automatically disconnects from the Realtime websocket. This can be disabled in the Realtime config by setting `disconnectOnNoSubscriptions` to false.
examples:
- id: remove-all-channels
name: Remove all channels
isSpotlight: true
code: |
```swift
supabase.realtime.removeAllChannels()
await supabase.removeAllChannels()
```
- id: get-channels
title: getChannels()
$ref: "@supabase/supabase-js.index.SupabaseClient.getChannels"
notes: |
Returns all Realtime channels.
examples:
- id: get-all-channels
name: Get all channels
isSpotlight: true
code: |
```swift
let channels = await supabase.channels
```
- id: list-buckets
@@ -30,10 +30,10 @@ export const CLIENT_LIBRARIES = [
},
{
language: 'Swift',
officialSupport: false,
officialSupport: true,
releaseState: undefined,
docsUrl: 'https://supabase.com/docs/reference/swift/initializing',
gitUrl: 'https://github.com/supabase-community/supabase-swift',
gitUrl: 'https://github.com/supabase/supabase-swift',
},
{
language: 'Kotlin',
@@ -148,7 +148,7 @@ It’s becoming easier to build applications with any language.
In the past few months, the community has rallied and shipped 3 new client libraries, complete with Docs:
- Swift:
- [Documentation](/docs/reference/swift/introduction) | [Source Code](https://github.com/supabase-community/supabase-swift)
- [Documentation](/docs/reference/swift/introduction) | [Source Code](https://github.com/supabase/supabase-swift)
- Shout-out to: [grsouza](https://github.com/grsouza) & [@maail](https://github.com/maail)
- Python:
- [Documentation](/docs/reference/python/initializing) | [Source Code](https://github.com/supabase-community/supabase-py)
@@ -412,7 +412,7 @@
/* Begin XCRemoteSwiftPackageReference section */
79A039C42B2B8EC20031D573 /* XCRemoteSwiftPackageReference "supabase-swift" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/supabase-community/supabase-swift";
repositoryURL = "https://github.com/supabase/supabase-swift";
requirement = {
kind = upToNextMajorVersion;
minimumVersion = 2.0.0;
@@ -13,7 +13,7 @@
{
"identity" : "supabase-swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/supabase-community/supabase-swift",
"location" : "https://github.com/supabase/supabase-swift",
"state" : {
"revision" : "1a7dad006f94749923e764343aaaeadbe74f0352",
"version" : "2.6.0"
@@ -217,7 +217,7 @@ export const CLIENT_LIBRARIES = [
libraries: [
{
name: 'supabase-swift',
url: 'https://github.com/supabase-community/supabase-swift',
url: 'https://github.com/supabase/supabase-swift',
},
{
name: 'postgrest-swift',