Skip to content

Commit 28fe855

Browse files
committed
Added Expo config plugin and fixed static linkage Swift header import
1 parent 209aead commit 28fe855

14 files changed

Lines changed: 1260 additions & 12 deletions

Iterable-React-Native-SDK.podspec

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,10 @@ Pod::Spec.new do |s|
2424
'DEFINES_MODULE' => 'YES',
2525
'CLANG_ENABLE_MODULES' => 'YES',
2626
'SWIFT_VERSION' => '5.0',
27+
'SWIFT_OBJC_INTERFACE_HEADER_NAME' => 'Iterable_React_Native_SDK-Swift.h',
2728
"CLANG_CXX_LANGUAGE_STANDARD" => rct_cxx_language_standard(),
29+
# Include paths to generated Swift header for static framework builds
30+
'HEADER_SEARCH_PATHS' => '$(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/Iterable-React-Native-SDK/Iterable_React_Native_SDK.framework/Headers" "${PODS_TARGET_SRCROOT}/ios/RNIterableAPI"',
2831
}
2932

3033
install_modules_dependencies(s)

TESTING_GUIDE.md

Lines changed: 367 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,367 @@
1+
# Testing Guide: Iterable iOS Static Linkage Fix
2+
3+
This guide walks you through testing the iOS static linkage changes and the new Expo config plugin.
4+
5+
---
6+
7+
## Prerequisites
8+
9+
Before starting, ensure you have the following installed:
10+
11+
```bash
12+
# Check Node.js (v18+ recommended)
13+
node --version
14+
15+
# Check Yarn
16+
yarn --version
17+
18+
# Check Ruby (for CocoaPods)
19+
ruby --version
20+
21+
# Check CocoaPods
22+
pod --version
23+
24+
# Check Xcode CLI tools
25+
xcode-select -p
26+
```
27+
28+
If missing any, install them:
29+
30+
```bash
31+
# Install Node.js via Homebrew
32+
brew install node
33+
34+
# Install Yarn
35+
npm install -g yarn
36+
37+
# Install CocoaPods
38+
sudo gem install cocoapods
39+
40+
# Install Xcode CLI tools (if not installed)
41+
xcode-select --install
42+
```
43+
44+
---
45+
46+
## Part 1: Test the React Native SDK Example App
47+
48+
### Step 1: Navigate to the React Native SDK
49+
50+
```bash
51+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
52+
```
53+
54+
### Step 2: Install Dependencies
55+
56+
```bash
57+
yarn install
58+
```
59+
60+
### Step 3: Build the SDK (includes plugin)
61+
62+
```bash
63+
yarn build
64+
```
65+
66+
This will:
67+
- Build the React Native SDK with `react-native-builder-bob`
68+
- Compile the Expo config plugin TypeScript to `plugin/build/`
69+
70+
### Step 4: Verify Plugin Build
71+
72+
```bash
73+
ls -la plugin/build/
74+
```
75+
76+
You should see:
77+
```
78+
index.js
79+
index.d.ts
80+
withIterableAutolinking.js
81+
withIterableAutolinking.d.ts
82+
withIterablePodfile.js
83+
withIterablePodfile.d.ts
84+
```
85+
86+
### Step 5: Navigate to Example App
87+
88+
```bash
89+
cd example
90+
```
91+
92+
### Step 6: Install Example App Dependencies
93+
94+
```bash
95+
yarn install
96+
```
97+
98+
### Step 7: Install iOS Pods
99+
100+
```bash
101+
cd ios
102+
pod install --repo-update
103+
cd ..
104+
```
105+
106+
**Expected output**: Pod installation completes without errors. Look for:
107+
- `Iterable-iOS-SDK` being installed
108+
- `Iterable-React-Native-SDK` being installed
109+
- No "transitive dependencies" errors
110+
111+
### Step 8: Build and Run iOS App
112+
113+
**Option A: Using Yarn (recommended)**
114+
```bash
115+
yarn ios
116+
```
117+
118+
**Option B: Using Xcode**
119+
```bash
120+
open ios/ReactNativeSdkExample.xcworkspace
121+
```
122+
Then in Xcode:
123+
1. Select a simulator (e.g., iPhone 15)
124+
2. Press `Cmd + B` to build
125+
3. Press `Cmd + R` to run
126+
127+
### Step 9: Verify Build Success
128+
129+
The build should complete without these errors:
130+
-`'Iterable_React_Native_SDK-Swift.h' file not found`
131+
-`transitive dependencies include statically linked binaries`
132+
- ❌ Duplicate pod declaration errors
133+
134+
If the app launches in the simulator, the fix is working.
135+
136+
---
137+
138+
## Part 2: Test the Expo Config Plugin
139+
140+
### Step 1: Run Plugin Unit Tests
141+
142+
```bash
143+
# From the react-native-sdk root
144+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
145+
146+
yarn test:plugin
147+
```
148+
149+
**Expected output**: All tests pass:
150+
```
151+
PASS __tests__/plugin.test.ts
152+
withIterableAutolinking
153+
disableAutolinking
154+
✓ should add @iterable/react-native-sdk to autolinking exclude list
155+
✓ should preserve existing exclude entries
156+
✓ should be idempotent - not duplicate entries
157+
withIterablePodfile
158+
ensureStaticLinkage
159+
✓ should keep existing static linkage unchanged
160+
✓ should convert dynamic linkage to static
161+
✓ should convert bare use_frameworks! to static linkage
162+
injectIterablePods
163+
✓ should inject Iterable pods after use_expo_modules!
164+
...
165+
```
166+
167+
### Step 2: Create a Test Expo App (Optional - Full Integration Test)
168+
169+
```bash
170+
# Create a new directory for testing
171+
cd /tmp
172+
npx create-expo-app@latest iterable-expo-test --template blank
173+
cd iterable-expo-test
174+
```
175+
176+
### Step 3: Link Local SDK to Test App
177+
178+
```bash
179+
# Add the local SDK as a dependency
180+
yarn add /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
181+
```
182+
183+
### Step 4: Configure the Plugin
184+
185+
Edit `app.json`:
186+
```json
187+
{
188+
"expo": {
189+
"name": "iterable-expo-test",
190+
"slug": "iterable-expo-test",
191+
"plugins": [
192+
["@iterable/react-native-sdk", { "enableNotificationExtension": true }]
193+
]
194+
}
195+
}
196+
```
197+
198+
### Step 5: Run Expo Prebuild
199+
200+
```bash
201+
npx expo prebuild --clean
202+
```
203+
204+
### Step 6: Verify Podfile Transformation
205+
206+
```bash
207+
cat ios/Podfile
208+
```
209+
210+
**Verify these entries exist:**
211+
212+
1. Static linkage is set:
213+
```ruby
214+
use_frameworks! :linkage => :static
215+
```
216+
217+
2. Iterable pods with dynamic override:
218+
```ruby
219+
# Iterable SDK (Expo Managed Workflow)
220+
pod 'Iterable-React-Native-SDK', :path => '../node_modules/@iterable/react-native-sdk', :linkage => :dynamic
221+
pod 'Iterable-iOS-SDK', :linkage => :dynamic
222+
```
223+
224+
3. Notification extension target (if enabled):
225+
```ruby
226+
target 'IterableNotifications' do
227+
use_frameworks! :linkage => :dynamic
228+
pod 'Iterable-iOS-AppExtensions'
229+
end
230+
```
231+
232+
### Step 7: Test Idempotency
233+
234+
```bash
235+
# Run prebuild again without --clean
236+
npx expo prebuild
237+
238+
# Check for duplicates
239+
grep -c "Iterable-React-Native-SDK" ios/Podfile
240+
```
241+
242+
**Expected**: Should output `1` (not duplicated)
243+
244+
### Step 8: Build the Expo App
245+
246+
```bash
247+
npx expo run:ios
248+
```
249+
250+
---
251+
252+
## Part 3: Verify iOS SDK Header Fix
253+
254+
### Step 1: Navigate to iOS SDK
255+
256+
```bash
257+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/iterable-swift-sdk
258+
```
259+
260+
### Step 2: Check Header Files Have C++ Guards
261+
262+
```bash
263+
# Check IterableSDK.h
264+
grep -A2 "__cplusplus" swift-sdk/IterableSDK.h
265+
```
266+
267+
**Expected output:**
268+
```c
269+
#ifdef __cplusplus
270+
extern "C" {
271+
#endif
272+
```
273+
274+
```bash
275+
# Check IterableAppExtensions.h
276+
grep -A2 "__cplusplus" notification-extension/IterableAppExtensions.h
277+
```
278+
279+
**Expected output:**
280+
```c
281+
#ifdef __cplusplus
282+
extern "C" {
283+
#endif
284+
```
285+
286+
### Step 3: Check Resource Bundle Name
287+
288+
```bash
289+
grep "resource_bundles" Iterable-iOS-SDK.podspec
290+
```
291+
292+
**Expected output:**
293+
```ruby
294+
s.resource_bundles = {'IterableSDKResources' => 'swift-sdk/Resources/**/*.{storyboard,xib,xcassets,xcdatamodeld}' }
295+
```
296+
297+
---
298+
299+
## Troubleshooting
300+
301+
### Error: `'Iterable_React_Native_SDK-Swift.h' file not found`
302+
303+
This means the C++ linkage fix isn't being picked up. Ensure:
304+
1. You're using the correct iOS SDK branch: `fix/SDK-290-Export-iOS-sdk-header-file`
305+
2. Run `pod cache clean --all` and reinstall pods
306+
307+
### Error: Pod install fails with dependency errors
308+
309+
```bash
310+
cd ios
311+
pod deintegrate
312+
pod cache clean --all
313+
pod install --repo-update
314+
```
315+
316+
### Error: Plugin build fails
317+
318+
```bash
319+
# Rebuild the plugin
320+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
321+
rm -rf plugin/build
322+
yarn build:plugin
323+
```
324+
325+
### Error: Tests fail with module not found
326+
327+
```bash
328+
# Install test dependencies
329+
cd plugin
330+
yarn add -D ts-jest @types/jest
331+
```
332+
333+
---
334+
335+
## Quick Commands Reference
336+
337+
```bash
338+
# Build everything
339+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
340+
yarn install && yarn build
341+
342+
# Run plugin tests
343+
yarn test:plugin
344+
345+
# Run example app
346+
cd example && yarn ios
347+
348+
# Clean rebuild
349+
yarn clean && yarn build
350+
351+
# Check git diff of your changes
352+
cd /Users/joao.dordio/dev/repos/codereview/ReactNativeStatic/react-native-sdk
353+
git diff --stat
354+
```
355+
356+
---
357+
358+
## Success Criteria
359+
360+
You've successfully tested the changes if:
361+
362+
1.`yarn build` completes without errors
363+
2.`yarn test:plugin` - All tests pass
364+
3. ✅ Example app builds and runs on iOS simulator
365+
4. ✅ No Swift header file not found errors
366+
5. ✅ Expo prebuild generates correct Podfile entries
367+
6. ✅ Running prebuild twice doesn't duplicate entries

app.plugin.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// This file is the entry point for the Expo config plugin.
2+
// It re-exports the compiled plugin from the plugin directory.
3+
4+
module.exports = require('./plugin/build');

ios/RNIterableAPI/RNIterableAPI.mm

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,11 @@ typedef NS_ENUM(NSInteger, InAppShowResponse) {
1717
skip = 1,
1818
};
1919

20+
#if __has_include(<Iterable_React_Native_SDK/Iterable_React_Native_SDK-Swift.h>)
21+
#import <Iterable_React_Native_SDK/Iterable_React_Native_SDK-Swift.h>
22+
#else
2023
#import "Iterable_React_Native_SDK-Swift.h"
24+
#endif
2125

2226
@interface RNIterableAPI () <ReactIterableAPIDelegate>
2327
@end

0 commit comments

Comments
 (0)