Skip to content

Commit ad08d19

Browse files
committed
refactor: improve AuthClient session initialization and add Alamofire migration guide
- Refactor AuthClient session initialization to use explicit adapters array - Add comprehensive Alamofire migration guide documenting breaking changes - Improve code readability and maintainability
1 parent 9c344d1 commit ad08d19

File tree

2 files changed

+337
-6
lines changed

2 files changed

+337
-6
lines changed

ALAMOFIRE_MIGRATION_GUIDE.md

Lines changed: 329 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,329 @@
1+
# Supabase Swift SDK - Alamofire Migration Guide
2+
3+
This guide covers the breaking changes introduced when migrating the Supabase Swift SDK from URLSession to Alamofire for HTTP networking.
4+
5+
## Overview
6+
7+
The migration to Alamofire introduces breaking changes in how modules are initialized and configured. The primary change is replacing custom `FetchHandler` closures with Alamofire `Session` instances across all modules.
8+
9+
## Breaking Changes by Module
10+
11+
### 🔴 AuthClient
12+
13+
**Before (URLSession-based):**
14+
```swift
15+
let authClient = AuthClient(
16+
url: authURL,
17+
headers: headers,
18+
localStorage: MyLocalStorage(),
19+
fetch: { request in
20+
try await URLSession.shared.data(for: request)
21+
}
22+
)
23+
```
24+
25+
**After (Alamofire-based):**
26+
```swift
27+
let authClient = AuthClient(
28+
url: authURL,
29+
headers: headers,
30+
localStorage: MyLocalStorage(),
31+
session: Alamofire.Session.default // ← Now requires Alamofire.Session
32+
)
33+
```
34+
35+
**Key Changes:**
36+
-**Removed**: `fetch: FetchHandler` parameter
37+
-**Added**: `session: Alamofire.Session` parameter (defaults to `.default`)
38+
- The `FetchHandler` typealias is still present for backward compatibility but is no longer used
39+
40+
### 🔴 FunctionsClient
41+
42+
**Before (URLSession-based):**
43+
```swift
44+
let functionsClient = FunctionsClient(
45+
url: functionsURL,
46+
headers: headers,
47+
fetch: { request in
48+
try await URLSession.shared.data(for: request)
49+
}
50+
)
51+
```
52+
53+
**After (Alamofire-based):**
54+
```swift
55+
let functionsClient = FunctionsClient(
56+
url: functionsURL,
57+
headers: headers,
58+
session: Alamofire.Session.default // ← Now requires Alamofire.Session
59+
)
60+
```
61+
62+
**Key Changes:**
63+
-**Removed**: `fetch: FetchHandler` parameter
64+
-**Added**: `session: Alamofire.Session` parameter (defaults to `.default`)
65+
66+
### 🔴 PostgrestClient
67+
68+
**Before (URLSession-based):**
69+
```swift
70+
let postgrestClient = PostgrestClient(
71+
url: databaseURL,
72+
schema: "public",
73+
headers: headers,
74+
fetch: { request in
75+
try await URLSession.shared.data(for: request)
76+
}
77+
)
78+
```
79+
80+
**After (Alamofire-based):**
81+
```swift
82+
let postgrestClient = PostgrestClient(
83+
url: databaseURL,
84+
schema: "public",
85+
headers: headers,
86+
session: Alamofire.Session.default // ← Now requires Alamofire.Session
87+
)
88+
```
89+
90+
**Key Changes:**
91+
-**Removed**: `fetch: FetchHandler` parameter
92+
-**Added**: `session: Alamofire.Session` parameter (defaults to `.default`)
93+
- The `FetchHandler` typealias is still present for backward compatibility but is no longer used
94+
95+
### 🔴 StorageClientConfiguration
96+
97+
**Before (URLSession-based):**
98+
```swift
99+
let storageConfig = StorageClientConfiguration(
100+
url: storageURL,
101+
headers: headers,
102+
session: StorageHTTPSession(
103+
fetch: { request in
104+
try await URLSession.shared.data(for: request)
105+
},
106+
upload: { request, data in
107+
try await URLSession.shared.upload(for: request, from: data)
108+
}
109+
)
110+
)
111+
```
112+
113+
**After (Alamofire-based):**
114+
```swift
115+
let storageConfig = StorageClientConfiguration(
116+
url: storageURL,
117+
headers: headers,
118+
session: Alamofire.Session.default // ← Now directly uses Alamofire.Session
119+
)
120+
```
121+
122+
**Key Changes:**
123+
-**Removed**: `StorageHTTPSession` wrapper class
124+
-**Changed**: `session` parameter now expects `Alamofire.Session` directly
125+
- Upload functionality is now handled internally by Alamofire
126+
127+
### 🟡 SupabaseClient (Indirect Changes)
128+
129+
The `SupabaseClient` initialization remains the same, but internally it now passes Alamofire sessions to the underlying modules:
130+
131+
**No changes to public API:**
132+
```swift
133+
// This remains the same
134+
let supabase = SupabaseClient(
135+
supabaseURL: supabaseURL,
136+
supabaseKey: supabaseKey
137+
)
138+
```
139+
140+
However, if you were customizing individual modules through options, you now need to provide Alamofire sessions:
141+
142+
**Before:**
143+
```swift
144+
let options = SupabaseClientOptions(
145+
db: SupabaseClientOptions.DatabaseOptions(
146+
// Custom fetch handlers were used internally
147+
)
148+
)
149+
```
150+
151+
**After:**
152+
```swift
153+
// Custom session configuration now required for advanced customization
154+
let customSession = Session(configuration: .default)
155+
// Then pass the session when creating individual clients
156+
```
157+
158+
## Migration Steps
159+
160+
### 1. Update Package Dependencies
161+
162+
Ensure your `Package.swift` includes Alamofire:
163+
164+
```swift
165+
dependencies: [
166+
.package(url: "https://github.com/supabase/supabase-swift", from: "3.0.0"),
167+
// Alamofire is now included as a transitive dependency
168+
]
169+
```
170+
171+
### 2. Update Import Statements
172+
173+
If you were using individual modules, you may need to import Alamofire:
174+
175+
```swift
176+
import Supabase
177+
import Alamofire // ← Add if using custom sessions
178+
```
179+
180+
### 3. Replace FetchHandler with Alamofire.Session
181+
182+
For each module initialization, replace `fetch` parameters with `session` parameters:
183+
184+
```swift
185+
// Replace this pattern:
186+
fetch: { request in
187+
try await URLSession.shared.data(for: request)
188+
}
189+
190+
// With this:
191+
session: .default
192+
// or
193+
session: myCustomSession
194+
```
195+
196+
### 4. Custom Session Configuration
197+
198+
If you need custom networking behavior (interceptors, retry logic, etc.), create a custom Alamofire session:
199+
200+
```swift
201+
// Custom session with retry logic
202+
let session = Session(
203+
configuration: .default,
204+
interceptor: RetryRequestInterceptor()
205+
)
206+
207+
let authClient = AuthClient(
208+
url: authURL,
209+
localStorage: MyLocalStorage(),
210+
session: session
211+
)
212+
```
213+
214+
### 5. Update Storage Upload Handling
215+
216+
If you were customizing storage upload behavior, now configure it through the Alamofire session:
217+
218+
```swift
219+
// Before: Custom StorageHTTPSession
220+
let storageSession = StorageHTTPSession(
221+
fetch: customFetch,
222+
upload: customUpload
223+
)
224+
225+
// After: Custom Alamofire session with upload configuration
226+
let session = Session(configuration: customConfiguration)
227+
let storageConfig = StorageClientConfiguration(
228+
url: storageURL,
229+
headers: headers,
230+
session: session
231+
)
232+
```
233+
234+
## Advanced Configuration
235+
236+
### Custom Interceptors
237+
238+
Alamofire allows you to add request/response interceptors:
239+
240+
```swift
241+
class AuthInterceptor: RequestInterceptor {
242+
func adapt(
243+
_ urlRequest: URLRequest,
244+
for session: Session,
245+
completion: @escaping (Result<URLRequest, Error>) -> Void
246+
) {
247+
var request = urlRequest
248+
request.setValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
249+
completion(.success(request))
250+
}
251+
}
252+
253+
let session = Session(interceptor: AuthInterceptor())
254+
```
255+
256+
### Background Upload/Download Support
257+
258+
Take advantage of Alamofire's background session support:
259+
260+
```swift
261+
let backgroundSession = Session(
262+
configuration: .background(withIdentifier: "com.myapp.background")
263+
)
264+
265+
let storageConfig = StorageClientConfiguration(
266+
url: storageURL,
267+
headers: headers,
268+
session: backgroundSession
269+
)
270+
```
271+
272+
### Progress Tracking
273+
274+
Monitor upload/download progress with Alamofire:
275+
276+
```swift
277+
// This functionality is now built into the modules
278+
// and can be accessed through Alamofire's progress APIs
279+
```
280+
281+
## Error Handling Changes
282+
283+
Error handling patterns have been updated to work with Alamofire's error types. Most error cases are handled internally, but you may encounter `AFError` types in edge cases.
284+
285+
## Performance Considerations
286+
287+
The migration to Alamofire brings several performance improvements:
288+
- Better connection pooling
289+
- Optimized request/response handling
290+
- Built-in retry mechanisms
291+
- Streaming support for large files
292+
293+
## Troubleshooting
294+
295+
### Common Issues
296+
297+
1. **"Cannot find 'Session' in scope"**
298+
- Add `import Alamofire` to your file
299+
300+
2. **"Cannot convert value of type 'FetchHandler' to expected argument type 'Session'"**
301+
- Replace `fetch:` parameter with `session:` and provide an Alamofire session
302+
303+
3. **"StorageHTTPSession not found"**
304+
- Replace with direct `Alamofire.Session` usage
305+
306+
### Testing Changes
307+
308+
Update your tests to work with Alamofire sessions instead of custom fetch handlers:
309+
310+
```swift
311+
// Before: Mock fetch handler
312+
let mockFetch: FetchHandler = { _ in
313+
return (mockData, mockResponse)
314+
}
315+
316+
// After: Mock Alamofire session or use dependency injection
317+
let mockSession = // Configure mock session
318+
```
319+
320+
## Getting Help
321+
322+
If you encounter issues during migration:
323+
324+
1. Check that all `fetch:` parameters are replaced with `session:`
325+
2. Ensure you're importing Alamofire when using custom sessions
326+
3. Review your custom networking code for compatibility with Alamofire patterns
327+
4. Consult the [Alamofire documentation](https://github.com/Alamofire/Alamofire) for advanced configuration options
328+
329+
For further assistance, please open an issue in the [supabase-swift repository](https://github.com/supabase/supabase-swift/issues).

Sources/Auth/AuthClient.swift

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -97,14 +97,16 @@ public actor AuthClient {
9797
AuthClient.globalClientID += 1
9898
clientID = AuthClient.globalClientID
9999

100+
var adapters: [any RequestAdapter] = []
101+
102+
if let apiKey = configuration.headers["apikey"] {
103+
adapters.append(SupabaseApiKeyAdapter(apiKey: apiKey))
104+
}
105+
adapters.append(SupabaseApiVersionAdapter())
106+
100107
Dependencies[clientID] = Dependencies(
101108
configuration: configuration,
102-
session: configuration.session.newSession(
103-
adapters: [
104-
configuration.headers["apikey"].map(SupabaseApiKeyAdapter.init(apiKey:)),
105-
SupabaseApiVersionAdapter(),
106-
].compactMap { $0 }
107-
),
109+
session: configuration.session.newSession(adapters: adapters),
108110
api: APIClient(clientID: clientID),
109111
codeVerifierStorage: .live(clientID: clientID),
110112
sessionStorage: .live(clientID: clientID),

0 commit comments

Comments
 (0)