Compare commits
1 Commits
0.1.0
...
mobile-v0.
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
411afa70a2 |
105
INTEGRATION.md
105
INTEGRATION.md
@@ -8,57 +8,45 @@ identically — see [`conformance/CONTRACT.md`](conformance/CONTRACT.md).
|
||||
|
||||
---
|
||||
|
||||
## Install — 0.1.0 beta (hosted on Gitea)
|
||||
## Install — 0.2.0 beta (public, no auth)
|
||||
|
||||
Everything is hosted on the org's Gitea — no external registry. The Android
|
||||
artifacts live in **Gitea's Maven package registry**; the iOS XCFramework is a
|
||||
**Gitea release asset** (`mobile-v0.1.0`).
|
||||
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.2.0`) on that repo; the Android artifacts live in the org's **Gitea Maven package registry** (anonymous read).
|
||||
|
||||
### Android — Gradle (Gitea Maven registry)
|
||||
### Android — Gradle (public Maven registry)
|
||||
```kotlin
|
||||
repositories {
|
||||
maven {
|
||||
url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven")
|
||||
// If the package registry isn't public, add a Gitea token:
|
||||
// credentials(HttpHeaderCredentials::class) { name = "Authorization"; value = "token ${'$'}giteaToken" }
|
||||
// authentication { create<HttpHeaderAuthentication>("header") }
|
||||
}
|
||||
maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials
|
||||
}
|
||||
dependencies {
|
||||
implementation("com.threehalveslabs.scoretracker:shared-android:0.1.0")
|
||||
implementation("com.threehalveslabs.scoretracker:shared-android:0.2.0")
|
||||
}
|
||||
```
|
||||
|
||||
### iOS — CocoaPods (release asset)
|
||||
### iOS — CocoaPods (public release asset)
|
||||
```ruby
|
||||
pod 'ScoreTracker',
|
||||
:podspec => 'https://git.3halves-labs.com/3HL-SCORE/score-anything-loyalty/raw/branch/main/mobile/ios/ScoreTracker/ScoreTracker.podspec'
|
||||
:podspec => 'https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/raw/branch/main/ScoreTracker.podspec'
|
||||
```
|
||||
|
||||
### iOS — Swift Package Manager (Gitea Swift registry)
|
||||
Published to Gitea's **Swift package registry** as `threehalveslabs.ScoreTracker`.
|
||||
Configure the registry once (per machine / CI), then add it as a normal
|
||||
dependency by **id** — no git URL needed:
|
||||
```bash
|
||||
swift package-registry set https://git.3halves-labs.com/api/packages/3HL-SCORE/swift
|
||||
# private registry → log in with a Gitea token:
|
||||
swift package-registry login https://git.3halves-labs.com/api/packages/3HL-SCORE/swift --token <gitea-token>
|
||||
```
|
||||
### iOS — Swift Package Manager (public git URL)
|
||||
The SPM package lives at the **root** of the public `public-sdks-score` repo, so
|
||||
add it by **git URL** — no registry config, no login:
|
||||
```swift
|
||||
// your app's Package.swift
|
||||
dependencies: [ .package(id: "threehalveslabs.ScoreTracker", from: "0.1.0") ]
|
||||
// then: .product(name: "ScoreTracker", package: "ScoreTracker")
|
||||
dependencies: [
|
||||
.package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.2.0")
|
||||
],
|
||||
// target: .product(name: "ScoreTracker", package: "public-sdks-score")
|
||||
```
|
||||
The package's binary `ScoreTrackerKit` target pulls the XCFramework from the
|
||||
`mobile-v0.1.0` release asset (SPM verifies the checksum). For a private release
|
||||
asset, SPM reads credentials from `~/.netrc`.
|
||||
|
||||
> Note: SPM-by-git-URL isn't available (the package lives in a monorepo subdir,
|
||||
> which SPM can't resolve) — the Swift registry above is the supported path.
|
||||
Or in Xcode: **File → Add Packages…** → paste the URL. The binary `ScoreTrackerKit`
|
||||
target pulls the XCFramework from the **public** `mobile-v0.2.0` release asset (SPM
|
||||
verifies the checksum) — no `~/.netrc` credentials needed. Verified with an
|
||||
anonymous `swift package resolve`.
|
||||
|
||||
### iOS — direct XCFramework
|
||||
Download `ScoreTrackerKit.xcframework.zip` from the **mobile-v0.1.0** release and
|
||||
drag the `.xcframework` into your Xcode project; add `ScoreClient.swift`.
|
||||
Download `ScoreTrackerKit.xcframework.zip` from the **mobile-v0.2.0** release on
|
||||
[`public-sdks-score`](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases)
|
||||
and drag the `.xcframework` into your Xcode project; add `ScoreClient.swift`.
|
||||
|
||||
---
|
||||
|
||||
@@ -71,7 +59,7 @@ let score = ScoreClient(
|
||||
publishableKey: "pk_live_…",
|
||||
siteId: "urc-ios",
|
||||
endpoint: "https://<middleware-host>",
|
||||
sdkVersion: "0.1.0",
|
||||
sdkVersion: "0.2.0",
|
||||
appVersion: Bundle.main.shortVersion,
|
||||
os: "iOS \(UIDevice.current.systemVersion)",
|
||||
device: UIDevice.current.model,
|
||||
@@ -106,7 +94,7 @@ val score = newScoreTracker(
|
||||
publishableKey = "pk_live_…",
|
||||
siteId = "urc-android",
|
||||
endpoint = "https://<middleware-host>",
|
||||
sdk = SdkInfo("@3halves-labs/score-tracker-android", "0.1.0"),
|
||||
sdk = SdkInfo("@3halves-labs/score-tracker-android", "0.2.0"),
|
||||
device = DeviceDescriptor(os = "Android ${Build.VERSION.RELEASE}", device = Build.MODEL,
|
||||
appVersion = BuildConfig.VERSION_NAME, locale = Locale.getDefault().toLanguageTag()),
|
||||
),
|
||||
@@ -152,6 +140,53 @@ Events declaring a category (e.g. `trackAdvertising(...)` on iOS, or
|
||||
`requires = listOf(ConsentCategory.ADVERTISING)` on Android) are dropped until
|
||||
that category is granted.
|
||||
|
||||
## PII scrubbing
|
||||
|
||||
Same options as the web tracker's `pii` (#482). Scrubbing runs **when you call
|
||||
`track()`, before the event is queued**, so a raw value never reaches the
|
||||
on-device queue (NSUserDefaults / SharedPreferences) or the network.
|
||||
|
||||
- **Denylist:** remove matching keys.
|
||||
- **Classify:** a per-key action. The first rule for a key wins.
|
||||
- `DROP`: remove the key.
|
||||
- `REDACT`: replace the value with `"<redacted>"`.
|
||||
- `TOKENIZE`: replace it with `t:1`, `t:2`, …, stable for the tracker's lifetime.
|
||||
- `HASH`: `h:` plus FNV-1a 32-bit hex. It's identical to the web tracker, so
|
||||
the same value hashes the same on both platforms. **Not** cryptographic.
|
||||
|
||||
Keys match exactly (case-sensitive) at any depth, including inside lists.
|
||||
|
||||
```kotlin
|
||||
// Android
|
||||
val score = newScoreTracker(
|
||||
context, config,
|
||||
pii = PiiOptions.Classify(listOf(
|
||||
PiiRule("email", PiiAction.HASH), // joinable across web + app
|
||||
PiiRule("phone", PiiAction.REDACT),
|
||||
PiiRule("memberNumber", PiiAction.TOKENIZE),
|
||||
PiiRule("dateOfBirth", PiiAction.DROP),
|
||||
)),
|
||||
)
|
||||
score.track("profile_updated", mapOf("email" to "fan@example.com", "favouriteTeam" to "home-club"))
|
||||
// queued and sent as {"email":"h:141e28bb","favouriteTeam":"home-club"}
|
||||
```
|
||||
```swift
|
||||
// iOS
|
||||
let score = ScoreClient(
|
||||
publishableKey: "pk_…", siteId: "app.example.com-1a2b3c",
|
||||
endpoint: "https://api.example.com", sdkVersion: "0.2.0",
|
||||
pii: PiiOptions.Classify(rules: [
|
||||
PiiRule(field: "email", action: .hash),
|
||||
PiiRule(field: "phone", action: .redact),
|
||||
PiiRule(field: "memberNumber", action: .tokenize),
|
||||
PiiRule(field: "dateOfBirth", action: .drop),
|
||||
])
|
||||
)
|
||||
```
|
||||
|
||||
To remove keys without per-field actions, use
|
||||
`PiiOptions.Denylist(listOf("email", "phone"))`.
|
||||
|
||||
## Auth0 (JWT)
|
||||
|
||||
Mirrors the web tracker (#109): supply a token provider — it's consulted before
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// swift-tools-version:5.9
|
||||
import PackageDescription
|
||||
|
||||
// Public SPM package for the Score iOS SDK. `ScoreTracker` (Swift facade,
|
||||
// ScoreClient) wraps the binary `ScoreTrackerKit` XCFramework, hosted as a
|
||||
// public release asset on this repo. Consume via git URL:
|
||||
// .package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.1.0")
|
||||
// SPM package for the iOS SDK (#178/#188). The `ScoreTracker` Swift facade
|
||||
// (ScoreClient) wraps the binary `ScoreTrackerKit` XCFramework, hosted as a
|
||||
// **public** Gitea release asset on `3HL-SCORE/public-sdks-score` (#284).
|
||||
// Build/refresh via `scripts/release.sh` (rebuild the XCFramework, re-zip,
|
||||
// recompute the checksum, re-upload to the public release).
|
||||
let package = Package(
|
||||
name: "ScoreTracker",
|
||||
platforms: [.iOS(.v14)],
|
||||
@@ -14,8 +15,8 @@ let package = Package(
|
||||
targets: [
|
||||
.binaryTarget(
|
||||
name: "ScoreTrackerKit",
|
||||
url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.1.0/ScoreTrackerKit.xcframework.zip",
|
||||
checksum: "ae4b4c9b2a7e386d58c1c1144d15c3b4e5f457099ac2677e7d22894a7e4ab3e5"
|
||||
url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.2.0/ScoreTrackerKit.xcframework.zip",
|
||||
checksum: "328f8e36fc0c71d5b82bd4cc79d3d12b4520dea2db2358c73922348d83144b47"
|
||||
),
|
||||
.target(
|
||||
name: "ScoreTracker",
|
||||
|
||||
38
README.md
38
README.md
@@ -1,14 +1,24 @@
|
||||
<!--
|
||||
Seed README for the PUBLIC distribution repo `3HL-SCORE/public-sdks-score` (#284).
|
||||
Copy this to that repo's root as README.md when publishing. Source of truth for
|
||||
the SDK lives in the private score-anything-loyalty repo under `mobile/`.
|
||||
-->
|
||||
# Score mobile SDKs (public distribution)
|
||||
|
||||
Public, auth-free distribution of the **Score mobile tracker** SDKs for iOS and Android — the mobile counterpart of the web `@3halves-labs/score-tracker`.
|
||||
Public, auth-free distribution of the **Score mobile tracker** SDKs for iOS and Android — the mobile counterpart of the web `@3halves-labs/score-tracker`. Lightweight app analytics / fan-engagement tracking with a durable offline queue, consent gating, and Auth0 JWT support.
|
||||
|
||||
## Install — 0.1.0 (no token / login required)
|
||||
> This repo hosts the **consumable artifacts** (release assets + package manifests). The SDK source lives in 3 Halves Labs' private platform repo.
|
||||
|
||||
### iOS — Swift Package Manager (git URL)
|
||||
## Install — 0.2.0 (no token / login required)
|
||||
|
||||
### iOS — Swift Package Manager
|
||||
```bash
|
||||
swift package-registry set https://git.3halves-labs.com/api/packages/3HL-SCORE/swift
|
||||
```
|
||||
```swift
|
||||
// Package.swift
|
||||
dependencies: [ .package(url: "https://git.3halves-labs.com/3HL-SCORE/public-sdks-score.git", from: "0.1.0") ]
|
||||
// target: .product(name: "ScoreTracker", package: "public-sdks-score")
|
||||
dependencies: [ .package(id: "threehalveslabs.ScoreTracker", from: "0.2.0") ]
|
||||
// target: .product(name: "ScoreTracker", package: "ScoreTracker")
|
||||
```
|
||||
|
||||
### iOS — CocoaPods
|
||||
@@ -18,16 +28,22 @@ pod 'ScoreTracker',
|
||||
```
|
||||
|
||||
### iOS — direct XCFramework
|
||||
Download `ScoreTrackerKit.xcframework.zip` from the [`mobile-v0.1.0` release](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases) and drag it into Xcode.
|
||||
Download `ScoreTrackerKit.xcframework.zip` from the [`mobile-v0.2.0` release](https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases) and drag it into Xcode.
|
||||
|
||||
### Android — Gradle
|
||||
```kotlin
|
||||
repositories { maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } } // public
|
||||
dependencies { implementation("com.threehalveslabs.scoretracker:shared-android:0.1.0") }
|
||||
repositories {
|
||||
maven { url = uri("https://git.3halves-labs.com/api/packages/3HL-SCORE/maven") } // public — no credentials
|
||||
}
|
||||
dependencies {
|
||||
implementation("com.threehalveslabs.scoretracker:shared-android:0.2.0")
|
||||
}
|
||||
```
|
||||
|
||||
## Docs
|
||||
## Quickstart & API
|
||||
|
||||
Full integration guide (init, consent, Auth0, offline/flush, event catalogue): **[`INTEGRATION.md`](INTEGRATION.md)**.
|
||||
See the full integration guide (init, consent, Auth0, offline/flush, event catalogue): **`INTEGRATION.md`** in this repo (published alongside each release).
|
||||
|
||||
SDK source lives in 3 Halves Labs' platform repo; this repo hosts the consumable artifacts. Versions tagged `0.1.0` (SPM) / `mobile-v0.1.0` (release asset).
|
||||
## Support
|
||||
|
||||
Issues / integration questions: contact 3 Halves Labs. Versions are tagged `mobile-v<version>`.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'ScoreTracker'
|
||||
s.version = '0.1.0'
|
||||
s.version = '0.2.0'
|
||||
s.summary = 'Score mobile tracker (iOS) — KMP shared core + Swift facade.'
|
||||
s.description = <<-DESC
|
||||
Lightweight app analytics / fan-engagement tracker. Emits the same event
|
||||
@@ -13,8 +13,8 @@ Pod::Spec.new do |s|
|
||||
s.platform = :ios, '14.0'
|
||||
s.swift_version = '5.9'
|
||||
|
||||
# Release attaches the zipped XCFramework; point :http at that asset.
|
||||
s.source = { :http => 'https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.1.0/ScoreTrackerKit.xcframework.zip' }
|
||||
# Release attaches the zipped XCFramework as a PUBLIC asset on public-sdks-score (#284).
|
||||
s.source = { :http => 'https://git.3halves-labs.com/3HL-SCORE/public-sdks-score/releases/download/mobile-v0.2.0/ScoreTrackerKit.xcframework.zip' }
|
||||
|
||||
s.vendored_frameworks = 'ScoreTrackerKit.xcframework'
|
||||
s.source_files = 'Sources/ScoreTracker/**/*.swift'
|
||||
|
||||
@@ -13,6 +13,7 @@ public final class ScoreClient {
|
||||
/// - Parameters:
|
||||
/// - endpoint: middleware base URL; events POST to `<endpoint>/api/tracking/website`.
|
||||
/// - initialConsent: defaults to "none" — nothing fires until `setConsent(...)`.
|
||||
/// - pii: field-level PII handling (#482), scrubbed before events are queued on the device.
|
||||
public init(
|
||||
publishableKey: String,
|
||||
siteId: String,
|
||||
@@ -22,7 +23,8 @@ public final class ScoreClient {
|
||||
os: String? = nil,
|
||||
device: String? = nil,
|
||||
locale: String? = nil,
|
||||
initialConsent: ConsentState = ConsentState.companion.NONE
|
||||
initialConsent: ConsentState = ConsentState.companion.NONE,
|
||||
pii: PiiOptions? = nil
|
||||
) {
|
||||
let config = TrackerConfig(
|
||||
publishableKey: publishableKey,
|
||||
@@ -31,7 +33,7 @@ public final class ScoreClient {
|
||||
sdk: SdkInfo(name: "@3halves-labs/score-tracker-ios", version: sdkVersion),
|
||||
device: DeviceDescriptor(os: os, device: device, appVersion: appVersion, locale: locale)
|
||||
)
|
||||
tracker = IosPlatformKt.doNewScoreTracker(config: config, initialConsent: initialConsent)
|
||||
tracker = IosPlatformKt.doNewScoreTracker(config: config, initialConsent: initialConsent, pii: pii)
|
||||
}
|
||||
|
||||
// MARK: - Consent (wire to your CMP / OneTrust)
|
||||
|
||||
Reference in New Issue
Block a user