Skip to content

Commit cc20211

Browse files
committed
feat: start implementing ASWebAuthenticationSession
1 parent 8dbadf8 commit cc20211

8 files changed

+118
-1
lines changed

example/App.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import {
2424
InAppBrowser,
2525
SFSafariViewController,
2626
ModalPresentationStyle,
27+
ASWebAuthenticationSession,
2728
ChromeCustomTabs,
2829
} from 'react-native-in-app-browser'
2930

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

6263
const URL = 'https://reactnative.dev'
64+
const AUTH_URL = 'https://github.com/login'
6365

6466
function App(): React.JSX.Element {
6567
const isDarkMode = useColorScheme() === 'dark'
@@ -114,6 +116,16 @@ function App(): React.JSX.Element {
114116
}}
115117
/>
116118
</Section>
119+
<Section title="🍎 ASWebAuthenticationSession">
120+
<Button
121+
title={`start(${AUTH_URL})`}
122+
onPress={() => {
123+
ASWebAuthenticationSession.start({
124+
url: AUTH_URL,
125+
})
126+
}}
127+
/>
128+
</Section>
117129
<Section title="🤖 ChromeCustomTabs">
118130
<Button
119131
title={`launch(${URL})`}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import Foundation
2+
import AuthenticationServices
3+
4+
class HybridASWebAuthenticationSession: HybridASWebAuthenticationSessionSpec {
5+
var hybridContext = margelo.nitro.HybridContext()
6+
7+
var memorySize: Int {
8+
return getSizeOf(self)
9+
}
10+
11+
private var authSession: ASWebAuthenticationSession?
12+
13+
var prefersEphemeralWebBrowserSession: Bool = false
14+
15+
func start(params: ASWebAuthenticationSessionStartParams) throws -> Void {
16+
NSLog("HybridASWebAuthenticationSession.start(url:%@) is being called", params.url)
17+
18+
guard let nativeUrl = URL(string: params.url) else {
19+
throw NSError(domain: "HybridASWebAuthenticationSession", code: 0, userInfo: [NSLocalizedDescriptionKey: "Invalid URL"])
20+
}
21+
22+
authSession = ASWebAuthenticationSession(url: nativeUrl, callbackURLScheme: nil) { session, error in
23+
if let error = error {
24+
NSLog("ASWebAuthenticationSession failed with error: %@", error.localizedDescription)
25+
// TODO: Implement error handling and callback to JavaScript
26+
} else if let callbackURL = session {
27+
NSLog("ASWebAuthenticationSession succeeded with URL: %@", callbackURL.absoluteString)
28+
// TODO: Implement success callback to JavaScript with the callbackURL
29+
} else {
30+
NSLog("ASWebAuthenticationSession completed without error or callback URL")
31+
// TODO: Implement callback to JavaScript for completion without result
32+
}
33+
34+
self.authSession = nil
35+
}
36+
37+
if !(authSession?.start() ?? false) {
38+
throw NSError(domain: "HybridASWebAuthenticationSession", code: 1, userInfo: [NSLocalizedDescriptionKey: "ASWebAuthenticationSession failed to start"])
39+
}
40+
}
41+
42+
func cancel() throws -> Void {
43+
guard let authSession = authSession else {
44+
throw NSError(domain: "HybridASWebAuthenticationSession", code: 2, userInfo: [NSLocalizedDescriptionKey: "ASWebAuthenticationSession is not initialized"])
45+
}
46+
47+
authSession.cancel()
48+
self.authSession = nil
49+
}
50+
}

nitro.json

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
"SFSafariViewController": {
1212
"swift": "HybridSFSafariViewController"
1313
},
14+
"ASWebAuthenticationSession": {
15+
"swift": "HybridASWebAuthenticationSession"
16+
},
1417
"ChromeCustomTabs": {
1518
"kotlin": "HybridChromeCustomTabs"
1619
}

nitrogen/generated/ios/NitroInAppBrowserAutolinking.mm

+8
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#import <type_traits>
1212

