# JanusSDK for iOS

This directory contains the source code for the JanusSDK iOS library, tests, and examples.

## Repository Structure

* **JanusSDK** - Core SDK source code
* **JanusSDKTests** - Unit and integration tests
* **janus-sdk-ios** - Binary distribution files (framework, XCFramework)
* **anus-sdk-ios/Example** - Example implementation of the SDK

## Development Workflow

### Opening and Testing in Xcode

1. Open `JanusSDK/JanusSDK.xcodeproj` in Xcode
2. Select the JanusSDK scheme and a simulator
3. Run tests using **Product > Test** (⌘U)

When running tests in Xcode, test results are stored in:
```
~/Library/Developer/Xcode/DerivedData/JanusSDK-*/Logs/Test/
```

These results can be viewed in Xcode's Test navigator or by opening the .xcresult bundles directly.

### Running Tests with Command-Line Script

The `run_tests.sh` script provides a consistent way to run tests from the command line:

```bash
./run_tests.sh
```

Features:
- Uses a dedicated `test-results` directory to store test outputs
- Creates timestamped result bundles (e.g., `TestResults_20250316_192530.xcresult`)
- Automatically cleans up old test results, keeping only the 5 most recent runs
- Provides clear pass/fail output

Test results are stored in the `./test-results/` directory and can be inspected using:
```bash
xcrun xcresulttool get --path ./test-results/TestResults_*.xcresult --format json
```

### Code Coverage

