iOS 7 and above is supported.
This guide only provides a brief integration description. For more details on the usage, see API Documentation.
pod 'TuisongbaoRealtimeEngine' in Podfile, and then execute pod install.#import <TuisongbaoRealtimeEngine/TuisongbaoRealtimeEngine.h> in Bridging Header.#import <TuisongbaoRealtimeEngine/TuisongbaoRealtimeEngine.h>import TuisongbaoRealtimeEngineTRE for all the classes and enumerations, and prefix kTRE for all the string constants.[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"];
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.
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.
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);
}];
Call disconnect on the connection object:
[connection disconnect];
To restore connection, call connect:
[connection connect];
The Pub/Sub related functions are mainly completed through ChannelManager, which can be obtained through engine.channelManager.
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"];
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");
}];
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.
The Chat related funcionts are mainly completed through engine.chatManager.
[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");
}];
kTREEventChatLoginSucceeded Event is suggested so as to sync up the updates during network disconnection.
For more events, see API Documentation.
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];
[chatManager logoutWithCallback:^(NSError *error) {
if (error) {
NSLog(@"Failed to sign out");
} else {
NSLog(@"Successfully signed out");
}
}];
NSLog(@"The state of the current user %@ is %@", chatManager.user.userId, @(chatManager.state));
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:
unreadMessageCount of the conversation and then update chatManager.totalUnreadMessageCount when there are new messages.lastMessage of each conversation.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.
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];
[conversation loadMessagesWithStartMessageId:nil
endMessage:nil
limit:nil
callback:^(NSArray *messages, NSError *error) {
if (error) {
NSLog(@"Failed to get");
return;
}
NSLog(@"Successfully got");
}];
[conversation resetUnread()];
[conversation deleteWithCallback:^(NSError *error) {
if (error) {
NSLog(@"Failed to delete");
return;
}
NSLog(@"Successfully deleted");
}];
Listen for new messages by binding kTREEventChatNewMessage Event on the TREChatConversation object:
[conversation bind:kTREEventChatNewMessage dataHandler:^(TREChatMessage *message) {
NSLog(@"New message");
}];
TREChatMessageTextContent* content = [[TREChatMessageTextContent alloc] initWithText:@"text message"];
TREChatMessage *message = [conversation sendMessage:content
withProgressCallback:nil
doneCallback:^(NSError *error) {}];
TREChatMessageImageContent *content = [[TREChatMessageImageContent alloc] initWithPath:imageFilePath];
TREChatMessage *message = [conversation sendMessage:content
withProgressCallback:^(float progress) {
// progress used for image upload progress prompt
}
doneCallback:^(NSError *error) {}];
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
}];
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) {}];
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
}];
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 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");
}];
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");
}];
[group loadUsersWithCallback:^(NSArray *users, NSError *error) {
if (error) {
NSLog(@"Failed to get");
return;
}
NSLog(@"Successfully got");
}];
Please refer to API Documentation.
If no special notes, just replacing the SDK would be enough.