In this tutorial we show how to join chat rooms.

 

 Our thanks goes to Matteo Morelli for the development of the Swift version of the sample project.

 

We assume that the developer already owns an account into the ArenaDaemon web platform and

owns the knowledge for creating a new application and retrieving the correspondent appKey.

For more information about how to create a developer account and for setup a new application,

please refer to the chapter "Create an appKey".

 

The chat module provides a set of methods within the SDK that allows players to join rooms

for exchanging textual messages.

 

The number of different rooms is theorically infinite.

A new room is created when the first player decides to join it calling the method

joinRoom:returnPlayersList: of the chatConnector property of the unique BDArenaConnector instance.

 

Said that, we can jump into the code! 

Create a new Xcode project and include the SDK as shown in chapter SDK Installation and setup.

chat_create_controllers 

 

This sample application uses an UITabBarViewController as rootViewController.

Each tabBarItem will represent a different chat room.

 

The second and most important UIViewController is the ChatViewController that will manage

all the actions and the events related to the chat room to which it will be associated with

 

 

Before doing any action with the daemons, the local player needs to be authenticated

so we need to add the following code to the AppDelegate class :

 

 

- (BOOL)application:(UIApplication *)application

        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

 

        .....

        // init BDArenaConnector and register current object to observers

        [BDArenaConnector initializeWithAppKey:@"YOUR_APP_KEY" 

                runInSandboxEnvironment:YES];

        [[BDArenaConnector getInstance] registerEventsObserver:self];

        [[BDArenaConnector getInstance] requestAuth];

        .....

 

        return YES;

}

 

- (void) dealloc{

        // unregister current object from observers

        [[BDArenaConnector getInstance] unregisterEventsObserver:self];

}

 

 

The above chunck of code will mind to perform player authentication in order to enable access to 

chat features.

In this same function, we create the main tabBarController object and

we assign it to the rootViewController:

 

 

