diff --git a/CHANGELOG.md b/CHANGELOG.md index 8a184a6..505ff50 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,8 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Initial Unity Package Manager distribution as `com.appstack.unity-sdk` for Unity 6 (`6000.0`) or newer. -- Support for iOS 15.0+ through Appstack iOS SDK `4.4.0` and Android API level - 21+ through Appstack Android SDK `1.7.0-SNAPSHOT` (a release candidate, pinned - for the native customer-user-id setter; move to the stable release before - shipping). +- Support for iOS 15.0+ through Appstack iOS SDK `4.5.0` and Android API level + 21+ through Appstack Android SDK `1.7.0`. - SDK configuration with an API key, log level, and optional customer user ID. - Standard and custom event tracking with optional event parameters. - Apple Ads attribution on iOS. @@ -26,3 +24,9 @@ Changelog](https://keepachangelog.com/en/1.0.0/). - Automatic Android native dependency resolution through EDM4U. - Automatic Android R8/ProGuard configuration with no custom keep-rules step. - Basic Integration sample for manual SDK configuration and event tracking. + +### Notes + +- `EventType.INSTALL` is emitted automatically by the native SDKs on first + launch. Both pinned native versions discard a manually sent `INSTALL`, so + `SendEvent(EventType.INSTALL)` is a no-op. diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 0911666..8413c8f 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -55,12 +55,9 @@ Cross-platform behavior that must remain aligned: Dependency versions are declared in the platform-specific editor integration: -- Android: `tech.appstack.android-sdk:appstack-android-sdk:1.7.0-SNAPSHOT` in - `Editor/AppstackDependencies.xml`. This is a release candidate, pinned so - `SetCustomerUserId` can be built against the native setter it bridges (first - shipped in 1.7.0). Snapshots are mutable and expire: swap it for the stable - release before shipping the package. -- iOS: `AppstackSDK` Swift package product at `4.4.0` in +- Android: `tech.appstack.android-sdk:appstack-android-sdk:1.7.0` in + `Editor/AppstackDependencies.xml` +- iOS: `AppstackSDK` Swift package product at `4.5.0` in `Editor/AppstackIOSPostProcessBuild.cs` When either native dependency changes, update the corresponding editor @@ -102,7 +99,7 @@ the application target so Xcode embeds and signs the dynamic framework. It also sets the Swift language version and enables Swift standard-library embedding on the application target. -The `4.4.0` Swift package uses its binary XCFramework. Its private Swift +The `4.5.0` Swift package uses its binary XCFramework. Its private Swift interfaces expose the `AppstackInternal` SPI used by this bridge. The native contract fixture compiles the production bridge against the exact tagged binary and must pass before adopting any future binary SDK tag. diff --git a/Documentation~/Android.md b/Documentation~/Android.md index a475000..e2c7bd4 100644 --- a/Documentation~/Android.md +++ b/Documentation~/Android.md @@ -30,18 +30,10 @@ to the Gradle templates used by your Unity project: repositories { mavenCentral() maven { url "https://central.sonatype.com/repository/maven-public" } - // Only needed while the pinned version below is a -SNAPSHOT release - // candidate; maven-public does not serve snapshots. Scoped to Appstack - // snapshots so no other dependency can resolve from a mutable repository. - maven { - url "https://central.sonatype.com/repository/maven-snapshots" - mavenContent { snapshotsOnly() } - content { includeGroup "tech.appstack.android-sdk" } - } } dependencies { - implementation "tech.appstack.android-sdk:appstack-android-sdk:1.7.0-SNAPSHOT" + implementation "tech.appstack.android-sdk:appstack-android-sdk:1.7.0" } ``` diff --git a/Editor/AppstackDependencies.xml b/Editor/AppstackDependencies.xml index 070ee83..15b605d 100644 --- a/Editor/AppstackDependencies.xml +++ b/Editor/AppstackDependencies.xml @@ -7,18 +7,10 @@ --> - - + https://repo1.maven.org/maven2 https://central.sonatype.com/repository/maven-public - https://central.sonatype.com/repository/maven-snapshots diff --git a/Editor/AppstackIOSPostProcessBuild.cs b/Editor/AppstackIOSPostProcessBuild.cs index b9bedca..f2dc367 100644 --- a/Editor/AppstackIOSPostProcessBuild.cs +++ b/Editor/AppstackIOSPostProcessBuild.cs @@ -10,7 +10,7 @@ internal sealed class AppstackIOSPostProcessBuild : IPostprocessBuildWithReport { private const string PackageUrl = "https://github.com/appstack-tech/ios-appstack-sdk.git"; - private const string PackageVersion = "4.4.0"; + private const string PackageVersion = "4.5.0"; private const string PackageProduct = "AppstackSDK"; public int callbackOrder => 999; diff --git a/Tests~/Integration/README.md b/Tests~/Integration/README.md index aed46c4..797a4b6 100644 --- a/Tests~/Integration/README.md +++ b/Tests~/Integration/README.md @@ -57,7 +57,7 @@ iOS exports an IL2CPP Xcode project and verifies all of the following before compiling it without code signing: - the Swift bridge is copied and compiled in `UnityFramework`; -- the SPM URL and exact `4.4.0` requirement are present; +- the SPM URL and exact `4.5.0` requirement are present; - `AppstackSDK` is linked to `UnityFramework` and the application target; - the Swift language and runtime-embedding build settings are present; - Xcode resolves the package, compiles the application, and produces diff --git a/Tests~/Integration/UnityProject/Assets/Editor/AppstackIntegrationBuild.cs b/Tests~/Integration/UnityProject/Assets/Editor/AppstackIntegrationBuild.cs index d447ba5..146d58e 100644 --- a/Tests~/Integration/UnityProject/Assets/Editor/AppstackIntegrationBuild.cs +++ b/Tests~/Integration/UnityProject/Assets/Editor/AppstackIntegrationBuild.cs @@ -261,7 +261,7 @@ private static void ValidateIOSExport(string output) project.Contains("https://github.com/appstack-tech/ios-appstack-sdk.git", StringComparison.Ordinal), "Xcode project is missing the Appstack Swift package URL."); Require( - project.Contains("version = 4.4.0;", StringComparison.Ordinal), + project.Contains("version = 4.5.0;", StringComparison.Ordinal), "Xcode project is missing the exact Appstack Swift package version."); Require( Count(project, "productName = AppstackSDK;") == 2, diff --git a/Tests~/Native/Android/real-artifact/build.gradle.kts b/Tests~/Native/Android/real-artifact/build.gradle.kts index dbe12a8..d744870 100644 --- a/Tests~/Native/Android/real-artifact/build.gradle.kts +++ b/Tests~/Native/Android/real-artifact/build.gradle.kts @@ -23,5 +23,5 @@ android { dependencies { // Must match Editor/AppstackDependencies.xml: this module exists to compile the // real bridge against the real artifact the package resolves at runtime. - implementation("tech.appstack.android-sdk:appstack-android-sdk:1.7.0-SNAPSHOT") + implementation("tech.appstack.android-sdk:appstack-android-sdk:1.7.0") } diff --git a/Tests~/Native/Android/settings.gradle.kts b/Tests~/Native/Android/settings.gradle.kts index 6597903..5fff1c6 100644 --- a/Tests~/Native/Android/settings.gradle.kts +++ b/Tests~/Native/Android/settings.gradle.kts @@ -16,15 +16,6 @@ dependencyResolutionManagement { repositories { google() mavenCentral() - // Native SDK release candidates go to the Central Portal snapshot repository, - // which mavenCentral() does not serve. Scoped so only Appstack snapshots - // resolve from here. - maven { - name = "appstackSnapshots" - url = uri("https://central.sonatype.com/repository/maven-snapshots/") - mavenContent { snapshotsOnly() } - content { includeGroup("tech.appstack.android-sdk") } - } } } diff --git a/Tests~/Native/README.md b/Tests~/Native/README.md index 2d2bf67..c1b5763 100644 --- a/Tests~/Native/README.md +++ b/Tests~/Native/README.md @@ -9,9 +9,8 @@ package artifact. The Android fixture has two modules: - `real-artifact` compiles the production Java bridge against - `tech.appstack.android-sdk:appstack-android-sdk:1.7.0-SNAPSHOT`, which must - match `Editor/AppstackDependencies.xml`. Release candidates resolve from the - Central Portal snapshot repository declared in `settings.gradle.kts`. + `tech.appstack.android-sdk:appstack-android-sdk:1.7.0`, which must match + `Editor/AppstackDependencies.xml`. - `contract-tests` compiles the same bridge against recording stubs and tests configuration, proxy metadata, log/event mapping, JSON conversion, getters, and immediate, suspended, and failed coroutine completion. @@ -28,7 +27,7 @@ The Android 35 SDK, JDK 17, Google Maven, and Maven Central must be available. The iOS runner copies the production Swift bridge into a temporary Swift package. It first runs deterministic XCTest cases against a recording `AppstackSDK` module, -then extracts the exact `4.4.0` XCFramework from an `ios-appstack-sdk` checkout, +then extracts the exact `4.5.0` XCFramework from an `ios-appstack-sdk` checkout, compiles the production bridge for an iOS 15 simulator target, and checks every expected C ABI symbol with `nm`. @@ -37,4 +36,10 @@ APPSTACK_IOS_DISTRIBUTION_REPO=/path/to/ios-appstack-sdk \ Tests~/Native/iOS/run-tests.sh ``` +Passing a checkout is the form to prefer, because only that form pins the tag. +The runner also accepts a path to an XCFramework or to a directory containing +one, as a local escape hatch; an XCFramework carries no trustworthy marketing +version, so those inputs cannot be checked against the pin and the runner says +so instead of claiming a verified version. + Xcode with an iOS Simulator SDK and Swift 5.9 or newer is required. diff --git a/Tests~/Native/iOS/run-tests.sh b/Tests~/Native/iOS/run-tests.sh index c9f4f33..6e77d48 100755 --- a/Tests~/Native/iOS/run-tests.sh +++ b/Tests~/Native/iOS/run-tests.sh @@ -22,15 +22,25 @@ cp "$BRIDGE_SOURCE" "$PACKAGE_DIR/Sources/AppstackUnityBridge/AppstackUnityBridg swift test --package-path "$PACKAGE_DIR" +# Must match the pin in Editor/AppstackIOSPostProcessBuild.cs. +EXPECTED_SDK_VERSION="4.5.0" + EXACT_SDK_DIR="$TEMP_DIR/exact-sdk" mkdir -p "$EXACT_SDK_DIR" if [[ -d "$SDK_INPUT/.git" || -f "$SDK_INPUT/.git" ]]; then - git -C "$SDK_INPUT" archive 4.4.0 AppstackSDK.xcframework | tar -x -C "$EXACT_SDK_DIR" + git -C "$SDK_INPUT" archive "$EXPECTED_SDK_VERSION" AppstackSDK.xcframework \ + | tar -x -C "$EXACT_SDK_DIR" XCFRAMEWORK="$EXACT_SDK_DIR/AppstackSDK.xcframework" + # Only this branch pins a tag, so only this branch can claim a version. An + # XCFramework carries no trustworthy marketing version (CFBundleShortVersionString + # is 1.0), so a caller-supplied binary cannot be checked against the pin. + VERIFIED_AGAINST="AppstackSDK $EXPECTED_SDK_VERSION" elif [[ "$SDK_INPUT" == *.xcframework ]]; then XCFRAMEWORK="$SDK_INPUT" + VERIFIED_AGAINST="the supplied XCFramework at $SDK_INPUT (version not verified)" else XCFRAMEWORK="$SDK_INPUT/AppstackSDK.xcframework" + VERIFIED_AGAINST="the XCFramework in $SDK_INPUT (version not verified)" fi SIMULATOR_FRAMEWORK="$XCFRAMEWORK/ios-arm64_x86_64-simulator/AppstackSDK.framework" @@ -67,4 +77,4 @@ for symbol in "${EXPECTED_SYMBOLS[@]}"; do fi done -echo "Verified iOS bridge against AppstackSDK 4.4.0 and all expected C symbols." +echo "Verified iOS bridge against $VERIFIED_AGAINST and all expected C symbols." diff --git a/USAGE.md b/USAGE.md index 77e785d..d11daff 100644 --- a/USAGE.md +++ b/USAGE.md @@ -124,7 +124,7 @@ return safe defaults. For example, `GetAppstackId()` returns `null` and | EventType | Description | |-------------------|--------------------------------| -| INSTALL | App install (SDK may track) | +| INSTALL | Automatic only; manual sends ignored | | LOGIN | User login | | SIGN_UP / REGISTER| Registration | | PURCHASE | Purchase (use revenue/currency)|