Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
40c16ed
README and Xcode 26 Beta updates
AlexNachbaur Jun 30, 2025
0e14894
Minor update to the Samples README
AlexNachbaur Jun 30, 2025
6d4d429
Amend the Xcode 26 Beta workaround implementation
AlexNachbaur Jun 30, 2025
b8d42be
Update swift language version detection script
AlexNachbaur Jun 30, 2025
7f0f91d
Introduce debugging for selecting Swift 6.1
AlexNachbaur Jun 30, 2025
a434944
Debug missing Xcode 16.4
AlexNachbaur Jul 1, 2025
e5b8d36
Updates for github actions missing versions of Xcode
AlexNachbaur Jul 1, 2025
dd27036
Ensuring the proper runners are selected
AlexNachbaur Jul 2, 2025
af8642e
Reduce parallel iteration count for async tests to avoid flaky CI rac…
AlexNachbaur Jul 2, 2025
c10a846
Do not parallelize Swift tests, due to limited CI runner speed
AlexNachbaur Jul 2, 2025
59095ad
Resolve inadequate test timings for CI
AlexNachbaur Jul 2, 2025
97fd3f1
Resolve unit test URLResponse race conditions
AlexNachbaur Jul 2, 2025
3a86a69
More test expectation timeout corrections
AlexNachbaur Jul 2, 2025
c9bce2c
Ensure logs can be preserved from failed swift tests
AlexNachbaur Jul 2, 2025
d6076a8
Fix test request match
AlexNachbaur Jul 2, 2025
9de893f
Fix a collision in log output naming
AlexNachbaur Jul 3, 2025
1055ce6
Try to resolve concurrency tests, and improve build output logs
AlexNachbaur Jul 3, 2025
9fad7f6
Ensure xcbeautify is installed on Linux
AlexNachbaur Jul 3, 2025
856550d
Fix a syntax error in the setup-swift action
AlexNachbaur Jul 3, 2025
fa5804a
Ensure homebrew is in the path
AlexNachbaur Jul 3, 2025
4542ba1
Include homebrew path updates in Linux
AlexNachbaur Jul 3, 2025
0f14a0b
Update to the newer CircleCI runner for UI tests
AlexNachbaur Jul 4, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/actions/setup-swift/versions.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,7 @@ swift:
- version: "6.1"
xcode_versions:
- "16.3"
- "16.4"
- version: "6.2"
xcode_versions:
- "26.0"
20 changes: 8 additions & 12 deletions .github/workflows/documentation-ghpages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,11 @@ on:
- '*'

env:
DEVELOPER_DIR: /Applications/Xcode_16.2.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer
ENABLE_DOC_GENERATION: YES
DOCC_JSON_PRETTYPRINT: YES
NSUnbufferedIO: YES

# NOTE: The DocC `generate-documentation` plugin does not handle the
# hostingBasePath well. In particular, it doesn't properly handle
# multiple child paths. Furthermore, the current 1.0.0 version of
# the plugin doesn't handle updates to the index.html or *.js
# files.
#
# This workflow should be revisited once Xcode 14 GA is released
# so the newer DocC utilities can be utilized.
jobs:
ExportToGHPages:
name: Export to Github Pages
Expand All @@ -37,14 +31,13 @@ jobs:

TARGET_LIST=""

mkdir -p "docs/okta-mobile-swift/$VERSION"

echo "Initializing target list"
for TARGET in $(swift package describe --type json | jq ".products[].name" | sed -e 's/"//g'); do
echo "🎯 $TARGET"
NAME=$(echo "$TARGET" | tr '[:upper:]' '[:lower:]')
TARGET_LIST="$TARGET_LIST --target $TARGET"

mkdir -p "docs/okta-mobile-swift/$VERSION/$NAME"
echo "<html><head><meta http-equiv='refresh' content='0;url=/okta-mobile-swift/$VERSION/documentation/$NAME/'></head></html>" > "docs/okta-mobile-swift/$VERSION/$NAME/index.html"
done

