Publish Score iOS SDK 0.6.0

This commit is contained in:
bdot
2026-10-07 20:38:39 -04:00
parent 84b3a4cb20
commit b898a75fde
6 changed files with 55 additions and 15 deletions

View File

@@ -8,9 +8,9 @@ identically — see [`conformance/CONTRACT.md`](conformance/CONTRACT.md).
--- ---
## Install — 0.5.0 beta (public, no auth) ## Install — 0.6.0 beta (public, no auth)
Distributed publicly from **[`3HL-SCORE/public-sdks-score`](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score)** (#284) — **no Gitea token / login required**. The iOS XCFramework is a public **release asset** (`mobile-v0.5.0`) on that repo; the Android artifacts live in the org's **Gitea Maven package registry** (anonymous read). Distributed publicly from **[`3HL-SCORE/public-sdks-score`](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score)** (#284) — **no Gitea token / login required**. The iOS XCFramework is a public **release asset** (`mobile-v0.6.0`) on that repo; the Android artifacts live in the org's **Gitea Maven package registry** (anonymous read).
### Android — Gradle (public Maven registry) ### Android — Gradle (public Maven registry)
```kotlin ```kotlin
@@ -18,7 +18,7 @@ repositories {
maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials
} }
dependencies { dependencies {
implementation("com.threehalveslabs.scoretracker:shared-android:0.5.0") implementation("com.threehalveslabs.scoretracker:shared-android:0.6.0")
} }
``` ```
@@ -34,17 +34,17 @@ add it by **git URL** — no registry config, no login:
```swift ```swift
// your app's Package.swift // your app's Package.swift
dependencies: [ dependencies: [
.package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.5.0") .package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.6.0")
], ],
// target: .product(name: "ScoreTracker", package: "public-sdks-score") // target: .product(name: "ScoreTracker", package: "public-sdks-score")
``` ```
Or in Xcode: **File → Add Packages…** → paste the URL. The binary `ScoreTrackerKit` Or in Xcode: **File → Add Packages…** → paste the URL. The binary `ScoreTrackerKit`
target pulls the XCFramework from the **public** `mobile-v0.5.0` release asset (SPM target pulls the XCFramework from the **public** `mobile-v0.6.0` release asset (SPM
verifies the checksum) — no `~/.netrc` credentials needed. Verified with an verifies the checksum) — no `~/.netrc` credentials needed. Verified with an
anonymous `swift package resolve`. anonymous `swift package resolve`.
### iOS — direct XCFramework ### iOS — direct XCFramework
Download `ScoreTracker-pod.zip` from the **mobile-v0.5.0** release on Download `ScoreTracker-pod.zip` from the **mobile-v0.6.0** release on
[`public-sdks-score`](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases). [`public-sdks-score`](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases).
It holds `ScoreTrackerKit.xcframework` and the Swift facade sources It holds `ScoreTrackerKit.xcframework` and the Swift facade sources
(`Sources/ScoreTracker/`: `ScoreClient.swift`, `Exports.swift`, `AppLifecycle.swift`). (`Sources/ScoreTracker/`: `ScoreClient.swift`, `Exports.swift`, `AppLifecycle.swift`).
@@ -155,6 +155,39 @@ event, pass it yourself: `requires: [.advertising]` on iOS (or the
`trackAdvertising(...)` shorthand), `requires = listOf(ConsentCategory.ADVERTISING)` `trackAdvertising(...)` shorthand), `requires = listOf(ConsentCategory.ADVERTISING)`
on Android. on Android.
## Regional privacy policy (GDPR, Quebec, LGPD, CPRA)
One `privacy` option sets the tracker's posture for the fan's region (#489),
with the same policies and values as the web tracker's `privacy` option. For URC,
which is UK/EU-facing, use **GDPR**:
```swift
// iOS
let score = ScoreClient(publishableKey: pk, siteId: "urc-ios", endpoint: endpoint,
privacy: PrivacyOptions(mode: .gdpr, region: nil, regionProvider: nil, overrides: nil))
```
```kotlin
// Android
val score = newScoreTracker(context, TrackerConfig(pk, "urc-android", endpoint,
privacy = PrivacyOptions(PrivacyMode.GDPR)))
```
| Policy | Starting consent | Queue kept at most | Drops `locale` / `device` |
|---|---|---|---|
| `GDPR` (EU, EEA, UK, CH) | nothing granted (opt-in) | 24 h | yes |
| `QUEBEC` (Law 25) | nothing granted | 24 h | yes |
| `LGPD` (Brazil) | nothing granted | 48 h | yes |
| `CPRA` (US) | analytics + personalization; not advertising | 168 h (the tracker's 72 h still applies) | no |
| `OFF` | no policy: as without the option | 72 h | no |
What the policy changes:
- **Starting consent:** applies only when you pass no `initialConsent`, and only until your first `setConsent`. A value you pass from your CMP always wins. Under GDPR nothing is sent until `setConsent`, as before.
- **Retention:** queued events older than the cap are dropped instead of sent, including events saved before a cold start.
- **Fingerprint-adjacent signals:** `locale` and the device model leave the envelope. `os` and `appVersion` stay.
- **Declared only:** "no session replay" and "no geo enrichment" are reported by `inspect()`, but the SDK does neither anyway.
`AUTO` picks the policy from `region` (ISO country, optionally with a subdivision: `GB`, `US-CA`, `CA-QC`) or a `regionProvider`; with neither, it uses GDPR, the strictest. The device locale is never used: it's a language setting, not a location. Resolve the region before creating the tracker; the policy is fixed for its lifetime. To tune a setting without forking the table, pass `overrides`, e.g. `PrivacyOverrides(retentionMaxHours = 12)`. `inspectJson()` shows the active policy under `privacy`.
## PII scrubbing ## PII scrubbing
Same options as the web tracker's `pii` (#482). Scrubbing runs **when you call Same options as the web tracker's `pii` (#482). Scrubbing runs **when you call

View File

@@ -15,8 +15,8 @@ let package = Package(
targets: [ targets: [
.binaryTarget( .binaryTarget(
name: "ScoreTrackerKit", name: "ScoreTrackerKit",
url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.5.0/ScoreTrackerKit.xcframework.zip", url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.6.0/ScoreTrackerKit.xcframework.zip",
checksum: "6943d712e2dcb5066f114e2fd14749fffebe79bab27a6ece3d1757b508f04d25" checksum: "dbf9bd9eec9e0c01cb28d7527e19e15909ddda95cf5fb48e50a1639e18ef1988"
), ),
.target( .target(
name: "ScoreTracker", name: "ScoreTracker",

View File

@@ -9,13 +9,13 @@ Public, auth-free distribution of the **Score mobile tracker** SDKs for iOS and
> This repo hosts the **consumable artifacts** (release assets + package manifests). The SDK source lives in 3 Halves Labs' private platform repo. > This repo hosts the **consumable artifacts** (release assets + package manifests). The SDK source lives in 3 Halves Labs' private platform repo.
## Install — 0.5.0 (no token / login required) ## Install — 0.6.0 (no token / login required)
### iOS — Swift Package Manager ### iOS — Swift Package Manager
Add this repo by git URL. There's no registry to configure and no login. Add this repo by git URL. There's no registry to configure and no login.
```swift ```swift
// Package.swift // Package.swift
dependencies: [ .package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.5.0") ] dependencies: [ .package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.6.0") ]
// target: .product(name: "ScoreTracker", package: "public-sdks-score") // target: .product(name: "ScoreTracker", package: "public-sdks-score")
``` ```
Or in Xcode: **File → Add Packages…** and paste the URL. (The old Swift package Or in Xcode: **File → Add Packages…** and paste the URL. (The old Swift package
@@ -29,7 +29,7 @@ pod 'ScoreTracker',
``` ```
### iOS — direct XCFramework ### iOS — direct XCFramework
Download `ScoreTracker-pod.zip` from the [`mobile-v0.5.0` release](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases). It contains `ScoreTrackerKit.xcframework` plus the Swift facade sources (`Sources/ScoreTracker/`). Drag the framework into Xcode and add the Swift files to your app target. Download `ScoreTracker-pod.zip` from the [`mobile-v0.6.0` release](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases). It contains `ScoreTrackerKit.xcframework` plus the Swift facade sources (`Sources/ScoreTracker/`). Drag the framework into Xcode and add the Swift files to your app target.
### Android — Gradle ### Android — Gradle
```kotlin ```kotlin
@@ -37,7 +37,7 @@ repositories {
maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials
} }
dependencies { dependencies {
implementation("com.threehalveslabs.scoretracker:shared-android:0.5.0") implementation("com.threehalveslabs.scoretracker:shared-android:0.6.0")
} }
``` ```

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = 'ScoreTracker' s.name = 'ScoreTracker'
s.version = '0.5.0' s.version = '0.6.0'
s.summary = 'Score mobile tracker (iOS) — KMP shared core + Swift facade.' s.summary = 'Score mobile tracker (iOS) — KMP shared core + Swift facade.'
s.description = <<-DESC s.description = <<-DESC
Lightweight app analytics / fan-engagement tracker. Emits the same event Lightweight app analytics / fan-engagement tracker. Emits the same event

View File

@@ -20,3 +20,8 @@ public typealias PiiAction = ScoreTrackerKit.PiiAction
/// The support snapshot returned by `ScoreClient.inspect()` (#490); its nested /// The support snapshot returned by `ScoreClient.inspect()` (#490); its nested
/// types are reached through it (`snapshot.identity.hasToken`). /// types are reached through it (`snapshot.identity.hasToken`).
public typealias InspectSnapshot = ScoreTrackerKit.InspectSnapshot public typealias InspectSnapshot = ScoreTrackerKit.InspectSnapshot
/// Regional privacy policy (#489): pass `PrivacyOptions(mode: .gdpr, …)` as
/// `ScoreClient(privacy:)`.
public typealias PrivacyOptions = ScoreTrackerKit.PrivacyOptions
public typealias PrivacyMode = ScoreTrackerKit.PrivacyMode
public typealias PrivacyOverrides = ScoreTrackerKit.PrivacyOverrides

View File

@@ -28,7 +28,8 @@ public final class ScoreClient {
os: String? = nil, os: String? = nil,
device: String? = nil, device: String? = nil,
locale: String? = nil, locale: String? = nil,
initialConsent: ConsentState = ConsentState.companion.NONE, initialConsent: ConsentState? = nil,
privacy: PrivacyOptions? = nil,
pii: PiiOptions? = nil, pii: PiiOptions? = nil,
tokenRefreshTimeoutSeconds: Double = 5, tokenRefreshTimeoutSeconds: Double = 5,
identifyReplayBufferSize: Int = 100 identifyReplayBufferSize: Int = 100
@@ -37,7 +38,8 @@ public final class ScoreClient {
publishableKey: publishableKey, publishableKey: publishableKey,
siteId: siteId, siteId: siteId,
endpoint: endpoint, endpoint: endpoint,
device: DeviceDescriptor(os: os, device: device, appVersion: appVersion, locale: locale) device: DeviceDescriptor(os: os, device: device, appVersion: appVersion, locale: locale),
privacy: privacy
) )
tracker = IosPlatformKt.doNewScoreTracker( tracker = IosPlatformKt.doNewScoreTracker(
config: config, config: config,