Skip to content

Commit bc90fb5

Browse files
mykyta-fronteggdianaKhortiuk-fronteggclaude
authored
FR-24939. (#73)
* FR-24939. Added SPM support. * chore(ios): bump FronteggSwift SPM pin 1.3.8 -> 1.3.10 (latest) Avoid regressing the iOS SDK: master is on FronteggSwift 1.3.10 (admin-portal native bridge). Pin the SPM migration to 1.3.10 across Package.swift, frontegg_spm.rb, the example Package.resolved + pbxproj SPM ref, and docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: dianaKhortiuk-frontegg <diana.khortiuk@frontegg.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 03a78d6 commit bc90fb5

16 files changed

Lines changed: 700 additions & 121 deletions

File tree

FronteggRN.podspec

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ Pod::Spec.new do |s|
1515
s.source = { :git => "https://github.com/frontegg/frontegg-react-native.git", :tag => "#{s.version}" }
1616

1717
s.source_files = "ios/**/*.{h,m,mm,swift}"
18+
s.exclude_files = "ios/Package.swift"
1819

1920
# Use install_modules_dependencies helper to install the dependencies if React Native version >=0.71.0.
2021
# See https://github.com/facebook/react-native/blob/febf6b7f33fdb4904669f99d795eba4c0f95d7bf/scripts/cocoapods/new_architecture.rb#L79.
22+
# FronteggSwift via SPM — linked in post_integrate by ios/frontegg_spm.rb (see docs/setup.md).
23+
2124
if respond_to?(:install_modules_dependencies, true)
2225
install_modules_dependencies(s)
23-
s.dependency "FronteggSwift", "1.3.10"
2426
else
2527
s.dependency "React-Core"
26-
s.dependency "FronteggSwift", "1.3.10"
2728

2829
# Don't install the dependencies when we run `pod install` in the old architecture.
2930
if ENV['RCT_NEW_ARCH_ENABLED'] == '1' then

android/src/main/java/com/frontegg/reactnative/FronteggRNModule.kt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import com.frontegg.android.AdminPortalActivity
1414
import com.frontegg.android.fronteggAuth
1515
import io.reactivex.rxjava3.core.Observable
1616
import io.reactivex.rxjava3.disposables.Disposable
17+
import kotlin.time.DurationUnit
18+
import kotlin.time.toDuration
1719

1820

1921
class FronteggRNModule(val reactContext: ReactApplicationContext) :
@@ -158,6 +160,31 @@ class FronteggRNModule(val reactContext: ReactApplicationContext) :
158160
}
159161
}
160162

