diff --git a/.github/workflows/docc.yml b/.github/workflows/docc.yml
index 0b7c4d2..e045153 100644
--- a/.github/workflows/docc.yml
+++ b/.github/workflows/docc.yml
@@ -36,16 +36,23 @@ jobs:
- uses: actions/checkout@v4
- name: Select Xcode
run: sudo xcode-select -s "/Applications/$XCODE_VERSION.app"
- - name: Generate DocC
- run: xcodebuild docbuild -scheme OAuthKit -derivedDataPath /tmp/docbuild -destination 'generic/platform=macOS';
- - name: Transform DocC
+ - name: Add Plugin Dependency
+ run: swift package add-dependency "https://github.com/apple/swift-docc-plugin" --branch main
+ - name: Generate Documentation
run: |
- $(xcrun --find docc) process-archive \
- transform-for-static-hosting /tmp/docbuild/Build/Products/Debug/OAuthKit.doccarchive \
+ swift package \
+ --allow-writing-to-package-directory \
+ --allow-writing-to-directory ${{github.workspace}}/docs \
+ generate-documentation \
+ --target OAuthKit \
+ --transform-for-static-hosting \
--hosting-base-path OAuthKit \
- --output-path docs;
+ --output-path ${{github.workspace}}/docs \
+ --source-service github \
+ --source-service-base-url https://github.com/codefiesta/OAuthKit/blob/main \
+ --checkout-path ${{github.workspace}};
- name: Update Index
- run: echo "" > docs/index.html;
+ run: echo "" > ${{github.workspace}}/docs/index.html;
- name: Upload Pages Artifact
uses: actions/upload-pages-artifact@v3
with:
diff --git a/README.md b/README.md
index e0d1c28..47adde4 100644
--- a/README.md
+++ b/README.md
@@ -17,15 +17,15 @@ OAuthKit is a contemporary, event-driven Swift Package that utilizes the [Observ
## OAuthKit Features
-OAuthKit is a small, lightweight package that provides out of the box [Swift Concurrency](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/) safety support and [Observable](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L36) OAuth 2.0 state events that allow fine grained control over when and how to start authorization flows.
+OAuthKit is a small, lightweight package that provides out of the box [Swift Concurrency](https://docs.swift.org/swift-book/documentation/the-swift-programming-language/concurrency/) safety support and [Observable](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth/state-swift.enum) OAuth 2.0 state events that allow fine grained control over when and how to start authorization flows.
Key features include:
- [Simple Configuration](#oauthkit-configuration)
-- [Keychain protection with biometrics or companion device](#oauth-initialized-with-keychain-protection-and-private-browsing)
-- [Private Browsing with non-persistent WebKit Datastores](#oauth-initialized-with-keychain-protection-and-private-browsing)
-- [Custom URLSession](#oauth-initialized-with-keychain-protection-and-private-browsing) configuration for complete control custom protocol specific data
-- [Observable State](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L36) driven events to allow full control over when and if users are prompted to authenticate with an OAuth provider
+- [Keychain protection with biometrics or companion device](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Keychain-Protection)
+- [Private Browsing with non-persistent WebKit Datastores](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#Private-Browsing)
+- [Custom URLSession](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/configuration#URL-Session) configuration for complete control custom protocol specific data
+- [Observable State](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/gettingstarted#Observing-OAuth-State) driven events to allow full control over when and if users are prompted to authenticate with an OAuth provider
- Supports all Apple Platforms (iOS, macOS, tvOS, visionOS, watchOS)
- [Support for every OAuth 2.0 Flow](#oauthkit-configuration)
- [Authorization Code](#oauth-20-authorization-code-flow)
@@ -160,7 +160,7 @@ struct ContentView: View {
```
## OAuthKit Configuration
-By default, the easiest way to configure OAuthKit is to simply drop an `oauth.json` file into your main bundle and it will get automatically loaded into your swift application and available as an [Environment](https://developer.apple.com/documentation/swiftui/environment) property wrapper. You can find an example `oauth.json` file [here](https://github.com/codefiesta/OAuthKit/blob/main/Tests/OAuthKitTests/Resources/oauth.json). OAuthKit provides flexible constructor options that allows developers to customize how their oauth client is initialized and what features they want to implement. See the [oauth.init(\_:bundle:options)](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L98) method for details.
+By default, the easiest way to configure OAuthKit is to simply drop an `oauth.json` file into your main bundle and it will get automatically loaded into your swift application and available as an [Environment](https://developer.apple.com/documentation/swiftui/environment) property wrapper. You can find an example `oauth.json` file [here](https://github.com/codefiesta/OAuthKit/blob/main/Tests/OAuthKitTests/Resources/oauth.json). OAuthKit provides flexible constructor options that allows developers to customize how their oauth client is initialized and what features they want to implement. See the [oauth.init(\_:bundle:options)](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth) method for details.
### OAuth initialized from main bundle (default)
```swift
@@ -222,7 +222,7 @@ let oauth: OAuth = .init(.main, options: options)
```
## OAuthKit Authorization Flows
-OAuth 2.0 authorization flows are started by calling the [oauth.authorize(provider:grantType:)](https://github.com/codefiesta/OAuthKit/blob/main/Sources/OAuthKit/OAuth.swift#L117) method.
+OAuth 2.0 authorization flows are started by calling the [oauth.authorize(provider:grantType:)](https://codefiesta.github.io/OAuthKit/documentation/oauthkit/oauth#Starting-an-authorization-flow) method.
A good resource to help understand the detailed steps involved in OAuth 2.0 authorization flows can be found on the [OAuth 2.0 Playground](https://www.oauth.com/playground/index.html).
diff --git a/Sources/OAuthKit/OAuth+State.swift b/Sources/OAuthKit/OAuth+State.swift
index 87031c0..cb3df55 100644
--- a/Sources/OAuthKit/OAuth+State.swift
+++ b/Sources/OAuthKit/OAuth+State.swift
@@ -10,43 +10,6 @@ import Foundation
extension OAuth {
/// Holds the OAuth state that is published to subscribers via the ``state`` property.
- ///
- /// A n example of observing the ``state`` property in SwiftUI:
- /// ```swift
- ///struct ContentView: View {
- ///
- /// @Environment(\.oauth)
- /// var oauth: OAuth
- ///
- /// var body: some View {
- /// VStack {
- /// switch oauth.state {
- /// case .empty:
- /// providerList
- /// case .authorizing(let provider, let grantType):
- /// Text("Authorizing [\(provider.id)] with [\(grantType.rawValue)]")
- /// case .requestingAccessToken(let provider):
- /// Text("Requesting Access Token [\(provider.id)]")
- /// case .requestingDeviceCode(let provider):
- /// Text("Requesting Device Code [\(provider.id)]")
- /// case .authorized(let provider, _):
- /// Button("Authorized [\(provider.id)]") {
- /// oauth.clear()
- /// }
- /// case .receivedDeviceCode(_, let deviceCode):
- /// Text("To login, visit")
- /// Text(.init("[\(deviceCode.verificationUri)](\(deviceCode.verificationUri))"))
- /// .foregroundStyle(.blue)
- /// Text("and enter the following code:")
- /// Text(deviceCode.userCode)
- /// }
- /// }
- /// .onChange(of: oauth.state) { oldState, newState in
- /// handle(state: newState)
- /// }
- /// }
- /// }
- /// ```
public enum State: Equatable, Sendable {
/// The state is empty and no authorizations or tokens have been issued.
diff --git a/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md b/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md
new file mode 100644
index 0000000..097bd55
--- /dev/null
+++ b/Sources/OAuthKit/OAuthKit.docc/Extensions/State.md
@@ -0,0 +1,48 @@
+# ``OAuthKit/OAuth/State``
+
+@Metadata {
+ @Available(iOS, introduced: "18.0")
+ @Available(macOS, introduced: "15.0")
+ @Available(tvOS, introduced: "18.0")
+ @Available(visionOS, introduced: "2.0")
+ @Available(watchOS, introduced: "11.0")
+}
+
+## Overview
+An example of observing the ``state`` property in SwiftUI:
+
+```swift
+struct ContentView: View {
+
+ @Environment(\.oauth)
+ var oauth: OAuth
+
+ var body: some View {
+ VStack {
+ switch oauth.state {
+ case .empty:
+ providerList
+ case .authorizing(let provider, let grantType):
+ Text("Authorizing [\(provider.id)] with [\(grantType.rawValue)]")
+ case .requestingAccessToken(let provider):
+ Text("Requesting Access Token [\(provider.id)]")
+ case .requestingDeviceCode(let provider):
+ Text("Requesting Device Code [\(provider.id)]")
+ case .authorized(let provider, _):
+ Button("Authorized [\(provider.id)]") {
+ oauth.clear()
+ }
+ case .receivedDeviceCode(_, let deviceCode):
+ Text("To login, visit")
+ Text(.init("[\(deviceCode.verificationUri)](\(deviceCode.verificationUri))"))
+ .foregroundStyle(.blue)
+ Text("and enter the following code:")
+ Text(deviceCode.userCode)
+ }
+ }
+ .onChange(of: oauth.state) { oldState, newState in
+ handle(state: newState)
+ }
+ }
+}
+```
diff --git a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md
index 36a5547..6338fe2 100644
--- a/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md
+++ b/Sources/OAuthKit/OAuthKit.docc/OAuthKit.md
@@ -41,4 +41,5 @@ This has the advantage of avoiding direct coupling with an authorization flow, e
- ``OAuth/GrantType``
### State Observability
+- ``OAuth/State``
- ``OAuth/state``