Skip to content
WhaleAppSDK

iOS

Complete WhaleAppSDK integration and public API reference for iOS

Requirements

  • iOS 13.0 or later.
  • Xcode 12.0 or later and Swift 5.0 or later.
  • Objective-C and Swift projects are supported.
  • Device arm64 and simulator x86_64 / arm64 architectures are supported.
  • Broker App is normally portrait-only. When a specific SDK page requests landscape, forward the orientation mask as described below.

Install the SDK

LBWhaleAppSDK provides two integration paths for iOS developers:

  • CocoaPods (recommended)
  • Manual integration

CocoaPods (recommended)

Extract LBWhaleAppSDK-XXX.zip, place the SDK directory in the project, and add:

source 'https://github.com/volcengine/volcengine-specs.git'
source 'https://github.com/aliyun/aliyun-specs.git'

pod 'LBWhaleAppSDK', :path => './LBWhaleAppSDK'

Then run pod install and open the generated workspace.

Manual integration

  1. Extract LBWhaleAppSDK-XXX.zip.
  2. Drag LBWhaleAppSDK.xcframework into the Xcode project.
  3. In General → Frameworks, Libraries, and Embedded Content, select Embed & Sign.
  4. Add all system frameworks listed in the delivered package to Build Phases → Link Binary With Libraries.

Start WhaleAppSDK

Import the umbrella header

Import the umbrella header in code:

#import <LBWhaleAppSDK/LBWhaleApp.h>

Swift projects should import it from the bridging header instead.

Initialize LBWhaleAppSDK

Initialize the SDK before opening any SDK page.

LBWhaleAppConfigMultilingual *appName =
    [[LBWhaleAppConfigMultilingual alloc] initWithEn:@"My Trading App"
                                                zhCN:@"我的交易应用"
                                                zhHK:@"我的交易應用"];

LBWhaleAppConfig *config = [[LBWhaleAppConfig alloc]
    initAppKey:@"<app-key>"
    appSecret:@"<app-secret>"
    appId:@"<app-id>"
    appName:appName
    defaultAccountChannel:@"<account-channel>"
    webDomainPrefix:@"<web-domain-prefix>"
    token:@"<client-token>"
    refreshToken:@"<client-refresh-token>"
    delegate:self
    extraCustomConfig:nil];

config.theme = LBWhaleAppConfigThemeAuto;
config.language = LBWhaleAppConfigLanguageEn;
config.priceColorType = LBWhaleAppConfigPriceColorFollowUserSetting;
config.env = LBWhaleAppConfigEnvProd;
config.sdkUIDelegate = self;

[LBWhaleApp startWithConfig:config];
Warning

Use only the environment and credentials delivered for the project. Do not hard-code real appSecret, token, or refresh token values in the repository.

Implement delegate methods

All LBWhaleAppDelegate methods are optional. Implement only the callbacks the project needs, in SDK lifecycle order.

Error code reference

Callbacks that carry an NSError always use the domain @"LBWhaleApp". Common codes:

NSError.code Meaning Handling
400 Missing required configuration or duplicate start Correct LBWhaleAppConfig and start again
401 Unrecoverable authentication failure or state-dependent API used before startup Destroy the SDK when needed and require Client sign-in
403xxx Invalid API Key or project configuration Verify the delivered project configuration with Whale

The SDK checks and renews tokens internally; Broker App does not call check-token or refresh-token APIs.

- (void)lbWhaleAppDidFinishLaunching {
    // SDK-dependent UI may now be opened.
}

- (void)lbWhaleAppStartFailedWithError:(NSError *)error {
    // 400: invalid or incomplete integration configuration.
    // 401 / 403xxx: authentication or API-key failure.
    // The SDK destroys itself for unrecoverable startup authentication failure.
    [MyErrorTracker trackSanitizedError:error];
    if (error.code != 400) {
        [self redirectToLoginPage];
    }
}

- (void)lbWhaleAppTokenDidChange:(NSString *)token {
    // Notification only. WhaleAppSDK has already renewed the session and
    // continues to manage validity and subsequent renewal.
}

- (void)lbWhaleAppDidRunInError:(NSError *)error {
    if (error.code == 401) {
        [LBWhaleApp logoutAndDestroy];
        [self redirectToLoginPage];
    }
}

- (BOOL)lbWhaleAppSDKCanOpenURL:(NSString *)url {
    // Return YES only when Broker App can route this URL.
    return [MyAppRouter canOpenURL:url];
}

