Smart Camera UI BizBundles

Last Updated on : 2024-08-01 06:49:29download

This topic describes the IPC UI BizBundles with different features. You can integrate with the desired UI BizBundles based on your business requirements.

We recommend that you integrate with the IPC Panel BizBundle as a whole. If you access the entry to a specific panel only, a logical conflict might occur in the context.

Smart Camera UI BizBundle

Smart Camera (IPC) UI BizBundle (ThingSmartCameraPanelBizBundle) is the panel SDK that provides a series of IPC features developed based on Smart Life App SDK.

Functional description

The following features are supported:

  • Preview panel
  • Playback panel
  • Cloud storage panel
  • Message center panel
  • Photo album panel
  • Setting panel

Integrate with the UI BizBundle

  1. Add the following code block to the Podfile:

    source "https://github.com/tuya/tuya-pod-specs"
    source 'https://cdn.cocoapods.org/'
    platform :ios, '11.0'
    
    target 'your_target_name' do
        # Adds the IPC Panel BizBundle.
        pod 'ThingSmartCameraPanelBizBundle'
    end
    
  2. In the root directory of your project, run pod update to integrate a third-party library by using CocoaPods. For more information about CocoaPods, see CocoaPods Guides.

  3. Add the following permission declaration to info.plist of your project:

    The BizBundle encapsulates a series of React Native (RN) API methods for panels. This requires specific declarations of privacy and permissions from Apple.

    • If a device panel supports image features such as an album, add the following permission declaration:
      NSPhotoLibraryAddUsageDescription
      
    • If a device panel supports microphone features such as video talk on an IPC, add the following permission declaration:
      NSMicrophoneUsageDescription
      

Service protocols

The BizBundle relies on the implementation of the protocol ThingCameraProtocol to provide services. You can view the ThingCameraProtocol.h file in the ThingModuleServices component.

#import <UIKit/UIKit.h>

@class ThingSmartDeviceModel;

@protocol ThingCameraProtocol <NSObject>

/**
 Returns the IPC native panel. Deprecated.
 @param devId The device ID of the IPC.
 @param uiName The UI name of the IPC. The value is included in deviceModel and varies depending on different panel versions.
 */
- (UIViewController *)viewControllerWithDeviceId:(NSString *)devId uiName:(NSString *)uiName DEPRECATED_MSG_ATTRIBUTE("viewControllerWithDeviceId:uiName: is deprecated, use `getPanelViewControllerWithDeviceModel:initialProps:contextProps:completionHandler:` in `ThingPanelProtocol` instead");

@optional

/**
 Navigates to the IPC playback panel.
 @param deviceModel The device model.
 */
- (void)deviceGotoCameraNewPlayBackPanel:(ThingSmartDeviceModel *)deviceModel;

/**
 Navigates to the IPC cloud storage panel.
 @param deviceModel The device model.
 */
- (void)deviceGotoCameraCloudStoragePanel:(ThingSmartDeviceModel *)deviceModel;

/**
 Navigates to the IPC message center panel.
 @param deviceModel The device model.
 */
- (void)deviceGotoCameraMessageCenterPanel:(ThingSmartDeviceModel *)deviceModel;

/**
 Navigates to the IPC photo album panel.
 @param deviceModel The device model.
 */
- (void)deviceGotoPhotoLibrary:(ThingSmartDeviceModel *)deviceModel;

@end

Depend on services

The BizBundle depends on the following protocols: ThingSmartHomeDataProtocol and ThingOTAGeneralProtocol.

  • ThingSmartHomeDataProtocol: provides current home information required to load the device panel and must be implemented.

    /**
    Returns the current home. If the current user does not have a home, nil is returned.
    
    @return ThingSmartHome
    */
    - (ThingSmartHome *)getCurrentHome;
    
  • ThingOTAGeneralProtocol: enters the device panel and checks for device firmware updates. The following API method is implemented to check for device firmware updates:

    /**
    Checks for device firmware updates, and if any, shows the update prompt.
    
    @param deviceModel The device that checks for firmware updates.
    @param isManual Specifies whether to enable manual checks for firmware updates.
    @param theme The theme color.
    YES: Manually check for updates. A loading dialog box appears during the check. If a new update is found (check for updates, forced updates, and update notifications), OTA VC is displayed.
    NO: Automatically check for updates. A loading dialog box does not appear during the check. When forced updates and update notifications are enabled, the firmware update prompt appears. Click **OK** to show OTA VC. */
    */
    - (void)checkFirmwareUpgrade:(ThingSmartDeviceModel *)deviceModel isManual:(BOOL)isManual theme:(ThingOTAControllerTheme)theme;
    

