Skip to content

Commit fddfd36

Browse files
authored
docs: update README (#153)
1 parent 70dc479 commit fddfd36

File tree

1 file changed

+25
-311
lines changed

1 file changed

+25
-311
lines changed

README.md

Lines changed: 25 additions & 311 deletions
Original file line numberDiff line numberDiff line change
@@ -4,34 +4,19 @@
44

55
Supabase client for swift. Mirrors the design of [supabase-js](https://github.com/supabase/supabase-js/blob/master/README.md).
66

7-
## Contents
8-
- [Installation](#installation)
9-
- [Usage](#usage)
10-
- [Login Implementation](#login-implementation)
11-
- [Social Login Implementation](#social-login-implementation)
12-
- [Setup Callback URL](#setup-callback-url)
13-
- [Google Sign In](#google-sign-in)
14-
- [Apple Sign In](#apple-sign-in)
15-
- [Other Social Logins](#other-social-logins)
16-
- [Basic CRUD Implementation](#basic-crud-implementation)
17-
- [Insert Data](#insert-data)
18-
- [Select Data](#select-data)
19-
- [Contributing](#contributing)
20-
- [Sponsors](#sponsors)
7+
* Documentation: [https://supabase.com/docs/reference/swift/introduction](https://supabase.com/docs/reference/swift/introduction)
218

22-
---
239

24-
## Installation
10+
## Usage
2511

26-
Swift Package Manager:
12+
Install the library using the Swift Package Manager.
2713

28-
Add the following lines to your `Package.swift` file:
2914
```swift
3015
let package = Package(
3116
...
3217
dependencies: [
3318
...
34-
.package(name: "Supabase", url: "https://github.com/supabase/supabase-swift.git", branch: "master"), // Add the package
19+
.package(name: "Supabase", url: "https://github.com/supabase/supabase-swift.git", from: "1.0.0"), // Add the package
3520
],
3621
targets: [
3722
.target(
@@ -44,306 +29,35 @@ let package = Package(
4429

4530
If you're using Xcode, [use this guide](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) to add `supabase-swift` to your project. Use `https://github.com/supabase/supabase-swift.git` for the url when Xcode asks.
4631

47-
## Usage
32+
If you don't want the full Supabase environment, you can also add individual packages, such as `Functions`, `GoTrue`, `Realtime`, `Storage`, or `PostgREST`.
4833

49-
To make requests to the `Supabase` database, you will need to initialize a `SupabaseClient` object:
34+
Then you're able to import the package and establish the connection with the database.
5035

5136
```swift
52-
let client = SupabaseClient(supabaseURL: "{ Supabase URL }", supabaseKey: "{ Supabase anonymous Key }")
37+
/// Create a single supabase client for interacting with your database
38+
let client = SupabaseClient(supabaseURL: URL(string: "https://xyzcompany.supabase.co")!, supabaseKey: "public-anon-key")
5339
```
5440

55-
## Login Implementation
56-
57-
Inside the `SupabaseClient` instance created before, you can find an `auth` property of type `GoTrueClient`. You can use it to perform sign in and sign up requests.
58-
59-
- Here's how to sign up with an email and password and get the signed in user `Session` info:
41+
### Initialize with custom options
6042

6143
```swift
62-
Task {
63-
do {
64-
try await client.auth.signUp(email: email, password: password)
65-
let session = try await client.auth.session
66-
print("### Session Info: \(session)")
67-
} catch {
68-
print("### Sign Up Error: \(error)")
69-
}
70-
}
71-
```
72-
73-
If you wish to add metadata for the user, you can pass it as part of the `data` parameter, just be sure to `import GoTrue` first to use the User metadata values.
74-
75-
```swift
76-
Task {
77-
do {
78-
try await client.auth.signUp(
79-
email: email,
80-
password: password,
81-
data: [
82-
"name": .string("John Doe"),
83-
"age": .number(25),
84-
"some_boolean_parameter": .bool(true)
85-
]
86-
)
87-
88-
let session = try await client.auth.session
89-
print("### Session Info: \(session)")
90-
} catch {
91-
print("### Sign Up Error: \(error)")
92-
}
93-
}
94-
```
95-
96-
- For existing users, here's how to log in with an email and password and get the logged in user `Session` info:
97-
98-
```swift
99-
Task {
100-
do {
101-
try await client.auth.signIn(email: email, password: password)
102-
let session = try await client.auth.session
103-
print("### Session Info: \(session)")
104-
} catch {
105-
print("### Sign Up Error: \(error)")
106-
}
107-
}
108-
```
109-
110-
## Social Login Implementation
111-
112-
### Setup Callback URL
113-
114-
We need to first set up the callback URL for all Social Logins inside the app.
115-
116-
- Setup the callback `URL` on `Info.plist`:
117-
118-
```xml
119-
<array>
120-
<dict>
121-
<key>CFBundleTypeRole</key>
122-
<string>Editor</string>
123-
<key>CFBundleURLSchemes</key>
124-
<array>
125-
<string>app.yourapp://login-callback</string>
126-
</array>
127-
</dict>
128-
</array>
129-
```
130-
131-
- Add this callback `URL` on `Supabase` under `Authentication -> URL Configuration -> Redirect URLs`.
132-
133-
### Google Sign In
134-
135-
- Setup Google Auth as per [Supabase's Documentation](https://supabase.com/docs/guides/auth/social-login/auth-google).
136-
- Note: For iOS we still need to use Google Consent Form for Web.
137-
- Import `SafariServices` in your `ViewController` and create a `SFSafariViewController` instance:
138-
139-
```swift
140-
import SafariServices
141-
142-
var safariVC: SFSafariViewController?
143-
```
144-
145-
- Get the `URL` for Google Sign in from `Supabase` and load it on `SFSafariViewController`.
146-
- Pass the previous callback `URL` you set up in the `redirecTo` parameter:
147-
148-
```swift
149-
Task {
150-
do {
151-
let url = try await client.auth.getOAuthSignInURL(provider: Provider.google, redirectTo: URL(string: {Your Callback URL})!)
152-
safariVC = SFSafariViewController(url: url as URL)
153-
self.present(safariVC!, animated: true, completion: nil)
154-
} catch {
155-
print("### Google Sign in Error: \(error)")
156-
}
157-
}
158-
```
159-
160-
- Handle the callback `URL` on `SceneDelegate` (for older projects, you can use `AppDelegate` if `SceneDelegate` is not present).
161-
- Post a `NotificationCenter` call to let the `ViewController` know the callback has been fired and pass the `URL` received. This `URL` will be used to get the user session.
162-
163-
```swift
164-
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
165-
if let url = URLContexts.first?.url as? URL {
166-
if url.host == "login-callback" {
167-
let urlDict: [String: URL] = ["url": url]
168-
NotificationCenter.default.post(name: Notification.Name("OAuthCallBack"), object: nil, userInfo: urlDict)
169-
}
170-
}
171-
}
172-
```
173-
174-
- In your `ViewController`, observe for the `Notification` and handle it minimizing the `SFSafariViewController` and getting the session:
175-
176-
```swift
177-
NotificationCenter.default.addObserver(
178-
self,
179-
selector: #selector(self.oAuthCallback(_:)),
180-
name: NSNotification.Name(rawValue: "OAuthCallBack"),
181-
object: nil)
182-
183-
@objc func oAuthCallback(_ notification: NSNotification){
184-
guard let url = notification.userInfo?["url"] as? URL else { return }
185-
Task {
186-
do {
187-
let session = try await SupaBaseAuth().client.session(from: url)
188-
print("### Session Info: \(session)")
189-
} catch {
190-
print("### oAuthCallback error: \(error)")
191-
}
192-
}
193-
safariVC?.dismiss(animated: true)
194-
}
195-
```
196-
197-
### Apple Sign In
198-
199-
- Setup Apple Auth as per [Supabase's Documentation](https://supabase.com/docs/guides/auth/social-login/auth-apple).
200-
- For Sign in with Apple follow the above as per Google Sign In and just replace the provider.
201-
- Once the user moves to the `SFSafariViewController`, an Apple native pop-up will slide up to continue with the sign in.
202-
203-
```swift
204-
Task {
205-
do {
206-
let url = try await client.auth.getOAuthSignInURL(provider: **Provider.apple**, redirectTo: URL(string: {Your Callback URL})!)
207-
safariVC = SFSafariViewController(url: url as URL)
208-
self.present(safariVC!, animated: true, completion: nil)
209-
} catch {
210-
print("### Apple Sign in Error: \(error)")
211-
}
212-
}
213-
```
214-
215-
### Other Social Logins
216-
217-
- If using a WebViews, other social logins will be similar to above. Just follow the [Supabase's Documentation](https://supabase.com/docs/guides/auth/) for their setup.
218-
219-
## Basic CRUD Implementation
220-
221-
First, import and initialize `SupabaseClient`, as explained in "Usage" section.
222-
223-
### Insert Data
224-
225-
- You can either use `Codable` or `Encodable` and `Decodable` protocols for the model's struct. However without either, you will get an error saying `Cannot convert value of type 'Void' to specified type 'InsertModel'` when trying to cast the response to your model.
226-
- Create a model which follows your table's data structure:
227-
228-
229-
```swift
230-
struct InsertModel: Encodable, Decodable {
231-
let id: Int? // you can choose to omit this depending on how you've setup your table
232-
let title: String?
233-
let desc: String?
234-
}
235-
236-
let insertData = InsertModel(title: "Test", desc: "Test Desc")
237-
let query = client.database
238-
.from("{ Your Table Name }")
239-
.insert(values: insertData,
240-
returning: .representation) // you will need to add this to return the added data
241-
.select(columns: "id") // specifiy which column names to be returned. Leave it empty for all columns
242-
.single() // specify you want to return a single value.
243-
244-
Task {
245-
do {
246-
let response: [InsertModel] = try await query.execute().value
247-
print("### Returned: \(response)")
248-
} catch {
249-
print("### Insert Error: \(error)")
250-
}
251-
}
252-
```
253-
254-
### Select Data
255-
256-
- Using the same model as before:
257-
258-
```swift
259-
let insertData = InsertModel(title: "Test", desc: "Test Desc")
260-
let query = client.database
261-
.from("{ Your Table Name }")
262-
.select() // keep it empty for all, else specify returned data
263-
.match(query: ["title" : insertData.title, "desc": insertData.desc])
264-
.single()
265-
266-
Task {
267-
do {
268-
let response: [InsertModel] = try await query.execute().value
269-
print("### Returned: \(response)")
270-
} catch {
271-
print("### Select Error: \(error)")
272-
}
273-
}
274-
```
275-
276-
### Update Data
277-
278-
- Using the same model as before:
279-
280-
```swift
281-
// Assuming the record above was inserted with id 1
282-
let updateData = InsertModel(id: 1, title: "Test Edited", desc: "Test Desc Edited")
283-
let query = client.database
284-
.from("{ Your Table Name }")
285-
.update(values: updateData,
286-
returning: .representation) // you will need to add this to return the updated data
287-
.select(columns: "id") // specifiy which column names to be returned. Leave it empty for all columns
288-
.single() // specify you want to return a single value.
289-
290-
Task {
291-
do {
292-
let response: [InsertModel] = try await query.execute().value
293-
print("### Returned: \(response)")
294-
} catch {
295-
print("### Update Error: \(error)")
296-
}
297-
}
298-
```
299-
300-
### Delete Data
301-
302-
```swift
303-
let query = client.database
304-
.from("{ Your Table Name }")
305-
.delete(returning: .representation) // you will need to add this to return the deleted data
306-
.match(
307-
query: ["id" : 1] // assuming the record above was inserted with id 1
308-
// You can add additional conditions here
309-
)
310-
.select() // specifiy which column names to be returned. Leave it empty for all columns
311-
.single()
312-
313-
Task {
314-
do {
315-
let response: [InsertModel] = try await query.execute().value
316-
print("### Returned: \(response)")
317-
} catch {
318-
print("### Delete Error: \(error)")
319-
}
320-
}
321-
```
322-
323-
## Postgres Functions
324-
325-
- Unlike the JavaScript library, you can't use the `rpc` method on the `SupabaseClient`, instead you need to use the `rpc` method on the `PostgresClient`:
326-
327-
```swift
328-
struct YourFunctionNameParams: Codable {
329-
let param1: String
330-
let param2: String
331-
}
332-
333-
let query = client.database.rpc(
334-
fn: "your_function_name",
335-
params: YourFunctionNameParams(param1: "param1", param2: "param2")
44+
let client = SupabaseClient(
45+
supabaseURL: URL(string: "https://xyzcompany.supabase.co")!,
46+
supabaseKey: "public-anon-key",
47+
options: SupabaseClientOptions(
48+
db: .init(
49+
schema: "public"
50+
),
51+
auth: .init(
52+
storage: MyCustomLocalStorage(),
53+
flowType: .pkce
54+
),
55+
global: .init(
56+
headers: ["x-my-custom-header": "my-app-name"],
57+
session: URLSession.myCustomSession
58+
)
59+
)
33660
)
337-
// Like in Supabase-js, you can use the `.single` method to return a single value.
338-
339-
Task {
340-
do {
341-
let response: [DataModel] = try await query.execute().value // Where DataModel is the model of the data returned by the function
342-
print("### Returned: \(response)")
343-
} catch {
344-
print("### RPC Error: \(error)")
345-
}
346-
}
34761
```
34862

34963
## Contributing

0 commit comments

Comments
 (0)