# Руководство по базовой интеграции iOS SDK

В этом разделе содержится информация о том, как интегрировать Pushwoosh SDK в ваше iOS-приложение.

## Предварительные требования

Для интеграции Pushwoosh iOS SDK в ваше приложение вам понадобится следующее:

<TranslatedFragment id="prerequisites-ios" />

## Шаги интеграции

### 1. Установка

Вы можете интегрировать Pushwoosh SDK в ваше приложение, используя **Swift Package Manager** или **CocoaPods**.

#### Swift Package Manager

В разделе **Package Dependencies** добавьте следующий пакет:
```
https://github.com/Pushwoosh/Pushwoosh-XCFramework
```

Чтобы использовать Pushwoosh iOS SDK, убедитесь, что вы добавили следующие четыре фреймворка в таргет вашего приложения при интеграции через Swift Package Manager:

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

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

#### CocoaPods

Откройте ваш `Podfile` и добавьте зависимость:

```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
```

Затем в терминале выполните следующую команду для установки зависимостей:
```bash
pod install
```

### 2. Capabilities (Возможности)

Чтобы включить Push-уведомления в вашем проекте, необходимо добавить определенные capabilities (возможности).

В разделе Signing & Capabilities добавьте следующие capabilities:
- `Push Notifications`
- `Background Modes`. После добавления этой capability отметьте флажок `Remote notifications`.

Если вы планируете использовать Time Sensitive Notifications (iOS 15+), также добавьте capability `Time Sensitive Notifications`.


### 3. Код инициализации

#### AppDelegate

Добавьте следующий код в ваш класс AppDelegate:

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

@main
struct MyApp: App {
    // Регистрируем AppDelegate как 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 {
        // Код инициализации
        // Устанавливаем кастомный делегат для обработки push-уведомлений
        Pushwoosh.sharedInstance().delegate = self

        // Регистрируемся для получения push-уведомлений
        Pushwoosh.sharedInstance().registerForPushNotifications()

        return true
    }

    // Обрабатываем токен, полученный от APNS
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Pushwoosh.sharedInstance().handlePushRegistration(deviceToken)
    }

    // Обрабатываем ошибку получения токена
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        Pushwoosh.sharedInstance().handlePushRegistrationFailure(error)
    }

    // для тихих push-уведомлений
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Pushwoosh.sharedInstance().handlePushReceived(userInfo)
        completionHandler(.noData)
    }

    // Срабатывает при получении push-уведомления
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageReceived message: PWMessage) {
        print("onMessageReceived: ", message.payload!.description)
    }

    // Срабатывает, когда пользователь нажимает на уведомление
    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 {
        // код инициализации
        // устанавливаем кастомный делегат для обработки push-уведомлений, в нашем случае AppDelegate
        Pushwoosh.sharedInstance().delegate = self;
        
        // регистрируемся для получения push-уведомлений
        Pushwoosh.sharedInstance().registerForPushNotifications()
        
        return true
    }
    
    // обрабатываем токен, полученный от APNS
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Pushwoosh.sharedInstance().handlePushRegistration(deviceToken)
    }
    
    // обрабатываем ошибку получения токена
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
        Pushwoosh.sharedInstance().handlePushRegistrationFailure(error);
    }
    
    // для тихих push-уведомлений
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        Pushwoosh.sharedInstance().handlePushReceived(userInfo)
        completionHandler(.noData)
    }
    
    // это событие срабатывает при получении push-уведомления
    func pushwoosh(_ pushwoosh: Pushwoosh, onMessageReceived message: PWMessage) {
        print("onMessageReceived: ", message.payload!.description)
    }

    // Срабатывает, когда пользователь нажимает на уведомление
    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 {
	//-----------ЧАСТЬ PUSHWOOSH-----------

	// устанавливаем кастомный делегат для обработки push-уведомлений, в нашем случае AppDelegate
	[Pushwoosh sharedInstance].delegate = self;

	// регистрируемся для получения push-уведомлений!
	[[Pushwoosh sharedInstance] registerForPushNotifications];

	return YES;
}

// обрабатываем токен, полученный от APNS
- (void)application:(UIApplication *)application
	didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
	[[Pushwoosh sharedInstance] handlePushRegistration:deviceToken];
}

// обрабатываем ошибку получения токена
- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
	[[Pushwoosh sharedInstance] handlePushRegistrationFailure:error];
}

// для тихих push-уведомлений
- (void)application:(UIApplication *)application
	didReceiveRemoteNotification:(NSDictionary *)userInfo
		  fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
		[[Pushwoosh sharedInstance] handlePushReceived:userInfo];
		completionHandler(UIBackgroundFetchResultNoData);
}

