UI Kit quickstart
Updated
A highly reliable global communication platform where users can chat one-to-one, in groups or in chat rooms.
Instant messaging connects people wherever they are and allows them to communicate with others in real time. Agora offers an open-source Chat UI Kit project on GitHub. With built-in user interfaces for key Chat features, the Agora Chat UI Kit enables you to quickly embed real-time messaging into your app without requiring extra effort on the UI.
For the latest Agora Chat UIKit documentation, refer to the UIKit 2.x Documentation GitHub repository.
Legacy UIkit 1.x documentation
This page shows sample code to add peer-to-peer messaging into your app by using the Agora Chat UI Kit.
Understand the tech
The following figure shows the workflow of how clients send and receive peer-to-peer messages:
Chat UI kit workflow
- Clients retrieve a token from your app server.
- Client A and Client B log in to Agora Chat.
- Client A sends a message to Client B. The message is sent to the Agora Chat server, and the server delivers the message to Client B. When Client B receives the message, the SDK triggers an event. Client B listens for the event and gets the message.
Prerequisites
- Xcode, preferably the latest version.
- A simulator or a physical mobile device running iOS 11.0 or later.
- CocoaPods. Refer to Getting Started with CocoaPods if you have not installed CocoaPods.
Project setup
In order to create the environment necessary to integrate Chat UI Samples into your app, do the following:
-
Create a new project for an iOS app. Make sure you select Storyboard as the Interface.
If you have added any team information, you see the Add account... button. Click it, input your Apple ID, and click Next. Your team information is added to the project.
-
Enable automatic signing for your project.
-
Set the target devices to deploy your iOS app.
-
Add project permissions for microphone and camera usage.
Open info in the project navigation panel, and add the following properties to the Property List:
Key Type Value Privacy - Photo Library Usage DescriptionString For photo library access Privacy - Microphone Usage DescriptionString For microphone access Privacy - Camera Usage DescriptionString For camera access App Transport Security Settings > Allow Arbitrary LoadsBoolean YES -
Integrate the UI Samples into your project.
-
Create a Podfile for your project.
In the Terminal, navigate to the root directory of your Xcode project and run the following command:
pod init -
Add dependencies to the UI Samples in the Podfile.
Open Podfile and replace the content with the following:
platform :ios, '11.0' target 'EaseChatKitExample' do # Pods for EaseChatKitExample pod 'chat-uikit' pod 'Masonry' end
-
-
Install the UI Samples.
In the Terminal, navigate to the root directory of your Xcode project and run the following command:
pod install
The Chat UI Samples is now added into your project.
Implementation
Implement peer-to-peer messaging
This section shows how to use Chat UI Samples to rapidly implement peer-to-peer messaging in your app.
Initialize UI Samples
Follow the steps to initialize the UI Samples.
-
To import the header file, open
SceneDelegate.min Xcode and add the following lines to import the header file:#import #import "AgoraLoginViewController.h" #import -
Initialize the UI Samples by calling the
initWithAgoraChatOptionsmethod. InSceneDelegate.m, replace thewillConnectToSessionmethod with the following code:- (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions { // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). AgoraChatOptions *options = [AgoraChatOptions optionsWithAppkey:@"41117440#383391"]; options.enableConsoleLog = YES; options.usingHttpsOnly = YES; options.enableDeliveryAck = YES; options.isAutoLogin = NO; // Initialize chat-starter-kit [EaseChatKitManager initWithAgoraChatOptions:options]; UIWindowScene *windowScene = (UIWindowScene *)scene; self.window = [[UIWindow alloc] initWithWindowScene:windowScene]; self.window.frame = windowScene.coordinateSpace.bounds; // Go to the login view self.window.rootViewController = [[AgoraLoginViewController alloc]init]; [self.window makeKeyAndVisible]; }
Log into Chat
Take the following steps to log into Chat.
-
In Xcode, go to File > New > File, and create a Cocoa Touch Class file named
AgoraChatHttpRequest. Make sure to set Subclass of asNSObject. Save the file under AgoraChatUIKit. -
Open
AgoraChatHttpRequest.hand replace the code with the following:#import NS_ASSUME_NONNULL_BEGIN @interface AgoraChatHttpRequest : NSObject + (instancetype)sharedManager; - (void)registerToApperServer:(NSString *)uName pwd:(NSString *)pwd completion:(void (^)(NSInteger statusCode, NSString *response))aCompletionBlock; - (void)loginToApperServer:(NSString *)uName pwd:(NSString *)pwd completion:(void (^)(NSInteger statusCode, NSString *response))aCompletionBlock; @end NS_ASSUME_NONNULL_ENDTo register to the Chat app server, open
AgoraChatHttpRequest.mand replace the code with the following:#import "AgoraChatHttpRequest.h" @interface AgoraChatHttpRequest() @property (readonly, nonatomic, strong) NSURLSession *session; @end @implementation AgoraChatHttpRequest + (instancetype)sharedManager { static dispatch_once_t onceToken; static AgoraChatHttpRequest *sharedInstance; dispatch_once(&onceToken, ^{ sharedInstance = [[AgoraChatHttpRequest alloc] init]; }); return sharedInstance; } - (instancetype)init { if (self = [super init]) { NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; configuration.timeoutIntervalForRequest = 120; _session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:[NSOperationQueue mainQueue]]; } return self; } - (void)registerToApperServer:(NSString *)uName pwd:(NSString *)pwd completion:(void (^)(NSInteger statusCode, NSString *aUsername))aCompletionBlock { NSURL *url = [NSURL URLWithString:@"https://a41.chat.agora.io/app/chat/user/register"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; NSMutableDictionary *headerDict = [[NSMutableDictionary alloc]init]; [headerDict setObject:@"application/json" forKey:@"Content-Type"]; request.allHTTPHeaderFields = headerDict; NSMutableDictionary *dict = [[NSMutableDictionary alloc]init]; [dict setObject:uName forKey:@"userAccount"]; [dict setObject:pwd forKey:@"userPassword"]; request.HTTPBody = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *responseData = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : nil; if (aCompletionBlock) { aCompletionBlock(((NSHTTPURLResponse*)response).statusCode, responseData); } }]; [task resume]; } - (void)loginToApperServer:(NSString *)uName pwd:(NSString *)pwd completion:(void (^)(NSInteger statusCode, NSString *response))aCompletionBlock { NSURL *url = [NSURL URLWithString:@"https://a41.chat.agora.io/app/chat/user/login"]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; request.HTTPMethod = @"POST"; NSMutableDictionary *headerDict = [[NSMutableDictionary alloc]init]; [headerDict setObject:@"application/json" forKey:@"Content-Type"]; request.allHTTPHeaderFields = headerDict; NSMutableDictionary *dict = [[NSMutableDictionary alloc]init]; [dict setObject:uName forKey:@"userAccount"]; [dict setObject:pwd forKey:@"userPassword"]; request.HTTPBody = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil]; NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { NSString *responseData = data ? [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding] : nil; if (aCompletionBlock) { aCompletionBlock(((NSHTTPURLResponse*)response).statusCode, responseData); } }]; [task resume]; } - (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential * _Nullable))completionHandler { if([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]){ NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; if(completionHandler) completionHandler(NSURLSessionAuthChallengeUseCredential,credential); } } @end -
Go to File > New > File and create a Cocoa Touch Class file named
AgoraLoginViewController. Make sure to set Subclass of asUIViewController. -
To import the header file, open
AgoraLoginViewController.mand add the following lines:#import "AgoraChatHttpRequest.h" // To send request to the Appserver #import //Chat SDK #import "ViewController.h"To sign up, add the following lines after
@implementation AgoraLoginViewController:// Register to the AppServer - (void)doSignUp { // Set the chat ID as vvv [[AgoraChatHttpRequest sharedManager] registerToApperServer:@"vvv" pwd:@"1" completion:^(NSInteger statusCode, NSString * _Nonnull response) { dispatch_async(dispatch_get_main_queue(),^{ if (response != nil) { NSData *responseData = [response dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *responsedict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; if (responsedict != nil) { NSString *result = [responsedict objectForKey:@"code"]; if ([result isEqualToString:@"RES_OK"]) { // Sign in Chat if registration succeeds [self doSignIn]; } } } }); }]; } - (void)doSignIn { // Sign in AppServer [[AgoraChatHttpRequest sharedManager] loginToApperServer:@"vvv" pwd:@"1" completion:^(NSInteger statusCode, NSString * _Nonnull response) { dispatch_async(dispatch_get_main_queue(), ^{ if (response && response.length > 0 && statusCode) { NSData *responseData = [response dataUsingEncoding:NSUTF8StringEncoding]; NSDictionary *responsedict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:nil]; NSString *token = [responsedict objectForKey:@"accessToken"]; NSString *loginName = [responsedict objectForKey:@"chatUserName"]; if (token && token.length > 0) { // Log into Chat SDK [[AgoraChatClient sharedClient] loginWithUsername:[loginName lowercaseString] agoraToken:token completion:^(NSString *aUsername, AgoraChatError *aError) { if (!aError) { ViewController *chatsVC = [[ViewController alloc] init]; UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:chatsVC]; navigationController.navigationBarHidden = YES; UIWindow *window = [[[UIApplication sharedApplication] windows] lastObject]; window.rootViewController = navigationController; } }]; } } }); }]; }Replace the
viewDidLoadfunction with the following code:- (void)viewDidLoad { [super viewDidLoad]; [self doSignIn]; // Do any additional setup after loading the view. }
Launch the chat storyboard
In this section, add an input box for getting username of the peer user, and a Chat button that loads the chat storyboard.
In ViewController.m, add the following code:
#define kIsBangsScreen ({\
BOOL isBangsScreen = NO; \
if (@available(iOS 11.0, *)) { \
UIWindow *window = [[UIApplication sharedApplication].windows firstObject]; \
isBangsScreen = window.safeAreaInsets.bottom > 0; \
} \
isBangsScreen; \
})
#define AgoraChatVIEWTOPMARGIN (kIsBangsScreen ? 34.f : 0.f)
#import "ViewController.h"
#import
#import
#import
@interface ViewController ()
@property (nonatomic, strong) EaseConversationModel *conversationModel;
@property (nonatomic, strong) AgoraChatConversation *conversation;
@property (nonatomic, strong) EaseChatViewController *chatController;
@property (nonatomic, strong) UITextField *conversationIdField;
@property (nonatomic, strong) UIButton *chatBtn;
@property (nonatomic, strong) UIButton *logoutBtn;
@endIn ViewController.m, replace the viewDidLoad method with the following code:
- (void)viewDidLoad {
[super viewDidLoad];
[self _setupChatSubviews];
}
- (void)viewWillAppear:(BOOL)animated
{
self.navigationController.navigationBarHidden = YES;
}
- (void)_setupChatSubviews
{
self.conversationIdField = [[UITextField alloc] init];
self.conversationIdField.backgroundColor = [UIColor systemGrayColor];
self.conversationIdField.delegate = self;
self.conversationIdField.borderStyle = UITextBorderStyleNone;
NSAttributedString *convAttrStr = [[NSAttributedString alloc] initWithString:@"single chat ID" attributes:@{NSForegroundColorAttributeName:[UIColor whiteColor]}];
self.conversationIdField.attributedPlaceholder = convAttrStr;
self.conversationIdField.font = [UIFont systemFontOfSize:17];
self.conversationIdField.textColor = [UIColor whiteColor];
self.conversationIdField.returnKeyType = UIReturnKeyDone;
self.conversationIdField.layer.cornerRadius = 5;
self.conversationIdField.layer.borderWidth = 1;
self.conversationIdField.layer.borderColor = [UIColor lightGrayColor].CGColor;
[self.view addSubview:self.conversationIdField];
[self.conversationIdField mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(30);
make.top.equalTo(self.view).offset(30 + AgoraChatVIEWTOPMARGIN);
make.height.mas_equalTo(@50);
make.width.mas_equalTo(@320);
}];
self.chatBtn = [[UIButton alloc] init];
self.chatBtn.clipsToBounds = YES;
self.chatBtn.layer.cornerRadius = 5;
self.chatBtn.backgroundColor = [UIColor colorWithRed:((float) 78 / 255.0f) green:0 blue:((float) 234 / 255.0f) alpha:1];
self.chatBtn.titleLabel.font = [UIFont systemFontOfSize:19];
[self.chatBtn setTitle:@"chat" forState:UIControlStateNormal];
[self.chatBtn setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[self.chatBtn addTarget:self action:@selector(chatAction) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.chatBtn];
[self.chatBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.equalTo(self.view).offset(30);
make.top.equalTo(self.conversationIdField.mas_bottom).offset(20);
make.height.mas_equalTo(@50);
make.width.mas_equalTo(@150);
}];
self.logoutBtn = [[UIButton alloc]init];
self.logoutBtn.backgroundColor = [UIColor redColor];
[self.logoutBtn setTitle:@"Log out" forState:UIControlStateNormal];
[self.logoutBtn addTarget:self action:@selector(logout) forControlEvents:UIControlEventTouchUpInside];
[self.view addSubview:self.logoutBtn];
[self.logoutBtn mas_makeConstraints:^(MASConstraintMaker *make) {
make.left.right.bottom.equalTo(self.view);
make.height.equalTo(@50);
}];
self.view.backgroundColor = [UIColor colorWithRed:242/255.0 green:242/255.0 blue:242/255.0 alpha:1.0];
}Add the following code in ViewController.m to create the input box and Chat button:
- (void)chatAction
{
[self.view endEditing:YES];
if (self.conversationIdField.text.length
);
}
}
export default App;-
Set the layout for the conversation.
Open
my-app/src/App.css, and replace the content with the following:/** App.css */ .container { height: 100%; width: 100% }
Test your app
When the app launches, you see the following interface and are logged into Chat.
To test the app, take the following steps:
- Enter the single chat ID. A single chat ID is the user ID of a peer user and for testing purposes, you can simply input
abc. - Click chat. An edit box pops up.
- Enter the message in the edit box and click Enter, the message is sent and displayed in the UI.
- You can also click + on the right of the edit box and try sending attachment messages.
Next steps
Reference
Agora provides the fully featured AgoraChat-ios demo app as an implementation reference.
