Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Document WebAuthentication #27

Merged
merged 1 commit into from
Aug 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion Sources/SafariUI/SafariUI.docc/SafariUI.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ SafariServices in SwiftUI

## Overview

`SafariUI` is a package that wraps [`SafariServices`](https://developer.apple.com/documentation/safariservices/) for use with SwiftUI applications. Currently, it contains a single SwiftUI view, called `SafariView`, which wraps [`SFSafariViewController`](https://developer.apple.com/documentation/safariservices/sfsafariviewcontroller).
`SafariUI` is a package that allows you to display instances of Safari inside your SwiftUI applications. Use ``WebAuthentication`` when using Safari to authenticate users, and ``SafariView`` for a standard Safari experience.

## Topics

Expand Down
2 changes: 1 addition & 1 deletion Sources/SafariUI/SafariUI.docc/SafariView.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

## Overview

The view includes Safari features such as Reader, AutoFill, Fraudulent Website Detection, and content blocking. The user's activity and interaction with `SafariView` are not visible to your app, which cannot access AutoFill data, browsing history, or website data. You do not need to secure data between your app and Safari. If you would like to share data between your app and Safari, so it is easier for a user to log in only one time, use [`ASWebAuthenticationSession`](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession) instead.
The view includes Safari features such as Reader, AutoFill, Fraudulent Website Detection, and content blocking. The user's activity and interaction with `SafariView` are not visible to your app, which cannot access AutoFill data, browsing history, or website data. You do not need to secure data between your app and Safari. If you would like to share data between your app and Safari, so it is easier for a user to log in only one time, use ``WebAuthentication`` instead.

- Important: In accordance with [App Store Review Guidelines](https://developer.apple.com/app-store/review/guidelines/), this view must be used to visibly present information to users; the view may not be hidden or obscured by other views or layers. Additionally, an app may not use `SafariView` to track users without their knowledge and consent.

Expand Down
17 changes: 17 additions & 0 deletions Sources/SafariUI/SafariUI.docc/WebAuthentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# ``WebAuthentication``

@Metadata {
@DocumentationExtension(mergeBehavior: append)
}

## Overview

Use a `WebAuthentication` instance to authenticate a user through a web service, including one run by a third party. Initialize the session with a URL that points to the authentication webpage. When the user starts the authentication session, the operating system shows a modal view telling them which domain the app is authenticating with and asking whether to proceed. If the user proceeds with the authentication attempt, a browser loads and displays the page, from which the user can authenticate. In iOS, the browser is a secure, embedded web view. In macOS, the system opens the user’s default browser if it supports web authentication sessions, or Safari otherwise.

On completion, the service sends a callback URL to the session with an authentication token. The session passes this URL back to the app through a completion handler. `AuthenticationSession` ensures that only the calling app’s session receives the authentication callback, even when more than one app registers the same callback URL scheme.

`WebAuthentication` is not a normal SwiftUI view. Unlike ``SafariView``, **must** be presented using one of the following included view modifiers:

- ``SwiftUI/View/webAuthentication(_:webAuthentication:)-74m38``
- ``SwiftUI/View/webAuthentication(_:webAuthentication:)-5x82p``
- ``SwiftUI/View/webAuthentication(_:id:webAuthentication:)``
6 changes: 6 additions & 0 deletions Sources/WebAuthentication/Modifiers.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ import SwiftUI

public extension View {

/// Set the private authentication requirements for authentication sessions within this view.
///
/// This modifier is the equivelent of the of the [`prefersEphemeralWebBrowserSession`](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession/3237231-prefersephemeralwebbrowsersessio) property of a [`ASWebAuthnticationSession`](https://developer.apple.com/documentation/authenticationservices/aswebauthenticationsession)
///
/// - Parameter prefersEphemeralWebBrowserSession: Whether or not the web authentication session should ask for a private authentication session.
/// - Returns: The modified view
func webAuthenticationPrefersEphemeralWebBrowserSession(_ prefersEphemeralWebBrowserSession: Bool = true) -> some View {
let modifer = WebAuthenticationPrefersEphemeralWebBrowserSessionModifier(prefersEphemeralWebBrowserSession: prefersEphemeralWebBrowserSession)
return ModifiedContent(content: self, modifier: modifer)
Expand Down
24 changes: 24 additions & 0 deletions Sources/WebAuthentication/Presentation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ import SwiftUI

public extension View {

/// Presents a ``WebAuthentication`` when a binding to a Boolean value that you provide is `true`.
///
/// Use this method when you want to present a ``WebAuthentication`` to the user when a Boolean value you provide is true.
///
/// - Parameters:
/// - isPresented: A binding to a Boolean value that determines whether to present the ``WebAuthentication`` that you create in the modifier’s content closure.
/// - webAuthentication: A closure that returns the ``WebAuthentication`` to present
/// - Returns: The modified view
func webAuthentication(
_ isPresented: Binding<Bool>,
webAuthentication: @escaping () -> WebAuthentication
Expand All @@ -35,6 +43,14 @@ public extension View {
return ModifiedContent(content: self, modifier: modifier)
}

/// Presents a ``WebAuthentication`` using the given item as a data source for the ``WebAuthentication``'s content
///
/// Use this method when you need to present a ``WebAuthentication`` with content from a custom data source.
///
/// - Parameters:
/// - item: A binding to an optional source of truth for the ``WebAuthentication``. When item is non-nil, the system passes the item’s content to the modifier’s closure. You display this content in a ``WebAuthentication`` that you create that the system displays to the user. If item changes, the system dismisses the ``WebAuthentication`` and replaces it with a new one using the same process.
/// - webAuthentication: A closure that returns the ``WebAuthentication`` to present
/// - Returns: The modified view
func webAuthentication<Item>(
_ item: Binding<Item?>,
webAuthentication: @escaping (Item) -> WebAuthentication
Expand All @@ -43,6 +59,14 @@ public extension View {
return ModifiedContent(content: self, modifier: modifier)
}

/// Presents a ``WebAuthentication`` using the given item as a data source for the ``WebAuthentication``'s content
///
/// Use this method when you need to present a ``WebAuthentication`` with content from a custom data source.
///
/// - Parameters:
/// - item: A binding to an optional source of truth for the ``WebAuthentication``. When item is non-nil, the system passes the item’s content to the modifier’s closure. You display this content in a ``WebAuthentication`` that you create that the system displays to the user. If item changes, the system dismisses the ``WebAuthentication`` and replaces it with a new one using the same process.
/// - id: A keypath used to generate stable identifier for instances of `Item`.
/// - webAuthentication: A closure that returns the ``WebAuthentication`` to present.
func webAuthentication<Item, Identifier>(
_ item: Binding<Item?>,
id: KeyPath<Item, Identifier>,
Expand Down
42 changes: 42 additions & 0 deletions Sources/WebAuthentication/WebAuthentication.swift
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,47 @@ public struct WebAuthentication {
// MARK: - Initializers

/// Create a web authentication session
///
/// You must present a `WebAuthentication` challenge to your users using one of our provided presentation view modifiers:
///
/// - ``SwiftUI/View/webAuthentication(_:webAuthentication:)-74m38``
/// - ``SwiftUI/View/webAuthentication(_:webAuthentication:)-5x82p``
/// - ``SwiftUI/View/webAuthentication(_:id:webAuthentication:)``
///
/// For example:
///
/// ```swift
/// struct AuthenticateButton: View {
/// var body: some View {
///
/// @State
/// var isPresented = false
///
/// static let authURL = URL(string: "https://www.myserver.com/auth?argument=foo")!
/// static let scheme = "myserver"
///
/// Button("Connect Github") {
/// isPresented.toggle()
/// }
/// .webAuthentication($isPresented) {
/// WebAuthentication(
/// url: authURL,
/// callbackURLScheme: scheme
/// ) { result in
/// do {
/// let callback = try result.get()
/// // Authentication complete. Perform callback.
/// } catch {
/// // Authentication failed. Display error message to user.
/// }
/// }
/// }
/// }
/// }
/// ```
///
/// You cannot display a `WebAuthentication` cannot be displayed any other way.
///
/// - Parameters:
/// - url: The URL pointing to the authentication page
/// - callbackURLScheme: The URL scheme that the app should expect when receiving the authentication callback
Expand All @@ -48,6 +89,7 @@ public struct WebAuthentication {

// MARK: - API

/// A completion handler for the web authentication session.
public typealias CompletionHandler = (Result<URL, any Error>) -> Void

// MARK: - Private
Expand Down