Things to note

  • Before the call of any API method, make sure that the current user is associated with the target device.
  • The call applies to IPCs only. The value of deviceModel.category must be sp.
  • Before the UI BizBundle is used, the getCurrentHome method provided by the protocol ThingSmartHomeDataProtocol must be implemented first.
  • The BizBundle and TuyaSmartCameraPanelSDK are mutually exclusive and cannot be integrated at the same time. For more information about the migration, see Migrate to BizBundle SDK.

Objective-C:

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingSmartHomeDataProtocol.h>

- (void)initCurrentHome {
    // Registers the protocol to be implemented.
    [[ThingSmartBizCore sharedInstance] registerService:@protocol(ThingSmartHomeDataProtocol) withInstance:self];
}

// Implements the protocol method.
- (ThingSmartHome *)getCurrentHome {
    ThingSmartHome *home = [ThingSmartHome homeWithHomeId:@"Current home ID"];
    return home;
}

Swift:

import ThingSmartDeviceKit

class ThingActivatorTest: NSObject,ThingSmartHomeDataProtocol{

    func test() {
        ThingSmartBizCore.sharedInstance().registerService(ThingSmartHomeDataProtocol.self, withInstance: self)
    }

    func getCurrentHome() -> ThingSmartHome! {
        let home = ThingSmartHome.init(homeId: 111)
        return home
    }

}

View a preview panel (UIViewController)

An IPC native preview panel supports a bunch of features. For example, you can implement live video preview, switching between video definition modes, audio switch control, screenshot capturing, video recording, video talk, motion detection, PTZ control, preset point addition or deletion, and auto-patrol control.

For more information about the live preview panel, see Device Control UI BizBundle.

IPC RN Panel BizBundle

IPC RN Panel BizBundle (ThingSmartCameraRNPanelBizBundle) is the React Native (RN) Panel BizBundle that provides a series of IPC features developed based on Smart Life App SDK.

Before you use the IPC RN Panel BizBundle, you must integrate with the Device Control UI BizBundle. For more information, see Device Control UI BizBundle.

Functional description

The following features are supported:

  • Preview panel
  • Playback panel
  • Cloud storage panel
  • Message center panel
  • Photo album panel
  • Setting panel

Integrate with the UI BizBundle

  1. Add the following code block to the Podfile:

    source "https://github.com/tuya/tuya-pod-specs.git"
    source 'https://cdn.cocoapods.org/'
    
    target 'your_target_name' do
        # Adds the panel control BizBundle.
        pod 'ThingSmartPanelBizBundle'
        # After you add the IPC Panel BizBundle and integrate with the RN BizBundle, integrate with this BizBundle to implement features such as native albums as expected.
        pod 'ThingSmartCameraPanelBizBundle'
        # Adds the IPC RN Panel BizBundle.
        pod 'ThingSmartCameraRNPanelBizBundle'
    end
    
  2. In the root directory of your project, run pod update to integrate a third-party library by using CocoaPods. For more information about CocoaPods, see CocoaPods Guides.

  3. Add the following permission declaration to info.plist of your project:

    The BizBundle encapsulates a series of RN API methods for panels. This requires specific declarations of privacy and permissions from Apple.

    • If a device panel supports image features such as an album, add the following permission declaration:
      NSPhotoLibraryAddUsageDescription
      
    • If a device panel supports microphone features such as video talk on an IPC, add the following permission declaration:
      NSMicrophoneUsageDescription
      

Description

The UI BizBundle relies on the implementation of the protocol ThingPanelProtocol to provide services. The ThingPanelProtocol.h file in the ThingModuleServices component includes:

#import <UIKit/UIKit.h>

@protocol ThingPanelProtocol <NSObject>