- (void)lbWhaleAppSDKDidRequestOpenURL:(NSString *)url {
    // Called after lbWhaleAppSDKCanOpenURL: returns YES, or when the SDK
    // cannot resolve a URL by itself.
    [MyAppRouter openURL:url];
}

- (void)lbWhaleAppWillDestroy {
    // Persist necessary non-sensitive state before SDK pages close.
}

Validate schemes, domains, and route allowlists before opening a URL that lbWhaleAppSDKDidRequestOpenURL: forwards.

lbWhaleAppRefreshTokenExpiredWithResolver: is called only after the SDK’s normal renewal path fails. Its default project behavior should abandon retry and return Broker App to a logged-out state. Only return new credentials when the project has explicitly agreed on a separate way to obtain a completely new Client session.

- (void)lbWhaleAppRefreshTokenExpiredWithResolver:
    (void(^)(NSString *token, NSString *refreshToken))resolveCompleted {
    resolveCompleted(nil, nil);
}
Note

The callback waits 30 seconds by default. Override the timeout with LBAPPSDKConfigKeyRefreshTokenResolverTimeout in extraCustomConfig only when required.

Observe SDK page lifecycle (optional)

Set LBWhaleAppUIDelegate on config.sdkUIDelegate to observe when the first SDK page opens and when the last SDK page closes. The callbacks track whether SDK pages exist, not whether the App is foregrounded.

config.sdkUIDelegate = self;

- (void)lbWhaleAppEnterSdkPage {
    // First live SDK page opened (0 → 1).
}

- (void)lbWhaleAppExitSdkPage {
    // Last live SDK page closed (1 → 0).
}

Open SDK pages

Call routing methods only after lbWhaleAppDidFinishLaunching.

[LBWhaleApp pushURL:@"lb://page/main"];
[LBWhaleApp presentURL:@"lb://page/discovery/search-stocks"];

NSDictionary *parameters = @{ @"id": @"ST/US/AAPL" };
[LBWhaleApp pushURL:@"lb://page/stock/detail"
          parameters:parameters
            animated:YES
           completed:^(BOOL succeeded, NSError *error) {
    if (!succeeded) {
        [MyErrorTracker trackSanitizedError:error];
    }
}];

pushURL: and presentURL: each provide variants for animated, parameters, and a completion callback.

Log out and destroy the SDK

Use [LBWhaleApp logoutAndDestroy] when the Client signs out or authentication becomes unrecoverable. It releases SDK memory and network resources. The public configuration object also declares -[LBWhaleAppConfig logout], which clears the current credentials without destroying the SDK. The source integration does not define a complete account-switch sequence, so use this method only after Whale confirms the applicable SDK version and call sequence for the project.

[LBWhaleApp logoutAndDestroy];

Support landscape pages

Read the orientation mask the current SDK page requires. A return value of 0 means the active page is not an SDK page, and Broker App decides the supported orientation.

+ (NSUInteger)requiredAppInterfaceOrientationMask;

Forward the mask from AppDelegate so SDK pages can render in the required orientation:

- (UIInterfaceOrientationMask)application:(UIApplication *)application
        supportedInterfaceOrientationsForWindow:(UIWindow *)window {
    NSUInteger mask = [LBWhaleApp requiredAppInterfaceOrientationMask];
    return mask > 0 ? mask : UIInterfaceOrientationMaskPortrait;
}

Message push

Choose one delivery path for each project. See Message-push integration for server setup and the standard message shape. The two paths are independent — integrate the one that matches the project’s push infrastructure.

Whale-managed channel

Whale delivers messages to Broker App through the SDK’s built-in channel. Broker App only starts the push service and reports the device token; the SDK owns notification display and click routing after startup (NotificationErrorNotStarted means the SDK must be started before routing).

Start the push service

Start the push service independently of SDK startup, ideally when the App launches.

[[LBWhaleApp pushService]
    startWithKey:@"<push-key>"
    andSecret:@"<push-secret>"
    andCompleted:^(NSError *error) {
        if (error) [MyErrorTracker trackSanitizedError:error];
    }];

Report the device token

Forward the APNs device token once it arrives. If the SDK has not started, it caches the token and binds it to the Client after startup. Pass YES for disableMultiDevices to deliver push only to the most recently signed-in device.

- (void)application:(UIApplication *)application
    didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
    [[LBWhaleApp pushService]
        updateDeviceToken:deviceToken
        disableMultiDevices:NO
        callback:^(NSError *error) {
            if (error) [MyErrorTracker trackSanitizedError:error];
        }];
}