163+
@ReactMethod
164+
fun isSteppedUp(maxAgeSeconds: Double, promise: Promise) {
165+
val maxAge =
166+
if (maxAgeSeconds < 0) null else maxAgeSeconds.toDuration(DurationUnit.SECONDS)
167+
promise.resolve(auth.isSteppedUp(maxAge))
168+
}
169+
170+
@ReactMethod
171+
fun stepUp(maxAgeSeconds: Double, promise: Promise) {
172+
val activity = currentActivity
173+
if (activity == null) {
174+
promise.reject("NO_ACTIVITY", "Current activity is null")
175+
return
176+
}
177+
val maxAge =
178+
if (maxAgeSeconds < 0) null else maxAgeSeconds.toDuration(DurationUnit.SECONDS)
179+
auth.stepUp(activity, maxAge) { error ->
180+
if (error != null) {
181+
promise.reject("STEP_UP_ERROR", error.message, error)
182+
} else {
183+
promise.resolve(null)
184+
}
185+
}
186+
}
187+
161188
@ReactMethod
162189
fun requestAuthorize(refreshToken: String, deviceTokenCookie: String?, promise: Promise) {
163190
try {

docs/setup.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,85 @@ This section guides you through configuring the Frontegg React Native SDK for bo
44

55
## Setup iOS Project
66

7+
### Integrate FronteggSwift via Swift Package Manager
8+
9+
The iOS native SDK (`FronteggSwift`) is delivered through **Swift Package Manager (SPM)** only. The CocoaPods pod `FronteggSwift` is **not** used (previously pinned at `1.2.76`). React Native still uses CocoaPods for `FronteggRN` and other dependencies; `FronteggSwift` is linked into the `FronteggRN` pod target via SPM after `pod install`.
10+
11+
**Requirements:** Xcode **15+**, iOS deployment target **14.0+**, CocoaPods.
12+
13+
#### 1. Update `ios/Podfile`
14+
15+
Inside your app target (the same block as `use_native_modules!`):
16+
17+
```ruby
18+
target 'YourApp' do
19+
# Required so the FronteggRN pod can import the FronteggSwift SPM product.
20+
use_frameworks! :linkage => :static
21+
22+
config = use_native_modules!
23+
# ... use_react_native! etc.
24+
```
25+
26+
After `post_install` (do **not** put the SPM hook inside `post_install` — CocoaPods would overwrite the patched `Pods` project):
27+
28+
```ruby
29+
post_install do |installer|
30+
react_native_post_install(installer, config[:reactNativePath], :mac_catalyst_enabled => false)
31+
# ...your other post_install hooks...
32+
end
33+
34+
post_integrate do |installer|
35+
require_relative '../node_modules/@frontegg/react-native/ios/frontegg_spm'
36+
FronteggSPM.link_frontegg_rn_pod(installer)
37+
end
38+
end
39+
```
40+
41+
Adjust the `require_relative` path if your `node_modules` layout differs (monorepo, etc.).
42+
43+
#### 2. Install pods
44+
45+
From the `ios` directory:
46+
47+
```bash
48+
cd ios
49+
bundle exec pod install # recommended if you use a Gemfile
50+
```
51+
52+
**React Native 0.72:** if `pod install` fails downloading `boost`, add the boost URL workaround at the top of your `Podfile` (see the [example `ios/Podfile`](https://github.com/frontegg/frontegg-react-native/blob/master/example/ios/Podfile)).
53+
54+
#### 3. Build and run
55+
56+
- Open **`YourApp.xcworkspace`** (not `.xcodeproj`).
57+
- For local development on a **simulator**, prefer:
58+
59+
```bash
60+
cd ..
61+
yarn start # Metro — one terminal
62+
yarn ios --simulator "iPhone 17 Pro Max"
63+
```
64+
65+
If a physical iPhone is connected, React Native may target the device and fail on code signing (`com.your.bundle`). Use `--simulator` or disconnect the device.
66+
67+
The `frontegg_spm` helper pins **FronteggSwift 1.3.10** from `https://github.com/frontegg/frontegg-ios-swift.git`, links it to the **FronteggRN** CocoaPods target, and configures the app Xcode project so SPM resolves without duplicate symbol errors at link time.
68+
69+
> **Embedded mode step-up:** `FronteggSwift` **1.3.10** routes `stepUp()` through the embedded `WKWebView` when `embeddedMode` is enabled (instead of `ASWebAuthenticationSession`), so MFA/step-up reuses the existing web session. Set `<key>embeddedMode</key><true/>` in `Frontegg.plist` if you use the embedded login box.
70+
71+
#### Step-up from JavaScript
72+
73+
```ts
74+
import { isSteppedUp, stepUp } from '@frontegg/react-native';
75+
76+
const maxAgeSeconds = 60;
77+
if (await isSteppedUp(maxAgeSeconds)) {
78+
// already stepped up
79+
} else {
80+
await stepUp(maxAgeSeconds);
81+
}
82+
```
83+
84+
See the [example `HomeScreen`](https://github.com/frontegg/frontegg-react-native/blob/master/example/src/HomeScreen.tsx) for a **Sensitive action** button matching the native iOS SDK demo.
85+
786
### Create Frontegg.plist
887

988
1. Add a new file named `Frontegg.plist` to your root project directory.

example/Gemfile.lock

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ GEM
4949
cocoapods-plugins (1.0.0)
5050
nap
5151
cocoapods-search (1.0.1)
52+
cocoapods-spm (0.1.20)
53+
xcodeproj (>= 1.23.0)
5254
cocoapods-trunk (1.6.0)
5355
nap (>= 0.8, < 2.0)
5456
netrc (~> 0.11)
@@ -92,6 +94,7 @@ PLATFORMS
9294

9395
DEPENDENCIES
9496
cocoapods (~> 1.12)
97+
cocoapods-spm (~> 0.1.20)
9598

9699
RUBY VERSION
97100
ruby 2.6.10p210

example/README.md

Lines changed: 14 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,32 @@
1-
This is a new [**React Native**](https://reactnative.dev) project, bootstrapped using [`@react-native-community/cli`](https://github.com/react-native-community/cli).
1+
# Frontegg React Native — example app
22

3-
# Getting Started
3+
## Prerequisites
44

5-
>**Note**: Make sure you have completed the [React Native - Environment Setup](https://reactnative.dev/docs/environment-setup) instructions till "Creating a new application" step, before proceeding.
5+
- [React Native environment](https://reactnative.dev/docs/environment-setup) (Node, Xcode 15+, CocoaPods)
6+
- Configure `ios/Frontegg.plist` with your Frontegg `baseUrl` and `clientId` (see [Setup Guide](../docs/setup.md))
67

7-
## Step 1: Start the Metro Server
8+
## iOS (SPM + CocoaPods)
89

9-
First, you will need to start **Metro**, the JavaScript _bundler_ that ships _with_ React Native.
10-
11-
To start Metro, run the following command from the _root_ of your React Native project:
10+
From the **example** directory:
1211

1312
```bash
14-
# using npm
15-
npm start
16-
17-
# OR using Yarn
18-
yarn start
13+
yarn install
14+
cd ios && bundle exec pod install && cd ..
15+
yarn start # terminal 1
16+
yarn ios --simulator "iPhone 17 Pro Max" # terminal 2 — use an available simulator name
1917
```
2018

21-
## Step 2: Start your Application
19+
Open `ios/ReactNativeExample.xcworkspace` in Xcode if you build from the IDE.
2220

23-
Let Metro Bundler run in its _own_ terminal. Open a _new_ terminal from the _root_ of your React Native project. Run the following command to start your _Android_ or _iOS_ app:
21+
> Use `--simulator` when a physical iPhone is connected, otherwise `yarn ios` may try to deploy to the device and fail on provisioning.
2422
25-
### For Android
23+
## Android
2624

2725
```bash
28-
# using npm
29-
npm run android
30-
31-
# OR using Yarn
3226
yarn android
3327
```
3428

35-
### For iOS
36-
37-
```bash
38-
# using npm
39-
npm run ios
40-
41-
# OR using Yarn
42-
yarn ios
43-
```
44-
45-
If everything is set up _correctly_, you should see your new app running in your _Android Emulator_ or _iOS Simulator_ shortly provided you have set up your emulator/simulator correctly.
46-
47-
This is one way to run your app — you can also run it directly from within Android Studio and Xcode respectively.
48-
49-
## Step 3: Modifying your App
50-
51-
Now that you have successfully run the app, let's modify it.
52-
53-
1. Open `App.tsx` in your text editor of choice and edit some lines.
54-
2. For **Android**: Press the <kbd>R</kbd> key twice or select **"Reload"** from the **Developer Menu** (<kbd>Ctrl</kbd> + <kbd>M</kbd> (on Window and Linux) or <kbd>Cmd ⌘</kbd> + <kbd>M</kbd> (on macOS)) to see your changes!
55-
56-
For **iOS**: Hit <kbd>Cmd ⌘</kbd> + <kbd>R</kbd> in your iOS Simulator to reload the app and see your changes!
57-
58-
## Congratulations! :tada:
59-
60-
You've successfully run and modified your React Native App. :partying_face:
61-
62-
### Now what?
63-
64-
- If you want to add this new React Native code to an existing application, check out the [Integration guide](https://reactnative.dev/docs/integration-with-existing-apps).
65-
- If you're curious to learn more about React Native, check out the [Introduction to React Native](https://reactnative.dev/docs/getting-started).
66-
67-
# Troubleshooting
68-
69-
If you can't get this to work, see the [Troubleshooting](https://reactnative.dev/docs/troubleshooting) page.
70-
71-
# Learn More
29+
## More
7230

7331
To learn more about React Native, take a look at the following resources:
7432

example/ios/Podfile

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
# boostorg.jfrog.io often returns a bad tarball; use archives.boost.io (RN 0.72 workaround).
2+
boost_podspec_path = File.expand_path('../node_modules/react-native/third-party-podspecs/boost.podspec', __dir__)
3+
if File.exist?(boost_podspec_path)
4+
boost_podspec = File.read(boost_podspec_path)
5+
unless boost_podspec.include?('archives.boost.io')
6+
File.write(
7+
boost_podspec_path,
8+
boost_podspec.gsub(
9+
'https://boostorg.jfrog.io/artifactory/main/release/1.76.0/source/boost_1_76_0.tar.bz2',
10+
'https://archives.boost.io/release/1.76.0/source/boost_1_76_0.tar.bz2'
11+
)
12+
)
13+
end
14+
end
15+
116
# Resolve react_native_pods.rb with node to allow for hoisting
217
require Pod::Executable.execute_command('node', ['-p',
318
'require.resolve(
@@ -26,6 +41,9 @@ if linkage != nil
2641
end
2742

2843
target 'ReactNativeExample' do
44+
# Required so FronteggRN (Swift) can import the FronteggSwift SPM product.
45+
use_frameworks! :linkage => :static
46+
2947
config = use_native_modules!
3048

3149
# Flags change depending on the env values.
@@ -59,4 +77,9 @@ target 'ReactNativeExample' do
5977
)
6078
__apply_Xcode_12_5_M1_post_install_workaround(installer)
6179
end
80+
81+
post_integrate do |installer|
82+
require_relative '../../ios/frontegg_spm'
83+
FronteggSPM.link_frontegg_rn_pod(installer)
84+
end
6285
end

example/ios/Podfile.lock

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,9 @@ PODS:
1010
- React-jsi (= 0.72.1)
1111
- ReactCommon/turbomodule/core (= 0.72.1)
1212
- fmt (6.2.1)
13-
- FronteggRN (1.2.14):
14-
- FronteggSwift (= 1.2.76)
13+
- FronteggRN (1.2.16):
1514
- RCT-Folly (= 2021.07.22.00)
1615
- React-Core
17-
- FronteggSwift (1.2.76):
18-
- Sentry (~> 8.46.0)
1916
- glog (0.3.5)
2017
- hermes-engine (0.72.1):
2118
- hermes-engine/Pre-built (= 0.72.1)
@@ -436,9 +433,6 @@ PODS:
436433
- RCT-Folly (= 2021.07.22.00)
437434
- React-Core
438435
- React-RCTImage
439-
- Sentry (8.46.0):
440-
- Sentry/Core (= 8.46.0)
441-
- Sentry/Core (8.46.0)
442436
- SocketRocket (0.6.1)
443437
- Yoga (1.14.0)
444438

@@ -491,9 +485,7 @@ DEPENDENCIES:
491485
SPEC REPOS:
492486
trunk:
493487
- fmt
494-
- FronteggSwift
495488
- libevent
496-
- Sentry
497489
- SocketRocket
498490

499491
EXTERNAL SOURCES:
@@ -589,8 +581,7 @@ SPEC CHECKSUMS:
589581
FBLazyVector: 55cd4593d570bd9e5e227488d637ce6a9581ce51
590582
FBReactNativeSpec: 799b0e1a1561699cd0e424e24fe5624da38402f0
591583
fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9
592-
FronteggRN: 38e704aa6bc3999f1251361e3bd17ff3ee4859b9
593-
FronteggSwift: df127087b79c5fc65240805136f36c7c28d4988d
584+
FronteggRN: ce2450115a3c86ad7dbcd5b991fe1ff2bcab04a7
594585
glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b
595586
hermes-engine: 9df83855a0fd15ef8eb61694652bae636b0c466e
596587
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
@@ -599,39 +590,38 @@ SPEC CHECKSUMS:
599590
RCTTypeSafety: 75fa444becadf0ebfa0a456b8c64560c7c89c7df
600591
React: 3e5b3962f27b7334eaf5517a35b3434503df35ad
601592
React-callinvoker: c3a225610efe0caadac78da53b6fe78e53eb2b03
602-
React-Codegen: fa4e79f8d56b5aa5f91d45984d21c21b31e211c8
603-
React-Core: cbfc97c3c0061d4fdaca617357086ba1347c730e
604-
React-CoreModules: 0d18899272223a2a038e4c2313a7760ca6b280a7
605-
React-cxxreact: f78070b70980e9e19fb448fec9d49a9181952535
606-
React-debug: 8aa2bd54b0f0011049300ce3339b0e51254ef3b5
607-
React-hermes: c783d9dcf275ec48f97b164824dcdfdda480e6a6
608-
React-jsi: cc0d4c585001fca0979591587e00e6d2a4c13820
609-
React-jsiexecutor: a2b883b0e3fbc606a1e6e97a15059b71d6da1715
593+
React-Codegen: 319a74f758104130092a5984431045056c32fbab
594+
React-Core: 40003a89fd94da98b03c3fad8834871299485cfa
595+
React-CoreModules: 1304c0710deb87054623ccc9c552e23a1fcce219
596+
React-cxxreact: f82f0f1832606fabb9e8c9d61c4230704a3d2d2f
597+
React-debug: 3e34ac6fb438f0e8c05a1678eedd6ebd8928245c
598+
React-hermes: f076cb5f7351d6cc1600125bef3259ea880460fb
599+
React-jsi: 9f381c8594161b2328b93cd3ba5d0bcfcd1e093a
600+
React-jsiexecutor: 184eae1ecdedc7a083194bd9ff809c93f08fd34c
610601
React-jsinspector: d0b5bfd1085599265f4212034321e829bdf83cc0
611-
React-logger: 70abe174614ac3f165e02ab8300fec50d2f9572d
612-
react-native-safe-area-context: 8745463257fac6150abd2281b02de640b3595ec7
613-
React-NativeModulesApple: 3f444b421d3c1e463414cb5aee385c4ffe6bae42
602+
React-logger: b8103c9b04e707b50cdd2b1aeb382483900cbb37
603+
react-native-safe-area-context: 9697629f7b2cda43cf52169bb7e0767d330648c2
604+
React-NativeModulesApple: bdfd86e972ea8103941faab9c7f64ea9be7e2be6
614605
React-perflogger: 3d501f34c8d4b10cb75f348e43591765788525ad
615606
React-RCTActionSheet: f5335572c979198c0c3daff67b07bd1ad8370c1d
616-
React-RCTAnimation: 5d0d31a4f9c49a70f93f32e4da098fb49b5ae0b3
617-
React-RCTAppDelegate: d285573b1d55da98149560f38df549293e4eb20d
618-
React-RCTBlob: f7777ca0bad9e6d98efe921003f9f3cca70730f1
619-
React-RCTImage: e15d22db53406401cdd1407ce51080a66a9c7ed4
620-
React-RCTLinking: 39815800ec79d6fb15e6329244d195ebeabf7541
621-
React-RCTNetwork: 2a6548e13d2577b112d4250ac5be74ae62e1e86b
622-
React-RCTSettings: a76aee44d5398144646be146c334b15c90ad9582
607+
React-RCTAnimation: 897b1170a1e934dee9b7eb7d5582920dea72c1c8
608+
React-RCTAppDelegate: f8dc4f198bb7a7fdc9ccd5a6e246936bbdacbe42
609+
React-RCTBlob: b69213136de8eed26fdf112602e8aaf91923093c
610+
React-RCTImage: 9f2303a18cec1f715a447dca5b82021643661e6b
611+
React-RCTLinking: f88453408f33a99f36bb4f6e11278ffbb81aa45f
612+
React-RCTNetwork: 5ef8d399ad389442404683d2572007ace0e26076
613+
React-RCTSettings: 516d917b059c94f33f85f601974429de7c3d34ca
623614
React-RCTText: afad390f3838f210c2bc9e1a19bb048003b2a771
624-
React-RCTVibration: 29bbaa5c57c02dc036d7e557584b492000b1d3e7
615+
React-RCTVibration: 28cc9ac2c062b515f207a1743f0f27083d62acc5
625616
React-rncore: 50966ce412d63bee9ffe5c98249857c23870a3c4
626617
React-runtimeexecutor: d129f2b53d61298093d7c7d8ebfafa664f911ce6
627-
React-runtimescheduler: c8f959651fd874b93feeb32781b1e402a6801ec2
628-
React-utils: c9e15d684b491d6324b4139790306836f0e8b1d6
629-
ReactCommon: f7d2978a6f8e8552a4908f067e65d4cfda686138
630-
RNScreens: 67dd26e0c1e6df63f4ccaaf281c1ecdd88c995c3
631-
Sentry: da60d980b197a46db0b35ea12cb8f39af48d8854
618+
React-runtimescheduler: 34e27d6db52587cf93e7d9d44d5ff2dc4948243a
619+
React-utils: 4324c58d17bcbcb8c49fe7f8c14b4f61d5dd4a42
620+
ReactCommon: e33f60179aae29423fcf4ea19fdedc038813ea3f
621+
RNScreens: 835807a1f3c74c8ea0d0b9e089bf14333141f17f
632622
SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17
633623
Yoga: 65286bb6a07edce5e4fe8c90774da977ae8fc009
634624

635-
PODFILE CHECKSUM: 010992354d93ba29cfe4cff5fab47f9b2920a2da
625+
PODFILE CHECKSUM: fc09f9972b0d9b6a48315e1f02b457d29013ffd5
636626

637-
COCOAPODS: 1.16.2
627+
COCOAPODS: 1.14.3

0 commit comments

Comments
 (0)