Hur man konfigurerar iOS-appens push-aviseringar med PushEngage

Du kan nu implementera push-notiser för din iOS-applikation med hjälp av vårt iOS App SDK. Du skulle behöva hjälp av din utvecklare eftersom det skulle vara en engångsintegration innan du kan skicka push-notiser till dem via PushEngage-instrumentpanelen.

Innan du börjar

  • Du behöver Xcode installerat på ditt system.
  • Ett giltigt utvecklarkonto och App ID är konfigurerade på Apple Developer Portal.

Vi kommer att följa dessa steg för att aktivera push-notiser för din iOS-applikation.

Konfigurera din app

Aktivera fjärrnotiser

1. Öppna ditt Xcode-projekt och välj rotprojektet i Project Navigator. Välj din huvudsakliga app-mål.

2. Navigera till Signing & Capabilities. Se till att bakgrundslägen-kapabiliteten är tillagd. Om inte, lägg till den genom att klicka på knappen "+ Capability".

3. På samma sätt, se till att Push-notiser-kapabiliteten är tillagd. Om inte, lägg till den med knappen "+ Capability".

Om kapabiliteten Push Notifications inte är synlig i Xcode. Du behöver följa stegen nedan:

1. Gå till ditt Apple Developer-konto.

2. Navigera till Certificates, Identifiers & Profiles.

3. Välj din App-identifierare. Redigera konfigurationen av ditt App ID och se till att Push Notifications är aktiverat.

4. Återgå till Xcode och försök att lägga till "Push Notifications"-kapabiliteten igen.

Aktivera bakgrundslägen

1. Navigera till Signing & Capabilities i ditt Xcode-projekt.

2. Inom Background Modes, aktivera både Remote notifications och Background Fetch.

Det här steget säkerställer att din app effektivt kan hantera fjärrnotiser och bakgrundshämtningar.

Här finns guiden för att skapa ditt APNs-certifikat.

Integrera PushEngage iOS SDK

PushEngage iOS SDK finns tillgängligt som ett Swift-paket och en CocoaPods-pod. Vi ber dig att gå igenom båda metoderna men bara använda en av dem när du slutför din installation.

Integrera PushEngage iOS SDK med SPM

För att integrera PushEngage iOS SDK med Swift Package Manager, följ dessa steg:

  1. Öppna XCode och navigera till ditt projekt. Välj fliken "Package dependencies". Klicka på +-knappen.
  1. Klistra in URL:en https://github.com/awesomemotive/pushengage-ios-sdk i sökfältet. Klicka på "Add Package".
  1. Välj ditt huvudsakliga app-mål under "Add to Target" och klicka på "Add Package".

Integrera PushEngage iOS SDK med CocoaPods

För att integrera PushEngage iOS SDK med CocoaPods, behöver du följa dessa steg:

Om CocoaPods inte är installerat, stäng ditt nuvarande Xcode-projekt och kör följande kommando i din projekts rotkatalog

sudo gem install cocoapods

Kör följande kommando för att initiera en Podfile i ditt projekt

pod init

Öppna den nyskapade Podfile med en textredigerare eller genom att följa kommandot i din terminal i projektets rotkatalog.

open Podfile

Lägg till PushEngage-beroendet under ditt projekts mål. Se till att din Podfile liknar exemplet nedan

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'YourProjectName' do
  # Add PushEngage SDK dependency
  pod 'PushEngage'
  post_install do |installer|
    installer.pods_project.targets.each do |target|
      target.build_configurations.each do |config|
        config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
      end
    end
  end
end

Spara Podfile och kör följande kommandon i terminalen.

pod repo update
pod install

Öppna den nyskapade filen <project-name>.xcworkspace i Xcode.

Initiera PushEngage iOS SDK

När du har integrerat SDK:n måste vi initiera iOS SDK i din AppDelegate.

Med Swift-språket, här är hur du kan göra det