Handle cold-start notifications

Forward launchOptions from didFinishLaunchingWithOptions: so the SDK can resolve a cold-start notification tap.

- (BOOL)application:(UIApplication *)application
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    NSError *error = [[LBWhaleApp pushService] handleLaunchOptions:launchOptions];
    if (error.code == NotificationErrorNotStarted) {
        // Start the SDK, then let it process this notification once ready.
    } else if (error.code == NotificationErrorNonSDK) {
        // Not a Whale notification; Broker App handles it.
    }
    return YES;
}

Handle foreground and click notifications

On iOS 10 and later, forward both UNUserNotificationCenterDelegate methods to the SDK.

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
        willPresentNotification:(UNNotification *)notification
          withCompletionHandler:(void (^)(UNNotificationPresentationOptions))completionHandler {
    NSError *error = [[LBWhaleApp pushService]
        handleSystemDelegateUserNotificationCenter:center
        willPresentNotification:notification];
    if (!error) {
        completionHandler(UNNotificationPresentationOptionNone);
        return;
    }
    // NotificationErrorNotStarted: start the SDK before retrying.
    // NotificationErrorNonSDK: Broker App handles this notification.
}

- (void)userNotificationCenter:(UNUserNotificationCenter *)center
    didReceiveNotificationResponse:(UNNotificationResponse *)response
             withCompletionHandler:(void (^)(void))completionHandler {
    NSError *error = [[LBWhaleApp pushService]
        handleSystemDelegateUserNotificationCenter:center
        didReceiveNotificationResponse:response];
    if (!error) {
        completionHandler();
        return;
    }
    // NotificationErrorNotStarted / NotificationErrorNonSDK: same handling as above.
}

Broker-managed channel

Broker App handles APNs registration and delivery on its own channel, and passes only Whale messages to the SDK. Use this path when push data does not come from standard APNs, when Broker App must pre-process or validate the payload before the SDK sees it, or when an existing push system should not take on the SDK’s built-in channel.

Identify Whale messages

After Broker App receives a message on its own channel, call checkIsLBNotificationWithUserInfo: to confirm it originated from Whale before forwarding it to the SDK.

NSDictionary *userInfo = notification.request.content.userInfo;
if ([LBWhaleAppPushService checkIsLBNotificationWithUserInfo:userInfo]) {
    // Forward to the SDK; see below.
} else {
    // Not a Whale message; Broker App handles it.
}

Show the foreground tip

When the App is foregrounded and a Whale message arrives, call sdkShowTipWithNotificationInfo:routerHandler: to let the SDK display the tip. routerHandler returns the route when the Client taps the tip.

NSError *error = [[LBWhaleApp pushService]
    sdkShowTipWithNotificationInfo:userInfo
    routerHandler:^(NSString *routerURL) {
        [MyAppRouter openURL:routerURL];
    }];
Note

Implementing routerHandler disables the SDK’s own navigation. Call routerURL inside the block to keep the expected tap-to-navigate behavior.

Handle notification navigation

After the Client taps a notification, call handleNotificationClickWithInfo:routerHandler: to let the SDK resolve the route. routerHandler behaves the same as for the foreground tip.

NSError *error = [[LBWhaleApp pushService]
    handleNotificationClickWithInfo:response.notification.request.content.userInfo
    routerHandler:^(NSString *routerURL) {
        [MyAppRouter openURL:routerURL];
    }];

Public API reference

Main classes

LBWhaleApp

The SDK’s entry point. Provides startup, logout, and page routing.

Member Purpose
sdkVersion SDK version
pushService Shared LBWhaleAppPushService instance
config Current startup configuration
sdkStatus NotStarted, Starting, Started, or IsDestroying
startWithConfig: Start the SDK asynchronously
logoutAndDestroy Log out and release SDK resources
pushURL:... / presentURL:... Open an SDK page, optionally with parameters, animation, and completion
requiredAppInterfaceOrientationMask Orientation required by the current SDK page, or 0 outside SDK pages

The complete routing declarations are:

+ (void)pushURL:(NSString *)url;
+ (void)presentURL:(NSString *)url;
+ (void)pushURL:(NSString *)url animated:(BOOL)animated;
+ (void)presentURL:(NSString *)url animated:(BOOL)animated;
+ (void)pushURL:(NSString *)url
     parameters:(NSDictionary * _Nullable)parameters
      completed:(void (^ _Nullable)(BOOL isSuccessed, NSError * _Nullable error))completed;