The best way to get code coverage is to use the Xcode Test navigator. Check the screenshots in this [post](https://stackoverflow.com/questions/76192332/how-can-i-enable-code-coverage-in-xcode-14-3-it-appears-different-from-other-v)

### Downloading Test Privacy Experience JSON Files

The SDK includes a utility script to download real-world Privacy Experience API responses for testing. This ensures the models can properly decode the actual API responses from different regions and properties.

To download test JSON files:

```bash
cd ../Shared/PrivacyExperienceMockJSON
./download.sh <host> <region> [property_id]
```

Parameters:
- `host` - The API host without https:// (e.g., privacy.ethyca.com)
- `region` - The region code (e.g., us_ca, de, gb)
- `property_id` - (Optional) A specific property ID

For example:
```bash
./download.sh privacy.ethyca.com de
./download.sh privacy.ethyca.com us_ca abc123
```

The script will:
1. Download the JSON response for the specified region/property
2. Format it using `jq` for readability
3. Save it with a timestamp in the filename
4. Validate the downloaded file is valid JSON

After downloading, run the `PrivacyExperienceDecoderTests` to verify the new JSON files can be properly decoded.

### Binary Distribution Files (janus-sdk-ios)

The `janus-sdk-ios` directory contains the compiled framework files that are intended for distribution and consumption by other applications. These binary files are what will be published for third-party developers to use.

### Building the Framework

To build the framework files for the example app:

```bash
./build_xcframework.sh
```

For debug builds:
```bash
./build_xcframework.sh --debug
```

**Note:** The Example app will NOT work unless this is included

This script:
1. Builds the SDK for device and simulator
2. Creates a universal XCFramework in the `janus-sdk-ios` directory
3. Updates the framework used by the example app
4. By default, builds a hardened release version with optimizations

### Running the Example App

1. Open `janus-sdk-ios/Example/JanusExample.xcodeproj` in Xcode
2. Select a simulator or connected device
3. Run the app (⌘R)

The example app demonstrates the integration and usage of the JanusSDK.

## Using Logdy for Local Log Monitoring

The example app includes an optional HTTPLogger that can send logs to a local [logdy](https://logdy.dev) instance for real-time log viewing and debugging.

### Installing Logdy

Install logdy using brew

```bash
brew install logdy
```

### Running Logdy

Start logdy with these settings to work with the example app:

```bash
logdy --no-analytics -p 8181 --api-key foobar
```

### Viewing Logs

Once logdy is running, simply run the example app and Janus SDK logs will appear in the logdy web interface at http://localhost:8181.

## Theme Customization (WIP - Not Customer Ready)

> **⚠️ WORK IN PROGRESS**  
> This theming system is currently under development and **should not be included in customer-facing documentation** until:
> - Full testing is complete across all iOS versions and dark mode scenarios
> - Implementation is finished on Flutter platform
> - Cross-platform consistency is verified
> - Colors not defined in theme (privacy notice row backgrounds, toggle buttons, etc)

The Janus iOS SDK supports custom theming through the `JanusTheme` object, allowing you to customize colors, fonts, and other visual elements while maintaining automatic light/dark mode support.

### Basic Usage

#### 1. Create Your Custom Theme

```swift
import JanusSDK

// Create a custom theme
let customTheme = JanusTheme(
    primaryColor: Color(red: 1.0, green: 0.34, blue: 0.13),  // Orange
    secondaryColor: Color.gray,
    textColor: Color(.label),                                 // Adapts to light/dark mode
    textUIColor: UIColor.label,                              // For HTML content
    backgroundColor: Color(.systemBackground),                // Adapts to light/dark mode
    secondaryButtonTextColor: Color(.label),                 // Adapts to light/dark mode
    secondaryButtonBorderColor: Color(.separator).opacity(0.6),
    headingFontSize: 20,
    bodyFontSize: 16,
    cornerRadius: 8.0
)
```

#### 2. Apply Your Theme in Configuration

```swift
import JanusSDK

let config = JanusConfiguration(
    apiHost: "https://privacy.mycompany.com",
    propertyId: "my-property-id",
    theme: customTheme
)

Janus.initialize(config: config) { success, error in
    // Handle initialization result
}
```

### Using Default Adaptive Theme

For automatic light/dark mode support with minimal customization:

```swift
// Use the default theme (automatically adapts to light/dark mode)
let config = JanusConfiguration(
    apiHost: "https://privacy.mycompany.com",
    propertyId: "my-property-id",
    theme: JanusTheme.default  // This automatically adapts to system appearance
)
```

### Custom Theme with System Colors

For a custom theme that still adapts to light/dark mode:

```swift
let adaptiveTheme = JanusTheme(
    primaryColor: Color(red: 1.0, green: 0.34, blue: 0.13),  // Custom brand color
    secondaryColor: Color.gray,
    textColor: Color(.label),                                 // System adaptive color
    textUIColor: UIColor.label,                              // System adaptive color
    backgroundColor: Color(.systemBackground),                // System adaptive color
    secondaryButtonTextColor: Color(.label),                 // System adaptive color  
    secondaryButtonBorderColor: Color(.separator).opacity(0.6),
    headingFontSize: 22,                                     // Custom font size
    bodyFontSize: 16,
    cornerRadius: 12.0                                       // Custom corner radius
)
```

### Available Theme Properties

| Property | Description | Default Value |
|----------|-------------|---------------|
| `primaryColor` | Primary color for buttons and highlights | Dark blue |
| `secondaryColor` | Secondary color for accents | Gray |
| `textColor` | Main text color (SwiftUI Color) | `Color(.label)` |
| `textUIColor` | Text color for HTML content (UIColor) | `UIColor.label` |
| `backgroundColor` | Main background color | `Color(.systemBackground)` |
| `secondaryButtonTextColor` | Secondary button text color | `Color(.label)` |
| `secondaryButtonBorderColor` | Secondary button border color | `Color(.separator)` |
| `headingFontSize` | Font size for headings | 20pt |
| `bodyFontSize` | Font size for body text | 16pt |
| `cornerRadius` | Corner radius for UI elements | 8pt |

### Automatic Dark Mode Support

The SDK automatically handles dark mode when you use system colors:

- `Color(.label)` - Black in light mode, white in dark mode
- `Color(.systemBackground)` - White in light mode, dark gray in dark mode  
- `Color(.separator)` - Adapts opacity based on light/dark mode
- `UIColor.label` - Ensures HTML content adapts to dark mode

### Advanced Theming

The theme system also automatically handles:
- **HTML Content**: Uses `textUIColor` for proper dark mode support in HTML descriptions
- **Secondary Buttons**: Improved contrast in both light and dark modes
- **Adaptive Colors**: System colors automatically adapt when the user switches between light/dark mode

### Publishing the SDK - Creating a Release

Use the publish script in the root of the project, with a dry run, then drop the dry-run parameter.

**Important** - Without the --dry-run parameter, this script WILL make commits to multiple repos and push to origin on your behalf.

```bash
./publish.sh --ios --dry-run
```

The publish script uses the following sub tasks to complete it's work, which can be run manually if you wish:

```
Usage: ./build_xcframework.sh [options]

Options:
  --debug                   Build with Debug configuration (disables hardening)
  --publish-dir <directory> Directory where final XCFramework will be published
                            If not specified, output goes to ./janus-sdk-ios
  --increment-major         Increment major version in podspec
  --increment-minor         Increment minor version in podspec
  --increment-patch         Increment patch version in podspec
  --set-version <version>   Set specific version in podspec (e.g., 1.2.0)
  --no-hardening            Disable hardening optimizations
  --no-strip                Disable symbol stripping
  --no-sign                 Disable code signing
  --help                    Display this help message
```

**Important:** The publish-dir should be your locally checked out copy of the binary spec repo: https://github.com/ethyca/janus-sdk-ios

```bash
./build_xcframework.sh --publish-dir ~/Repos/janus-sdk-ios --increment-patch
```

**Note:** After running this script, local files will be updated with the new checksums and new versions that should be committed to git. In addition, instructions will be provided for properly tagging and pushing to the spec repo. In addition to pushing code to janus-sdk-ios, the fideplus repo will have the version numbers changed within it and require a code push