import PushEngage
class AppDelegate: UIResponder, UIApplicationDelegate {
    var window: UIWindow?
    override init() {
        super.init()
        PushEngage.swizzleInjection(isEnabled: true)
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
       // Set your PushEngage App ID (replace       "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD" with your actual App ID)
        PushEngage.setAppId(key: "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD")
        // Start PushEngage initial info
        PushEngage.setInitialInfo(for: application, with: launchOptions)
        // Enable logs for debugging (optional)
        PushEngage.enableLogs = true
        return true
    }
}

Med Objective-C-språket, här är hur du kan göra det

#import "AppDelegate.h"
@import PushEngage;
@implementation AppDelegate

- (instancetype)init {
    self = [super init];
    if (self) {
       [PushEngage swizzleInjectionWithIsEnabled:YES];
    }
    return self;
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Set your PushEngage App ID (replace "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD" with your actual App ID)
    [PushEngage setAppIdWithKey:@"APP_ID_FROM_PUSH_ENGAGE_DASHBOARD"];
    // Set initial info
    [PushEngage setInitialInfoFor:application with:launchOptions];
    // Enable logs for debugging (optional)
    [PushEngage setEnableLogs:YES];
    return YES;
}

@end

Ibland, när du använder SwiftUI, kanske AppDelegate inte är tillgänglig som standard. I sådana fall kan du initiera PushEngage SDK i din huvudsakliga App-fil. Här är ett exempel i SwiftUI

import SwiftUI
import PushEngage

@main
struct PEDemoApp: App {
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate {
    
    override init() {
        super.init()
        PushEngage.swizzleInjection(isEnabled: true)
    }
    
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        PushEngage.setAppId(key: "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD")
        PushEngage.setIntialInfo(for: application,
                                             with: launchOptions)
        
        PushEngage.enableLogs = true
        return true
    }
}

Notera: När du utvecklar din app kan det vara användbart att aktivera loggar från PushEngage SDK för felsökningsändamål. Det är dock viktigt att inaktivera loggar i produktionsbyggen för att undvika att exponera känslig information.

Skapa Notification Service Extension

Notification Service Extension förbättrar din iOS-apps förmåga att ta emot notiser. Detta används för att modifiera notisens innehåll eller hämta/bearbeta data vid mottagande av notisen. Du kan följa stegen nedan för att skapa en Notification Service Extension:

1. Öppna Xcode och navigera till ditt projekt. Välj Arkiv » Nytt » Mål från menyn.

2. I mallvalsfönstret, välj Notification Service Extension och klicka på Nästa.

3. Ange ett namn för din extension, till exempel PushEngageNotificationServiceExtension, och klicka på Slutför.

4. När du är klar med att skapa Notification Service Extension, kan du bli ombedd att aktivera den. Aktivera den inte omedelbart.

Att aktivera extensionen skulle skifta Xcodes felsökningsfokus från din app till extensionen. Om du aktiverar den av misstag, oroa dig inte; du kan byta tillbaka till att felsöka din app inom Xcode.

Initiera PushEngage SDK för Notification Service Extension

För att säkerställa korrekt funktion av PushEngage SDK i din iOS Notification Service Extension, behöver du följa dessa steg:

1. Öppna Podfile som är associerad med ditt projekt.

2. Sedan behöver du lägga till beroendet. Infoga följande kodavsnitt i din Podfile:

target 'Your_Main_Application_Target' do
      pod 'PushEngage'
      post_install do |installer|
          installer.pods_project.targets.each do |target|
            target.build_configurations.each do |config|
              config.build_settings['APPLICATION_EXTENSION_API_ONLY'] = 'NO'
          end
        end
      end
     
      target 'Your_Notification_Service_Extension_Target' do
              pod 'PushEngage'
      end
end

3. Kör följande kommandon i din terminal inom din rotprojektkatalog:

pod repo update
pod install