+ (void)presentURL:(NSString *)url
        parameters:(NSDictionary * _Nullable)parameters
         completed:(void (^ _Nullable)(BOOL isSuccessed, NSError * _Nullable error))completed;
+ (void)pushURL:(NSString *)url
     parameters:(NSDictionary * _Nullable)parameters
       animated:(BOOL)animated
      completed:(void (^ _Nullable)(BOOL isSuccessed, NSError * _Nullable error))completed;
+ (void)presentURL:(NSString *)url
        parameters:(NSDictionary * _Nullable)parameters
          animated:(BOOL)animated
         completed:(void (^ _Nullable)(BOOL isSuccessed, NSError * _Nullable error))completed;

LBWhaleAppConfig

Startup configuration containing identity credentials, UI options, and the event-callback delegate. Build it with initAppKey:... and pass it to [LBWhaleApp startWithConfig:]. theme, language, and priceColorType can change at any time before or after startup.

@interface LBWhaleAppConfig : NSObject
@property (nonatomic, copy, readonly) NSString *appKey;
@property (nonatomic, copy, readonly) NSString *appSecret;
@property (nonatomic, copy, readonly) NSString *appId;
@property (nonatomic, strong, readonly) LBWhaleAppConfigMultilingual *appName;
@property (nonatomic, copy, readonly) NSString *defaultAccountChannel;
@property (nonatomic, copy, readonly) NSString *webDomainPrefix;
@property (nonatomic, copy, readonly) NSString *token;
@property (nonatomic, copy, readonly) NSString *refreshToken;
@property (nonatomic, weak, readonly, nullable) id<LBWhaleAppDelegate> delegate;
@property (nonatomic, weak, nullable) id<LBWhaleAppUIDelegate> sdkUIDelegate;
@property (nonatomic, assign) LBWhaleAppConfigTheme theme;
@property (nonatomic, assign) LBWhaleAppConfigLanguage language;
@property (nonatomic, assign) LBWhaleAppConfigPriceColor priceColorType;
@property (nonatomic, assign) LBWhaleAppConfigEnv env;
@property (nonatomic, copy, readonly, nullable) NSDictionary *extraCustomConfig;

- (instancetype)initAppKey:(NSString *)appKey
                  appSecret:(NSString *)appSecret
                      appId:(NSString *)appId
                    appName:(LBWhaleAppConfigMultilingual *)appName
      defaultAccountChannel:(NSString *)defaultAccountChannel
            webDomainPrefix:(NSString *)webDomainPrefix
                      token:(NSString *)token
               refreshToken:(NSString *)refreshToken
                   delegate:(nullable id<LBWhaleAppDelegate>)delegate
          extraCustomConfig:(nullable NSDictionary *)extraCustomConfig;

/// Clears the current Client credentials to switch accounts without destroying the SDK.
- (void)logout;
@end

Custom parameters

extraCustomConfig supports these public keys:

Key Value Purpose
LBAPPSDKConfigKeyDisableIDFA NSNumber boolean Disable IDFA access and the ATT prompt
LBAPPSDKConfigDebugEggDisable NSNumber boolean Disable the system debug panel
LBAPPSDKConfigKeyDeviceId NSString Supply a project-defined device identifier
LBAPPSDKConfigKeyFileDirectory NSString Override the SDK cache directory
LBAPPSDKConfigKeyRefreshTokenResolverTimeout NSNumber seconds Change the exceptional renewal callback timeout
LBAPPSDKConfigKeyColor nested dictionary Customize supported push-tip colors
LBAPPSDKConfigKeyFontCrypto UIFontDescriptor Replace the market-data digit font
LBAPPSDKConfigKeyFontMonospaced UIFontDescriptor Replace the regular monospaced font
LBAPPSDKConfigKeyFontMonospacedBold UIFontDescriptor Replace the bold monospaced font

Color maps use LBAPPSDKConfigKeyColorLight and LBAPPSDKConfigKeyColorDark. Supported push-tip keys include default background, title, content, and icon colors, plus order-completed, order-failed, order-limit, and other-message overrides.

