中文简体    English


iOS App SDK Quick Integration

This chapter mainly introduces how to quickly integrate the SDK into the project, compile it successfully, and display the real-time live screen on the APP.

AppSDK Click to download

Ready to work

  • Xcode

  • iOS App SDK files

    The files included in the iOS App SDK file

    IvyConstants.h
    IvyIoDef.h
    IvyCamera.h
    IvyObject.h
    IvyPlayer.h
    IvySDPlayer.h
    IvySDDownloader.h
    IvyVoicePlayer.h
    IvySdkManager.h
    libIvySdk.a

Integrate iOS App SDK

create project

project configuration

Add SDK to project

Add dependency library

Link Binary With Libraries, new libc++.1.tbd library

Set Bitcode

Set Bitcode to NO

Initialize SDK

Introduce header files to initialize SDK

Adapt to iOS version

Beginning with iOS 14, the “Local Network” permission pop-up window will be triggered when the device is configured and controlled locally on the local area network. After the user clicks Allow, the app can send data to the local area network. If the user clicks Deny, the relevant function will not be available. At present, Apple does not provide any API to judge this permission. It is recommended that developers prompt and guide users to check “System Settings - App Settings” when the relevant functions cannot be used normally to confirm whether the “Local Network” permission is enabled.

Initialization

Initialize the SDK

Initialize the App Sdk through the initializer method in IvySdkManager.

[[IvySdkManager shared] initializer];

Set the P2P server region through the setP2PRegion method in IvySdkManager.

[[IvySdkManager shared] setP2PRegion:1];

*Note: The use does not distinguish between domestic and foreign UIDs, and the P2P server address needs to be set, which can be set according to the country where the user is located. By default, the non-Chinese P2P server is used. *

Distribution network

QR code distribution network

Generate a QR code string for network configuration through the qrCodeString:password:deviceUID:bindingToken method in IvySdkManager.

NSString *qrCodeString = [[IvySdkManager shared] qrCodeString:SSID password:password deviceUID:deviceUID bindingToken:bindingToken];

Use this string to generate a QR code image. Align the QR code with the IPC device in the network configuration state, and the device will automatically configure the network after successfully recognizing the QR code information.

*Note: You can use the local area network search function to regularly detect whether the device is successfully connected to the network. *

Sonic distribution network

Through the IvyVoicePlayer class, the sound wave distribution network is performed.

_voicePlayer = [[IvyVoicePlayer alloc] initWithSSID:SSID password:password deviceUID:deviceUID];
_voicePlayer.delegate = self;

[_voicePlayer play]; // start playing sound waves

Play sound waves with a voicePlayer object. The IPC device in the network configuration state will automatically configure the network after it is successful.

The playback result of the sound wave distribution network can be obtained through the proxy IvyVoicePlayerDelegate. To leave the configuration page, you need to stop calling the stop method to stop playback.

*Note: You can use the local area network search function to regularly detect whether the device is successfully connected to the network. *

LAN Search

Use the searchDevices: method in IvySdkManager to search for devices in the local area network.

[[IvySdkManager shared] searchDevices:^(NSArray<IvyDevLan *> * _Nonnull devices) {

}];

It can be compared with the deviceUID of the network device through the uid property in IvyDevLan.

Create IvyCamera object

NSString *deviceUID = kDeviceUID;
NSString *username = kUsername;
NSString *password = kPassword;
IvyCamera *obj = [[IvyCamera alloc] initWithDeviceUID:deviceUID username:username password:password];

deviceUID: UID of the device, usually a 24-bit string, such as: ZSZ77RNGE3821F2WZZZZBY2Z

username: User name, the factory user name is admin by default

password: User password, the factory user password needs to be obtained by calling the following method

[[IvySdkManager shared] resetPasswordByDeviceUID:deviceUID];

*Note: Only one IvyCamera object is created for a device, and the IvyCamera object is recommended to be saved as a global object. In the case of a non-global object, the connection is automatically released when the object is released. *

Login device

After the IvyCamera object is created, you can call the loginCamera method to log in to the device

[obj loginCamera:^(IVYIO_HANDLE_STATE handleState, IVYIO_RESULT cmdResult) {
    NSLog(@"... loginCamera handleState:%@ cmdResult:%@", @(handleState), @(cmdResult));
}];

Note: The loginCamera: method only needs to judge the current state of the device through the handleState result.

Process login result

  1. The handleState is IVYIO_HANDLE_STATE_ONLINE, indicating that the device has been successfully logged in, and subsequent operations can be performed.

  2. The handleState is IVYIO_HANDLE_STATE_ON_RESET, indicating that the device is in the factory state, and the user name and password of the device need to be changed forcibly before subsequent operations.

[obj modifyUserNameAndPassword:username newPassword:password onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {
  if (cmdResult == IVYIO_RESULT_OK) {
      NSLog(@"...success");
  } else {
      NSLog(@"...failed");
  }
}];
  1. The handleState is IVYIO_HANDLE_STATE_USR_OR_PWD_ERR, indicating that the username or password used to create the IvyCamera object is incorrect. Using the correct username and password, call the following method to update the device information, [obj updateUsername:username password:password];. Log in to the device again after success, and process the login result.

  2. The handleState is IVYIO_HANDLE_STATE_MAX_USERS, indicating that the device exceeds the maximum number of users.

  3. The handleState is IVYIO_HANDLE_STATE_LOCKED, indicating that the device is automatically locked because the user name and password are incorrectly logged in the device several times within a short period of time. After a few minutes, try to log in to the device again.

Get device information

After logging in to the device successfully, you can obtain the relevant information of the device.

Get device information

The IvyDevInfo object contains information such as the firmware version of the device.

[self.ivyCamera getDevInfo:^(IvyDevInfo * _Nonnull devInfo, IVYIO_RESULT cmdResult) {
    if (cmdResult == IVYIO_RESULT_OK) {

    } else {

    }
}];

Get device capability set

Through the IvyDevAbility object, you can determine the capabilities supported by the device.

[self.ivyCamera getDevAbility:^(IvyDevAbility * _Nonnull devAbility, IVYIO_RESULT cmdResult) {
    if (cmdResult == IVYIO_RESULT_OK) {

    } else {

    }
}];

live streaming

After creating the IvyPlayer object, you need to implement the object’s IvyPlayerDelegate proxy method to accept the real-time data obtained by the live broadcast. Implement the corresponding callback method according to the decodeType of the decoded data during playback.

Start playing

Return according to the agent, and show the live screen.

[self.ivyPlayer playLive:self.ivyCamera decodeType:IvyVideoDecodeUIImage];

decodeType: Video data format type.

select IvyVideoDecodeUIImage for decodeType and implement the following proxy methods

- (void)ivyPlayer:(IvyPlayer *)ivyPlayer didReciveFrame:(UIImage *)image isFirstFrame:(BOOL)isFirstFrame;

Otherwise, the following proxy methods need to be implemented

- (void)ivyPlayer:(IvyPlayer *)ivyPlayer didReciveIVYFrame:(IVYIO_FRAME *)frame isFirstFrame:(BOOL)isFirstFrame;

*Note: IvyVideoDecodeUIImage is usually selected as decodeType. *

Stop play

[self.ivyPlayer stop];

*Note: Generally, call * in - (void)viewWillDisappear:(BOOL)animated.

monitoring

Set by the validAudio property.

@property (nonatomic, assign) BOOL validAudio;

The result of the IvyPlayerOpenAudio command can be judged by returning ivyPlayer:playerCommand:result.

*Note: It is recommended to set the listening state after playLive:decodeType:. *

Intercom

open intercom

- (void)startTalk;

Turn off the intercom

- (void)endTalk;

The result of IvyPlayerOpenTalk and IvyPlayerCloseTalk commands can be judged by returning ivyPlayer:playerCommand:result.

Capture

Directly save the current live screen content.

Video

Call the following method to record the current live video.

- (void)startRecord:(NSString *)filepath onCompletion:(IvyCameraResultBlock)resultBlock;

*Note: When the monitoring is turned off, the recording will have no sound. *

Night vision mode toggle

- (void)setDayNightConfig:(BOOL)onoff mode:(NSInteger)mode onCompletion:(IvyCameraResultBlock)resultBlock;

mode: IR light mode (0: Auto 1: Manual 2: Schedule)

onoff: IR light switch (only effective in manual mode)

In manual mode, turn on the night vision infrared light

[self.ivyCamera setDayNightConfig:YES mode:2 onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {
    if (cmdResult == IVYIO_RESULT_OK) {

    } else {

    }
}];

Sharpness toggle

Get the resolution supported by the device

[self.ivyCamera getSupportedStreamTypes:^(NSArray * _Nonnull types, IVYIO_RESULT cmdResult) {

}];

types: refer to IvyDefinitionType definition

Get current resolution

[self.ivyCamera getStreamType:^(IvyDefinitionType streamType, IVYIO_RESULT cmdResult) {
}];

set sharpness

IvyDefinitionType type = IvyDefinitionHD;
[self.ivyCamera setStreamType:type onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {
    if (cmdResult == IVYIO_RESULT_OK) {

    } else {

    }
}];

PTZ

turn up

IVY_PTZ_CMD ptzCmd = IVY_PTZ_MOVE_UP;
[self.ivyCamera setPTZCmd:ptzCmd onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {}];

zoom

IVY_PTZ_CMD ptzCmd = IVY_PTZ_ZOOM_IN;
[self.ivyCamera setPTZCmd:ptzCmd onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {}];

focus

IVY_PTZ_CMD ptzCmd = IVY_PTZ_FOCUS_NEAR;
[self.ivyCamera setPTZCmd:ptzCmd onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {}];

Note: After operating PTZ, you need to call IVY_PTZ_STOP to stop.

Live code example

//
//ViewController.m
// Demo
//
// Created by JackChan on 10/5/2021.
// Copyright © 2021 JackChan. All rights reserved.
//

#import "ViewController.h"
#import "IvyCamera.h"
#import "IvyPlayer.h"
#import "IvySdkManager.h"

#define kDeviceUID @"DN5K12U4AB3BD3821111ABZZZ"
#define kUsername @"a"
#define kPassword @"abc123"

@interface ViewController() <IvyPlayerDelegate>

@property (nonatomic, strong) IvyCamera *ivyCamera;

@property (nonatomic, strong) IvyPlayer *ivyPlayer;

@property (nonatomic, strong) UIImageView *imageView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.

    NSString *deviceUID = kDeviceUID;
    NSString *username = @"admin";
    NSString *password = [[IvySdkManager shared] resetPasswordByDeviceUID:deviceUID];

    _ivyCamera = [[IvyCamera alloc] initWithDeviceUID:deviceUID username:username password:password];

    [self.view addSubview:self.imageView];
    self.imageView.frame = CGRectMake(0, CGRectGetHeight(self.view.frame) * 0.3, CGRectGetWidth(self.view.frame), CGRectGetWidth(self.view.frame) * 9 / 16.f);
}

- (void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];

    [self loginCamera];
}

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    [self.ivyPlayer stop];
}

#pragma mark - Private Methods
- (void)loginCamera {
    __weak typeof(self) weakSelf = self;

    [self.ivyCamera loginCamera:^(IVYIO_HANDLE_STATE handleState, IVYIO_RESULT cmdResult) {
        NSLog(@"... loginCamera End handleState:%@ cmdResult:%@", @(handleState), @(cmdResult));

        switch(handleState) {
            case IVYIO_HANDLE_STATE_ONLINE: {
                [weakSelf playLive];
            }
                break;

            case IVYIO_HANDLE_STATE_ON_RESET: {
                [weakSelf modifyAccount];
            }
                break;

            default:
                break;
        }
    }];
}

- (void)playLive {
    [self.ivyPlayer playLive:self.ivyCamera decodeType:IvyVideoDecodeUIImage];
}

- (void)modifyAccount {
    __weak typeof(self) weakSelf = self;

    [self.ivyCamera modifyUserNameAndPassword:kUsername newPassword:kPassword onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {
        if (IVYIO_RESULT_OK == cmdResult) {
            [weakSelf loginCamera];
        }
    }];
}

#pragma mark - IvyPlayerDelegate
- (void)ivyPlayer:(IvyPlayer *)ivyPlayer didReciveFrame:(UIImage *)image isFirstFrame:(BOOL)isFirstFrame {
    self.imageView.image = image;
    if (isFirstFrame) {

    }
}

- (void)ivyPlayer:(IvyPlayer *)ivyPlayer playerCommand:(IvyPlayerCommand)command result:(IVYIO_RESULT)result {
    NSLog(@"... command:%@ result:%@", @(command), @(result));
}

#pragma mark - Getter && Setter
- (IvyPlayer *)ivyPlayer {
    if (!_ivyPlayer) {
        _ivyPlayer = [IvyPlayer new];
        _ivyPlayer.delegate = self;
    }
    return _ivyPlayer;
}

- (UIImageView *)imageView {
    if (!_imageView) {
        _imageView = [UIImageView new];
        _imageView.backgroundColor = [UIColor colorWithWhite:0 alpha:0.1];
    }
    return _imageView;
}

@end

Live example effect

SD card

Search SD card recording list

How to search SD card recording list

- (void)getSDCardRecordList:(NSUInteger)startTime endTime:(NSUInteger)endTime recordType:(NSInteger)recordType onCompletion:(IvyCameraResultBlock)resultBlock;

startTime: start time

endTime: end time

recordType: record type

Search for all SD card recording examples of the current day:

NSInteger year, month, day;
NSInteger recordType = 2;

{
    NSDate *date = [NSDate date];
    NSCalendar *calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
    calendar.timeZone = [NSTimeZone timeZoneWithName:@"UTC"];
    NSDateComponents *components = [calendar components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:date];

    year = components.year;
    month = components.month;
    day = components.day;
}

NSDateComponents *components = [[NSDateComponents alloc] init];

components.year = year;
components.month = month;
components.day = day;
components.minute = 0;
components.second = 0;

NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [calendar dateFromComponents:components];

NSUInteger st = (unsigned int)[date timeIntervalSince1970];
NSUInteger et = st + 24 * 3600 - 1;

[self.ivyCamera getSDCardRecordList:st endTime:et recordType:recordType onCompletion:^(id _Nullable obj, IVYIO_RESULT cmdResult) {

    if (IVYIO_RESULT_OK == cmdResult) {
        NSArray *records = obj;

    } else {

    }
}];

Note: You can also load the SD card recording list by paging, see the following method.

- (void)getSDCardRecordList:(NSUInteger)startTime endTime:(NSUInteger)endTime recordType:(NSInteger)recordType startNo:(NSInteger)startNo onCompletion:(void(^)(IvyRecordList *recordList, IVYIO_RESULT cmdResult))resultBlock;

Play SD card video

Create SD card player

@property (nonatomic, strong) IvySDPlayer *player;

- (IvySDPlayer *)player {
    if (!_player) {
        _player = [IvySDPlayer new];
        _player.delegate = self;
        _player.validAudio = YES;
    }
    return _player;
}

Implement SD card player proxy IvySDPlayerDelegate

#pragma mark - IvySDPlayerDelegate

- (void)ivySDPlayer:(IvySDPlayer *)player didReciveFrame:(UIImage *)image isFirstFrame:(BOOL)isFirstFrame {
    self.imageView.image = image;
    if (isFirstFrame) {

    }
}

- (void)ivySDPlayer:(IvySDPlayer *)player playerCommand:(IvyPlayerCommand)command result:(IVYIO_RESULT)result {
    NSLog(@"... command:%@ result:%@", @(command), @(result));
    _command = command; // save state
    switch (command) {
        case IvyPlayerOpenVideo: {

        }
            break;

        case IvyPlayerFinished:
        case IvyPlayerStopped: {
            dispatch_async(dispatch_get_main_queue(), ^{
                self.imageView.image = nil;
            });

            if (_nextObject) {
                [self playBack:_nextObject];
                _nextObject = nil;
            }
        }
            break;

        default:
            break;
    }
}

Play the objects in the incoming video list

id<IvyRecordObject> obj = self.records.firstObject;
[self.player playBack:self.ivyCamera recordObject:obj decodeType:IvyVideoDecodeUIImage];

Get SD card information

It can obtain information such as whether there is an SD card and the capacity of the SD card.

[self.ivyCamera getSDCardInfo:^(IvySDInfo * _Nonnull ivySDInfo, IVYIO_RESULT cmdResult) {
    if (1 == ivySDInfo.isExist) {

    } else {

    }
}];

Format SD card

[self.ivyCamera setSDCardFormat:^(id _Nullable obj, IVYIO_RESULT cmdResult) {}];

Note: sdFormatError is not 0 and freeSpace and totalSpace are 0, indicating that formatting is required. The timeout for this interface is 120 seconds

文档更新时间: 2023-07-20 19:31   作者:庄小婵