// это событие срабатывает при получении push-уведомления
- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageReceived:(PWMessage *)message {
    NSLog(@"onMessageReceived: %@", message.payload);
}

// это событие срабатывает, когда пользователь нажимает на уведомление
- (void)pushwoosh:(Pushwoosh *)pushwoosh onMessageOpened:(PWMessage *)message {
    NSLog(@"onMessageOpened: %@", message.payload);
}

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

#### Info.plist

В вашем `Info.plist`:
- установите для ключа `Pushwoosh_APPID` значение кода приложения Pushwoosh.
- установите для ключа `Pushwoosh_API_TOKEN` значение [Pushwoosh Device API Token](/ru/developer/api-reference/api-access-token/#device-api-token)

### 4. Отслеживание доставки сообщений

Pushwoosh поддерживает отслеживание событий доставки для push-уведомлений через Notification Service Extension

#### Добавление Notification Service Extension

1. В Xcode выберите **File** > **New** > **Target...**
2. Выберите **Notification Service Extension** и нажмите **Next.**
3. Введите имя таргета и нажмите **Finish.**
4. При запросе на активацию нажмите **Cancel.**

#### Зависимости для Notification Service Extension (только для CocoaPods)

Примечание: Если вы используете Swift Package Manager для управления зависимостями, вы можете пропустить этот шаг, так как зависимости добавляются автоматически.

Откройте ваш `Podfile` и добавьте зависимость для таргета:

```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
```

Выполните следующую команду в терминале, чтобы обновить зависимости:

```shell
pod update
```

#### Добавление Pushwoosh SDK в Notification Service Extension

Этот код позволяет перехватывать и обрабатывать уведомления в вашем notification extension.

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

class NotificationService: UNNotificationServiceExtension {

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

    override func didReceive(_ request: UNNotificationRequest, withContentHandler contentHandler: @escaping (UNNotificationContent) -> Void) {
        // Pushwoosh **********
        PWNotificationExtensionManager.shared().handle(request, contentHandler: contentHandler)
        // ********************
        
        self.contentHandler = contentHandler
        bestAttemptContent = (request.content.mutableCopy() as? UNMutableNotificationContent)
        
        if let bestAttemptContent = bestAttemptContent {
            // Здесь можно изменить содержимое уведомления...
            contentHandler(bestAttemptContent)
        }
    }
    
    override func serviceExtensionTimeWillExpire() {
        // Вызывается непосредственно перед тем, как расширение будет завершено системой.
        // Используйте это как возможность доставить вашу "лучшую попытку" измененного контента, иначе будет использована исходная полезная нагрузка push-уведомления.
        if let contentHandler = contentHandler, let bestAttemptContent =  bestAttemptContent {
            contentHandler(bestAttemptContent)
        }
    }

}
```
</TabItem>

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

@interface NotificationService : UNNotificationServiceExtension

@end

@implementation NotificationService

- (void)didReceiveNotificationRequest:(UNNotificationRequest *)request withContentHandler:(void (^)(UNNotificationContent * _Nonnull))contentHandler {
    // Pushwoosh **********
    [[PWNotificationExtensionManager sharedManager] handleNotificationRequest:request contentHandler:contentHandler];
    //*********************
}

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

#### Info.plist

В Info.plist вашего Notification Service Extension добавьте:
- `Pushwoosh_APPID` - ваш код приложения.

### 5. Запуск проекта

1. Соберите и запустите проект.
2. Перейдите в Панель управления Pushwoosh и [отправьте push-уведомление](/ru/product/messaging-channels/push-notifications/send-push-notifications/one-time-push).
3. Вы должны увидеть уведомление в приложении.

## Расширенная интеграция Pushwoosh iOS

На этом этапе вы уже интегрировали SDK и можете отправлять и получать push-уведомления. Теперь давайте рассмотрим основную функциональность.

### Push-уведомления

В Pushwoosh SDK есть два колбэка, предназначенных для обработки push-уведомлений:
- `onMessageReceived`: Этот метод вызывается при получении push-уведомления.
- `onMessageOpened`: Этот метод вызывается, когда пользователь взаимодействует с уведомлением (открывает его).

Эти колбэки позволяют разработчикам управлять получением push-уведомлений и взаимодействием пользователя с ними в своих приложениях.

<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.sharedInstance().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 sharedInstance] 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>


### Конфигурация пользователя

Сосредоточившись на поведении и предпочтениях отдельных пользователей, вы можете предоставлять персонализированный контент, что приведет к повышению удовлетворенности и лояльности пользователей.

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

class Registration {

    func afterUserLogin(user: User) {
        let pushwoosh = Pushwoosh.sharedInstance()
        // устанавливаем User ID
        if let userId = user.userId {
            pushwoosh.setUserId(userId)
        }

        // устанавливаем email пользователя
        if let userEmail = user.email {
            pushwoosh.setEmail(userEmail)
        }

        // устанавливаем номер SMS пользователя
        if let userSmsNumber = user.SmsNumber {
            pushwoosh.registerSmsNumber(userSmsNumber)
        }

        // устанавливаем номер WhatsApp пользователя
        if let userWhatsAppNumber = user.WhatsAppNumber {
            pushwoosh.registerSmsNumber(userWhatsAppNumber)
        }

        // установка дополнительной информации о пользователе в качестве тегов для 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 sharedInstance];

    // устанавливаем User ID
    if (user.userId) {
        [pushwoosh setUserId:user.userId];
    }

    // устанавливаем email пользователя
    if (user.email) {
        [pushwoosh setEmail:user.email];
    }

    // установка дополнительной информации о пользователе в качестве тегов для 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>

### Теги

Теги — это пары «ключ-значение», присваиваемые пользователям или устройствам, которые позволяют сегментировать аудиторию на основе таких атрибутов, как предпочтения или поведение, для целевых сообщений.

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

class UpdateUser {
    func afterUserUpdateProfile(user: User) {
        let pushwoosh = Pushwoosh.sharedInstance()
        
        // устанавливаем список любимых категорий
        pushwoosh.setTags(["favorite_categories" : user.getFavoriteCategories()])
        
        // устанавливаем платежную информацию
        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 sharedInstance];

    // устанавливаем список любимых категорий
    [pushwoosh setTags:@{@"favorite_categories" : user.getFavoriteCategories}];

    // устанавливаем платежную информацию
    NSDictionary *tags = @{
        @"is_subscribed": @(user.isSubscribed),
        @"payment_status": user.getPaymentStatus,
        @"billing_address": user.getBillingAddress
    };
    [pushwoosh setTags:tags];
}

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


### События

События — это определенные действия пользователя или происшествия в приложении, которые можно отслеживать для анализа поведения и запуска соответствующих сообщений или действий.

<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.sharedInstance()
    
        // Отслеживаем событие покупки
        PWInAppManager.shared().postEvent("purchase", withAttributes: [
            "product_id": product.getId(),
            "product_name": product.getName(),
            "price": product.getPrice(),
            "quantity": product.getQuantity()
        ])
    
        // Устанавливаем теги пользователя
        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 sharedInstance];

    // Отслеживаем событие покупки
    [[PWInAppManager sharedManager] postEvent:@"purchase" withAttributes:@{
        @"product_id": [product getId],
        @"product_name": [product getName],
        @"price": @([product getPrice]),
        @"quantity": @([product getQuantity])
    }];

    // Устанавливаем теги пользователя
    NSTimeInterval lastPurchaseDate = [[NSDate date] timeIntervalSince1970];
    double lifetimeSpend = /* получаем текущие пожизненные траты */ + [product getPrice];

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

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

### Rich Media

Rich media — это интерактивный и мультимедийный контент, такой как изображения, видео или HTML, используемый в уведомлениях и In-App сообщениях для повышения вовлеченности пользователей.

<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>




## Устранение неполадок

### Ошибка сборки модуля 'PushwooshFramework'

При сборке проекта вы можете столкнуться с ошибкой, похожей на эту:

```
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)')
```

**Причина:** Эта ошибка не связана с несовместимостью версий компилятора Swift. Начиная с версии 6.8.0 Pushwoosh iOS SDK, SDK разделен на несколько взаимодействующих друг с другом компонентов. Ошибка возникает, когда в ваш проект добавлены не все необходимые фреймворки.

**Решение:** Убедитесь, что все четыре необходимых фреймворка добавлены в таргет вашего приложения при интеграции через Swift Package Manager:

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

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

Чтобы проверить это в Xcode:
1. Выберите ваш проект в Project Navigator
2. Выберите таргет вашего приложения
3. Перейдите в **General** > **Frameworks, Libraries, and Embedded Content**
4. Убедитесь, что в списке присутствуют все четыре фреймворка

---

Если у вас возникнут какие-либо проблемы в процессе интеграции, обратитесь к разделу [поддержка и сообщество](/ru/developer/pushwoosh-sdk/support-and-community).