Skip to content

Commit

Permalink
feat: start implementing ASWebAuthenticationSession
Browse files Browse the repository at this point in the history
  • Loading branch information
renanmav committed Oct 22, 2024
1 parent 8dbadf8 commit cc20211
Show file tree
Hide file tree
Showing 8 changed files with 118 additions and 1 deletion.
12 changes: 12 additions & 0 deletions example/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import {
InAppBrowser,
SFSafariViewController,
ModalPresentationStyle,
ASWebAuthenticationSession,
ChromeCustomTabs,
} from 'react-native-in-app-browser'

Expand Down Expand Up @@ -60,6 +61,7 @@ function Section({ children, title }: SectionProps): React.JSX.Element {
}

const URL = 'https://reactnative.dev'
const AUTH_URL = 'https://github.com/login'

function App(): React.JSX.Element {
const isDarkMode = useColorScheme() === 'dark'
Expand Down Expand Up @@ -114,6 +116,16 @@ function App(): React.JSX.Element {
}}
/>
</Section>
<Section title="🍎 ASWebAuthenticationSession">
<Button
title={`start(${AUTH_URL})`}
onPress={() => {
ASWebAuthenticationSession.start({
url: AUTH_URL,
})
}}
/>
</Section>
<Section title="🤖 ChromeCustomTabs">
<Button
title={`launch(${URL})`}
Expand Down
50 changes: 50 additions & 0 deletions ios/HybridASWebAuthenticationSession.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import Foundation
import AuthenticationServices

class HybridASWebAuthenticationSession: HybridASWebAuthenticationSessionSpec {
var hybridContext = margelo.nitro.HybridContext()

var memorySize: Int {
return getSizeOf(self)
}

private var authSession: ASWebAuthenticationSession?

var prefersEphemeralWebBrowserSession: Bool = false

func start(params: ASWebAuthenticationSessionStartParams) throws -> Void {
NSLog("HybridASWebAuthenticationSession.start(url:%@) is being called", params.url)

guard let nativeUrl = URL(string: params.url) else {
throw NSError(domain: "HybridASWebAuthenticationSession", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"])
}

authSession = ASWebAuthenticationSession(url: nativeUrl, callbackURLScheme: nil) { session, error in
if let error = error {
NSLog("ASWebAuthenticationSession failed with error: %@", error.localizedDescription)
// TODO: Implement error handling and callback to JavaScript
} else if let callbackURL = session {
NSLog("ASWebAuthenticationSession succeeded with URL: %@", callbackURL.absoluteString)
// TODO: Implement success callback to JavaScript with the callbackURL
} else {
NSLog("ASWebAuthenticationSession completed without error or callback URL")
// TODO: Implement callback to JavaScript for completion without result
}

self.authSession = nil
}

if !(authSession?.start() ?? false) {
throw NSError(domain: "HybridASWebAuthenticationSession", code: 1, userInfo: [NSLocalizedDescriptionKey: "ASWebAuthenticationSession failed to start"])
}
}

func cancel() throws -> Void {
guard let authSession = authSession else {
throw NSError(domain: "HybridASWebAuthenticationSession", code: 2, userInfo: [NSLocalizedDescriptionKey: "ASWebAuthenticationSession is not initialized"])
}

authSession.cancel()
self.authSession = nil
}
}
3 changes: 3 additions & 0 deletions nitro.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
"SFSafariViewController": {
"swift": "HybridSFSafariViewController"
},
"ASWebAuthenticationSession": {
"swift": "HybridASWebAuthenticationSession"
},
"ChromeCustomTabs": {
"kotlin": "HybridChromeCustomTabs"
}
Expand Down
8 changes: 8 additions & 0 deletions nitrogen/generated/ios/NitroInAppBrowserAutolinking.mm
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#import <type_traits>

#include "HybridSFSafariViewControllerSpecSwift.hpp"
#include "HybridASWebAuthenticationSessionSpecSwift.hpp"

@interface NitroInAppBrowserAutolinking : NSObject
@end
Expand All @@ -28,6 +29,13 @@ + (void) load {
return std::make_shared<HybridSFSafariViewControllerSpecSwift>(swiftPart);
}
);
HybridObjectRegistry::registerHybridObjectConstructor(
"ASWebAuthenticationSession",
[]() -> std::shared_ptr<HybridObject> {
auto swiftPart = NitroInAppBrowser::NitroInAppBrowserAutolinking::createASWebAuthenticationSession();
return std::make_shared<HybridASWebAuthenticationSessionSpecSwift>(swiftPart);
}
);
}

@end
12 changes: 12 additions & 0 deletions nitrogen/generated/ios/NitroInAppBrowserAutolinking.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,16 @@ public final class NitroInAppBrowserAutolinking {
let hybridObject = HybridSFSafariViewController()
return hybridObject.createCxxBridge()
}

/**
* Creates an instance of a Swift class that implements `HybridASWebAuthenticationSessionSpec`,
* and wraps it in a Swift class that can directly interop with C++ (`HybridASWebAuthenticationSessionSpecCxx`)
*
* This is generated by Nitrogen and will initialize the class specified
* in the `"autolinking"` property of `nitro.json` (in this case, `HybridASWebAuthenticationSession`).
*/
public static func createASWebAuthenticationSession() -> HybridASWebAuthenticationSessionSpecCxx {
let hybridObject = HybridASWebAuthenticationSession()
return hybridObject.createCxxBridge()
}
}
31 changes: 31 additions & 0 deletions src/ASWebAuthenticationSession.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { Platform } from 'react-native'
import { NitroModules } from 'react-native-nitro-modules'
import type { ASWebAuthenticationSession as ASWebAuthenticationSessionType } from './specs/ASWebAuthenticationSession.nitro'

export * from './specs/ASWebAuthenticationSession.nitro'

let ASWebAuthenticationSession: ASWebAuthenticationSessionType

const ASWebAuthenticationSessionStub: ASWebAuthenticationSessionType = {
name: 'ASWebAuthenticationSession',
equals: () => false,
dispose: () => {},
prefersEphemeralWebBrowserSession: false,
start: () => {
console.warn('ASWebAuthenticationSession.start is only supported on iOS.')
},
cancel: () => {
console.warn('ASWebAuthenticationSession.cancel is only supported on iOS.')
},
}

if (Platform.OS === 'ios') {
ASWebAuthenticationSession =
NitroModules.createHybridObject<ASWebAuthenticationSessionType>(
'ASWebAuthenticationSession'
)
} else {
ASWebAuthenticationSession = ASWebAuthenticationSessionStub
}

export { ASWebAuthenticationSession }
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ export * from './InAppBrowser'

// Platform specific interfaces
export * from './SFSafariViewController'
export * from './ASWebAuthenticationSession'
export * from './ChromeCustomTabs'
2 changes: 1 addition & 1 deletion src/specs/ASWebAuthenticationSession.nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import type { HybridObject } from 'react-native-nitro-modules'

export interface ASWebAuthenticationSession
extends HybridObject<{ ios: 'swift' }> {
prefersEphemeralWebBrowserSession: boolean
start(params: ASWebAuthenticationSessionStartParams): void
cancel(): void
prefersEphemeralWebBrowserSession: boolean
}

export interface ASWebAuthenticationSessionStartParams {
Expand Down

0 comments on commit cc20211

Please sign in to comment.