# Guía de integración básica del SDK de iOS 7.0+

Esta sección contiene información sobre cómo integrar el SDK de Pushwoosh en su aplicación de iOS.

## Prerrequisitos

Para integrar el SDK de Pushwoosh para iOS en su aplicación, necesitará lo siguiente:

<TranslatedFragment id="prerequisites-ios" />

## Pasos de integración

### 1. Instalación

Puede integrar el SDK de Pushwoosh en su aplicación utilizando **Swift Package Manager** o **CocoaPods**.

#### Swift Package Manager

En la sección **Package Dependencies**, agregue el siguiente paquete:
```
https://github.com/Pushwoosh/Pushwoosh-XCFramework
```

Para usar el SDK de Pushwoosh para iOS, asegúrese de agregar los siguientes tres frameworks al target de su aplicación al integrar a través de Swift Package Manager:

* ```PushwooshFramework```
* ```PushwooshCore```
* ```PushwooshBridge```

<img src="/ios-spm-1.webp" alt=""/>

#### CocoaPods

Abra su `Podfile` y agregue la dependencia:

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

target 'MyApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  pod 'PushwooshXCFramework'

end
```

Luego, en la terminal, ejecute el siguiente comando para instalar las dependencias:
```bash
pod install
```

### 2. Capacidades

Para habilitar las Notificaciones Push en su proyecto, necesita agregar ciertas capacidades.

En la sección Signing & Capabilities, agregue las siguientes capacidades:
- `Push Notifications`
- `Background Modes`. Después de agregar esta capacidad, marque la casilla para `Remote notifications`.

Si tiene la intención de usar Notificaciones Sensibles al Tiempo (iOS 15+), agregue también la capacidad de `Time Sensitive Notifications`.


### 3. Código de inicialización

#### AppDelegate

Agregue el siguiente código a su clase AppDelegate:

<Tabs syncKey="code-example">
<TabItem label="SwiftUI">
```swift
import SwiftUI
import PushwooshFramework

@main
struct MyApp: App {
    // Registrar AppDelegate como UIApplicationDelegate
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

class AppDelegate: NSObject, UIApplicationDelegate, PWMessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        // Código de inicialización
        // Establecer delegado personalizado para el manejo de push
        Pushwoosh.configure.delegate = self

        // Registrarse para notificaciones push
        Pushwoosh.configure.registerForPushNotifications()

        return true
    }

    // Manejar token recibido de APNS
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Pushwoosh.configure.handlePushRegistration(deviceToken)
    }

    // Manejar error al recibir el token
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        Pushwoosh.configure.handlePushRegistrationFailure(error)
    }

    //para notificaciones push silenciosas
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Pushwoosh.configure.handlePushReceived(userInfo)
        completionHandler(.noData)
    }

    // Se dispara cuando se recibe un push
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageReceived message: PWMessage) {
        print("onMessageReceived: ", message.payload!.description)
    }

    // Se dispara cuando un usuario toca la notificación
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {
        print("onMessageOpened: ", message.payload!.description)
    }
}

struct ContentView: View {
    var body: some View {
        Text("Pushwoosh with SwiftUI")
            .padding()
    }
}
```
</TabItem>

<TabItem label="Swift">
```swift
import PushwooshFramework

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, PWMessagingDelegate {

    var window: UIWindow?

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
        //código de inicialización
        //establecer delegado personalizado para el manejo de push, en nuestro caso AppDelegate
        Pushwoosh.configure.delegate = self;

        //registrarse para notificaciones push
        Pushwoosh.configure.registerForPushNotifications()

        return true
    }

    //manejar token recibido de APNS
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Pushwoosh.configure.handlePushRegistration(deviceToken)
    }

    //manejar error al recibir el token
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        Pushwoosh.configure.handlePushRegistrationFailure(error);
    }

    //para notificaciones push silenciosas
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Pushwoosh.configure.handlePushReceived(userInfo)
        completionHandler(.noData)
    }

    //este evento se dispara cuando se recibe el push
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageReceived message: PWMessage) {
        print("onMessageReceived: ", message.payload!.description)
    }

    // Se dispara cuando un usuario toca la notificación
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {
        print("onMessageOpened: ", message.payload!.description)
    }
}
```
</TabItem>

<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
	//-----------PARTE DE PUSHWOOSH-----------

	// establecer delegado personalizado para el manejo de push, en nuestro caso AppDelegate
	[Pushwoosh configure].delegate = self;

	//¡registrarse para notificaciones push!
	[[Pushwoosh configure] registerForPushNotifications];

	return YES;
}

//manejar token recibido de APNS
- (void)application:(UIApplication *)application
	didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	[[Pushwoosh configure] handlePushRegistration:deviceToken];
}

//manejar error al recibir el token
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
	[[Pushwoosh configure] handlePushRegistrationFailure:error];
}

//para notificaciones push silenciosas
- (void)application:(UIApplication *)application
	didReceiveRemoteNotification:(NSDictionary *)userInfo
		  fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
		[[Pushwoosh configure] handlePushReceived:userInfo];
		completionHandler(UIBackgroundFetchResultNoData);
}

//este evento se dispara cuando se recibe el push
- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageReceived:(PWMessage *)message {
    NSLog(@"onMessageReceived: %@", message.payload);
}

//este evento se dispara cuando el usuario toca la notificación
- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageOpened:(PWMessage *)message {
    NSLog(@"onMessageOpened: %@", message.payload);
}

@end
```
</TabItem>
</Tabs>