4. I din Notification Service Extension-mål, importera PushEngage-ramverket och lägg till nödvändig initialiseringskod. Här är hur du kan göra det.

Använda Swift

import UserNotifications
import PushEngage

@available(iOSApplicationExtension 10.0, *)
class PushEngageNotificationServiceExtension: UNNotificationServiceExtension {

    var contentHandler: ((UNNotificationContent) -> Void)?
    var bestAttemptContent: UNMutableNotificationContent?
    var request : UNNotificationRequest?

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        self.request = request
        self.contentHandler = contentHandler
        self.bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestContent = bestAttemptContent {
            PushEngage.didReceiveNotificationExtensionRequest(request, bestContentHandler: bestContent)
            contentHandler(bestContent)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        // Called just before the extension will be terminated by the system.
        // Use this as an opportunity to deliver your "best attempt" at modified content, otherwise the original push payload will be used.
        if let contentHandler = contentHandler, let request = request ,let bestAttemptContent =  bestAttemptContent {
            guard let content = PushEngage.serviceExtensionTimeWillExpire(request, content: bestAttemptContent) else {
                contentHandler(bestAttemptContent)
                return
            }
            contentHandler(content)
        }
    }

}

Använda Objective-C

#import "NotificationService.h"
@import PushEngage;

@interface NotificationService ()

@property (nonatomic, strong) void (^contentHandler)(UNNotificationContent *contentToDeliver);
@property (nonatomic, strong) UNMutableNotificationContent *bestAttemptContent;
@property (nonatomic, strong) UNNotificationRequest *request;

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    self.request = request;
    self.contentHandler = contentHandler;
    self.bestAttemptContent = [request.content mutableCopy];
    
    if (self.bestAttemptContent) {
        [PushEngage didReceiveNotificationExtensionRequest:request bestContentHandler:self.bestAttemptContent];
        contentHandler(self.bestAttemptContent);
    }
}

- (void)serviceExtensionTimeWillExpire {

    if (self.contentHandler && self.request && self.bestAttemptContent) {
        UNNotificationContent *content = [PushEngage serviceExtensionTimeWillExpire:self.request content:self.bestAttemptContent];
        if (content) {
            self.contentHandler(self.bestAttemptContent);
            return;
        }
    }
    self.contentHandler(self.bestAttemptContent);
}

@end

Skapa Notification Content Extension

För att förbättra sättet genom att lägga till anpassat UI, behöver du skapa en Notification Content Extension. Följ stegen nedan för att ställa in tillägget:

1. I Xcode, gå till Arkiv » Nytt » Mål.

2. Välj Notification Content Extension och klicka på Nästa.

3. Välj inte “Aktivera” i dialogrutan som visas efter att ha klickat på Slutför. Att avbryta gör att Xcode felsöker din app istället för tillägget. Om du av misstag aktiverar det, byt tillbaka till att felsöka din app inom Xcode (bredvid körknappen).

4. I projektnavigatören, välj den översta projektdirektori och välj NotificationContentExtension-målet i projektet från mållistan som skapades i steg nr. 2.

5. Ställ in Deployment Target till iOS 10 eller senare, vilket är den version av iOS som Apple släppte stödet för detta tillägg. 

Initiera PushEngage SDK för Notification Content Extension

För att säkerställa korrekt funktion av PushEngage SDK i din iOS Notification Content Extension, behöver du följa dessa steg:

1. Öppna Podfile som är associerad med ditt projekt.

2. Lägg till beroendet, infoga följande kodavsnitt i din Podfile:

target 'Your_Main_Application_Target' do
  pod 'PushEngage'
  target 'Your_Notification_Content_Extension' do
    pod 'PushEngage'
  end
end

3. Kör följande kommandon i din terminal inom din rotprojektkatalog:

pod repo update

pod install

4. I din Notification Content Extension-mål, importera PushEngage-ramverket och lägg till nödvändig initialiseringskod. Här är hur du kan göra det med några exempel på UI-element:

