# Delegate Methods

### Default Handling of Remote Notifications

Netmera automatically handles all `UIApplicationDelegate` methods related to remote notifications. You don’t need to implement these methods in your **App Delegate** unless your app has special use cases that require custom logic.

### Custom Implementation (If Needed)

If your app needs custom handling for remote notification delegate methods, you can implement them in your `UIApplicationDelegate`. You can then add your specific logic inside those methods. For more details on the delegate methods related to push notifications, check the:  [**UI Application Delegate Protocol Reference**](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIApplicationDelegate_Protocol/index.html#//apple_ref/doc/uid/TP40006786-CH3-SW17)**.**

### Accessing Notification Data

To retrieve the remote notification payload, use the `[Netmera recentPushObject]` or `Netmera.recentPushObject()` method. This method returns a `NetmeraPushObject` instance, which contains the notification data. You can call this method within your `UIApplicationDelegate` methods to access the data of the received notification.

## Push Delegate Methods

Netmera iOS SDK provides delegate protocols to customize and observe push notification behavior.

There are two delegate protocols:

* `NetmeraPushDelegate` → Customize how push notifications are presented and handled
* `NetmeraPushLifecycleDelegate` → Listen to push lifecycle events

To enable these callbacks, set the delegates in your `AppDelegate`:

```swift
Netmera.setPushDelegate(self)
Netmera.setPushLifecycleDelegate(self)
```

***

### NetmeraPushDelegate

`NetmeraPushDelegate` allows you to customize how push notifications are **presented and handled** in your app.

With this delegate you can control:

* Web view presentation
* Foreground notification presentation
* URL opening behavior

```swift
extension AppDelegate: NetmeraPushDelegate {

  /// Returns who will present the in-app web view (or widget) for this push.
  /// Return `.appHandles` only if you implement `presentWebView(for:)`; otherwise return `.sdkHandles`.
  func webViewPresentationDecision(for push: NetmeraBasePush) -> PushDelegateDecision {
    UserDefaults.standard.bool(forKey: NotificationDelegateSetting.webViewHandling.rawValue) ? .appHandles : .sdkHandles
  }

  /// Called when the delegate has indicated it will present the web view.
  /// Present your own web view or widget UI for the given push. Invoked on the main queue.
  func presentWebView(for push: NetmeraBasePush) {
    guard let top = UIApplication.topViewController() else { return }
    let popup = PushContentPopupViewController()
    let nav = UINavigationController(rootViewController: popup)
    nav.modalPresentationStyle = .pageSheet

    if #available(iOS 15.0, *) {
      if let sheet = nav.sheetPresentationController {
        sheet.detents = [.medium(), .large()]
        sheet.prefersGrabberVisible = true
      }
    }

    top.present(nav, animated: true) {
      Netmera.displayContent(for: push, in: popup.webView) {
        DispatchQueue.main.async {
          nav.dismiss(animated: true)
        }
      }
    }
  }

  /// Returns who will present this notification while the app is in the foreground.
  /// Return `.appHandles` only if you implement `presentNotification(for:)`; otherwise return `.sdkHandles`.
  func notificationPresentationDecision(for push: NetmeraBasePush) -> PushDelegateDecision {
    UserDefaults.standard.bool(forKey: NotificationDelegateSetting.presentationHandling.rawValue) ? .appHandles : .sdkHandles
  }

  /// Called when the delegate has indicated it will present the foreground notification.
  /// Implement custom in-foreground behavior (e.g. in-app UI). The system will not show the notification.
  func presentNotification(for push: NetmeraBasePush) {
    print("presentNotification")
    showAlertInIndependentWindow(title: "Presenting Notification", message: push.jsonString)
  }

  /// Returns who will open the given URL in a push context (e.g. link from web view content).
  /// Return `.appHandles` only if you implement `openURL(_:for:)`; otherwise return `.sdkHandles`.
  func urlOpeningDecision(for url: URL, push: NetmeraBasePush) -> PushDelegateDecision {
    if url.host == "your_domain" || UserDefaults.standard.bool(forKey: NotificationDelegateSetting.deeplinkHandling.rawValue) {
      return .appHandles
    }
    return .sdkHandles
  }

  /// Called when the delegate has indicated it will open the URL.
  /// Open the URL in your preferred way (e.g. in-app browser or deeplink).
  func openURL(_ url: URL, for push: NetmeraBasePush) {
    print("openURL \(url)")
    showAlertInIndependentWindow(title: "App handling link", message: url.absoluteString)
  }
}
```

***

### NetmeraPushLifecycleDelegate

`NetmeraPushLifecycleDelegate` allows you to observe **push lifecycle events**, such as receiving or opening a push notification.

```swift
extension AppDelegate: NetmeraPushLifecycleDelegate {

  /// Called when the device token has been registered with APNs. Use this to forward the token to your server if needed.
  func didRegisterDeviceToken(_ deviceToken: String) {
    print("Device Token: \(deviceToken)")
  }

  /// Called when the app has received a push payload and converted it to a push object.
  /// Invoked when a remote notification is delivered (e.g. background or app launch) or when a user-visible
  /// notification is about to be presented in the foreground (payload with `content-available` 0 or absent).
  /// Use for analytics, logging, or updating app state when a push arrives.
  public func didReceive(_ push: NetmeraBasePush) {
    guard let payload = push.jsonString else { return }

    PushEventMonitor.shared.history.append(PushInfo(date: Date(), payload: payload))
    print("Received push saved to history!")
  }

  /// Called when the user opened the app from this push (e.g. tapped the notification). Use for analytics or navigation.
  public func didOpen(_ push: NetmeraBasePush) {
    guard let payload = push.jsonString else { return }

    print("Did Open Push with payload: \(payload)")
  }

  /// Called when the user tapped an action button on the push. The `identifier` is the action’s button identifier.
  public func didClickActionButton(_ identifier: String, for push: NetmeraBasePush) {
    guard let payload = push.jsonString else { return }

    print("Did Click Action Button with \(identifier) for payload: \(payload)")
  }

  /// Called when the user tapped a carousel item. The `identifier` is the item’s identifier, if any.
  public func didClickCarouselItem(_ identifier: String?, for push: NetmeraBasePush) {
    guard let payload = push.jsonString else { return }

    print("Did Click Carousel Item with \(identifier ?? "NaN") for payload: \(payload)")
  }
}
```