echo
Expand All @@ -56,9 +49,12 @@ jobs:
--hosting-base-path "okta-mobile-swift/$VERSION" \
--output-path "docs/okta-mobile-swift/$VERSION" \
--include-extended-types \
--symbol-graph-minimum-access-level public \
--experimental-skip-synthesized-symbols \
--enable-experimental-combined-documentation \
--enable-experimental-mentioned-in \
--enable-experimental-external-link-support \
--enable-experimental-overloaded-symbol-presentation \
$TARGET_LIST
- name: Deploy documentation to Github Pages
uses: peaceiris/actions-gh-pages@v3
Expand Down
29 changes: 18 additions & 11 deletions .github/workflows/tests.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ jobs:
os:
- macos-latest-large
- ubuntu-latest
swift_version: ["5.10", "6.0"]
swift_version: ["5.10", "6.0", "6.1", "6.2"]
exclude:
- os: ubuntu-latest
swift_version: "5.10"
Expand All @@ -200,7 +200,7 @@ jobs:
matrix:
platform: [iOS, tvOS, watchOS, macOS, visionOS]
env:
DEVELOPER_DIR: /Applications/Xcode_16.2.app/Contents/Developer
DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer
timeout-minutes: 10
steps:
- uses: actions/checkout@master
Expand All @@ -222,20 +222,23 @@ jobs:
- destination: "platform=iOS Simulator,OS=18.2,name=iPhone 16 Pro Max"
xcode_version: "16.2"
os: macos-15-large
- destination: "platform=tvOS Simulator,OS=18.2,name=Apple TV"
xcode_version: "16.2"
- destination: "platform=iOS Simulator,OS=18.5,name=iPhone 16 Pro Max"
xcode_version: "16.4"
os: macos-15-large
- destination: "platform=tvOS Simulator,OS=18.5,name=Apple TV"
xcode_version: "16.4"
os: macos-15-large
- destination: "platform=visionOS Simulator,OS=1.0,name=Apple Vision Pro"
xcode_version: "15.4"
os: macos-14-xlarge
- destination: "platform=visionOS Simulator,OS=2.2,name=Apple Vision Pro"
xcode_version: "16.2"
- destination: "platform=visionOS Simulator,OS=2.5,name=Apple Vision Pro"
xcode_version: "16.4"
os: macos-15-xlarge
- destination: "platform=watchOS Simulator,OS=11.1,name=Apple Watch Series 10 (46mm)"
xcode_version: "16.2"
- destination: "platform=watchOS Simulator,OS=11.5,name=Apple Watch Series 10 (46mm)"
xcode_version: "16.4"
os: macos-15-large
- destination: "platform=macOS,name=My Mac"
xcode_version: "16.2"
xcode_version: "16.4"
os: macos-15-large
runs-on: ${{ matrix.os }}
env:
Expand Down Expand Up @@ -350,15 +353,16 @@ jobs:
if: ${{ !github.event.pull_request.draft && needs.Preflight.outputs.has_documentation_changes == 'true' }}
runs-on: macos-latest
env:
DEVELOPER_DIR: /Applications/Xcode_16.2.app/Contents/Developer
ENABLE_DOC_GENERATION: YES
DOCC_JSON_PRETTYPRINT: YES
DEVELOPER_DIR: /Applications/Xcode_16.4.app/Contents/Developer
DESTINATION: "${{ matrix.destination }}"
LOG_NAME: "${{github.job}}-${{ matrix.xcode_version }}-${{ matrix.destination }}"
NSUnbufferedIO: YES
steps:
- uses: actions/checkout@master
- name: Swift Package Documentation lint
run: |
export DOCC_JSON_PRETTYPRINT=YES
mkdir -p ~/Build/Docs

TARGET_LIST=""
Expand All @@ -372,9 +376,12 @@ jobs:
--disable-indexing \
--output-path ~/Build/Docs \
--include-extended-types \
--symbol-graph-minimum-access-level public \
--experimental-skip-synthesized-symbols \
--enable-experimental-combined-documentation \
--enable-experimental-mentioned-in \
--enable-experimental-external-link-support \
--enable-experimental-overloaded-symbol-presentation \
--analyze \
--emit-fixits \
$TARGET_LIST | ./.github/workflows/swift-log-renderer.sh
9 changes: 6 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// swift-tools-version:6.0
// The swift-tools-version declares the minimum version of Swift required to build this package.

import Foundation
import PackageDescription

