Skip to content

Commit db242c5

Browse files
authored
Merge branch 'master' into chore/update-readme
2 parents 96b89d2 + fafbe73 commit db242c5

27 files changed

Lines changed: 1356 additions & 36 deletions
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
name: Validate Release PR
2+
3+
on:
4+
pull_request:
5+
types: [labeled, opened, synchronize, edited]
6+
7+
permissions:
8+
contents: read
9+
pull-requests: read
10+
11+
jobs:
12+
validate:
13+
if: >-
14+
(github.event.action == 'labeled' && github.event.label.name == 'release') ||
15+
(github.event.action != 'labeled' && contains(github.event.pull_request.labels.*.name, 'release'))
16+
runs-on: ubuntu-latest
17+
steps:
18+
- uses: actions/checkout@v4
19+
20+
- name: Validate Release PR
21+
env:
22+
PR_BODY: ${{ github.event.pull_request.body }}
23+
run: |
24+
errors=()
25+
26+
# --- Extract version from source of truth ---
27+
version=$(grep -oP 's\.version\s*=\s*"\K[^"]+' Iterable-iOS-SDK.podspec)
28+
if [ -z "$version" ]; then
29+
echo "::error::Could not extract version from Iterable-iOS-SDK.podspec"
30+
exit 1
31+
fi
32+
echo "Detected version: $version"
33+
34+
# --- Check: Docs PR linked ---
35+
if ! echo "$PR_BODY" | grep -qiP "github\.com/Iterable/iterable-docs/pull/\d+"; then
36+
errors+=("No docs PR link found in the PR description. Add a link to the iterable-docs PR (e.g. https://github.com/Iterable/iterable-docs/pull/123).")
37+
fi
38+
39+
# --- Check: CHANGELOG entry ---
40+
if ! grep -qF "## [$version]" CHANGELOG.md; then
41+
errors+=("CHANGELOG.md is missing an entry for version [$version].")
42+
fi
43+
44+
# --- Check: Version consistency ---
45+
podspec_sdk=$(grep -oP "s\.version\s*=\s*\"\K[^\"]+" Iterable-iOS-SDK.podspec)
46+
podspec_ext=$(grep -oP "s\.version\s*=\s*\"\K[^\"]+" Iterable-iOS-AppExtensions.podspec)
47+
swift_ver=$(grep -oP 'static let sdkVersion\s*=\s*"\K[^"]+' swift-sdk/SDK/IterableAPI.swift)
48+
49+
if [ "$podspec_sdk" != "$version" ]; then
50+
errors+=("Iterable-iOS-SDK.podspec s.version is '$podspec_sdk', expected '$version'.")
51+
fi
52+
if [ "$podspec_ext" != "$version" ]; then
53+
errors+=("Iterable-iOS-AppExtensions.podspec s.version is '$podspec_ext', expected '$version'.")
54+
fi
55+
if [ "$swift_ver" != "$version" ]; then
56+
errors+=("IterableAPI.swift sdkVersion is '$swift_ver', expected '$version'.")
57+
fi
58+
59+
# --- Report ---
60+
if [ ${#errors[@]} -gt 0 ]; then
61+
echo "::error::Release validation failed with ${#errors[@]} issue(s):"
62+
for err in "${errors[@]}"; do
63+
echo "::error:: - $err"
64+
done
65+
exit 1
66+
fi
67+
68+
echo "All release validations passed for version $version."

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,4 @@ CI.swift
3939
*.mdb
4040
.build/arm64-apple-macosx/debug/IterableSDK.build/output-file-map.json
4141
.build
42+
.mcp.json

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,21 @@ All notable changes to this project will be documented in this file.
44
This project adheres to [Semantic Versioning](http://semver.org/).
55
## [Unreleased]
66

7+
## [6.6.7]
8+
### Fixed
9+
- Fixed module export for CocoaPods, enabling Obj-C/C++ compatibility
10+
- Added `extern "C"` guards to umbrella headers (`IterableSDK.h`, `IterableAppExtensions.h`) for C++ compatibility
11+
- Renamed CocoaPods resource bundle from `Resources` to `IterableSDKResources` to avoid naming collisions with other pods, with automatic fallback to the legacy name
12+
13+
## [6.6.6]
14+
### Fixed
15+
- Fixed more Carthage issues
16+
- Fixed issue that prevented multiple applications using a shared keychain access group.
17+
- Improves in-app full screen position to display over the entire screen includind the status bar.
18+
19+
### Added
20+
- Made `isIterableDeepLink` method public
21+
722
## [6.6.5]
823
### Fixed
924
- Fixed an issue where concurrent API requests failing with JWT-related 401 errors could be dropped instead of retried after a new token was obtained, ensuring all affected calls are executed once authentication succeeds.

CLAUDE.md

Lines changed: 163 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,167 @@
22

33
🤖 **AI Agent Instructions**
44

5-
Please read the `AGENT_README.md` file for comprehensive project information, development workflow, and testing procedures.
5+
## Project Overview
6+
This is the **Iterable Swift SDK** for iOS/macOS integration. The SDK provides:
7+
- Push notification handling
8+
- In-app messaging
9+
- Event tracking
10+
- User management
11+
- Unknown user tracking
612

7-
All the information you need to work on this Iterable Swift SDK project is documented there.
13+
## Key Architecture
14+
- **Core SDK**: `swift-sdk/` - Main SDK implementation
15+
- **Sample Apps**: `sample-apps/` - Example integrations
16+
- **Tests**: `tests/` - Unit tests, UI tests, and integration tests
17+
- **Notification Extension**: `notification-extension/` - Rich push support
18+
19+
## Development Workflow
20+
21+
### 🔨 Building the SDK
22+
```bash
23+
./agent_build.sh
24+
```
25+
- Validates compilation on iOS Simulator
26+
- Shows build errors with context
27+
- Requires macOS with Xcode
28+
29+
### Listing All Available Tests
30+
31+
# List all available test suites
32+
```bash
33+
./agent_test.sh --list
34+
```
35+
36+
### 🧪 Running Tests
37+
```bash
38+
# Run all tests
39+
./agent_test.sh
40+
41+
# Run specific test suite
42+
./agent_test.sh IterableApiCriteriaFetchTests
43+
44+
# Run specific unit test (dot notation - recommended)
45+
./agent_test.sh "IterableApiCriteriaFetchTests.testForegroundCriteriaFetchWhenConditionsMet"
46+
47+
# Run any specific test with path
48+
./agent_test.sh "unit-tests/IterableApiCriteriaFetchTests/testForegroundCriteriaFetchWhenConditionsMet"
49+
```
50+
- Executes on iOS Simulator with accurate pass/fail reporting
51+
- Returns exit code 0 for success, 1 for failures
52+
- Shows detailed test counts and failure information
53+
- `--list` shows all test suites with test counts
54+
- Requires password for xcpretty installation (first run)
55+
56+
## Project Structure
57+
```
58+
swift-sdk/
59+
├── swift-sdk/ # Main SDK source
60+
│ ├── Core/ # Public APIs and models
61+
│ ├── Internal/ # Internal implementation
62+
│ ├── SDK/ # Main SDK entry points
63+
│ └── ui-components/ # SwiftUI/UIKit components
64+
├── tests/ # Test suites
65+
│ ├── unit-tests/ # Unit tests
66+
│ ├── ui-tests/ # UI automation tests
67+
│ └── endpoint-tests/ # API endpoint tests
68+
├── sample-apps/ # Example applications
69+
└── notification-extension/ # Push notification extension
70+
```
71+
72+
## Key Classes
73+
- **IterableAPI**: Main SDK interface
74+
- **IterableConfig**: Configuration management
75+
- **InternalIterableAPI**: Core implementation
76+
- **UnknownUserManager**: Unknown user tracking
77+
- **LocalStorage**: Data persistence
78+
79+
## Common Tasks
80+
81+
### Adding New Features
82+
1. Build first: `./agent_build.sh`
83+
2. Implement in `swift-sdk/Internal/` or `swift-sdk/SDK/`
84+
3. Add tests in `tests/unit-tests/`
85+
4. Verify: `./agent_test.sh` (all tests) or `./agent_test.sh YourTestSuite` (specific suite)
86+
87+
### Debugging Build Issues
88+
- Build script shows compilation errors with file paths
89+
- Check Xcode project references in `swift-sdk.xcodeproj/project.pbxproj`
90+
- Verify file renames are reflected in project file
91+
92+
### Test Failures
93+
- Test script shows specific failures with line numbers and detailed error messages
94+
- Run failing tests individually: `./agent_test.sh "TestSuite.testMethod"`
95+
- Mock classes available in `tests/common/`
96+
- Update parameter names when refactoring APIs
97+
98+
## Requirements
99+
- **macOS**: Required for Xcode builds
100+
- **Xcode**: Latest stable version
101+
- **Ruby**: For xcpretty (auto-installed)
102+
- **iOS Simulator**: For testing
103+
104+
## Quick Start for AI Agents
105+
1. Run `./agent_build.sh` to verify project builds
106+
2. Run `./agent_test.sh` to check test health (or `./agent_test.sh TestSuite` for specific suite)
107+
3. Make changes to source files
108+
4. Re-run both scripts to validate
109+
5. Debug failing tests: `./agent_test.sh "TestSuite.testMethod"`
110+
6. Commit when both pass ✅
111+
112+
## Test Filtering Examples
113+
```bash
114+
# Debug specific failing tests
115+
./agent_test.sh "IterableApiCriteriaFetchTests.testForegroundCriteriaFetchWhenConditionsMet"
116+
117+
# Run a problematic test suite
118+
./agent_test.sh ValidateCustomEventUserUpdateAPITest
119+
120+
# Check auth-related tests
121+
./agent_test.sh AuthTests
122+
```
123+
124+
## AI Agent Memory System
125+
126+
### 🧠 Update Instructions for AI Agents
127+
**IMPORTANT**: When you discover something useful while working on this codebase, update this README to help future AI agents. Add learnings to the sections below.
128+
129+
### 📍 Code Location Map
130+
- **Auth Logic**: `swift-sdk/Internal/AuthManager.swift` (main auth manager), `swift-sdk/Internal/Auth.swift` (auth models)
131+
- **API Calls**: `swift-sdk/Internal/api-client/ApiClient.swift` (main client), `swift-sdk/Internal/Network/NetworkHelper.swift` (networking)
132+
- **Models**: `swift-sdk/Core/Models/` (all data structures - CommerceItem, IterableInAppMessage, etc.)
133+
- **Main Entry**: `swift-sdk/SDK/IterableAPI.swift` (public-facing methods), `swift-sdk/Internal/InternalIterableAPI.swift` (core implementation) — note: public API surface lives in `IterableAPI.swift`, implementation details in `ApiClient.swift`
134+
- **Request Handling**: `swift-sdk/Internal/api-client/Request/` (online/offline processors)
135+
136+
### 🛠️ Common Task Recipes
137+
138+
**Add New API Endpoint:**
139+
1. Add path constant to `swift-sdk/Core/Constants.swift` in `Const.Path`
140+
2. Add method to `ApiClientProtocol.swift` and implement in `ApiClient.swift`
141+
3. Create request in `swift-sdk/Internal/api-client/Request/RequestCreator.swift`
142+
4. Add to `RequestHandlerProtocol.swift` and `RequestHandler.swift`
143+
144+
**Modify Auth Logic:**
145+
- Main logic: `swift-sdk/Internal/AuthManager.swift`
146+
- Token storage: `swift-sdk/Internal/Utilities/Keychain/IterableKeychain.swift`
147+
- Auth failures: Handle in `RequestProcessorUtil.swift`
148+
149+
**Add New Model:**
150+
- Create in `swift-sdk/Core/Models/YourModel.swift`
151+
- Make it `@objcMembers public class` for Objective-C compatibility
152+
- Implement `Codable` if it needs JSON serialization
153+
154+
### 🐛 Common Failure Solutions
155+
156+
**"Test X failed"** → Check test file in `tests/unit-tests/` - often parameter name mismatches after refactoring
157+
158+
**"Build failed: file not found"** → Update `swift-sdk.xcodeproj/project.pbxproj` to include new/renamed files
159+
160+
**"Auth token issues"** → Check `AuthManager.swift` and ensure JWT format is correct in tests
161+
162+
**"Network request fails"** → Check endpoint in `Constants.swift` and request creation in `RequestCreator.swift`
163+
164+
## Notes
165+
- Always test builds after refactoring
166+
- Parameter name changes require test file updates
167+
- Project file (`*.pbxproj`) may need manual updates for file renames
168+
- Sample apps demonstrate SDK usage patterns

Iterable-iOS-AppExtensions.podspec

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = "Iterable-iOS-AppExtensions"
33
s.module_name = "IterableAppExtensions"
4-
s.version = "6.6.5"
4+
s.version = "6.6.7"
55
s.summary = "App Extensions for Iterable SDK"
66

77
s.description = <<-DESC

Iterable-iOS-SDK.podspec

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Pod::Spec.new do |s|
22
s.name = "Iterable-iOS-SDK"
33
s.module_name = "IterableSDK"
4-
s.version = "6.6.5"
4+
s.version = "6.6.7"
55
s.summary = "Iterable's official SDK for iOS"
66

77
s.description = <<-DESC
@@ -20,12 +20,13 @@ Pod::Spec.new do |s|
2020
s.documentation_url = "https://support.iterable.com/hc/en-us/articles/360035018152-Iterable-s-iOS-SDK"
2121

2222
s.pod_target_xcconfig = {
23-
'SWIFT_VERSION' => '5.3'
23+
'SWIFT_VERSION' => '5.3',
24+
'DEFINES_MODULE' => 'YES',
2425
}
2526

2627
s.swift_version = '5.3'
2728

28-
s.resource_bundles = {'Resources' => 'swift-sdk/Resources/**/*.{storyboard,xib,xcassets,xcdatamodeld}' }
29+
s.resource_bundles = {'IterableSDKResources' => 'swift-sdk/Resources/**/*.{storyboard,xib,xcassets,xcdatamodeld}' }
2930

3031
s.header_dir = 'IterableSDK'
3132
end

agent_build.sh

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
3+
# This script is to be used by LLMs and AI agents to build the Iterable Swift SDK on macOS.
4+
# It uses xcpretty to format the build output and only shows errors.
5+
# It also checks if the build is successful and exits with the correct status.
6+
7+
# Check if running on macOS
8+
if [[ "$(uname)" != "Darwin" ]]; then
9+
echo "❌ This script requires macOS to run Xcode builds"
10+
exit 1
11+
fi
12+
13+
# Make sure xcpretty is installed
14+
if ! command -v xcpretty &> /dev/null; then
15+
echo "xcpretty not found, installing via gem..."
16+
sudo gem install xcpretty
17+
fi
18+
19+
echo "Building Iterable Swift SDK..."
20+
21+
# Create a temporary file for the build output
22+
TEMP_OUTPUT=$(mktemp)
23+
24+
# Run the build and capture all output
25+
xcodebuild \
26+
-project swift-sdk.xcodeproj \
27+
-scheme "swift-sdk" \
28+
-configuration Debug \
29+
-sdk iphonesimulator \
30+
build > $TEMP_OUTPUT 2>&1
31+
32+
# Check the exit status
33+
BUILD_STATUS=$?
34+
35+
# Show errors and warnings if build failed
36+
if [ $BUILD_STATUS -eq 0 ]; then
37+
echo "✅ Iterable SDK build succeeded!"
38+
else
39+
echo "❌ Iterable SDK build failed with status $BUILD_STATUS"
40+
echo ""
41+
echo "🔍 Build errors:"
42+
grep -E 'error:|fatal:' $TEMP_OUTPUT | head -10
43+
echo ""
44+
echo "⚠️ Build warnings:"
45+
grep -E 'warning:' $TEMP_OUTPUT | head -5
46+
fi
47+
48+
# Remove the temporary file
49+
rm $TEMP_OUTPUT
50+
51+
exit $BUILD_STATUS

0 commit comments

Comments
 (0)