diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index fcccc7f..6d0287a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -35,3 +35,29 @@ jobs: channel: 'stable' - run: cd packages/sdk-flutter && flutter pub get - run: cd packages/sdk-flutter && flutter analyze + + maui: + name: .NET MAUI SDK + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + - name: Install MAUI workloads + run: dotnet workload install android ios + - name: Download Screeb iOS XCFramework + run: | + SCREEB_IOS_URL=$(curl -sL https://api.github.com/repos/ScreebApp/sdk-ios-public/releases/latest | python3 -c "import sys,json; print(next(a['browser_download_url'] for a in json.load(sys.stdin)['assets'] if a['name']=='Screeb.zip'))") + curl -sL "$SCREEB_IOS_URL" -o /tmp/Screeb.zip + unzip -q /tmp/Screeb.zip -d /tmp/screeb_ios + mkdir -p packages/sdk-maui/native/ios + cp -r /tmp/screeb_ios/Screeb.xcframework packages/sdk-maui/native/ios/ + - name: Restore + run: dotnet restore packages/sdk-maui/ScreebMaui.csproj + - name: Build Android + run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-android --no-restore + - name: Build iOS + run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-ios --no-restore + - name: Run unit tests + run: dotnet test packages/sdk-maui/tests/ScreebUtilsTests.csproj diff --git a/.github/workflows/publish-maui.yml b/.github/workflows/publish-maui.yml new file mode 100644 index 0000000..6edd3d1 --- /dev/null +++ b/.github/workflows/publish-maui.yml @@ -0,0 +1,42 @@ +name: Publish Screeb.Maui + +on: + push: + tags: + - 'sdk-maui/v*' + +jobs: + publish: + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '9.0.x' + + - name: Install MAUI workloads + run: dotnet workload install android ios + + - name: Download Screeb iOS XCFramework + run: | + SCREEB_IOS_URL=$(curl -sL https://api.github.com/repos/ScreebApp/sdk-ios-public/releases/latest | python3 -c "import sys,json; print(next(a['browser_download_url'] for a in json.load(sys.stdin)['assets'] if a['name']=='Screeb.zip'))") + curl -sL "$SCREEB_IOS_URL" -o /tmp/Screeb.zip + unzip -q /tmp/Screeb.zip -d /tmp/screeb_ios + mkdir -p packages/sdk-maui/native/ios + cp -r /tmp/screeb_ios/Screeb.xcframework packages/sdk-maui/native/ios/ + + - name: Restore + run: dotnet restore packages/sdk-maui/ScreebMaui.csproj + + - name: Build Android + run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-android -c Release --no-restore + + - name: Build iOS + run: dotnet build packages/sdk-maui/ScreebMaui.csproj -f net9.0-ios -c Release --no-restore + + - name: Pack + run: dotnet pack packages/sdk-maui/ScreebMaui.csproj -c Release --no-build -o ./nupkg + + - name: Push to NuGet + run: dotnet nuget push ./nupkg/*.nupkg --api-key ${{ secrets.NUGET_API_KEY }} --source https://api.nuget.org/v3/index.json --skip-duplicate diff --git a/.gitignore b/.gitignore index cae1ee9..2c00c19 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,14 @@ yarn-error.log* .config.env .vscode + +# MAUI SDK - native binaries (downloaded at build time) +packages/sdk-maui/native/ios/Screeb.xcframework/ +packages/sdk-maui/native/ios/Screeb.zip +packages/sdk-maui/native/ios/sdk-ios-public-*/ + +# .NET build artifacts +packages/sdk-maui/bin/ +packages/sdk-maui/obj/ +examples/example-maui/bin/ +examples/example-maui/obj/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 9ea4ab3..26dc38f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -52,5 +52,8 @@ npx lerna version --scope=@screeb/sdk-browser # Flutter # 1. Bump version in packages/sdk-flutter/pubspec.yaml -# 2. git tag sdk-flutter/vX.Y.Z && git push --tags +git tag sdk-flutter/vX.Y.Z && git push --tags + +# MAUI (NuGet) +git tag sdk-maui/v0.1.0 && git push --tags ``` diff --git a/README.md b/README.md index 57f39a1..0b3c64d 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ Public SDKs for [Screeb](https://screeb.app) — the Product Discovery platform. | Vue | [`@screeb/sdk-vue`](packages/sdk-vue) | [npm](https://www.npmjs.com/package/@screeb/sdk-vue) | [Install](https://developers.screeb.app/sdk-vue/install) | | Ionic | Uses `@screeb/sdk-angular` / `@screeb/sdk-react` / `@screeb/sdk-browser` | — | [Install](https://developers.screeb.app/sdk-js/sdk-ionic) | | React Native | [`@screeb/react-native`](packages/sdk-reactnative) | [npm](https://www.npmjs.com/package/@screeb/react-native) | [Install](https://developers.screeb.app/sdk-react-native/install) | +| .NET MAUI | [`Screeb.Maui`](packages/sdk-maui) | [NuGet](https://www.nuget.org/packages/Screeb.Maui) | [Install](https://developers.screeb.app/sdk-maui/install) | | Flutter | [`plugin_screeb`](packages/sdk-flutter) | [pub.dev](https://pub.dev/packages/plugin_screeb) | [Install](https://developers.screeb.app/sdk-flutter/install) | | iOS | Closed source ([`sdk-ios-public`](https://github.com/ScreebApp/sdk-ios-public) — SPM mirror) | [SPM](https://github.com/ScreebApp/sdk-ios-public) | [Install](https://developers.screeb.app/sdk-ios/install) | | Android | Closed source | [Maven](https://central.sonatype.com/artifact/app.screeb.sdk/survey) | [Install](https://developers.screeb.app/sdk-android/install) | @@ -29,6 +30,7 @@ Public SDKs for [Screeb](https://screeb.app) — the Product Discovery platform. | Ionic | Angular 16 + Capacitor | [`examples/example-ionic`](examples/example-ionic) | | Expo | React Native + Expo | [`examples/example-expo`](examples/example-expo) | | React Native | React Native CLI | [`examples/example-reactnative`](examples/example-reactnative) | +| .NET MAUI | .NET MAUI | [`examples/example-maui`](examples/example-maui) | | Flutter | Flutter | [`examples/example-flutter`](examples/example-flutter) | | Android | Android (Kotlin) | [`examples/example-android`](examples/example-android) | | iOS | iOS (Swift) | [`examples/example-ios`](examples/example-ios) | diff --git a/commitlint.config.js b/commitlint.config.js index 3742de1..464f831 100644 --- a/commitlint.config.js +++ b/commitlint.config.js @@ -13,7 +13,9 @@ module.exports = { "sdk-angular", "example-angular", "sdk-vue", - "example-vue" + "example-vue", + "sdk-maui", + "example-maui" ]], "scope-empty": [2, "never"], "scope-min-length": [2, "always", 1], diff --git a/examples/example-maui/App.xaml b/examples/example-maui/App.xaml new file mode 100644 index 0000000..54475ab --- /dev/null +++ b/examples/example-maui/App.xaml @@ -0,0 +1,10 @@ + + + + + #6200EE + + + diff --git a/examples/example-maui/App.xaml.cs b/examples/example-maui/App.xaml.cs new file mode 100644 index 0000000..dd7d14b --- /dev/null +++ b/examples/example-maui/App.xaml.cs @@ -0,0 +1,27 @@ +using static Screeb.Maui.Screeb; + +namespace ExampleMaui; + +public partial class App : Application +{ + public App() + { + InitializeComponent(); + MainPage = new MainPage(); + } + + protected override async void OnStart() + { + base.OnStart(); + await InitSdk( + channelId: "0e2b609a-8dce-4695-a80f-966fbfa87a88", + userId: "maui-user-123", + properties: new Dictionary + { + ["platform"] = "maui", + ["plan"] = "free" + }, + initOptions: new Screeb.Maui.ScreebInitOptions { IsDebugMode = true } + ); + } +} diff --git a/examples/example-maui/MainPage.xaml b/examples/example-maui/MainPage.xaml new file mode 100644 index 0000000..49d9be1 --- /dev/null +++ b/examples/example-maui/MainPage.xaml @@ -0,0 +1,24 @@ + + + + +