Nojoom 1.0.2
See the version list below for details.
dotnet add package Nojoom --version 1.0.2
NuGet\Install-Package Nojoom -Version 1.0.2
<PackageReference Include="Nojoom" Version="1.0.2" />
<PackageVersion Include="Nojoom" Version="1.0.2" />
<PackageReference Include="Nojoom" />
paket add Nojoom --version 1.0.2
#r "nuget: Nojoom, 1.0.2"
#:package Nojoom@1.0.2
#addin nuget:?package=Nojoom&version=1.0.2
#tool nuget:?package=Nojoom&version=1.0.2
Nojoom Lifestyle SDK for .NET MAUI
Official .NET MAUI bindings for the Nojoom Lifestyle SDK. A single package embeds the Nojoom offers / coupons experience into a MAUI app on both Android and iOS.
You give the SDK a session token; it renders its entire UI itself — home, offer categories, merchant listings, offer details with maps, coupons, favourites, redemption (QR / code), and contacts. Your app builds none of those screens.
| Target | Included |
|---|---|
net9.0-android |
Managed binding + all runtime AARs (Jetpack Compose, Coil, Google Maps, Huawei Map Kit, Retrofit/OkHttp, Nimbus JWT) |
net9.0-ios |
Managed binding + native NojoomLifestyles.xcframework (device + simulator slices) |
One PackageReference covers both platforms.
Install
dotnet add package Nojoom --version 1.0.2
<PackageReference Include="Nojoom" Version="1.0.2" />
Requirements
- .NET 9 with the MAUI /
androidandiosworkloads. - Android minimum API level 24; iOS minimum 13.0.
Host-app configuration
These cannot be carried by the package and must be supplied by the consuming app.
Android — required NuGet pins (build/runtime conflict fix)
com.google.gson and a few AndroidX versions conflict with what Microsoft.Maui.Core pins. Add
these to your app project or you'll hit NU1107 at build or a crash at runtime:
<ItemGroup Condition="$(TargetFramework.Contains('-android'))">
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData" Version="2.10.0.2" />
<PackageReference Include="Xamarin.AndroidX.Lifecycle.LiveData.Core" Version="2.10.0.2" />
<PackageReference Include="Xamarin.AndroidX.SavedState.SavedState.Ktx" Version="1.4.0.2" />
</ItemGroup>
The NU1608 "version outside constraint" warnings these produce are expected and benign.
(Non-MAUI Xamarin.Android hosts must also add the GoogleGson NuGet ≥ 2.10.1 — a MAUI app
already provides it transitively.)
The SDK's networking stack also needs com.squareup.okio (Okio) present at runtime. Apps using
Firebase Analytics/Messaging already get it transitively via Xamarin.AndroidX.DataStore.*; if
yours doesn't, add Square.OkIO.JVM (≥ 3.9.0) yourself.
Android — Google Maps API key (required)
The SDK shows a Google Map on offer-detail screens. Add your key to the host
AndroidManifest.xml (play-services-maps reads it from the host, never the SDK). Without it the
app hard-crashes with IllegalStateException: API key not found when a map opens.
<application ...>
<meta-data android:name="com.google.android.geo.API_KEY" android:value="YOUR_MAPS_KEY" />
</application>
Huawei devices additionally need an AppGallery Connect project (agconnect-services.json + Map
Kit key) in the host app.
iOS
No extra references or pins — the native NojoomLifestyles.xcframework ships inside the package
and links automatically.
Initialize & launch
The one runtime input is a session token from your own login flow. No API key or encryption
keys are needed — those are embedded in the SDK. Initialization is async — only show the SDK UI
after onSuccess.
Android — launch NojoomActivity
using Com.Nojoom.Lifestyles.Public;
using Microsoft.Maui.ApplicationModel;
var activity = Platform.CurrentActivity;
var intent = NojoomActivity.CreateIntent(activity, token);
activity.StartActivity(intent); // NojoomActivity self-initializes and renders its own UI
iOS — initialize, present on success
using NojoomLifestyles;
using Microsoft.Maui.ApplicationModel;
using UIKit;
NojoomSDK.Initialize(
token,
onSuccess: () => MainThread.BeginInvokeOnMainThread(() =>
{
// Grab the app's top-most view controller to present from.
var root = UIApplication.SharedApplication.KeyWindow?.RootViewController;
while (root?.PresentedViewController is not null)
root = root.PresentedViewController;
var vc = NojoomSDK.MakeContentViewController();
vc.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
root?.PresentViewController(vc, animated: true, completionHandler: null);
}),
onError: message => { /* show error, prompt re-login */ });
Session callbacks (optional, both platforms)
Three optional callbacks: session-expired, token-refresh, offer-redeemed.
Register them before launching NojoomActivity:
NojoomActivity.SetOnOfferRedeemed(new RedeemListener(token => { /* forward token to backend */ }));
NojoomActivity.SetOnRefreshToken(new RefreshTokenListener(async () => await GetFreshTokenAsync()));
RedeemListener and RefreshTokenListener are small adapter classes you add to your app —
each wraps a C# delegate in the SDK's Java interface and must extend Java.Lang.Object to cross
the JNI boundary. Paste these two classes as-is:
using Com.Nojoom.Lifestyles.Public;
// Adapts an Action<string> to INojoomRedeemListener.
sealed class RedeemListener : Java.Lang.Object, INojoomRedeemListener
{
readonly Action<string> _onOfferRedeemed;
public RedeemListener(Action<string> onOfferRedeemed) => _onOfferRedeemed = onOfferRedeemed;
public void OnOfferRedeemed(string token) => _onOfferRedeemed(token);
}
// Adapts an async Func<Task<string?>> to INojoomRefreshTokenListener.
// The SDK calls OnRefreshToken on the main thread and blocks a background thread (up to 30s)
// waiting for the reply, so run the refresh OFF the main thread and deliver via
// result.OnToken(...) from whatever thread it finishes on (pass null if the refresh failed).
sealed class RefreshTokenListener : Java.Lang.Object, INojoomRefreshTokenListener
{
readonly Func<Task<string?>> _onRefreshToken;
public RefreshTokenListener(Func<Task<string?>> onRefreshToken) => _onRefreshToken = onRefreshToken;
public void OnRefreshToken(INojoomTokenCallback result) => _ = Task.Run(async () =>
{
string? newToken;
try { newToken = await _onRefreshToken(); } catch { newToken = null; }
result.OnToken(newToken);
});
}
iOS — full Initialize overload
NojoomSDK.Initialize(
token,
onSuccess: () => { /* present MakeContentViewController() */ },
onError: message => { /* show error */ },
onSessionExpired: () => { /* prompt re-login */ },
onRefreshToken: completion => Task.Run(async () =>
{
string? fresh;
try { fresh = await GetFreshTokenAsync(); } catch { fresh = null; }
completion.Provide(fresh); // any thread; null = refresh failed
}),
onOfferRedeemed: redeemToken => { /* forward opaque token to your backend */ });
Pass null for any callback you don't need.
Behaviour notes
- The SDK owns the whole screen; your app gets no navigation callbacks until the user backs out.
- Security is on by default: screenshots/recording of SDK screens are blocked, plus device integrity checks. Relaxed automatically on debug builds so emulator/QA is unaffected.
- Token carries a ~1-hour backend expiry + configurable idle timeout (default 30 min).
API surface
Android (Com.Nojoom.Lifestyles.Public) — NojoomActivity.CreateIntent(context, token),
SetOnOfferRedeemed, SetOnRefreshToken; NojoomSDK.Initialize/IsInitialized/Reset;
INojoomRedeemListener, INojoomRefreshTokenListener, INojoomTokenCallback. (NojoomSDKView
is intentionally not bound — use NojoomActivity.)
iOS (NojoomLifestyles) — NojoomSDK.Initialize(token, onSuccess, onError[, onSessionExpired, onRefreshToken, onOfferRedeemed]), MakeContentViewController(), IsInitialized, Reset(),
NojoomTokenCompletion.Provide(token).
License
Proprietary. All rights reserved. See LICENSE.txt.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net9.0-android35.0 is compatible. net9.0-ios18.0 is compatible. net10.0-android was computed. net10.0-ios was computed. |
-
net9.0-android35.0
- Xamarin.AndroidX.Activity (>= 1.12.4.1)
- Xamarin.Google.Android.Play.Core.Common (>= 2.0.4.7)
- Xamarin.Google.Android.Play.Integrity (>= 1.4.0.6)
- Xamarin.GooglePlayServices.Base (>= 118.2.0.6)
- Xamarin.GooglePlayServices.Basement (>= 118.7.1.1)
- Xamarin.GooglePlayServices.Maps (>= 118.2.0.2)
- Xamarin.GooglePlayServices.Tasks (>= 118.3.2.1)
- Xamarin.Kotlin.StdLib (>= 2.3.10.1)
- Xamarin.KotlinX.Coroutines.Android (>= 1.10.2.3)
-
net9.0-ios18.0
- No dependencies.
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.