#### Info.plist

En su `Info.plist`:
- establezca la clave `Pushwoosh_APPID` en el Código de Aplicación de Pushwoosh.
- establezca la clave `Pushwoosh_API_TOKEN` en el [Token de API de Dispositivo de Pushwoosh](/es/developer/api-reference/api-access-token/#device-api-token)

### 4. Seguimiento de la entrega de mensajes

Pushwoosh admite el seguimiento de eventos de entrega para notificaciones push a través de la Extensión de Servicio de Notificación

#### Agregar Extensión de Servicio de Notificación

1. En Xcode, seleccione **Archivo** > **Nuevo** > **Target...**
2. Elija **Extensión de Servicio de Notificación** y presione **Siguiente.**
3. Ingrese el nombre del target y presione **Finalizar.**
4. Cuando se le pida la activación, presione **Cancelar.**

#### Dependencias para la Extensión de Servicio de Notificación (solo CocoaPods)

Nota: Si está utilizando Swift Package Manager para gestionar las dependencias, puede omitir este paso, ya que las dependencias se agregan automáticamente.

Abra su `Podfile` y agregue la dependencia para el target:

```ruby title="Podfile"
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MyApp' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  pod 'PushwooshXCFramework'

end

target 'MyAppNotificationExtension' do
  use_frameworks!

  pod 'PushwooshXCFramework'

end
```

Ejecute el siguiente comando en la terminal para actualizar las dependencias:

```shell
pod update
```

#### Agregar el SDK de Pushwoosh a la Extensión de Servicio de Notificación

Reemplace la clase `NotificationService` generada con una subclase de `PushwooshNotificationServiceExtension`. Pushwoosh se encarga de todo lo que necesita un push: enviar el evento de entrega, contar las insignias, descargar el adjunto multimedia y el fallback de tiempo de espera obligatorio `serviceExtensionTimeWillExpire`. No se requiere ningún otro código.

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class NotificationService: PushwooshNotificationServiceExtension {}
```
</TabItem>

<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@interface NotificationService : PushwooshNotificationServiceExtension
@end

@implementation NotificationService
@end
```
</TabItem>
</Tabs>

Nota: puede omitir el archivo fuente por completo — establezca la `NSExtensionPrincipalClass` de la extensión en `PushwooshNotificationServiceExtension` en su Info.plist y no escriba ningún código.

Para modificar la notificación antes de que se muestre, anule `didReceive(_:withContentHandler:)`, llame a `super` con su propio manejador de contenido, mute el contenido dentro de él y luego reenvíelo al manejador original. Pushwoosh seguirá ejecutando el evento de entrega, la insignia, el adjunto y el fallback de tiempo de espera.

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import UserNotifications
import PushwooshFramework

class NotificationService: PushwooshNotificationServiceExtension {

    override func didReceive(_ request: UNNotificationRequest,
                             withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        super.didReceive(request) { content in
            let mutable = (content.mutableCopy() as? UNMutableNotificationContent) ?? content
            // Modifique el contenido de la notificación aquí...
            contentHandler(mutable)
        }
    }

}
```
</TabItem>

<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@interface NotificationService : PushwooshNotificationServiceExtension
@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request
                   withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    [super didReceiveNotificationRequest:request withContentHandler:^(UNNotificationContent *content) {
        UNMutableNotificationContent *mutable = [content mutableCopy];
        // Modifique el contenido de la notificación aquí...
        contentHandler(mutable);
    }];
}

@end
```
</TabItem>
</Tabs>

#### Info.plist

La extensión hereda `Pushwoosh_APPID` (y otras claves `Pushwoosh_*`) de la aplicación anfitriona, por lo que no necesita duplicarlas en el Info.plist de la extensión. Agregue una clave allí solo cuando desee anular el valor del anfitrión.

Para sincronizar el recuento de insignias y la configuración del proxy inverso con la aplicación, comparta un [Grupo de Aplicaciones](/es/developer/pushwoosh-sdk/ios-sdk/setting-up-badges) entre la aplicación y la extensión. Agregue la capacidad de Grupos de Aplicaciones a ambos targets, luego establezca el ID del Grupo de Aplicaciones en el Info.plist de la **aplicación principal**:
- `PW_APP_GROUPS_NAME` - su identificador de Grupo de Aplicaciones (por ejemplo, `group.com.example.app`).

La extensión hereda este valor de la aplicación anfitriona, por lo que no necesita repetirlo en el Info.plist de la extensión — agréguelo allí solo para anular el anfitrión. Alternativamente, proporciónelo en el código anulando `pushwooshAppGroupsName`.

### 5. Ejecutar el proyecto

1. Compile y ejecute el proyecto.
2. Vaya al Panel de Control de Pushwoosh y [envíe una notificación push](/es/product/messaging-channels/push-notifications/send-push-notifications/one-time-push).
3. Debería ver la notificación en la aplicación.

## Integración extendida de Pushwoosh para iOS

En esta etapa, ya ha integrado el SDK y puede enviar y recibir notificaciones push. Ahora, exploremos la funcionalidad principal

### Notificaciones push

En el SDK de Pushwoosh, hay dos callbacks diseñados para manejar las notificaciones push:
- `onMessageReceived`: Este método se invoca cuando se recibe una notificación push.
- `onMessageOpened`: Este método se llama cuando el usuario interactúa con (abre) la notificación

Estos callbacks permiten a los desarrolladores gestionar la recepción y la interacción del usuario con las notificaciones push dentro de sus aplicaciones

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class AppDelegate: NSObject, UIApplicationDelegate, PWMessagingDelegate {

    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        Pushwoosh.configure.delegate = self;
    }

    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageOpened message: PWMessage) {
        if let payload = message.payload {
            print("onMessageOpened: \(payload)")
        }
    }

    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageReceived message: PWMessage) {
        if let payload = message.payload {
            print("onMessageReceived: \(payload)")
        }
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@interface AppDelegate () <PWMessagingDelegate>

@end

@implementation AppDelegate

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[Pushwoosh configure] setDelegate:self];
    return YES;
}

- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageOpened:(PWMessage *)message {
    if (message.payload) {
        NSLog(@"onMessageOpened: %@", message.payload);
    }
}

- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageReceived:(PWMessage *)message {
    if (message.payload) {
        NSLog(@"onMessageReceived: %@", message.payload);
    }
}
@end
```
</TabItem>
</Tabs>


### Configuración de usuario

Al centrarse en el comportamiento y las preferencias individuales de los usuarios, puede ofrecer contenido personalizado, lo que conduce a una mayor satisfacción y lealtad del usuario

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class Registration {

    func afterUserLogin(user: User) {
        let pushwoosh = Pushwoosh.configure
        // establecer ID de usuario
        if let userId = user.userId {
            pushwoosh.setUserId(userId)
        }

        // establecer email de usuario
        if let userEmail = user.email {
            pushwoosh.setEmail(userEmail)
        }

        // establecer número de SMS del usuario
        if let userSmsNumber = user.SmsNumber {
            pushwoosh.registerSmsNumber(userSmsNumber)
        }

        // establecer número de WhatsApp del usuario
        if let userWhatsAppNumber = user.WhatsAppNumber {
            pushwoosh.registerSmsNumber(userWhatsAppNumber)
        }

        // establecer información adicional del usuario como etiquetas para Pushwoosh
        if let age = user.userDetails.age,
            let name = user.userDetails.userName,
            let lastLogin = user.userDetails.lastLoginDate {
            pushwoosh.setTags([
                "age": age,
                "name": name,
                "last_login": lastLogin
            ])
        }
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@implementation Registration

- (void)afterUserLogin:(User *)user {
    Pushwoosh *pushwoosh = [Pushwoosh configure];

    // establecer ID de usuario
    if (user.userId) {
        [pushwoosh setUserId:user.userId];
    }

    // establecer email de usuario
    if (user.email) {
        [pushwoosh setEmail:user.email];
    }

    // establecer información adicional del usuario como etiquetas para Pushwoosh
    if (user.userDetails.age && user.userDetails.userName && user.userDetails.lastLoginDate) {
        NSDictionary *tags = @{
            @"age": user.userDetails.age,
            @"name": user.userDetails.userName,
            @"last_login": user.userDetails.lastLoginDate
        };
        [pushwoosh setTags:tags];
    }
}

@end
```
</TabItem>
</Tabs>