- (BOOL)application:(UIApplication *)application

        didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{

 

        .....

        // create tabBarController

        MainTabBarController* mainController = [[MainTabBarController alloc

                        initWithNibName:@"MainTabBarController" bundle:nil];

 

        // allocate 3 chat room view controllers passing room names

        NSArray* roomNames = [NSArray arrayWithObjects:

                @"room 1",

                @"room 2",

                @"room 3",

                @"room 4",

                nil];

 

        // allocate mutable array that later will be passed to the tabBarController

        NSMutableArray* tabBarViewControllers = [[NSMutableArray alloc] init];

 

        //

        for(NSString* roomName in roomNames){

                // allocate the chat controller passing the room name

                ChatRoomViewController* chat = [[ChatRoomViewController alloc]

                        initWithRoomName:roomName];

 

                // add to array

                [tabBarViewControllers addObject:chat];

        }

 

        // set viewControllers

        mainController.viewControllers= tabBarViewControllers;

        self.window.rootViewController= mainController;

 

}

 

 

 

In the MainTabBarController, we add the delegates for retrieving local player's authentication results.

When the local player will be successfully authenticated, we'll connect to the chat module.

When the connection to the chat will be estabilished, we'll loop through ChatViewControllers triggering

the joinRoom call.

 

 

- (void) arenaConnector:(BDArenaConnector*)connector

        authReceivedForLocalPlayerWithData:(BDArenaPlayerData*)playerData

        alreadyMet:(BOOL)alreadyMet

        isOffline:(BOOL)isOffline{

 

        // connect to chat daemon

        [[BDArenaConnectorgetInstance].chatConnector connect];

}

 

- (void) arenaConnector:(BDArenaConnector*)connector

        authFailedForLocalPlayerWithError:(NSError*)error{

        // handle errors

}

 

- (void) arenaChatConnectionEstabilished{

        // trig controllers to join rooms

        for(ChatRoomViewController* chatController in self.viewControllers){

                [chatController joinRoom];

        }

}

 

- (void) arenaChatConnectionFailedWithError:(NSError*)error{

        // handle errors

}

 

- (void) arenaChatConnectionDidClose{

        // handle errors

}

 

 

 

The ChatViewController implements several mechanisms and takes care fill an UITableView

in order to show the messages received from players.

We put the focus on the UITextField used by the local player to send messages to the chat room

and on the BDArenaConnector delegates that inform about the events that occur during a chat session.

 

First of all, the ChatViewController allocates a NSMutableArray (called conversationsArray) and uses it

to store the messages received into the chat room (both from remote players and sent by the local player).

conversationArray represents the data model for the UITableView.

 

Starting from the local player events, we implement the UITextFieldDelegate methods as follow:

 

 

- (BOOL)textFieldShouldReturn:(UITextField *)textField{

    

        if([textField.text length] > 0){

                [self sendMessageInRoom:textField.text];

        }

    

        // reset text field

        textField.text  = @"";

        return YES;

}

 

- (BOOL)textFieldShouldBeginEditing:(UITextField *)textField{

        ....

        return YES;

 

}

 

 

 

The sendMessageInRoom: method sends the message in room and adds the sent message to the conversationArray associating it with the local player's information:

 

 

 

- (void) sendMessageInRoom:(NSString*)message{

 

        // send message in room

        [[BDArenaConnector getInstance].chatConnector 

                sendMessage:message inRoom:theRoomName];

 

        // store the message into conversationArray

        NSDictionary* item = [[NSDictionary alloc] initWithObjectsAndKeys:

 

                message,                                                                               

                                                                      @"message",

                [[BDArenaConnector getInstance] getLocalPlayerData].nickname,

                                                                      @"nickname",

                [[BDArenaConnector getInstance] getLocalPlayerData].avatarImageThumbUrl,

                                                                      @"avatarUrl",

                nil];

 

                [conversationArray insertObject:item atIndex:0];

 

        ... 

}

 

 

 

For the management of the events generated by remote players, we implement the following

BDArenaChatConnectorDelegate methods:

 

 

 

- (void) arenaChat:(BDArenaChatConnector*)connector

         roomJoined:(NSString*)roomName

 numberOfPlayers:(NSInteger)numberOfPlayers

          playersList:(NSArray*)players{

 

        if([[roomName lowercaseString] isEqualToString:[theRoomName lowercaseString]]){

                // do your stuff for the room managed by this controller

        }

}

 

- (void) arenaChat:(BDArenaChatConnector*)connector

                player:(BDArenaPlayerData*)playerData

         joinedRoom:(NSString*)roomName{

 

        if([[roomName lowercaseString] isEqualToString:[theRoomName lowercaseString]]){

                // do your stuff for the room managed by this controller

        }

}

 

 

- (void) arenaChat:(BDArenaChatConnector*)connector

                player:(BDArenaPlayerData*)playerData

            leftRoom:(NSString*)roomName{

 

        if([[roomName lowercaseString] isEqualToString:[theRoomName lowercaseString]]){

                // do your stuff for the room managed by this controller

        }

}

 

- (void) arenaChat:(BDArenaChatConnector*)connector

newMessageReceived:(NSString*)message

              inRoom:(NSString*)roomName

         fromPlayer:(BDArenaPlayerData*)playerData{

 

        if([[roomName lowercaseString] isEqualToString:[theRoomName lowercaseString]]){

 

                NSDictionary* item= [[NSDictionary allocinitWithObjectsAndKeys:

                                message,                                                @"message",

                                playerData.nickname,                               @"nickname",

                                playerData.avatarImageThumbUrl,              @"avatarUrl",

                nil];

 

                [conversationArrayinsertObject:item atIndex:0];

 

                ...

        }

}

 

 

IMPORTANT : in each method of the protocol we have implemented

if([[roomName lowercaseString] isEqualToString:[theRoomName lowercaseString]])

instruction.

This because each ChatViewController allocated for rooms management registers itself

as observer of the SDK's events and, therefore, will receive events related to every room joined

by the local player.

In order to filter events and ensure that each ChatViewController will process only

the events related to the chat room it is associated with, we store the room name

in an instance variable (theRoomName) and we use it as filter when some event occurs.

 

The application looks like follows:

tutorial_chat_app 


 

 

Sample project

Download the sample project for this tutorial [Objective-C | Swift].

Download the sample project with players restrictions management (BAN) [Objective-C].