Skip to content

Commit 6b852ad

Browse files
authored
Minimum OS Support (#142)
1 parent 7c34049 commit 6b852ad

4 files changed

Lines changed: 49 additions & 113 deletions

File tree

.github/workflows/codeql.yml

Lines changed: 0 additions & 81 deletions
This file was deleted.

Package.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,16 @@
1-
// swift-tools-version: 6.2
1+
// swift-tools-version: 6.1
22
// The swift-tools-version declares the minimum version of Swift required to build this package.
33

44
import PackageDescription
55

66
let package = Package(
77
name: "OAuthKit",
88
platforms: [
9-
.iOS(.v26),
10-
.macOS(.v26),
11-
.tvOS(.v26),
12-
.visionOS(.v26),
13-
.watchOS(.v26)
9+
.iOS(.v17),
10+
.macOS(.v15),
11+
.tvOS(.v18),
12+
.visionOS(.v1),
13+
.watchOS(.v10)
1414
],
1515
products: [
1616
.library(

README.md

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
![Build](https://github.com/codefiesta/OAuthKit/actions/workflows/swift.yml/badge.svg)
2-
![Swift 6.2+](https://img.shields.io/badge/Swift-6.2%2B-gold.svg)
2+
![Swift 6.1+](https://img.shields.io/badge/Swift-6.1%2B-gold.svg)
33
![Xcode 26.0+](https://img.shields.io/badge/Xcode-26.0%2B-tomato.svg)
4-
![iOS 26.0+](https://img.shields.io/badge/iOS-26.0%2B-crimson.svg)
5-
![macOS 26.0+](https://img.shields.io/badge/macOS-26.0%2B-skyblue.svg)
6-
![tvOS 26.0+](https://img.shields.io/badge/tvOS-26.0%2B-blue.svg)
7-
![visionOS 26.0+](https://img.shields.io/badge/visionOS-26.0%2B-violet.svg)
8-
![watchOS 26.0+](https://img.shields.io/badge/watchOS-26.0%2B-magenta.svg)
4+
![iOS 17.0+](https://img.shields.io/badge/iOS-17.0%2B-crimson.svg)
5+
![macOS 15.0+](https://img.shields.io/badge/macOS-15.0%2B-skyblue.svg)
6+
![tvOS 18.0+](https://img.shields.io/badge/tvOS-18.0%2B-blue.svg)
7+
![visionOS 1.0+](https://img.shields.io/badge/visionOS-1.0%2B-violet.svg)
8+
![watchOS 10.0+](https://img.shields.io/badge/watchOS-10.0%2B-magenta.svg)
99
[![License: MIT](https://img.shields.io/badge/License-MIT-indigo.svg)](https://opensource.org/licenses/MIT)
1010
![Code Coverage](https://img.shields.io/endpoint?url=https://gist.githubusercontent.com/codefiesta/87655b6e3c89b9198287b2fefbfa641f/raw/oauthkit-coverage.json)
1111

@@ -36,11 +36,11 @@ Key features include:
3636

3737
## OAuthKit Installation
3838

39-
OAuthKit can be installed using [Swift Package Manager](https://www.swift.org/documentation/package-manager/). If you need to build with Swift Tools `6.1` and Apple APIs > `26.0` use version [1.5.1](https://github.com/codefiesta/OAuthKit/releases/tag/1.5.1).
39+
OAuthKit can be installed using [Swift Package Manager](https://www.swift.org/documentation/package-manager/).
4040

4141
```swift
4242
dependencies: [
43-
.package(url: "https://github.com/codefiesta/OAuthKit", from: "2.0.1")
43+
.package(url: "https://github.com/codefiesta/OAuthKit", from: "2.1.0")
4444
]
4545
```
4646

Sources/OAuthKit/OAuth.swift

Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,18 @@ public final class OAuth: Sendable {
5151
#if os(macOS) || os(iOS) || os(visionOS)
5252
@ObservationIgnored
5353
var context: LAContext = .init()
54+
55+
var policy: LAPolicy = {
56+
#if os(macOS) || os(iOS)
57+
if #available(macOS 15.0, iOS 18.0, *) {
58+
return .deviceOwnerAuthenticationWithBiometricsOrCompanion
59+
}
60+
return .deviceOwnerAuthenticationWithBiometrics
61+
#else
62+
return .deviceOwnerAuthenticationWithBiometrics
63+
#endif
64+
}()
65+
5466
#endif
5567

5668
@ObservationIgnored
@@ -117,15 +129,15 @@ public extension OAuth {
117129
state = .authorizing(provider, grantType)
118130
case .deviceCode:
119131
state = .requestingDeviceCode(provider)
120-
Task.immediate {
132+
task { [self] in
121133
await requestDeviceCode(provider: provider)
122134
}
123135
case .clientCredentials:
124-
Task.immediate {
136+
task { [self] in
125137
await requestClientCredentials(provider: provider)
126138
}
127139
case .refreshToken:
128-
Task.immediate {
140+
task { [self] in
129141
await refreshToken(provider: provider)
130142
}
131143
}
@@ -138,7 +150,7 @@ public extension OAuth {
138150
/// - code: the code to exchange
139151
/// - pkce: the pkce data
140152
func token(provider: Provider, code: String, pkce: PKCE? = nil) {
141-
Task.immediate {
153+
task { [self] in
142154
await requestToken(provider: provider, code: code, pkce: pkce)
143155
}
144156
}
@@ -233,19 +245,12 @@ private extension OAuth {
233245

234246
#if os(macOS) || os(iOS) || os(visionOS)
235247
let localizedReason = context.localizedReason.isNotEmpty ? context.localizedReason: defaultAuthenticationWithBiometricsOrCompanionReason
236-
#if os(macOS) || os(iOS)
237-
let policy: LAPolicy = .deviceOwnerAuthenticationWithBiometricsOrCompanion
238-
#else
239-
let policy: LAPolicy = .deviceOwnerAuthenticationWithBiometrics
240-
#endif
241248
var error: NSError?
242249
if context.canEvaluatePolicy(policy, error: &error) {
243250
context.evaluatePolicy(policy, localizedReason: localizedReason) { [weak self] success, error in
244-
guard let self else { return }
245-
Task.immediate { @MainActor in
246-
if success {
247-
self.loadAuthorizations()
248-
}
251+
guard let self, success else { return }
252+
Task { @MainActor [self] in
253+
loadAuthorizations()
249254
}
250255
}
251256
}
@@ -257,7 +262,7 @@ private extension OAuth {
257262

258263
/// Starts the network monitor.
259264
func monitor() {
260-
Task {
265+
task { [self] in
261266
await networkMonitor.start()
262267
}
263268
}
@@ -284,7 +289,7 @@ private extension OAuth {
284289
let timeInterval: TimeInterval = .init(deviceCode.interval)
285290
let task = Task.delayed(timeInterval: timeInterval) { [weak self] in
286291
guard let self else { return }
287-
await self.poll(provider: provider, deviceCode: deviceCode)
292+
await poll(provider: provider, deviceCode: deviceCode)
288293
}
289294
tasks.append(task)
290295
}
@@ -304,18 +309,30 @@ private extension OAuth {
304309
// Schedule the auto refresh task
305310
let task = Task.delayed(timeInterval: timeInterval) { [weak self] in
306311
guard let self else { return }
307-
await self.refreshToken(provider: provider)
312+
await refreshToken(provider: provider)
308313
}
309314
tasks.append(task)
310315
} else {
311316
// Execute the task immediately
312-
Task.immediate {
317+
task { [self] in
313318
await refreshToken(provider: provider)
314319
}
315320
}
316321
}
317322
}
318323
}
324+
325+
/// Create and immediately start running a new detached task in the context of this actor.
326+
/// - Parameters:
327+
/// - priority: the task priority
328+
/// - operation: the operation to be run immediately upon entering the task.
329+
func task(priority: TaskPriority = .high, operation: sending @escaping @isolated(any) () async throws -> Void) {
330+
if #available(macOS 26, iOS 26, watchOS 26, tvOS 26, visionOS 26, *) {
331+
Task.immediate(operation: operation)
332+
} else {
333+
Task(priority: priority, operation: operation)
334+
}
335+
}
319336
}
320337

321338
// MARK: URLRequests

0 commit comments

Comments
 (0)