/**
 * Returns the device panel controller.
 * @param deviceModel  The device model.
 * @param initialProps The custom initialization parameter to be set in initialProps of the RN application with the key 'extraInfo'.
 * @param contextProps The context of the custom panel to be set in Panel Context with the key 'extraInfo'.
 * @param completionHandler The callback returns the view controller.
 */
- (void)getPanelViewControllerWithDeviceModel:(ThingSmartDeviceModel *)deviceModel
                                 initialProps:(nullable NSDictionary *)initialProps
                                 contextProps:(nullable NSDictionary *)contextProps
                            completionHandler:(void (^ _Nullable)(__kindof UIViewController * _Nullable panelViewController, NSError * _Nullable error))completionHandler;

@end

Depend on services

The BizBundle depends on the following protocols: ThingSmartHomeDataProtocol and ThingOTAGeneralProtocol.

  • ThingSmartHomeDataProtocol: provides current home information required to load the device panel and must be implemented.

    /**
    Returns the current home. If the current user does not have a home, nil is returned.
    
    @return ThingSmartHome
    */
    - (ThingSmartHome *)getCurrentHome;
    
  • ThingOTAGeneralProtocol: enters the device panel and checks for device firmware updates. The following API method is implemented to check for device firmware updates:

    /**
    Checks for device firmware updates, and if any, shows the update prompt.
    
    @param deviceModel The device that checks for firmware updates.
    @param isManual Specifies whether to enable manual checks for firmware updates.
    @param theme The theme color.
    YES: Manually check for updates. A loading dialog box appears during the check. If a new update is found (check for updates, forced updates, and update notifications), OTA VC is displayed.
    NO: Automatically check for updates. A loading dialog box does not appear during the check. When forced updates and update notifications are enabled, the firmware update prompt appears. Click **OK** to show OTA VC.
    */
    - (void)checkFirmwareUpgrade:(ThingSmartDeviceModel *)deviceModel isManual:(BOOL)isManual theme:(ThingOTAControllerTheme)theme;
    

Things to note

  • Before the call of any API method, make sure that the current user is associated with the target device.
  • The call applies to IPCs only. The value of deviceModel.category must be sp.
  • Before the UI BizBundle is used, the getCurrentHome method provided by the protocol ThingSmartHomeDataProtocol must be implemented first.
  • This BizBundle must be integrated together with the BizBundle ThingSmartCameraPanelBizBundle. The IPC album panel and other certain features are supported by ThingSmartCameraPanelBizBundle.

Objective-C:

#import <ThingSmartBizCore/ThingSmartBizCore.h>
#import <ThingModuleServices/ThingSmartHomeDataProtocol.h>

- (void)initCurrentHome {
    // Registers the protocol to be implemented.
    [[ThingSmartBizCore sharedInstance] registerService:@protocol(ThingSmartHomeDataProtocol) withInstance:self];
}

// Implements the protocol method.
- (ThingSmartHome *)getCurrentHome {
    ThingSmartHome *home = [ThingSmartHome homeWithHomeId:@"Current home ID"];
    return home;
}

Swift:

import ThingSmartDeviceKit

class ThingActivatorTest: NSObject,ThingSmartHomeDataProtocol{

    func test() {
        ThingSmartBizCore.sharedInstance().registerService(ThingSmartHomeDataProtocol.self, withInstance: self)
    }

    func getCurrentHome() -> ThingSmartHome! {
        let home = ThingSmartHome.init(homeId: 111)
        return home
    }

}

View a preview panel (UIViewController)

An IPC RN preview panel supports a bunch of features. For example, you can implement live video preview, switching between video definition modes, audio switch control, screenshot capturing, video recording, and video talk.

Objective-C:

id<ThingPanelProtocol> impl = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingPanelProtocol)];
// Returns the panel view controller and enables automatic navigation.
if (deviceModel) {
    [impl getPanelViewControllerWithDeviceModel:deviceModel initialProps:nil contextProps:nil completionHandler:^(__kindof UIViewController * _Nullable panelViewController, NSError * _Nullable error) {
    }];
}

Swift:

let impl = ThingSmartBizCore.sharedInstance().service(of: ThingPanelProtocol.self) as? ThingPanelProtocol
// Returns the panel view controller and enables automatic navigation.
impl?.getPanelViewController(with: deviceModel, initialProps: nil, contextProps: nil, completionHandler: { (vc, err) in

})

