Skip to content

Commit e62ad89

Browse files
authored
fix: linux build (#350)
* fix: linux build * fix: add missing callback version of receive method * fix: conditionally import AuthenticationSevices * ci: run only AuthTests * add make dot-env step * Fix tests in linux * chore: add supported platforms in README * Update README.md * ci: add linux job to all workflows
1 parent dfe09bc commit e62ad89

File tree

11 files changed

+245
-96
lines changed

11 files changed

+245
-96
lines changed

.github/workflows/auth.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,21 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=Auth make test-library
43+
44+
test-linux:
45+
name: Test Auth (Linux)
46+
strategy:
47+
fail-fast: false
48+
matrix:
49+
swift-version: ["5.9", "5.10"]
50+
runs-on: ubuntu-latest
51+
steps:
52+
- uses: actions/checkout@v3
53+
with:
54+
fetch-deptch: 0
55+
- uses: swift-actions/setup-swift@v2
56+
with:
57+
swift-version: ${{ matrix.swift-version }}
58+
- run: make dot-env
59+
- name: Run tests
60+
run: swift test --filter AuthTests.

.github/workflows/functions.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=Functions make test-library
43+
test-linux:
44+
name: Test Functions (Linux)
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
swift-version: ["5.9", "5.10"]
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v3
52+
with:
53+
fetch-deptch: 0
54+
- uses: swift-actions/setup-swift@v2
55+
with:
56+
swift-version: ${{ matrix.swift-version }}
57+
- run: make dot-env
58+
- name: Run tests
59+
run: swift test --filter FunctionsTests.

.github/workflows/postgrest.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=PostgREST make test-library
43+
test-linux:
44+
name: Test Postgrest (Linux)
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
swift-version: ["5.9", "5.10"]
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v3
52+
with:
53+
fetch-deptch: 0
54+
- uses: swift-actions/setup-swift@v2
55+
with:
56+
swift-version: ${{ matrix.swift-version }}
57+
- run: make dot-env
58+
- name: Run tests
59+
run: swift test --filter PostgRESTTests.

.github/workflows/realtime.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=Realtime make test-library
43+
test-linux:
44+
name: Test Realtime (Linux)
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
swift-version: ["5.9", "5.10"]
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v3
52+
with:
53+
fetch-deptch: 0
54+
- uses: swift-actions/setup-swift@v2
55+
with:
56+
swift-version: ${{ matrix.swift-version }}
57+
- run: make dot-env
58+
- name: Run tests
59+
run: swift test --filter RealtimeTests.

.github/workflows/storage.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=Storage make test-library
43+
test-linux:
44+
name: Test Storage (Linux)
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
swift-version: ["5.9", "5.10"]
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v3
52+
with:
53+
fetch-deptch: 0
54+
- uses: swift-actions/setup-swift@v2
55+
with:
56+
swift-version: ${{ matrix.swift-version }}
57+
- run: make dot-env
58+
- name: Run tests
59+
run: swift test --filter StorageTests.

.github/workflows/supabase.yml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,20 @@ jobs:
4040
run: sudo xcode-select -s /Applications/Xcode_15.3.app
4141
- name: Run tests
4242
run: PLATFORM="${{ matrix.platform }}" SCHEME=Supabase make test-library
43+
test-linux:
44+
name: Test Supabase (Linux)
45+
strategy:
46+
fail-fast: false
47+
matrix:
48+
swift-version: ["5.9", "5.10"]
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v3
52+
with:
53+
fetch-deptch: 0
54+
- uses: swift-actions/setup-swift@v2
55+
with:
56+
swift-version: ${{ matrix.swift-version }}
57+
- run: make dot-env
58+
- name: Run tests
59+
run: swift test --filter SupabaseTests.

README.md

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,22 @@ Supabase client for swift. Mirrors the design of [supabase-js](https://github.co
66

77
* Documentation: [https://supabase.com/docs/reference/swift/introduction](https://supabase.com/docs/reference/swift/introduction)
88

9+
## Supported Platforms
10+
11+
| Platform | Support |
12+
|--------|--------|
13+
| iOS ||
14+
| macOS ||
15+
| watchOS ||
16+
| tvOS ||
17+
| visionOS ||
18+
| Linux | ☑️ |
19+
| Windows | ☑️ |
20+
21+
> ✅ Official support
22+
>
23+
> ☑️ Works but not officially supported, and not guaranttee to keep working on future versions of the library.
24+
925
## Usage
1026

1127
Install the library using the Swift Package Manager.

Sources/Auth/AuthClient.swift

Lines changed: 67 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
import _Helpers
2-
import AuthenticationServices
32
import Foundation
43

4+
#if canImport(AuthenticationServices)
5+
import AuthenticationServices
6+
#endif
7+
58
#if canImport(FoundationNetworking)
69
import FoundationNetworking
710
#endif
@@ -652,75 +655,77 @@ public final class AuthClient: @unchecked Sendable {
652655
return try await session(from: resultURL)
653656
}
654657

655-
/// Sign-in an existing user via a third-party provider using ``ASWebAuthenticationSession``.
656-
///
657-
/// - Parameters:
658-
/// - provider: The third-party provider.
659-
/// - redirectTo: A URL to send the user to after they are confirmed.
660-
/// - scopes: A space-separated list of scopes granted to the OAuth application.
661-
/// - queryParams: Additional query params.
662-
/// - configure: A configuration closure that you can use to customize the internal
663-
/// ``ASWebAuthenticationSession`` object.
664-
///
665-
/// - Note: This method support the PKCE flow.
666-
/// - Warning: Do not call `start()` on the `ASWebAuthenticationSession` object inside the
667-
/// `configure` closure, as the method implementation calls it already.
668-
@available(watchOS 6.2, tvOS 16.0, *)
669-
@discardableResult
670-
public func signInWithOAuth(
671-
provider: Provider,
672-
redirectTo: URL? = nil,
673-
scopes: String? = nil,
674-
queryParams: [(name: String, value: String?)] = [],
675-
configure: @Sendable (_ session: ASWebAuthenticationSession) -> Void = { _ in }
676-
) async throws -> Session {
677-
try await signInWithOAuth(
678-
provider: provider,
679-
redirectTo: redirectTo,
680-
scopes: scopes,
681-
queryParams: queryParams
682-
) { @MainActor url in
683-
try await withCheckedThrowingContinuation { continuation in
684-
guard let callbackScheme = (configuration.redirectToURL ?? redirectTo)?.scheme else {
685-
continuation.resume(throwing: AuthError.invalidRedirectScheme)
686-
return
687-
}
688-
689-
#if !os(tvOS) && !os(watchOS)
690-
var presentationContextProvider: DefaultPresentationContextProvider?
691-
#endif
692-
693-
let session = ASWebAuthenticationSession(
694-
url: url,
695-
callbackURLScheme: callbackScheme
696-
) { url, error in
697-
if let error {
698-
continuation.resume(throwing: error)
699-
} else if let url {
700-
continuation.resume(returning: url)
701-
} else {
702-
continuation.resume(throwing: AuthError.missingURL)
658+
#if canImport(AuthenticationServices)
659+
/// Sign-in an existing user via a third-party provider using ``ASWebAuthenticationSession``.
660+
///
661+
/// - Parameters:
662+
/// - provider: The third-party provider.
663+
/// - redirectTo: A URL to send the user to after they are confirmed.
664+
/// - scopes: A space-separated list of scopes granted to the OAuth application.
665+
/// - queryParams: Additional query params.
666+
/// - configure: A configuration closure that you can use to customize the internal
667+
/// ``ASWebAuthenticationSession`` object.
668+
///
669+
/// - Note: This method support the PKCE flow.
670+
/// - Warning: Do not call `start()` on the `ASWebAuthenticationSession` object inside the
671+
/// `configure` closure, as the method implementation calls it already.
672+
@available(watchOS 6.2, tvOS 16.0, *)
673+
@discardableResult
674+
public func signInWithOAuth(
675+
provider: Provider,
676+
redirectTo: URL? = nil,
677+
scopes: String? = nil,
678+
queryParams: [(name: String, value: String?)] = [],
679+
configure: @Sendable (_ session: ASWebAuthenticationSession) -> Void = { _ in }
680+
) async throws -> Session {
681+
try await signInWithOAuth(
682+
provider: provider,
683+
redirectTo: redirectTo,
684+
scopes: scopes,
685+
queryParams: queryParams
686+
) { @MainActor url in
687+
try await withCheckedThrowingContinuation { continuation in
688+
guard let callbackScheme = (configuration.redirectToURL ?? redirectTo)?.scheme else {
689+
continuation.resume(throwing: AuthError.invalidRedirectScheme)
690+
return
703691
}
704692

705693
#if !os(tvOS) && !os(watchOS)
706-
// Keep a strong reference to presentationContextProvider until the flow completes.
707-
_ = presentationContextProvider
694+
var presentationContextProvider: DefaultPresentationContextProvider?
708695
#endif
709-
}
710-
711-
configure(session)
712696

713-
#if !os(tvOS) && !os(watchOS)
714-
if session.presentationContextProvider == nil {
715-
presentationContextProvider = DefaultPresentationContextProvider()
716-
session.presentationContextProvider = presentationContextProvider
697+
let session = ASWebAuthenticationSession(
698+
url: url,
699+
callbackURLScheme: callbackScheme
700+
) { url, error in
701+
if let error {
702+
continuation.resume(throwing: error)
703+
} else if let url {
704+
continuation.resume(returning: url)
705+
} else {
706+
continuation.resume(throwing: AuthError.missingURL)
707+
}
708+
709+
#if !os(tvOS) && !os(watchOS)
710+
// Keep a strong reference to presentationContextProvider until the flow completes.
711+
_ = presentationContextProvider
712+
#endif
717713
}
718-
#endif
719714

720-
session.start()
715+
configure(session)
716+
717+
#if !os(tvOS) && !os(watchOS)
718+
if session.presentationContextProvider == nil {
719+
presentationContextProvider = DefaultPresentationContextProvider()
720+
session.presentationContextProvider = presentationContextProvider
721+
}
722+
#endif
723+
724+
session.start()
725+
}
721726
}
722727
}
723-
}
728+
#endif
724729

725730
/// Gets the session data from a OAuth2 callback URL.
726731
@discardableResult
@@ -1281,7 +1286,7 @@ extension AuthClient {
12811286
public static let authChangeSessionInfoKey = "AuthClient.authChangeSession"
12821287
}
12831288

1284-
#if !os(tvOS) && !os(watchOS)
1289+
#if canImport(AuthenticationServices) && !os(tvOS) && !os(watchOS)
12851290
@MainActor
12861291
final class DefaultPresentationContextProvider: NSObject,
12871292
ASWebAuthenticationPresentationContextProviding

Sources/Realtime/V2/WebSocketClient.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,3 +215,14 @@ final class SocketStream: AsyncSequence, Sendable {
215215
try await task.send(message)
216216
}
217217
}
218+
219+
#if os(Linux) || os(Windows)
220+
extension URLSessionWebSocketTask {
221+
func receive(completionHandler: @Sendable @escaping (Result<URLSessionWebSocketTask.Message, any Error>) -> Void) {
222+
Task {
223+
let result = await Result(catching: { try await self.receive() })
224+
completionHandler(result)
225+
}
226+
}
227+
}
228+
#endif

Tests/AuthTests/AuthClientTests.swift

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -324,17 +324,18 @@ final class AuthClientTests: XCTestCase {
324324
XCTAssertEqual(emitReceivedEvents.value.map(\.0), [.signedIn])
325325
}
326326

327-
@available(watchOS 6.2, tvOS 16.0, *)
328327
func testSignInWithOAuthWithInvalidRedirecTo() async {
329328
let sut = makeSUT()
330329

331330
do {
332331
try await sut.signInWithOAuth(
333332
provider: .google,
334-
redirectTo: nil
335-
) { _ in
336-
XCTFail("Should not call launchFlow.")
337-
}
333+
redirectTo: nil,
334+
launchFlow: { _ in
335+
XCTFail("Should not call launchFlow.")
336+
return URL(string: "https://supabase.com")!
337+
}
338+
)
338339
} catch let error as AuthError {
339340
XCTAssertEqual(error, .invalidRedirectScheme)
340341
} catch {

0 commit comments

Comments
 (0)