Använda Swift

import UIKit
import UserNotifications
import UserNotificationsUI
import PushEngage

@available(iOSApplicationExtension 10.0, *)
class NotificationViewController: UIViewController, UNNotificationContentExtension {
    
    fileprivate var hostingView: UIHostingController<ContentView>?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        self.view.backgroundColor = .white
    }
    
    func didReceive(_ notification: UNNotification) {
        if(notification.request.content.categoryIdentifier == "your_identifier"){
            let payLoad = PushEngage.getCustomUIPayLoad(for: notification.request)
  //pass the payload to your custom View
            let view = CustomView(payLoadInfo: payLoad)
            hostingView = UIHostingController(rootView: view)
If let customView = self.hostingView {
            addChild(hostingView!)
}
        }
    }
    
}


Objective-C:

#import "NotificationViewController.h"
#import <UserNotifications/UserNotifications.h>
#import <UserNotificationsUI/UserNotificationsUI.h>

@import PushEngage;
@import UIKit;

@interface NotificationViewController () <UNNotificationContentExtension>

@property IBOutlet UILabel *label;
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@property (weak, nonatomic) IBOutlet UIButton *firstButton;
@property (weak, nonatomic) IBOutlet UIButton *secondButton;

@end

@implementation NotificationViewController

- (IBAction)firstbuttonAction:(id)sender {
    // do what action you want to perform.
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any required interface initialization here.
}

- (void)didReceiveNotification:(UNNotification *)notification {
    
    NotificationViewController * __block blockSelf = self;
    CustomUIModel *object = [PushEngage getCustomUIPayLoadFor:notification.request];
    dispatch_async(dispatch_get_main_queue(), ^{
        blockSelf.label.text = object.title;
        blockSelf.imageView.image = object.image;
        [blockSelf.firstButton setTitle:object.buttons.firstObject.text forState:UIControlStateNormal];
        [blockSelf.secondButton setTitle:object.buttons.lastObject.text forState:UIControlStateNormal];
        blockSelf = NULL;
    });
}

@end

Lägg till App Groups

App Groups är avgörande för kommunikation mellan huvudappen, anmälsningstjänstens tillägg och innehållstillägget. Du kan följa dessa steg för att lägga till App Groups i ditt iOS-projekt:

Om du har en befintlig appgrupp och bara vill använda den, hoppa till steg nr. 5.

1. I ditt Xcode-projekt, i projektnavigatören, välj den översta projektdirektori och välj huvudmålet för appen.

2. Navigera till fliken Signing & Capabilities.

3. Klicka på knappen “+ Capability” och välj App Groups från listan.

4. Klicka på + -knappen för att lägga till en App Group. Lägg till ett unikt namn till din App Group och klicka på OK.

5. I huvudredigeringsområdet, välj huvudmålet för din app och skapa en appgrupp. Ange namnet på gruppen i din applikations Info.plist med nyckeln PushEngage_App_Group_Key.

6. Lägg till samma nyckel och värde i Notification Service Extensionens Info.plist-fil.

7. Välj samma appgrupp i Main Application Target och YourNotificationServiceExtension.

Se till att du väljer ditt anmälsningstjänsttillägg i ovanstående steg.

Djupkoppling

Djupkoppling gör det möjligt för dina prenumeranter att navigera direkt till en specifik skärm inom applikationen eller en utsedd webbsida när de interagerar med push-meddelanden. Som standard, om du anger en giltig URL, kommer prenumeranten att omdirigeras till den webbsidan.

