# Mobile SDKs

PushGenius ships native SDKs for **iOS**, **Android**, **React Native**, **Flutter**, and **Ionic / Capacitor**. They share one small API: initialize with your app ID, ask for permission, and identify the user. Find your app ID in the dashboard under Settings. Sending to browsers too? See [Web push](https://pushgeni.us/docs/web.md).

## Install

**iOS** (Xcode → File → Add Package Dependencies)

```
https://github.com/PushGenius/ios-sdk.git
Dependency rule: Up to Next Major Version, 0.2.0
```

**Android** (settings.gradle.kts, app/build.gradle.kts)

```kotlin
// settings.gradle.kts, in dependencyResolutionManagement.repositories
maven { url = uri("https://jitpack.io") }

// app/build.gradle.kts
implementation("com.github.PushGenius:android-sdk:0.2.0")
```

**React Native** (Terminal)

```sh
npm install @pushgenius/react-native
cd ios && pod install
```

**Flutter** (Terminal)

```sh
flutter pub add pushgenius
```

**Ionic** (Terminal)

```sh
npm install @pushgenius/ionic
npx cap sync
```

On iOS, enable the **Push Notifications** capability and **Background Modes → Remote notifications** in Xcode. The SDK picks up the APNs device token itself, so no AppDelegate changes are needed. On Android, add your `google-services.json` to the app module and apply the `com.google.gms.google-services` Gradle plugin. Requires iOS 15+.

## Quick start

**iOS** (AppDelegate.swift)

```swift
import PushGenius

BigBrain.initialize("YOUR_APP_ID")
BigBrain.Notifications.requestPermission(true)
BigBrain.login("user-123")
BigBrain.User.addTag(key: "plan", value: "pro")
```

**Android** (App.kt)

```kotlin
import us.pushgeni.sdk.BigBrain

BigBrain.initialize("YOUR_APP_ID")
BigBrain.Notifications.requestPermission(true)
BigBrain.login("user-123")
BigBrain.User.addTag("plan", "pro")
```

**React Native** (App.tsx)

```ts
import { BigBrain } from "@pushgenius/react-native";

BigBrain.initialize("YOUR_APP_ID");
await BigBrain.Notifications.requestPermission(true);
BigBrain.login("user-123");
BigBrain.User.addTag("plan", "pro");
```

**Flutter** (main.dart)

```dart
import 'package:pushgenius/pushgenius.dart';

await BigBrain.initialize('YOUR_APP_ID');
await BigBrain.Notifications.requestPermission(true);
await BigBrain.login('user-123');
await BigBrain.User.addTag('plan', 'pro');
```

**Ionic** (main.ts)

```ts
import { BigBrain } from "@pushgenius/ionic";

await BigBrain.initialize("YOUR_APP_ID");
await BigBrain.Notifications.requestPermission();
await BigBrain.login("user-123");
await BigBrain.User.addTag("plan", "pro");
```

## Users, tags, and aliases

Call `login` with your own user ID so you can target that person from your backend. Tags are simple key/value strings you can build segments from.

**iOS** (Swift)

```swift
BigBrain.login("user-123")
BigBrain.User.addTags(["plan": "pro", "locale": "en"])
BigBrain.User.removeTag("trial")
BigBrain.User.addAlias(label: "crm_id", id: "C-88412")
BigBrain.logout()
```

**Android** (Kotlin)

```kotlin
BigBrain.login("user-123")
BigBrain.User.addTags(mapOf("plan" to "pro", "locale" to "en"))
BigBrain.User.removeTag("trial")
BigBrain.User.addAlias("crm_id", "C-88412")
BigBrain.logout()
```

**React Native** (TypeScript)

```ts
BigBrain.login("user-123");
BigBrain.User.addTags({ plan: "pro", locale: "en" });
BigBrain.User.removeTag("trial");
BigBrain.User.addAlias("crm_id", "C-88412");
BigBrain.logout();
```

**Flutter** (Dart)

```dart
await BigBrain.login('user-123');
await BigBrain.User.addTags({'plan': 'pro', 'locale': 'en'});
await BigBrain.User.removeTag('trial');
await BigBrain.User.addAlias('crm_id', 'C-88412');
await BigBrain.logout();
```

**Ionic** (TypeScript)

```ts
await BigBrain.login("user-123");
await BigBrain.User.addTags({ plan: "pro", locale: "en" });
await BigBrain.User.removeTag("trial");
await BigBrain.User.addAlias("crm_id", "C-88412");
await BigBrain.logout();
```

## Permission and opt-out

`BigBrain.Notifications.requestPermission()` shows the system prompt and registers the device token with APNs or FCM. On every platform you can opt a user out without uninstalling via `BigBrain.User.pushSubscription.optOut()`, and back in with `BigBrain.User.pushSubscription.optIn()`.

## Taps and delivery tracking

Register `BigBrain.Notifications.addClickListener` to decide what happens when someone taps a notification, such as opening the order a “Your order shipped” message is about. The listener gets the notification’s ID and its `additionalData`: the custom `data` object you sent with the message. Values arrive as strings, and numbers or nested objects are JSON-encoded.

**iOS** (Swift)

```swift
BigBrain.Notifications.addClickListener { event in
  // event.additionalData holds the data you sent with the message
  if let orderId = event.additionalData["order_id"] as? String {
    router.openOrder(orderId)
  }
}
```

**Android** (Kotlin)

```kotlin
BigBrain.Notifications.addClickListener { event ->
    // event.additionalData holds the data you sent with the message
    val orderId = event.additionalData["order_id"] as? String
    if (orderId != null) openOrder(orderId)
}
```

**React Native** (TypeScript)

```ts
const subscription = BigBrain.Notifications.addClickListener((event) => {
  // event.additionalData holds the data you sent with the message
  const orderId = event.additionalData?.order_id;
  if (typeof orderId === "string") navigation.navigate("Order", { orderId });
});

// When the screen that registered it goes away:
subscription?.remove();
```

- **Taps that launch your app.** If the tap starts your app, the SDK holds the event until you register a listener, then delivers it. Register the listener early in startup so you get it. Listeners run on the main thread.
- **iOS.** If your app already has a `UNUserNotificationCenter` delegate, the SDK passes every callback on to it. If it doesn’t, notifications that arrive while the app is open show as a banner.
- **Android.** The SDK displays every PushGenius notification itself, whether your app is open, in the background, or closed, so it can report each one as received. A tap opens your launcher activity, with the notification’s data also in the intent extras. Set a monochrome small icon with the `com.google.firebase.messaging.default_notification_icon` meta-data in your manifest; otherwise the app icon is used.
- **Flutter and Ionic.** There’s no click listener yet, but taps and receipts are still tracked.

### What the dashboard counts

- **Sent:** APNs or FCM accepted the message for that device.
- **Received:** the device reported that the notification arrived. Android reports every notification. On iOS, notifications that arrive while your app is in the background or closed are only reported if you add the notification service extension below. A tap also counts as received.
- **Clicked:** someone tapped the notification, whether your app was open, in the background, or closed.

Each device counts at most once per message toward Received and toward Clicked.

### Count background receipts on iOS

iOS doesn’t run your app when a notification arrives in the background, but it does run a Notification Service Extension. Add one and every notification is reported as received, even when your app is closed. This works the same way for native, React Native, Flutter, and Ionic apps.

1. In Xcode, choose **File → New → Target → Notification Service Extension** and name it `NotificationService`. Set its minimum iOS version to match your app’s.
2. Add the package `https://github.com/PushGenius/ios-sdk.git` if your project doesn’t have it yet, and add its **PushGeniusNotificationService** library to the extension target only.
3. Replace the contents of the extension’s `NotificationService.swift` with the code below.

```swift
import PushGeniusNotificationService

class NotificationService: BigBrainNotificationService {}
```

If your app calls `setHost`, override `host` in that class too. In a Flutter app, if the build then fails with a dependency cycle, open the Runner target’s **Build Phases** and drag **Embed Foundation Extensions** above **Run Script**.

Source: https://pushgeni.us/docs/sdks