let strictConcurrencyEnabled = true
Expand Down Expand Up @@ -43,9 +44,6 @@ var package = Package(
.library(name: "OktaDirectAuth", targets: ["OktaDirectAuth"]),
.library(name: "OktaIdxAuth", targets: ["OktaIdxAuth"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.4.0")
],
targets: [
.target(name: "AuthFoundation",
dependencies: [],
Expand Down Expand Up @@ -114,3 +112,8 @@ package.products.append(
.library(name: "BrowserSignin", targets: ["BrowserSignin"])
)
#endif

if ProcessInfo.processInfo.environment["ENABLE_DOC_GENERATION"] != nil {
package.dependencies.append(.package(url: "https://github.com/apple/swift-docc-plugin",
from: "1.4.0"))
}
6 changes: 6 additions & 0 deletions Package@swift-5.10.swift
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// swift-tools-version:5.10
// The swift-tools-version declares the minimum version of Swift required to build this package.

import Foundation
import PackageDescription

let strictConcurrencyEnabled = true
Expand Down Expand Up @@ -121,3 +122,8 @@ package.products.append(
.library(name: "BrowserSignin", targets: ["BrowserSignin"])
)
#endif

if ProcessInfo.processInfo.environment["ENABLE_DOC_GENERATION"] != nil {
package.dependencies.append(.package(url: "https://github.com/apple/swift-docc-plugin",
from: "1.4.0"))
}
58 changes: 47 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,18 @@
[<img src="https://www.okta.com/sites/default/files/Dev_Logo-01_Large-thumbnail.png" align="right" width="256px"/>](https://devforum.okta.com/)
[![Latest Release](https://img.shields.io/github/v/release/okta/okta-mobile-swift)](https://github.com/okta/okta-mobile-swift/releases/latest)
[![Swift Versions](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fokta%2Fokta-mobile-swift%2Fbadge%3Ftype%3Dswift-versions)](https://swiftpackageindex.com/okta/okta-mobile-swift)
[![Platforms](https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2Fokta%2Fokta-mobile-swift%2Fbadge%3Ftype%3Dplatforms)](https://swiftpackageindex.com/okta/okta-mobile-swift)
[![Tests](https://github.com/okta/okta-mobile-swift/actions/workflows/tests.yaml/badge.svg)](https://github.com/okta/okta-mobile-swift/actions/workflows/tests.yaml)
[![Swift Package Manager](https://img.shields.io/badge/Swift_Package_Manager-compatible-green?style=flat)](https://swiftpackageindex.com/okta/okta-mobile-swift)
[![CocoaPods](https://img.shields.io/badge/CocoaPods-compatible-green?style=flat)](https://cocoapods.org/pods/OktaAuthFoundation)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![Support](https://img.shields.io/badge/support-Developer%20Forum-blue.svg)][devforum]
[![API Reference](https://img.shields.io/badge/docs-reference-lightgrey.svg)][swiftdocs]

[![SDK Documentation](https://img.shields.io/badge/docs-SDK%20Documentation-blue.svg)][sdkdocumentation]
[![Integration Guide](https://img.shields.io/badge/docs-Integration%20Guide-blue.svg)][integrationdocs]

# Okta Client SDK for Swift

[<img src="https://www.okta.com/sites/default/files/Dev_Logo-01_Large-thumbnail.png" align="right" width="256px"/>](https://devforum.okta.com/)

The Okta Client SDK represents a collection of SDKs for different languages, each of which itself is a modular ecosystem of libraries that build upon one-another to enable client applications to:

* Authenticate clients with an Authorization Server (AS) using a variety of authentication flows.
Expand All @@ -27,15 +34,16 @@ This library uses semantic versioning and follows Okta's [Library Version Policy
| Version | Status |
| ------- | ---------------------------------- |
| 1.8.3 | Retiring |
| 2.0.0 | ✔️ Stable |
| 2.0.0 | |
| 2.0.1 | ✔️ Stable |

The latest release can always be found on the [releases page][github-releases].

## Need help?

If you run into problems using the SDK, you can:

* Review the API documentation for [AuthFoundation][authfoundation-docs], [OAuth2Auth][oauth2auth-docs], [OktaDirectAuth][oktadirectauth-docs], [OktaIdxAuth][oktaidxauth-docs], and [BrowserSignin][browsersignin-docs]
* Review the [API documentation](sdkdocumentation) for [AuthFoundation][authfoundation-docs], [OAuth2Auth][oauth2auth-docs], [OktaDirectAuth][oktadirectauth-docs], [OktaIdxAuth][oktaidxauth-docs], and [BrowserSignin][browsersignin-docs]
* Ask questions on the [Okta Developer Forums][devforum]
* Post [issues][github-issues] here on GitHub (for code errors)

Expand Down Expand Up @@ -346,6 +354,33 @@ if let credential = try Credential.find(where: { $0.email == "user@example.com"
}
```

### Authorizing outgoing requests to a Resource Server (RS)

While the traditional approach of manually adding the `access_token` value to an HTTP header is supported, the Credential class provides conveniences that drastically improves your developer experience when working with the Authorization header.

The recommended approach to is to use the `authorize(_:)` function, which accepts a URLRequest object and adds the appropriate headers to the request's HTTP headers with the appropriate token information. The are two versions of the same function:

1. A synchronous function that simply adds the access token header to the request.
2. An `async` function that ensures the token has not expired, and proactively refreshes the token on your behalf before adding the headers to the request.

For example:

```swift
// Retrieve the credentials for the user
guard let credential = Credential.default else { return }

// Create the API request
var request = URLRequest(url: URL(string: "https://api.example.com/some/path")!)
request.method = "POST"

// Authorize the request with the user's credentials. The request is
// passed as a pointer so it is updated in-place.
try await credential.authorize(&request)

// Send the request, retrieving the results.
let (data, response) = try await URLSession.shared.data(for: request)
```

### Rate Limit Handling

The Okta API will return 429 responses if too many requests are made within a given time. Please see [Rate Limiting at Okta](https://developer.okta.com/docs/api/getting_started/rate-limits) for a complete
Expand Down Expand Up @@ -484,15 +519,16 @@ docker run --rm --privileged --interactive --tty \
We are happy to accept contributions and PRs! Please see the [contribution guide](CONTRIBUTING.md) to understand how to structure a contribution.

[devforum]: https://devforum.okta.com/
[swiftdocs]: https://developer.okta.com/okta-mobile-swift/latest/
[integrationdocs]: https://developer.okta.com/docs/guides/sign-into-mobile-app-redirect/ios/main/
[lang-landing]: https://developer.okta.com/code/swift/
[github-issues]: https://github.com/okta/okta-mobile-swift/issues
[github-releases]: https://github.com/okta/okta-mobile-swift/releases
[authfoundation-docs]: https://okta.github.io/okta-mobile-swift/development/authfoundation/
[oktadirectauth-docs]: https://okta.github.io/okta-mobile-swift/development/oktadirectauth/
[oktaidxauth-docs]: https://okta.github.io/okta-mobile-swift/development/oktaidxauth/
[oauth2auth-docs]: https://okta.github.io/okta-mobile-swift/development/oauth2auth/
[browsersignin-docs]: https://okta.github.io/okta-mobile-swift/development/browsersignin/
[sdkdocumentation]: https://okta.github.io/okta-mobile-swift/development/documentation/
[authfoundation-docs]: https://okta.github.io/okta-mobile-swift/development/documentation/authfoundation/
[oktadirectauth-docs]: https://okta.github.io/okta-mobile-swift/development/documentation/oktadirectauth/
[oktaidxauth-docs]: https://okta.github.io/okta-mobile-swift/development/documentation/oktaidxauth/
[oauth2auth-docs]: https://okta.github.io/okta-mobile-swift/development/documentation/oauth2auth/
[browsersignin-docs]: https://okta.github.io/okta-mobile-swift/development/documentation/browsersignin/
[Rate Limiting at Okta]: https://developer.okta.com/docs/api/getting_started/rate-limits
[okta-library-versioning]: https://developer.okta.com/code/library-versions
[support-policy]: #support-policy
2 changes: 1 addition & 1 deletion Samples/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ These samples show you how to add different ways to sign-in a user, called authe

## Using the Samples

These samples are designed to be built and run from the `OktaClientSDK` workspace. To use them outside of the workspace:
These samples are designed to be built and run from the `OktaClient.xcworkspace` workspace. To use them outside of the workspace:

1. Copy the sample folder to the desired location.
2. Copy the `Shared` folder to the same location at the same level as the sample folder.
Expand Down
18 changes: 13 additions & 5 deletions Sources/AuthFoundation/Utilities/CoalescedResult.swift
Comment thread
AlexNachbaur marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import Foundation
public actor CoalescedResult<T: Sendable>: Sendable {
private let taskName: String?
private var task: BackgroundTask?
private let queue: DispatchQueue
Comment thread
AlexNachbaur marked this conversation as resolved.
Outdated
private var continuations: [CheckedContinuation<T, any Error>] = []
private var _value: T?
private var _isActive: Bool = false {
Expand All @@ -38,17 +39,24 @@ public actor CoalescedResult<T: Sendable>: Sendable {
/// - Parameter taskName: The name of a background task to initiate while the operation is active.
public init(taskName: String? = nil) {
self.taskName = taskName
self.queue = DispatchQueue(label: "com.okta.coalescedResult.\(taskName ?? "unspecified")")
}

/// Indicates if the asynchronous operation is being performed.
nonisolated public var isActive: Bool {
let semaphore = DispatchSemaphore(value: 0)
nonisolated(unsafe) var result: Bool = false
Task.detached {
result = await self._isActive
semaphore.signal()

let group = DispatchGroup()
group.enter()
queue.async { [weak self] in
Task {
guard let self else { return }
result = await self._isActive
group.leave()
}
}
semaphore.wait()
group.wait()

return result
Comment thread
AlexNachbaur marked this conversation as resolved.
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ extension ASWebAuthenticationSession: @retroactive @unchecked Sendable, Authenti
#endif

@available(iOS 13.0, macOS 10.15, tvOS 16.0, watchOS 7.0, visionOS 1.0, macCatalyst 13.0, *)
protocol BrowserSigninProviderFactory {
protocol BrowserSigninProviderFactory: Sendable {
static func createWebAuthenticationProvider(for webAuth: BrowserSignin,
from window: BrowserSignin.WindowAnchor?,
usesEphemeralSession: Bool) async throws -> (any BrowserSigninProvider)?
Expand Down
Loading