IPC Setting Panel BizBundle

IPC Setting Panel BizBundle (ThingSmartCameraSettingBizBundle) helps you develop the panel that provides a series of IPC setting features developed based on Smart Life App SDK.

Functional description

The following features are supported:

  • Device details
  • Basic settings
  • SD card settings
  • Value-added services
  • Restart and other certain features

Integrate with the UI BizBundle

  1. Add the following code block to the Podfile:

    source "https://github.com/tuya/tuya-pod-specs.git"
    source 'https://cdn.cocoapods.org/'
    
    target 'your_target_name' do
        # Adds the IPC Setting Panel BizBundle.
        pod 'ThingSmartCameraSettingBizBundle'
    end
    
  2. In the root directory of your project, run pod update to integrate a third-party library by using CocoaPods. For more information about CocoaPods, see CocoaPods Guides.

Service protocols

The BizBundle depends on the protocol ThingCameraSettingProtocol to provide services. You can view the ThingCameraSettingProtocol.h file in the ThingModuleServices component.

#import <UIKit/UIKit.h>
@protocol ThingCameraSettingProtocol <NSObject>

/**
 Generate settingViewController
 Returns the IPC setting panel.
 @param params The parameters of the camera setting page. For example, the homepage is indicated by @{@"devId" : Device ID, @"cameraSettingPanelIdentifier" : @"cameraSettingIndexIdentifier"}.
 */
- (UIViewController *)settingViewControllerWithDeviceParams:(NSDictionary *)params;

/**
 Generate config item
 Generates custom settings.
 @param tag see developer doc identifiers.
 @param visible whether is visible or not
 @param callBack you can custom jump action
 */
- (id)generateSettingCustomModelWithTag:(NSString *)tag visible:(BOOL)visible callBack:(void(^_Nullable)(void))callBack;

/**
 Config custom setting action and display
 Configures whether settings are visible and navigates between settings.
 @param items custom items, generated by generateSettingCustomModelWithTag:visible:callBack:
 */
- (void)configCustomItemWithItems:(NSArray<id>*)items;

@end

Things to note

  • Before the call of any API method, make sure that the current user is associated with the target device.
  • The BizBundle applies to IPCs only. The value of deviceModel.category must be sp.
  • By default, after this BizBundle is integrated, IPC settings can be implemented.

Configure the setting page (ThingCameraSettingProtocol)

Customizes the configurations of the setting page. For example, display or hide features, and intercept tapping events. Required API methods are defined in ThingCameraSettingProtocol.

API description

/**
 Generate config item
 Generates custom settings.
 @param tag see developer doc identifiers.
 @param visible whether is visible or not
 @param callBack you can custom jump action
 */
- (id)generateSettingCustomModelWithTag:(NSString *)tag visible:(BOOL)visible callBack:(void(^_Nullable)(void))callBack;

Parameters

Parameter Description
visible Specifies whether to display a feature. Valid values:
  • YES: displays a feature.
  • NO: hides a feature.
callBack The callback to invoke when a tapping event is intercepted. The navigation event in the callback can be customized.
tag The tag of a feature. Its values are described in the following table.

Values of tag