The exact public keys are LBAPPSDKConfigKeyPushTipView, LBAPPSDKConfigKeyPTVDefaultBackground, LBAPPSDKConfigKeyPTVDefaultTitle, LBAPPSDKConfigKeyPTVDefaultContent, LBAPPSDKConfigKeyPTVDefaultIcon, LBAPPSDKConfigKeyPTVOrderCompleted, LBAPPSDKConfigKeyPTVOrderFailed, LBAPPSDKConfigKeyPTVOrderLimit, LBAPPSDKConfigKeyPTVOther, LBAPPSDKConfigKeyPTVLimitTitleColor, LBAPPSDKConfigKeyPTVLimitContentColor, and LBAPPSDKConfigKeyPTVLimitIconColor.

Custom font configuration

The SDK supports custom font configuration so Broker App can replace SDK-embedded fonts. Configure the font mapping in extraCustomConfig when creating LBWhaleAppConfig.

Configuration method

UIFontDescriptor *customMonospacedFont =
    [UIFontDescriptor fontDescriptorWithName:@"YourCustomFont-Monospaced" size:0];
UIFontDescriptor *customMonospacedBoldFont =
    [UIFontDescriptor fontDescriptorWithName:@"YourMonospaceFont-MonospacedBold" size:0];
UIFontDescriptor *customCryptoFont =
    [UIFontDescriptor fontDescriptorWithName:@"YourCryptoFont" size:0];

NSDictionary *extraConfig = @{
    LBAPPSDKConfigKeyFontMonospaced: customMonospacedFont,
    LBAPPSDKConfigKeyFontMonospacedBold: customMonospacedBoldFont,
    LBAPPSDKConfigKeyFontCrypto: customCryptoFont
};

LBWhaleAppConfig *config = [[LBWhaleAppConfig alloc]
    initAppKey:@"<app-key>"
    appSecret:@"<app-secret>"
    appId:@"<app-id>"
    appName:appName
    defaultAccountChannel:@"<account-channel>"
    webDomainPrefix:@"<web-domain-prefix>"
    token:@"<client-token>"
    refreshToken:@"<client-refresh-token>"
    delegate:self
    extraCustomConfig:extraConfig];

Supported font types

Notes

  • Register the custom font in the App’s Info.plist, or register it in code, before use.
  • Use the font’s PostScript name or full name, not its file name.
  • The SDK falls back to its bundled font when the specified font is unavailable.
  • Set the font descriptor size to 0; the SDK selects an appropriate size for each context.

LBWhaleAppConfigMultilingual

Multilingual App name configuration.

@interface LBWhaleAppConfigMultilingual : NSObject
@property (nonatomic, copy, readonly) NSString *en;
@property (nonatomic, copy, readonly, nullable) NSString *zhCN;
@property (nonatomic, copy, readonly, nullable) NSString *zhHK;
@property (nonatomic, readonly) NSString *currentLanguageText;
- (instancetype)initWithEn:(NSString *)en
                       zhCN:(nullable NSString *)zhCN
                       zhHK:(nullable NSString *)zhHK;
@end

Enum types

LBWhaleAppConfigPriceColor - Price and color display

typedef NS_ENUM(NSInteger, LBWhaleAppConfigPriceColor) {
    LBWhaleAppConfigPriceColorFollowUserSetting, // Follow the Client's in-SDK setting (default).
    LBWhaleAppConfigPriceColorRedUpGreenDown,    // Force red-up, green-down.
    LBWhaleAppConfigPriceColorGreenUpRedDown     // Force green-up, red-down.
};

LBWhaleAppConfigTheme - Theme mode

typedef NS_ENUM(NSInteger, LBWhaleAppConfigTheme) {
    LBWhaleAppConfigThemeAuto,   // Follow the system setting (default).
    LBWhaleAppConfigThemeLight,
    LBWhaleAppConfigThemeDark
};

LBWhaleAppConfigLanguage - Display language

typedef NS_ENUM(NSInteger, LBWhaleAppConfigLanguage) {
    LBWhaleAppConfigLanguageEn,
    LBWhaleAppConfigLanguageZhCN,
    LBWhaleAppConfigLanguageZhHK
};

LBWhaleAppConfigEnv - Runtime environment

typedef NS_ENUM(NSInteger, LBWhaleAppConfigEnv) {
    LBWhaleAppConfigEnvProd, // Production (default).
    LBWhaleAppConfigEnvSit,
    LBWhaleAppConfigEnvTest
};

Do not select a non-production environment unless the Whale project team supplies matching configuration.

Delegate protocols

LBWhaleAppDelegate

SDK event-callback delegate. Every method is optional.

@protocol LBWhaleAppDelegate <NSObject>
@optional

/// The SDK renewed the session; the new token is informational only.
- (void)lbWhaleAppTokenDidChange:(nonnull NSString *)token;

