Skip to content

Latest commit

 

History

History
124 lines (91 loc) · 5.51 KB

File metadata and controls

124 lines (91 loc) · 5.51 KB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build & Test Commands

Use the xcodebuildmcp CLI (skill: xcodebuildmcp-cli) instead of raw xcodebuild. This is an Xcode project (.xcodeproj), not a workspace.

# Build iOS SDK
xcodebuildmcp simulator build \
  --project-path PACECloudSDK.xcodeproj \
  --scheme PACECloudSDK \
  --simulator-name "iPhone 16" \
  --configuration Development

# Build watchOS SDK
xcodebuildmcp simulator build \
  --project-path PACECloudSDK.xcodeproj \
  --scheme PACECloudWatchSDK \
  --simulator-name "Apple Watch Series 10 (46mm)" \
  --configuration Development

# Run all tests
xcodebuildmcp simulator test \
  --project-path PACECloudSDK.xcodeproj \
  --scheme PACECloudSDKTests \
  --simulator-name "iPhone 16" \
  --configuration Development

# Run a single test class
xcodebuildmcp simulator test \
  --project-path PACECloudSDK.xcodeproj \
  --scheme PACECloudSDKTests \
  --simulator-name "iPhone 16" \
  --configuration Development \
  --json '{"extraArgs": ["-only-testing", "PACECloudSDKTests/GeoServiceTests"]}'

# Run a single test method
xcodebuildmcp simulator test \
  --project-path PACECloudSDK.xcodeproj \
  --scheme PACECloudSDKTests \
  --simulator-name "iPhone 16" \
  --configuration Development \
  --json '{"extraArgs": ["-only-testing", "PACECloudSDKTests/GeoServiceTests/testLocationBasedStations"]}'

# Lint
swiftlint --config .swiftlint.yml

# Run tests via fastlane (CI only)
bundle exec fastlane test

Platform: iOS 15+, watchOS 7+, Swift 5.5+. Build configurations: Development, Sandbox, Production. Tests use Development.

Architecture

PACECloudSDK is a Connected Fueling SDK organized into three Kits, each a singleton:

  • IDKit (PACECloudSDK/IDKit/) — OpenID Connect authentication via AppAuth. Manages OAuth2 flows, token lifecycle (auto-refresh on 401), session caching, biometry/PIN, and token exchange for service delegation.
  • AppKit (PACECloudSDK/AppKit/) — Hosts web apps in WKWebView with a JavaScript-to-native bridge (WKScriptMessageHandler). Handles app discovery, lifecycle, cookie management, and a drawer UI for location-based apps.
  • POIKit (PACECloudSDK/POIKit/) — Gas station discovery and GeoJSON data. GeoAPIManager fetches/caches GeoJSON from CDN (1-hour TTL). GeoJSONStreamParser does memory-efficient streaming parse with optional spatial filtering and per-feature autoreleasepool.

API layer (PACECloudSDK/API/) — Code-generated clients (SwagGen from OpenAPI specs) under Generated/ subdirectories. CustomAPIClient adds exponential backoff (max 8 retries), automatic 401 token refresh, and concurrent JSON decoding. Sub-APIs: POI, Pay, Fueling, User, CDN, Communication.

Utils (PACECloudSDK/Utils/) — SDKUserDefaults and SDKKeychain wrappers (direct UserDefaults/Keychain access is forbidden by SwiftLint), Logger with file rotation, environment config from Plist files, and shared extensions.

Entry point: PACECloudSDK.shared.setup(with: Configuration(...)) initializes all kits.

Environment-specific URLs (API gateway, OID endpoints, CDN) are loaded from Utils/Plists/Environment-{development,sandbox,production}.plist.

Targets

Target Platform Description
PACECloudSDK iOS Full SDK (source)
PACECloudSlimSDK iOS Slim variant for App Clips (binary)
PACECloudWatchSDK watchOS Watch companion apps (binary)
PACECloudSDKTests iOS Unit tests
UnitTestDummy iOS Host app for tests

When adding new source files, add them to both PACECloudSDK and PACECloudWatchSDK targets in project.pbxproj.

Code Generation

Files under API/*/Generated/ directories are auto-generated by SwagGen from OpenAPI specs — never edit them by hand. Directories excluded from linting: API/Generated, API/Pay/Generated, API/POI/Generated, API/Fueling/Generated, API/User/Generated, API/GeoJSON/Generated, API/Communication/Generated. Also excluded: POIKit/Vendor, POIKit/POIKitApi/Model, POIKit/POISearch/Model.

SwiftLint Rules

SwiftLint runs as a build tool plugin. Key rules beyond defaults:

  • force_unwrapping — opt-in, warns on !
  • sorted_imports — imports must be alphabetically sorted
  • switch_case_on_newline — each case on its own line
  • Custom: vertical_whitespace_between_cases — blank line required between switch cases
  • Custom: user_defaults_wrapper (error) — must use SDKUserDefaults, not UserDefaults
  • Custom: keychain_wrapper (error) — must use SDKKeychain, not direct Keychain APIs
  • Line length limit: 180 characters
  • Generated code directories are excluded from linting

Testing Patterns

Tests use MockURLProtocol registered via PACECloudSDK.shared.customURLProtocol to intercept network requests. Standard test setUp:

PACECloudSDK.shared.customURLProtocol = MockURLProtocol()
PACECloudSDK.shared.setup(with: .init(
    apiKey: "apiKey",
    clientId: "unit-test-dummy",
    environment: .development,
    isRedirectSchemeCheckEnabled: false,
    geoAppsScope: "pace-drive-ios-min"
))

Mock responses are switched using CommandLineArgument enum values added via addCommandLineArguments(_:) helper on XCTestCase. Test execution order is randomized.

Dependencies

  • AppAuth (~> 1.5.0) — OAuth2/OpenID Connect (PACE fork)
  • SwiftProtobuf (~> 1.22.0) — Protocol Buffers for vector tile models
  • Japx (~> 5.0.0) — JSON:API parsing

Distributed via SPM, CocoaPods, and Carthage.