1313
#include "HybridSFSafariViewControllerSpecSwift.hpp"
14+
#include "HybridASWebAuthenticationSessionSpecSwift.hpp"
1415

1516
@interface NitroInAppBrowserAutolinking : NSObject
1617
@end
@@ -28,6 +29,13 @@ + (void) load {
2829
return std::make_shared<HybridSFSafariViewControllerSpecSwift>(swiftPart);
2930
}
3031
);
32+
HybridObjectRegistry::registerHybridObjectConstructor(
33+
"ASWebAuthenticationSession",
34+
[]() -> std::shared_ptr<HybridObject> {
35+
auto swiftPart = NitroInAppBrowser::NitroInAppBrowserAutolinking::createASWebAuthenticationSession();
36+
return std::make_shared<HybridASWebAuthenticationSessionSpecSwift>(swiftPart);
37+
}
38+
);
3139
}
3240

3341
@end

nitrogen/generated/ios/NitroInAppBrowserAutolinking.swift

+12
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,16 @@ public final class NitroInAppBrowserAutolinking {
1717
let hybridObject = HybridSFSafariViewController()
1818
return hybridObject.createCxxBridge()
1919
}
20+
21+
/**
22+
* Creates an instance of a Swift class that implements `HybridASWebAuthenticationSessionSpec`,
23+
* and wraps it in a Swift class that can directly interop with C++ (`HybridASWebAuthenticationSessionSpecCxx`)
24+
*
25+
* This is generated by Nitrogen and will initialize the class specified
26+
* in the `"autolinking"` property of `nitro.json` (in this case, `HybridASWebAuthenticationSession`).
27+
*/
28+
public static func createASWebAuthenticationSession() -> HybridASWebAuthenticationSessionSpecCxx {
29+
let hybridObject = HybridASWebAuthenticationSession()
30+
return hybridObject.createCxxBridge()
31+
}
2032
}

src/ASWebAuthenticationSession.ts

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Platform } from 'react-native'
2+
import { NitroModules } from 'react-native-nitro-modules'
3+
import type { ASWebAuthenticationSession as ASWebAuthenticationSessionType } from './specs/ASWebAuthenticationSession.nitro'
4+
5+
export * from './specs/ASWebAuthenticationSession.nitro'
6+
7+
let ASWebAuthenticationSession: ASWebAuthenticationSessionType
8+
9+
const ASWebAuthenticationSessionStub: ASWebAuthenticationSessionType = {
10+
name: 'ASWebAuthenticationSession',
11+
equals: () => false,
12+
dispose: () => {},
13+
prefersEphemeralWebBrowserSession: false,
14+
start: () => {
15+
console.warn('ASWebAuthenticationSession.start is only supported on iOS.')
16+
},
17+
cancel: () => {
18+
console.warn('ASWebAuthenticationSession.cancel is only supported on iOS.')
19+
},
20+
}
21+
22+
if (Platform.OS === 'ios') {
23+
ASWebAuthenticationSession =
24+
NitroModules.createHybridObject<ASWebAuthenticationSessionType>(
25+
'ASWebAuthenticationSession'
26+
)
27+
} else {
28+
ASWebAuthenticationSession = ASWebAuthenticationSessionStub
29+
}
30+
31+
export { ASWebAuthenticationSession }

src/index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ export * from './InAppBrowser'
33

44
// Platform specific interfaces
55
export * from './SFSafariViewController'
6+
export * from './ASWebAuthenticationSession'
67
export * from './ChromeCustomTabs'

src/specs/ASWebAuthenticationSession.nitro.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ import type { HybridObject } from 'react-native-nitro-modules'
22

33
export interface ASWebAuthenticationSession
44
extends HybridObject<{ ios: 'swift' }> {
5+
prefersEphemeralWebBrowserSession: boolean
56
start(params: ASWebAuthenticationSessionStartParams): void
67
cancel(): void
7-
prefersEphemeralWebBrowserSession: boolean
88
}
99

1010
export interface ASWebAuthenticationSessionStartParams {

0 commit comments

Comments
 (0)