Hantering av webbadresser:

  • Ange PushEngageInAppEnabled till JA i Info.plist, sedan laddas URL:en inom applikationen med WKWebview.
  • Ange PushEngageInAppEnabled till NEJ i Info.plist, om du vill att din prenumerant ska omdirigeras till Safari för att ladda URL:en. 
  • Ange PushEngageAutoHandleDeeplinkURL till JA i Info.plist, sedan kommer SDK:n att hantera djupkopplingen enligt PushEngageInAppEnabled-konfigurationen.
  • Ange PushEngageAutoHandleDeeplinkURL till NEJ i Info.plist, sedan kommer kontrollen av att hantera djupkopplingen att ges till klientappen från SDK:n.
  • Om djupkopplingen inte är en giltig URL måste du konfigurera navigering genom att använda setNotificationOpenHandler i AppDelegate inom metoden didFinishLaunchingWithOptions. Detta gör att du kan navigera till en specifik skärm baserat på den angivna strängen, som visas nedan. Om det inte är konfigurerat kommer SDK:n helt enkelt att öppna applikationen.
ios-deeplink

Använder Swift:

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    
    override init() {
        super.init()
        // method Swizzling enabled for the application.
        PushEngage.swizzleInjection(isEnabled: true)
    }

   func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

     PushEngage.setAppId(key: "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD")
     PushEngage.setInitialInfo(for: application,with: launchOptions)
        
        
     // Notification open handler.
     // deep linking screen
     // here ShoesScreen and pepay are example deep link texts
     PushEngage.setNotificationOpenHandler { (result) in
            //replace this block with your own handling
            let additionData = result.notification.additionalData
            if result.notificationAction.actionID == "ShoesScreen" {
                print(additionData ?? [])
                let storyBoard = UIStoryboard(name: "Main", bundle: .main)
                let viewController = storyBoard.instantiateViewController(withIdentifier: "SportViewController")
                let navcontroller = application.windows.first?.rootViewController as? UINavigationController
                navcontroller?.popToRootViewController(animated: true)
                navcontroller?.pushViewController(viewController, animated: true)
            } else if result.notificationAction.actionID == "SalesScreen" {
                let storyBoard = UIStoryboard(name: "Main", bundle: .main)
                let viewController = storyBoard.instantiateViewController(withIdentifier: "NotificationApiTestViewconttoller")
                let navcontroller = application.windows.first?.rootViewController as? UINavigationController
                navcontroller?.popToRootViewController(animated: true)
                navcontroller?.pushViewController(viewController, animated: true)
            } else if result.notificationAction.actionID == "pepay" {
                let storyBoard = UIStoryboard(name: "Main", bundle: .main)
                let viewController = storyBoard.instantiateViewController(withIdentifier: "PEPay")
                let navcontroller = application.windows.first?.rootViewController as? UINavigationController
                navcontroller?.popToRootViewController(animated: true)
                navcontroller?.pushViewController(viewController, animated: true)
            }
        }
        
        PushEngage.enableLogs = true
        
        return true
    }
}

Använder Objective-C :

@implementation AppDelegate


- (instancetype)init
{
    self = [super init];
    if (self) {
       [PushEngage swizzleInjectionWithIsEnabled: YES];
    }
    return self;
}

typedef void (^PEnotificationOpenHandler)(PENotificationOpenResult * nonnull);

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    UNUserNotificationCenter.currentNotificationCenter.delegate = self;
    PEnotificationOpenHandler actionHandler = ^void(PENotificationOpenResult *result) {
       //replace this block with your own handling
        if ([result.notificationAction.actionID isEqualToString: @"ShoesScreen"]) {
            AddToCart *controller = [AddToCart new];
            UINavigationController *navigationController = (UINavigationController *) application.windows.firstObject.rootViewController;
            [navigationController popToRootViewControllerAnimated:YES];
            [navigationController pushViewController:controller animated:YES];
        } else if ([result.notificationAction.actionID isEqualToString: @"SalesScreen"]) {
            SportsViewcontroller *controller = [SportsViewcontroller new];
            UINavigationController *navigationController = (UINavigationController *) application.windows.firstObject.rootViewController;
            [navigationController popToRootViewControllerAnimated:YES];
            [navigationController pushViewController:controller animated:YES];
        }
    };
    application.applicationIconBadgeNumber = 0;
    [PushEngage setAppIdWithKey:@"APP_ID_FROM_PUSH_ENGAGE_DASHBOARD"];
    [PushEngage setInitialInfoFor:application with:launchOptions];
    [PushEngage setNotificationOpenHandlerWithBlock:actionHandler];
    [PushEngage setEnableLogs:true];
    return YES;
}
@end