### Etiquetas

Las etiquetas son pares clave-valor asignados a usuarios o dispositivos, lo que permite la segmentación basada en atributos como preferencias o comportamiento, habilitando la mensajería dirigida.

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class UpdateUser {
    func afterUserUpdateProfile(user: User) {
        let pushwoosh = Pushwoosh.configure

        // establecer lista de categorías favoritas
        pushwoosh.setTags(["favorite_categories" : user.getFavoriteCategories()])

        // establecer información de pago
        pushwoosh.setTags([
            "is_subscribed": user.isSubscribed(),
            "payment_status": user.getPaymentStatus(),
            "billing_address": user.getBillingAddress()
        ])
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>

@implementation UpdateUser

- (void)afterUserUpdateProfile:(User *)user {
    Pushwoosh *pushwoosh = [Pushwoosh configure];

    // establecer lista de categorías favoritas
    [pushwoosh setTags:@{@"favorite_categories" : user.getFavoriteCategories}];

    // establecer información de pago
    NSDictionary *tags = @{
        @"is_subscribed": @(user.isSubscribed),
        @"payment_status": user.getPaymentStatus,
        @"billing_address": user.getBillingAddress
    };
    [pushwoosh setTags:tags];
}

@end
```
</TabItem>
</Tabs>


### Eventos

Los eventos son acciones u ocurrencias específicas del usuario dentro de la aplicación que se pueden rastrear para analizar el comportamiento y desencadenar mensajes o acciones correspondientes

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class Registration {

    func afterUserLogin(user: User) {
        if let userName = user.getUserName(), let lastLogin = user.getLastLoginDate() {
            PWInAppManager.shared().postEvent("login", withAttributes: [
                "name": userName,
                "last_login": lastLogin
            ])
        }
    }

    func afterUserPurchase(user: User, product: Product) {
        let pushwoosh = Pushwoosh.configure

        // Rastrear evento de compra
        PWInAppManager.shared().postEvent("purchase", withAttributes: [
            "product_id": product.getId(),
            "product_name": product.getName(),
            "price": product.getPrice(),
            "quantity": product.getQuantity()
        ])

        // Establecer etiquetas de usuario
        let lastPurchaseDate = Date().timeIntervalSince1970
        let lifetimeSpend = getCurrentLifetimeSpend() + product.getPrice()

        pushwoosh.setTags([
            "last_purchase_date": lastPurchaseDate,
            "lifetime_spend": lifetimeSpend
        ])
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import <PushwooshFramework/PushwooshFramework.h>
#import <PushwooshFramework/PWInAppManager.h>

@implementation Registration

- (void)afterUserLogin:(User *)user {
    NSString *userName = [user getUserName];
    NSDate *lastLogin = [user getLastLoginDate];

    if (userName && lastLogin) {
        [[PWInAppManager sharedManager] postEvent:@"login" withAttributes:@{
            @"name": userName,
            @"last_login": lastLogin
        }];
    }
}

- (void)afterUserPurchase:(User *)user product:(Product *)product {
    Pushwoosh *pushwoosh = [Pushwoosh configure];

    // Rastrear evento de compra
    [[PWInAppManager sharedManager] postEvent:@"purchase" withAttributes:@{
        @"product_id": [product getId],
        @"product_name": [product getName],
        @"price": @([product getPrice]),
        @"quantity": @([product getQuantity])
    }];

    // Establecer etiquetas de usuario
    NSTimeInterval lastPurchaseDate = [[NSDate date] timeIntervalSince1970];
    double lifetimeSpend = /* obtener el gasto total actual */ + [product getPrice];

    NSDictionary *tags = @{
        @"last_purchase_date": @(lastPurchaseDate),
        @"lifetime_spend": @(lifetimeSpend)
    };

    [pushwoosh setTags:tags];
}

@end
```
</TabItem>
</Tabs>

### Rich Media

Rich media se refiere a contenido interactivo y multimedia, como imágenes, videos o HTML, utilizado en notificaciones y mensajes in-app para mejorar la participación del usuario

<Tabs syncKey="code-example">
<TabItem label="Swift">
```swift
import PushwooshFramework

class ViewController: UIViewController, PWRichMediaPresentingDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        let richMediaConfiguration = PWModalWindowConfiguration.shared()

        PWRichMediaManager.shared().delegate = self
        richMediaConfiguration.configureModalWindow(with: .PWModalWindowPositionBottom,
                                                             present: .PWAnimationPresentFromBottom,
                                                             dismiss: .PWAnimationDismissDown)
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager!, shouldPresent richMedia: PWRichMedia!) -> Bool {
        print("Rich media will be presented with: \(richMedia.pushPayload!)")
        return true
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager!, didPresent richMedia: PWRichMedia!) {
        print("Rich media has been presented with: \(richMedia.pushPayload!)")
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager!, didClose richMedia: PWRichMedia!) {
        print("Rich media has been closed with: \(richMedia.pushPayload!)")
    }

    func richMediaManager(_ richMediaManager: PWRichMediaManager!, presentingDidFailFor richMedia: PWRichMedia!, withError error: (any Error)!) {
        print("Failed to present rich media with: \(richMedia.pushPayload!). Error: \(error.localizedDescription)")
    }
}
```
</TabItem>
<TabItem label="Objective-C">
```objective-c
#import "ViewController.h"
#import <PushwooshFramework/PushwooshFramework.h>
#import <PushwooshFramework/PWRichMediaManager.h>
#import <PushwooshFramework/PWModalWindowConfiguration.h>

@interface ViewController () <PWRichMediaPresentingDelegate>

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

    [[PWRichMediaManager sharedManager] setDelegate:self];
    [[PWModalWindowConfiguration shared] configureModalWindowWith:PWModalWindowPositionBottom
                                                 presentAnimation:PWAnimationPresentFromBottom
                                                 dismissAnimation:PWAnimationDismissDown];
}

- (BOOL)richMediaManager:(PWRichMediaManager *)richMediaManager shouldPresentRichMedia:(PWRichMedia *)richMedia {
    NSLog(@"Rich media will be presented with: %@", richMedia.pushPayload);
    return YES;
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didPresentRichMedia:(PWRichMedia *)richMedia {
    NSLog(@"Rich media has been presented with: %@", richMedia.pushPayload);
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager didCloseRichMedia:(PWRichMedia *)richMedia {
    NSLog(@"Rich media has been closed with:: %@", richMedia.pushPayload);
}

- (void)richMediaManager:(PWRichMediaManager *)richMediaManager presentingDidFailForRichMedia:(PWRichMedia *)richMedia withError:(NSError *)error {
    NSLog(@"Failed to present rich media with: %@. Error: %@", richMedia.pushPayload, error.localizedDescription);
}

@end
```
</TabItem>
</Tabs>




## Solución de problemas

### Error al compilar el módulo 'PushwooshFramework'

Al compilar su proyecto, puede encontrar un error similar a:

```
Failed to build module 'PushwooshFramework'; this SDK is not supported by the compiler
(the SDK is built with 'Apple Swift version 5.10 (swiftlang-5.10.0.13 clang-1500.3.9.4)',
while this compiler is 'Apple Swift version 6.1.2 effective-5.10 (swiftlang-6.1.2.1.2 clang-1700.0.13.5)')
```

**Causa:** Este error no está relacionado con la incompatibilidad de la versión del compilador de Swift. A partir de la versión 6.8.0 del SDK de Pushwoosh para iOS, el SDK está modularizado en varios componentes que interactúan entre sí. El error ocurre cuando no todos los frameworks requeridos se agregan a su proyecto.

**Solución:** Asegúrese de que los cuatro frameworks requeridos se agreguen al target de su aplicación al integrar a través de Swift Package Manager:

* ```PushwooshFramework```
* ```PushwooshCore```
* ```PushwooshBridge```
* ```PushwooshLiveActivities```

<img src="/ios-spm-1.webp" alt=""/>

Para verificar esto en Xcode:
1. Seleccione su proyecto en el Navegador de Proyectos
2. Seleccione el target de su aplicación
3. Vaya a **General** > **Frameworks, Libraries, and Embedded Content**
4. Confirme que los cuatro frameworks están en la lista

---

Si encuentra algún problema durante el proceso de integración, consulte la sección de [soporte y comunidad](/es/developer/pushwoosh-sdk/support-and-community).