Value Feature
cameraSetting_iconInfoItem Device icon and name
cameraSetting_infoItem Device information
cameraSetting_autoItem Tap-to-run and automation scenes
cameraSetting_networkItem Device network information
cameraSetting_thirdPartyItem Third-party services supported
cameraSetting_privateModeCfgItem Privacy mode switch
cameraSetting_basicSectionHeaderCfgItem Title of basic setting
cameraSetting_basicFuncCfgItem Basic settings
cameraSetting_nightvisionCfgItem Night vision mode
cameraSetting_irNightCfgItem Infrared night vision
cameraSetting_displaySettingCfgItem Display settings
cameraSetting_soundCfgItem Audio adjustment
cameraSetting_workModeCfgItem Working mode
cameraSetting_advanceSectionHeaderCfgItem Title of advanced setting
cameraSetting_detectCfgItem Detection alerts
cameraSetting_pirFuncCfgItem PIR
cameraSetting_powerCfgItem Battery management
cameraSetting_bellCfgItem Bell settings
cameraSetting_sirenSettingCfgItem Siren adjustment
cameraSetting_videoLayoutCfgItem Video layout
cameraSetting_presentPointCfgItem Preset point setting
cameraSetting_onvifCfgItem Open Network Video Interface Forum (ONVIF)
cameraSetting_gatewaySectionHeaderCfgItem Gateway title
cameraSetting_gatewayCfgItem Gateway
cameraSetting_storageSectionHeaderCfgItem Title of storage setting
cameraSetting_storageCfgItem Storage settings
cameraSetting_valueAddedSectionHeaderCfgItem Value-added service title
cameraSetting_valueAddedCfgItem Value-added services
cameraSetting_offlineSectionHeaderCfgItem Title of a device offline notification
cameraSetting_offlineCfgItem Device offline notification
cameraSetting_otherSectionHeaderCfgItem Other titles
cameraSetting_feedbackCfgItem FAQ & feedback
cameraSetting_addToHomeCfgItem Add to the home screen
cameraSetting_firmwareCfgItem Device update
cameraSetting_restartCfgItem Restart a device
cameraSetting_removeCfgItem Remove a device
cameraSetting_indicatorLightItem Status indicator
cameraSetting_besharedItem Device source
cameraSetting_soundDetectedItem Sound detection
cameraSetting_apModeItem AP mode
cameraSetting_unlockItem Remote unlocking
cameraSetting_cloudDisk Pages of cloud disks managed on a base station
cameraSetting_privacyZone Privacy area setting
cameraSetting_recording_time Time setting of a single video clip
cameraSetting_parking_mode Parking mode setting
cameraSetting_collision_alert Collision alert
cameraSetting_antiDismantle Anti-pry alert switch
cameraSetting_messageSetting Push notification settings
cameraSetting_carInspection Vehicle model detection switch
cameraSetting_nonCarInspection Non-motor vehicle detection switch
cameraSetting_thirdPartyHeaderItem Third-party title supported
cameraSetting_pirSetItem PIR setting
cameraSetting_stationDoorbellItem Setting of base station bell
cameraSetting_stationDetectionItem Base station detection alert

API description

/**
 Config custom setting action and display
 Configures whether settings are visible and navigates between settings.
 @param items custom items, generated by generateSettingCustomModelWithTag:visible:callBack:
 */
- (void)configCustomItemWithItems:(NSArray<id>*)items;

Parameters

Parameter Description
items An array of items generated by generateSettingCustomModelWithTag:visible:callBack:.

Objective-C:

id <ThingCameraSettingProtocol> cameraSettingProtocol = [[ThingSmartBizCore sharedInstance] serviceOfProtocol:@protocol(ThingCameraSettingProtocol)];

id item1 = [cameraSettingProtocol generateSettingCustomModelWithTag:@"cameraSetting_infoItem" visible:NO callBack:nil];
id item2 = [cameraSettingProtocol generateSettingCustomModelWithTag:@"cameraSetting_networkItem" visible:NO callBack:nil];

[cameraSettingProtocol configCustomItemWithItems:@[item1, item2]];

Swift:

let cameraSettingProtocolImpl = ThingSmartBizCore.sharedInstance().service(of: ThingCameraSettingProtocol.self) as? ThingCameraSettingProtocol
if let impl = cameraSettingProtocolImpl {
    let item1 = impl.generateSettingCustomModel(withTag: "cameraSetting_infoItem", visible: false, callBack: nil)
    let item2 = impl.generateSettingCustomModel(withTag: "cameraSetting_networkItem", visible: false, callBack: nil)
    impl.configCustomItem(withItems: [item1!, item2!])
}

Adapt to iOS 16 to implement full-screen preview

iOS 16 has certain updates in UIKit. For example, the feature of switching between the portrait and landscape orientations does not support forward compatibility.

The IPC UI BizBundle provides compatibility with iOS 16 in terms of switching between portrait and landscape orientations. If a display error still occurs respecting switching between the portrait and landscape orientations after you upgrade the IPC UI BizBundle, it might be caused by incompatibility. Probably, your adaption to iOS 16 is incompatible with the way the IPC UI BizBundle adapts to iOS 16. To fix the problem, we recommend that you adapt your app to iOS 16 in the following ways to implement switching between portrait and landscape orientations as needed:

  • Use case 1: Except for the pages provided by the IPC UI BizBundle, your app currently supports video playing in the portrait orientation only. In this case, we recommend that you perform the following adaptation process:

    1. Add the following method to the class AppDelegate.m to make sure the app supports both portrait and landscape orientations.

      - (UIInterfaceOrientationMask)application:(UIApplication *)application
      supportedInterfaceOrientationsForWindow:(UIWindow *)window {
          return UIInterfaceOrientationMaskAll;
      }
      
    2. Add the UIViewController Category and UIViewController+Category. Meanwhile, add the following method to make sure all pages that currently only support the portrait orientation are compatible with the landscape orientation.

      -(BOOL)shouldAutorotate {
          return NO;
      }
      
      -(UIInterfaceOrientationMask)supportedInterfaceOrientations {
          return UIInterfaceOrientationMaskPortrait;
      }
      
      -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          return UIInterfaceOrientationPortrait;
      }
      
    3. Add UINavigationController Category, and UINavigationController+Category. Meanwhile, add the following method to make sure your app is compatible with the UI BizBundle as required in terms of adaptation to the switching between portrait and landscape orientations on iOS 16.

      -(BOOL)shouldAutorotate {
          return [self.topViewController shouldAutorotate];
      }
      
      -(UIInterfaceOrientationMask)supportedInterfaceOrientations {
          return [self.topViewController supportedInterfaceOrientations];
      }
      
      -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          return [self.topViewController preferredInterfaceOrientationForPresentation];
      }
      
  • Use case 2: Except for the pages provided by the IPC UI BizBundle, your app also supports video playing in the landscape orientation. In this case, we recommend that you perform the following adaptation process:

    1. Add the following method to the class AppDelegate.m to make sure the app supports both portrait and landscape orientations.

      - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window {
          return UIInterfaceOrientationMaskAll;
      }
      
    2. Add UINavigationController Category, and UINavigationController+Category. Meanwhile, add the following method to make sure your app is compatible with the UI BizBundle as required in terms of adaptation to the switching between portrait and landscape orientations on iOS 16.

      -(BOOL)shouldAutorotate {
          return [self.topViewController shouldAutorotate];
      }
      
      -(UIInterfaceOrientationMask)supportedInterfaceOrientations {
          return [self.topViewController supportedInterfaceOrientations];
      }
      
      -(UIInterfaceOrientation)preferredInterfaceOrientationForPresentation {
          return [self.topViewController preferredInterfaceOrientationForPresentation];
      }
      
    3. In your project, add the following method to the pages that currently support the portrait orientation only. If BaseViewController is consistently used in your project, you only need to add the following method to the parent class.

      Do not add the method directly in the format of Category. If your project does not use a consistent base class, add the method to each viewController class that supports the portrait orientation only.

      - (BOOL)shouldAutorotate {
          return NO;
      }
      
      - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
          return UIInterfaceOrientationMaskPortrait;
      }
      
    4. Add the following content to the pages that support the landscape orientation.

      Add the private category UIViewController+privete of UIViewController, and declare the method - (void)thing_rotateWindowIfNeed;.

      You do not need to implement this method, but only need to declare it. The UI BizBundle implements this method.

      @interface UIViewController (privete)
      
      - (void)thing_rotateWindowIfNeed;
      
      @end
      
    5. Add the global variable to the page controller A that supports the landscape orientation.

      @property (nonatomic, assign) BOOL fullScreen;
      
    6. Add the following method to the class of A:

      - (BOOL)shouldAutorotate {
          return YES;
      }
      
      - (UIInterfaceOrientationMask)supportedInterfaceOrientations {
          if (self.fullScreen) {
              return UIInterfaceOrientationMaskLandscapeRight;
          }
          return UIInterfaceOrientationMaskPortrait;
      }
      
    7. To display the page of A when it is opened, you might deal with the following use cases:

      • Use case 1: The landscape orientation appears immediately after the page is opened. For this purpose, in the method -(void)viewDidload; of the page controller A, set the variable fullScreen to YES, and call [self thing_rotateWindowIfNeed];.

      • Use case 2: The landscape orientation appears after users tap a button on the opened page. For this purpose, add the following code block to the response method of the button:

        - (void)fullScreenAction {
            self.fullScreen = !self.fullScreen;
            [self thing_rotateWindowIfNeed];
        }