Hantera notiser i förgrunden

När aviseringar kommer in i förgrundsläge måste du bestämma om du vill visa aviseringen för enheten eller inte. För att hantera aviseringar i förgrundsläge, använd setNotificationWillShowInForgroundHandler

Om slutförandeblocket inte anropas av dig alls, kommer SDK:n att anropa slutförandeblocket efter 29 sekunder. I vilket fall som helst, tyst eller alert avisering när applikationen är i förgrundsläge.

Använda Swift

class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    
    override init() {
        super.init()
        // method Swizzling enabled for the application.
       PushEngage.swizzleInjection(isEnabled: true)
    }

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {

        PushEngage.setAppId(key: "APP_ID_FROM_PUSH_ENGAGE_DASHBOARD")
        PushEngage.setInitialInfo(for: application, with: launchOptions)
        
        // Notification handler when notification deliver's and app is in foreground.
        
        PushEngage.setNotificationWillShowInForgroundHandler { notification, completion in
            if notification.contentAvailable == 1 {
                // in case the developer failed to set the completion handler. After 29 sec the handler will call from the SDK after 29 sec.
                completion(nil)
            } else {
                completion(notification)
            }
        }
        
        PushEngage.enableLogs = true
        
        return true
    }
}


Använda Objective-C

@implementation AppDelegate


- (instancetype)init
{
    self = [super init];
    if (self) {
       [PushEngage swizzleInjectionWithIsEnabled: YES];
    }
    return self;
}
// please create this handlers 
typedef void (^ _Nonnull PENotificationDisplayHandler)(PENotification * _Nullable);

-(BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    UNUserNotificationCenter.currentNotificationCenter.delegate = self;
    
    [PushEngage setNotificationWillShowInForgroundHandlerWithBlock:^(PENotification * _Nonnull notification, PENotificationDisplayHandler completion) {
        if (notification.contentAvailable == 1) {
            completion(nil);
        } else {
            completion(notification);
        }
    }];
    [PushEngage setAppIdWithKey:@"APP_ID_FROM_PUSH_ENGAGE_DASHBOARD"];
    [PushEngage setInitialInfoFor:application with:launchOptions];
    [PushEngage setEnableLogs:true];
    return YES;
}
@end

Felsökning

Lösa byggproblem relaterade till sandboxing

Problem:

Du upplever byggproblem relaterade till sandboxing.

Lösning:

  • Öppna ditt projekt i Xcode.
  • Navigera till Build Settings.
  • Leta reda på alternativet User Script Sandboxing.
  • Ställ in det till Nej.
Problem med metodkorsning i Firebase och PushEngage SDK:er

Problem:

Du använder både Firebase SDK och PushEngage SDK med metodkorsning aktiverad för båda, och det orsakar problem.

Lösning:

Inaktivera metodkorsning för PushEngage SDK och följ de manuella stegen för att hantera PushEngage-metoder. Du kan hitta detaljerade instruktioner på:
PushEngage iOS SDK Dokumentation

Om du vill utforska fler av iOS SDK:s möjligheter kan du gå igenom vår detaljerade API-dokumentation.

Om du stöter på några problem, vänligen kontakta oss genom att klicka här. Vårt supportteam kommer att kunna hjälpa dig.

Senast uppdaterad 9 mars 2026

Engagera och behåll besökare efter att de har lämnat din webbplats

Öka värdet av varje webbesök med push-notiser som är svåra att missa.

  • Evigt gratis-plan
  • Enkel installation
  • 5-stjärnig support