/// The SDK raised a runtime error after startup.
- (void)lbWhaleAppDidRunInError:(nonnull NSError *)error;

/// The SDK failed to start.
- (void)lbWhaleAppStartFailedWithError:(nonnull NSError *)error;

/// The SDK finished starting.
- (void)lbWhaleAppDidFinishLaunching;

/// The SDK cannot resolve this URL by itself.
- (void)lbWhaleAppSDKDidRequestOpenURL:(NSString *)openUrl;

/// Return YES when Broker App can open this URL.
- (BOOL)lbWhaleAppSDKCanOpenURL:(NSString *)url;

/// The SDK is about to destroy itself.
- (void)lbWhaleAppWillDestroy;

/// The SDK's own token renewal failed; call resolveCompleted with new
/// credentials, or with (nil, nil) before the timeout to fail the request.
- (void)lbWhaleAppRefreshTokenExpiredWithResolver:(void(^)(NSString *token, NSString *refreshToken))resolveCompleted;

/// Forwards SDK analytics events. Never add credentials or Client-sensitive information.
- (void)lbWhaleAppAnalyticsEventWithName:(NSString *)name properties:(NSDictionary *)properties;

@end

LBWhaleAppUIDelegate

SDK page lifecycle delegate, set through LBWhaleAppConfig.sdkUIDelegate. Both methods fire on the main thread.

@protocol LBWhaleAppUIDelegate <NSObject>

/// The first SDK page opened.
- (void)lbWhaleAppEnterSdkPage;

/// The last SDK page closed.
- (void)lbWhaleAppExitSdkPage;

@end

Push service

LBWhaleAppPushService

Push-service class. Access the shared instance through LBWhaleApp.pushService; no manual initialization is required.

@property (nonatomic, copy, readonly, nullable) NSString *pushAppKey;
@property (nonatomic, copy, readonly, nullable) NSString *pushAppSecret;
@property (nonatomic, strong, readonly, nullable) NSData *deviceToken;
@property (nonatomic, copy, readonly, nullable) NSString *pushDeviceId;
@property (nonatomic, assign, readonly) BOOL isStarted;
@property (nonatomic, assign, readonly) BOOL disableMultiDevices;

+ (BOOL)checkIsLBNotificationWithUserInfo:(NSDictionary *)userInfo;
- (void)startWithKey:(NSString *)appPushKey
           andSecret:(NSString *)appPushSecret
        andCompleted:(void (^ _Nullable)(NSError * _Nullable error))completed;
- (void)updateDeviceToken:(NSData *)deviceToken
      disableMultiDevices:(BOOL)disableMultiDevices
                 callback:(void (^ _Nullable)(NSError * _Nullable error))callback;
- (NSError * _Nullable)handleLaunchOptions:(NSDictionary *)launchOptions;
- (NSError * _Nullable)handleSystemDelegateUserNotificationCenter:(UNUserNotificationCenter *)center
                                           willPresentNotification:(UNNotification *)notification;
- (NSError * _Nullable)handleSystemDelegateUserNotificationCenter:(UNUserNotificationCenter *)center
                                    didReceiveNotificationResponse:(UNNotificationResponse *)response;
- (NSError * _Nullable)sdkShowTipWithNotificationInfo:(NSDictionary *)notification
                                        routerHandler:(void (^ _Nullable)(NSString *routerURL))routerHandler;
- (NSError * _Nullable)handleNotificationClickWithInfo:(NSDictionary *)response
                                         routerHandler:(void (^ _Nullable)(NSString *routerURL))routerHandler;

LBWhaleNotificationHandlingErrorCode contains NotificationErrorNotStarted, NotificationErrorNonSDK, and NotificationErrorPushStartFailed.

Additional notes

The delivered podspec declares these external dependencies:

spec.dependency 'RangersAPM/Crash', '>= 5.1.6'
spec.dependency 'RangersAPM/APMLog', '>= 5.1.6'
spec.dependency 'RangersAPM/CN', '>= 5.1.6'
spec.dependency 'RangersAPM/WatchDog', '>= 5.1.6'
spec.dependency 'RangersAPM/CloudCommand', '>= 5.1.6'
spec.dependency 'AlicloudPush', '>= 3.2.2'
spec.dependency 'IQKeyboardManager', '>= 6.5.9'

They are not embedded in the SDK binary. If Broker App already uses a conflicting version, coordinate the resolved version with the Whale project team instead of packaging two incompatible implementations.

Whale Docs