Quasar: OneSignal PushNotifications unter iOS

      0
OneSignal iOS Push Notifications

Ich bin ein großer Fan des Quasar Frameworks. Nachdem ich nun Tage damit verbracht habe personalisierte OneSignal Push Notifications mit Quasar und Capacitor unter iOS zum Laufen zu kriegen, möchte ich mein Ergebnis mit dir teilen. Um den Notifications Dienst zu konfigurieren müssen wir uns an den nativen iOS Code heran wagen. Aber keine Sorge: Wir kriegen das hin!

Was ist OneSignal?

Weißer Schriftzug One Signal und das OneSignal Logo auf rotem Hintergrund

OneSignal ist ein Dienst mit dem du kostenlos Push Notifications versenden kannst. Der Dienst kann auf verschiedene Art und Weisen eingebunden werden. Für die Webentwicklung würde man normalerweise auf die Web-Anbindung setzen. Allerdings unterstützt Safari nach wie vor keine Web Push Notifications. Wir müssen daher die native Anbindung verwenden.

Zunächst brauchen wir aber ein OneSignal Konto. Registriere dich und erstelle ein App bis du zu dem Punkt kommst, wo dir eine App ID zugewiesen wird. Diese brauchen wir für den nächsten Schritt.

Voraussetzungen & OneSignal Basis Konfiguration

Zunächst benötigt ihr natürlich eine Quasar App. Diese sollte Capacitor und nicht Cordova verwenden. Wie du Capacitor für deine App aktivierst findest du hier.

Die App steht also bereit. Nun wollen OneSignal konfigurieren. Da die Dokumentation des Dienstes wirklich gut ist, möchte ich hier nicht großartig auf die Basis Konfiguration eingehen. Folg also einfach der Anleitung und hinterlege die ID aus dem vorherigen Schritt.

OneSignal ID an den App-User binden

Nun kommen wir zum spannenden Teil, der mich Tage lang beschäftigt hat und nirgends im Internet beschrieben wird – bis heute.

Um personalisierte Notifications zu verschicken, müssen wir die ID, die von OneSignal beim Aktivieren der Notifications generiert wird, dem User in unserer App zuweisen.

Der Workflow sieht folgendermaßen aus:

  1. User öffnet die App
  2. Dialog „Möchten Sie Push Notifications erhalten“ öffnet sich
  3. User akzeptiert
  4. OneSignal Plugin speichert die ID zwischen
  5. User logged sich ein
  6. Javascript Code fragt die ID beim OneSignal Plugin an und gibt sie an die API o.ä. weiter

Punkt 1-3 solltest du mit der Basis Konfiguration bereits erreicht haben. Öffne nun mit folgendem Befehl Xcode:

quasar dev -m capacitor -T ios

Als erstes erstellen wir nun unser Plugin. Klick dazu im Verzeichnisbaum mit der rechten Maustaste auf „App“ und erstelle eine neue Datei. Bei dem Dialog, der sich öffnet wählst du „Swift File“ aus und gibst der Datei den Namen „OneSignalPlugin“.

Die neu erstellte Datei füllst du mit folgendem Code.

// OneSignalPlugin.swift

import Capacitor

extension Notification.Name {
    static let onOneSignalOptin = Notification.Name("onOneSignalOptin")
}

@objc(OneSignalPlugin)

public class OneSignalPlugin: CAPPlugin {
    var notificationsEnabled: Bool = false
    var oneSignalId: String = "undefined"

    /**
     * Add event listener for NotificationCenter
     *
     * @see AppDelegate.swift
     */
    public override func load() {
        print("Init OneSignalPlugin")
        NotificationCenter.default.addObserver(self, selector: #selector(optin(_:)), name: .onOneSignalOptin, object: nil)
    }

    /**
     * Executes on "onOneSignalOptin" event.
     * Set oneSignalId so you can call getStatus() in your javascript code.
     *
     * e.g.: await window.Capacitor.Plugins.OneSignalPlugin.getId()
     */
    @objc func optin(_ notification:Notification) {
        print("OneSignalPlugin: optin")

        let oneSignalId = notification.userInfo?["oneSignalId"] ?? "undefined"
        let notificationsEnabled = notification.userInfo?["notificationsEnabled"] ?? false

        self.oneSignalId = oneSignalId as! String
        self.notificationsEnabled = notificationsEnabled as! Bool
    }

    @objc func getStatus(_ call: CAPPluginCall) {
        call.resolve([
            "notificationsEnabled": self.notificationsEnabled,
            "oneSignalId": self.oneSignalId
        ])
    }
}

Um das Plugin einzubinden müssen wir eine weitere Datei erstellen. Klick wieder auf „App“ und erstell eine neue Datei. Im Dialog wählst du dies Mal „Objective-C File“ (das Icon mit dem kleinen m). Auch diese Datei nennen wir „OneSignalPlugin“. Wenn du danach gefragt wirst, ob automatische eine Header Datei erstellt werden soll, wähle ja aus.

// OneSignalPlugin.m

#import <Foundation/Foundation.h>
#import <Capacitor/Capacitor.h>

CAP_PLUGIN(OneSignalPlugin, "OneSignalPlugin",
    CAP_PLUGIN_METHOD(optin, CAPPluginReturnPromise);
    CAP_PLUGIN_METHOD(getStatus, CAPPluginReturnPromise);
)

Diese Datei ist eigentlich nur dazu da um die Funktionen des Plugins bekannt zu machen. Dadurch sind diese auch von außen erreichbar.

Nun öffne die Datei AppDelegate.swift. Diese solltest du bereits aus der OneSignal Basis Konfiguration denken. Wir erweitern nun den Code in der promptForPushNotifications Funktion.

// AppDelegate.swift

...

OneSignal.promptForPushNotifications(userResponse: { accepted in
    print("User accepted notifications: \(accepted)")

    let oneSignalId = OneSignal.getPermissionSubscriptionState()?.subscriptionStatus.userId ?? "undefined"

    NotificationCenter.default.post(name: .onOneSignalOptin, object: nil, userInfo: [
        "notificationsEnabled": accepted,
        "oneSignalId": oneSignalId
    ])
})

...

Damit haben wir alles im nativen iOS Code erledigt. Jetzt können wir uns wieder den uns bekannten Gefilden zuwenden. Öffne die Stelle im Javascript Code, wo du den User Login behandelst. Bei mir passiert das in der Vue.js.

// Login.vue

...

methods: {
    async doLogin () {
        await login()
        await this.updateOneSignal()

        this.$router.replace({ name: 'home' })
    },

    /**
     * One Signal is processed in native iOS/Android code.
     * We have to call a capacitor plugin call in order to get the current status.
     */
    async updateOneSignal () {
        if (!this.$q.platform.is.ios) {
            // Skip, because Notifications are only available
            // on real devices.
            return
        }

        const { OneSignalPlugin } = window.Capacitor.Plugins
        const { notificationsEnabled, oneSignalId } = await OneSignalPlugin.getStatus()

        if (!notificationsEnabled) {
            return
        }

        // Tell your API or whatever the oneSignalId
        await axios.post('/update-one-signal', { oneSignalId })
    },
},

...

Herzlichen Glückwunsch! Nun hast du OneSignal erfolgreich in deiner Quasar App konfiguriert.

Schreib mir gerne auf Twitter, falls die Anleitung dir weitergeholfen hat, um OneSignal Push Notifications mit Quasar einzurichten.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert