Client - iOS - Guide

Before reading this document, please first take a look at Realtime Engine Guide.

iOS Version Compatibility

iOS 7 and above is supported.

API Documentation

This guide only provides a brief integration description. For more details on the usage, see API Documentation.

Installation

  • Add pod 'TuisongbaoRealtimeEngine' in Podfile, and then execute pod install.
  • As for the Swift project, add #import <TuisongbaoRealtimeEngine/TuisongbaoRealtimeEngine.h> in Bridging Header.

Manual Installation

  • Download SDK, and then:
    • Introduce TuisongbaoRealtimeEngine.framework
    • Introduce TuisongbaoRealtimeEngine.framework/TuisongbaoRealtimeEngine.plist. This file should be referenced separately as it is not included automatically when the framework is added.
  • Introduce the following dependencies:
    • libicucore.dylib
    • libz.dylib
    • Qiniu SDK, which is used for upload of multimedia message files in Chat mode.

Preliminaries

  • Introduce SDK in the file header:
    • Objective-C :#import <TuisongbaoRealtimeEngine/TuisongbaoRealtimeEngine.h>
    • Swift :import TuisongbaoRealtimeEngine
  • SDK naming conversions: Use prefix TRE for all the classes and enumerations, and prefix kTRE for all the string constants.
  • Call [TREDebug enable] to turn on debug log, and [TREDebug disable] to turn it off.
  • About TREEventEmitter:

    It has implemented the local Pub/Sub mode based on trigger and bind. For example:

      @interface MyClass : TREEventEmitter
      @end
    
      @implementation MyCalss
      @end
    
      MyClass *myObj = [[MyClass alloc] init];
    
      // Bind event handler
      [myObj bind:@"cool-event" dataHandler:^(NSString *msg) {
          NSLog(@"Message from cool-event: %@", msg);
      }];
    
      // Trigger an event and pass parameters
      [myObj trigger:@"cool-event" data:@"Hello world!"];
    
      // Unbind event handler
      [myObj unbind:@"cool-event"];
    
    Note that this Pub/Sub can only be used on local objects, and the alleged Pub/Sub applilcation mode of the Realtime Engine refers to the remote trigger and subscription based on realtime network connection. After remote events reach the local, use TREEventEmitter to deliver them to the applicaiton, which is as easy as used locally.

    The TREConnection, TREChannel and TREChatManager classes in SDK have all been integrated with TREEventEmitter to provide local or remote event notifications. For more details on specific event names and the parameters that can be received by handlers, see API Documentation.

    Strong references are used inside TREEventEmitter to maintain binding, and bind and unbind should be called in pairs to avoid memory leak. For developers’ convenience, apart from binding block, the binding of the Target-Action mode is also supported. For more details on how to select appropriate interfaces, see API Documentation.

Configure and Establish Connection

Pass various options through the second parameter while instantiating TREEngine.

NSDictionary *options = @{
    // Authenticate user's address
    kTREEngineOptionAuthEndpoint : @"http://yourdomain.com/tuisongbao_engine/auth"
};
TREEngine *engine = [[TREEngine alloc] initWithAppID:@"YOUR_APP_ID" options:options];

Connection will be set up automatically after instantiation, and you can use the TREEngine instance returned for later various operations.

Connection Event

On the engine.connection object, you can listen for the following Events:

  • state_changed: Triggered when the connection state is chaged.
  • connecting_in: Notify how soon the next reconnection will be made.
  • error: Triggered when an error occurs.
[connection bind:kTREEventConnectionStateChanged dataHandler:^(NSDictionary *data) {
    NSLog(@"The connection state is changed from %@ to %@", @(data[@"previous"]), @(data[@"current"]));
}];

[connection bind:kTREEventConnectionConnectingIn dataHandler:^(NSUInteger inTime) {
    NSLog(@"The reconnection will be made in %@ sec", @(inTime));
}];

[connection bind:kTREEventConnectionError dataHandler:^(NSError *error) {
    NSLog(@"Connection error: %@", error);
}];

Disconnect

Call disconnect on the connection object:

[connection disconnect];

To restore connection, call connect:

[connection connect];

Pub/Sub

The Pub/Sub related functions are mainly completed through ChannelManager, which can be obtained through engine.channelManager.

Subscribe Channel

TREChannel *channel = [channelManager subscribe:@"demo"];

Calling the above method will return the TREChannel instance, which can be used for the bind operation to listen for the remote events:

[channel bind:@"cool-event" dataHandler:^(NSString *msg) {
    NSLog(@"The remote messages from demo Channel are received: %@", msg);
}];

Unsubscribe through the unsubscribe method:

[channelManager unsubscribe:@"demo"];

Channel Event

All the Channels can handle the subscription result through listening for the kTREEventChannelSubscriptionSucceededandkTREEventChannelSubscriptionError` Event:

[channel bind:kTREEventChannelSubscriptionSucceeded handler:^{
    NSLog(@"Successfully subscribed ");
}];

[channel bind:kTREEventChannelSubscriptionError dataHandler:^(NSError *error) {
    NSLog(@"Failed to subscribe");
}];

As for Presence Channel and kTREEventChannelSubscriptionSucceeded, the handler will get an extra parameter, i.e., the list of current online users:

[channel bind:kTREEventChannelSubscriptionSucceeded dataHandler:^(NSArray *users) {
    NSLog(@"Subscribed succesfully");
}];

In addition, you can bind the kTREEventPresenceChannelUserAdded and kTREEventPresenceChannelUserRemoved Event on the Presence Channel object to handle notifications of users’ coming online and going offline:

[channel bind:kTREEventPresenceChannelUserAdded dataHandler:^(TREPresenceChannelUser *user) {
    NSLog(@"The user came online");
}];

[channel bind:kTREEventPresenceChannelUserRemoved dataHandler:^(TREPresenceChannelUser *user) {
    NSLog(@"The user went offline");
}];

Chat

The Chat messages can only be received when the application is opened, otherwise, unable to be received normally. If necessary, the Push SDK can offer the offline notification function. Please refer to iOS Push Guide for integration, after which the offline messages will automatically reach users’ mobiles through the Push* service. No additional configuration is required for the realtime engine.

Get ChatManager

The Chat related funcionts are mainly completed through engine.chatManager.

ChatManager Event

[chatManager bind:kTREEventChatLoginSucceeded handler:^{
    NSLog(@"Successfully signed in");
}];

[chatManager bind:kTREEventChatLoginFailed dataHandler:^(NSError *error) {
    NSLog(@"Failed to sign in");
}];

[chatManager bind:kTREEventChatNewMessage dataHandler:^(TREChatMessage *message) {
    NSLog(@"New message");
}];
Note that when the network is not stable, SDK will automatically resign in, and the corresponding Events will be retriggered. That developers refresh the conversation list and so on in the kTREEventChatLoginSucceeded Event is suggested so as to sync up the updates during network disconnection.

For more events, see API Documentation.

Sign In

This operation is asynchronous. Please refer to the above example to listen for the related events to get the result.

NSDictionary *authOptions = @{
    kTREEngineOptionAuthData: @"USER_TOKEN";
};
[chatManager loginWithAuthOptions:authOptions];

Sign out

[chatManager logoutWithCallback:^(NSError *error) {
    if (error) {
        NSLog(@"Failed to sign out");
    } else {
        NSLog(@"Successfully signed out");
    }
}];

Get Current Users and Their Sign-in State

NSLog(@"The state of the current user %@ is %@", chatManager.user.userId, @(chatManager.state));

Get Conversation List

Get the conversation list through chatManager.conversationManager, and filter through conversation type and target:

[conversationManager loadWithType:nil target:nil callback:^(NSArray *conversations, NSError *error) {
    if (error) {
        NSLog(@"Failed to get");
        return;
    }

    NSLog(@"Successfully got");
}];

After calling loadWithType:target:callback:, directly use chatManager.conversations to display the conversation list. The internal mechanism of chatManager contains:

  • Automatically update unreadMessageCount of the conversation and then update chatManager.totalUnreadMessageCount when there are new messages.
  • Automatically maintain lastMessage of each conversation.
  • Automatically sort conversations in descending order and so on according to lastActiveAt. For more details, see API Documentation.

You can get events of list change by listening for kTREEventChatConversationsChanged so as to update UI in due time.

Get TREChatConversation Instance

Developers can call the methods on the TREChatConversation instance to send messages, delete conversations, reset unread messages, and so forth. It can be obtained from the coversation list as mentioned in the above example, or you can acquire a specific conversation through a set of conversationManager.conversationWith* methods:

[conversationManager conversationWithUser:user];
[conversationManager conversationWithGroup:group];
[conversationManager conversationWithMessage:message];
[conversationManager conversationWithType:type target:target];

Get Conversation History

[conversation loadMessagesWithStartMessageId:nil
                                  endMessage:nil
                                       limit:nil
                                    callback:^(NSArray *messages, NSError *error) {
                                        if (error) {
                                            NSLog(@"Failed to get");
                                            return;
                                        }

                                        NSLog(@"Successfully got");
                                    }];

Reset Unread Messages of a Conversation as 0

[conversation resetUnread()];

Delete Conversations

[conversation deleteWithCallback:^(NSError *error) {
    if (error) {
        NSLog(@"Failed to delete");
        return;
    }

    NSLog(@"Successfully deleted");
}];

Listen for New Mesages

Listen for new messages by binding kTREEventChatNewMessage Event on the TREChatConversation object:

[conversation bind:kTREEventChatNewMessage dataHandler:^(TREChatMessage *message) {
    NSLog(@"New message");
}];

Send Text Messages

TREChatMessageTextContent* content = [[TREChatMessageTextContent alloc] initWithText:@"text message"];
TREChatMessage *message = [conversation sendMessage:content
                               withProgressCallback:nil
                                       doneCallback:^(NSError *error) {}];

Send Image Messages

TREChatMessageImageContent *content = [[TREChatMessageImageContent alloc] initWithPath:imageFilePath];
TREChatMessage *message = [conversation sendMessage:content
                               withProgressCallback:^(float progress) {
                                   // progress used for image upload progress prompt
                               }
                                       doneCallback:^(NSError *error) {}];

Send Audio Messages

Recording audios using the helper class provided by SDK is suggested:

TREAudioRecorder *audioRecorder = [TREAudioRecorder sharedInstance];
[audioRecorder startWithMaxDuration:nil
                   progressCallback:^(float progress, float peakPower) {
                       // When specifying maxDuration (the maximum lenght of audio recording), you can prompt the recording progress or remaining time according to progress
                       // peakPower used for making volume prompt of audio recording
                   }
                       doneCallback:^(BOOL isSuccessful, NSString *recordFilePath) {
                           // isSuccessful indicates whether audio recording is successful
                           // recordFilePath is the file path of saving audio recording, which can be directly used for constructing audio message content. See the example below
                       }];
TREChatMessageVoiceContent *content = [[TREChatMessageVoiceContent alloc] initWithPath:voiceFilePath];
TREChatMessage *message = [conversation sendMessage:content
                               withProgressCallback:^(float progress) {
                                   // progress used for audio upload progress prompt
                               }
                                       doneCallback:^(NSError *error) {}];

In addition, there is the helper class for audio playing in SDK to play audio messages easily:

TREAudioPlayer *audioPalyer = [TREAudioPlayer sharedInstance];
[audioPalyer startWithData:voiceData callback:^(BOOL isSuccessful) {
    // isSuccessful indicates whether it's played successfully
}];

Send Video Messages

Given that recording videos is closely linked to UI, this SDK doesn’t provide the helper class temporarily, so developers need to implement it themselves. While recording, use aac encoder for audios and h264 encoder for videos.

TREChatMessageVideoContent *content = [[TREChatMessageVideoContent alloc] initWithPath:voiceFilePath];
TREChatMessage *message = [conversation sendMessage:content
                               withProgressCallback:^(float progress) {
                                   // progress used for video upload progress prompt
                               }
                                       doneCallback:^(NSError *error) {}];

Send Location Data Messages

SDK contains the helper class to make it easy to get the current location:

TRELocationManager *locationManager = [TRELocationManager sharedInstance];
[locationManager currentLocationWithCallback:^(BOOL isSuccessful, CLLocation *location) {
    // isSuccessful indicates whether location is obtained successfully
    // location used for constructing location data message content. See the example below
}];
Note that for iOS 8, to use the requestWhenInUseAuthorization request permission inside TRELocationManager, please configure NSLocationWhenInUseUsageDescription in info.plist. For more details, see Here.
TREChatMessageLocationContent *content =
        [[TREChatMessageLocationContent alloc] initWithLatitude:location.coordinate.latitude
                                                      longitude:location.coordinate.longitude
                                                // Point of interest, if not provided, the server will get it from Baidu Maps
                                                pointOfInterest:nil];
TREChatMessage *message = [conversation sendMessage:content
                               withProgressCallback:nil
                                       doneCallback:^(NSError *error) {}];

Get Group List

Get the group list through chatManager.groupManager and filter according to group ID:

[groupManager loadWithGroupId:nil callback:^(NSArray *groups, NSError *error) {
    if (error) {
        NSLog(@"Failed to get");
        return;
    }

    NSLog(@"Successfully got");
}];

Create Groups

NSDictionary *options = @{
    // Whether a group is public (YES: The request for joining a group from any user will be directly passed without verification; NO: Need the administrator to verify)
    kTREChatGroupOptionIsPublic: @(YES),
    // Except the creator (owner), whether other group users can send invitations to join the group (YES: allowed; NO: not allowed)
    kTREChatGroupOptionUserCanInvite: @(YES)
};
[groupManager createWithUserIds:@[@"USER_ID1", @"USER_ID2"]
                        options:options
                       callback:^(TREChatGroup *group, NSError *error) {
                           if (error) {
                               NSLog(@"Failed to create");
                               return;
                           }

                           NSLog(@"Successfully created");
                       }];

Get Group User List

[group loadUsersWithCallback:^(NSArray *users, NSError *error) {
    if (error) {
        NSLog(@"Failed to get");
        return;
    }

    NSLog(@"Successfully got");
}];

Other APIs

Please refer to API Documentation.

Upgrade Steps

If no special notes, just replacing the SDK would be enough.

v2.0.0 to v2.1.0

  • Replace the SDK
  • Integrate with Chat video messages according to the document

v1.0.0 to v2.0.0

  • Replace the SDK
  • Changes made to most of the APIs. Please adjust accordingly in line with the document
  Back To Top