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

ASW prototype #1780

Draft
wants to merge 4 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 1 commit
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
39 changes: 36 additions & 3 deletions AdyenActions/Components/Redirect/BrowserComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,46 @@
//

@_spi(AdyenInternal) import Adyen
import AuthenticationServices
import SafariServices
import UIKit

internal protocol BrowserComponentDelegate: AnyObject {
func didCancel()
func didFail(error: Error)
func didOpenExternalApplication()
}

@available(iOS 17.4, *)
internal final class ASWebComponent: NSObject, ASWebAuthenticationPresentationContextProviding {
func presentationAnchor(for session: ASWebAuthenticationSession) -> ASPresentationAnchor {
UIApplication.shared.keyWindow!
}

internal weak var delegate: BrowserComponentDelegate?
private var session: ASWebAuthenticationSession?

internal init(url: URL) {
self.url = url
}

private let url: URL

func start() {
session = ASWebAuthenticationSession(url: url,
callback: ASWebAuthenticationSession.Callback.customScheme("myapp"),
completionHandler: { [weak delegate] url, error in
if let url {
RedirectComponent.applicationDidOpen(from: url)
} else {
delegate?.didFail(error: error ?? ComponentError.cancelled)
}
})
session?.presentationContextProvider = self
session?.start()
}

}

/// A component that opens a URL in web browsed and presents it.
internal final class BrowserComponent: NSObject, PresentableComponent {

Expand All @@ -24,6 +56,7 @@ internal final class BrowserComponent: NSObject, PresentableComponent {
private let componentName = "browser"

internal lazy var viewController: UIViewController = {

let safariViewController = SFSafariViewController(url: url)
safariViewController.delegate = self
safariViewController.modalPresentationStyle = style?.modalPresentationStyle ?? .formSheet
Expand Down Expand Up @@ -64,7 +97,7 @@ internal final class BrowserComponent: NSObject, PresentableComponent {
if didOpenExternalApp {
self.delegate?.didOpenExternalApplication()
} else {
self.delegate?.didCancel()
self.delegate?.didFail(error: ComponentError.cancelled)
}
}
}
Expand All @@ -82,7 +115,7 @@ extension BrowserComponent: SFSafariViewControllerDelegate, UIAdaptivePresentati

/// Called when user drag VC down to dismiss.
internal func presentationControllerDidDismiss(_ presentationController: UIPresentationController) {
self.delegate?.didCancel()
self.delegate?.didFail(error: ComponentError.cancelled)
}

/// Called when the user opens the current page in the default browser by tapping the toolbar button.
Expand Down
27 changes: 17 additions & 10 deletions AdyenActions/Components/Redirect/RedirectComponent.swift
Original file line number Diff line number Diff line change
Expand Up @@ -64,8 +64,8 @@ public final class RedirectComponent: ActionComponent {
APIClient(apiContext: context.apiContext).retryAPIClient(with: SimpleScheduler(maximumCount: 2))
}()

private var browserComponent: BrowserComponent?
private var browserComponent: NSObject?

/// The component configurations.
public var configuration: Configuration

Expand Down Expand Up @@ -132,12 +132,19 @@ public final class RedirectComponent: ActionComponent {
}

private func openInAppBrowser(_ action: RedirectAction) {
let component = BrowserComponent(url: action.url,
context: context,
style: configuration.style)
component.delegate = self
browserComponent = component
presentationDelegate?.present(component: component)
if #available(iOS 17.4, *) {
let aswCOnponent = ASWebComponent(url: action.url)
aswCOnponent.delegate = self
aswCOnponent.start()
browserComponent = aswCOnponent
} else {
let component = BrowserComponent(url: action.url,
context: context,
style: configuration.style)
component.delegate = self
browserComponent = component
presentationDelegate?.present(component: component)
}
}

// MARK: - Custom scheme link handling
Expand Down Expand Up @@ -197,13 +204,13 @@ public final class RedirectComponent: ActionComponent {

extension RedirectComponent: BrowserComponentDelegate {

internal func didCancel() {
func didFail(error: any Swift.Error) {
if browserComponent != nil {
browserComponent = nil
delegate?.didFail(with: ComponentError.cancelled, from: self)
}
}

internal func didOpenExternalApplication() {
delegate?.didOpenExternalApplication(component: self)
}
Expand Down
Loading