<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sendbird Devs</title>
    <description>The latest articles on DEV Community by Sendbird Devs (@sendbird_devs).</description>
    <link>https://dev.to/sendbird_devs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F749325%2Fa959ffae-9ee1-4efb-a537-32f4df63f3a3.jpg</url>
      <title>DEV Community: Sendbird Devs</title>
      <link>https://dev.to/sendbird_devs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sendbird_devs"/>
    <language>en</language>
    <item>
      <title>SwiftUI vs. UIKit: What is the best choice for building an iOS user interface in 2024?</title>
      <dc:creator>Sendbird Devs</dc:creator>
      <pubDate>Sat, 10 Feb 2024 00:44:48 +0000</pubDate>
      <link>https://dev.to/sendbird/swiftui-vs-uikit-what-is-the-best-choice-for-building-an-ios-user-interface-in-2024-6dc</link>
      <guid>https://dev.to/sendbird/swiftui-vs-uikit-what-is-the-best-choice-for-building-an-ios-user-interface-in-2024-6dc</guid>
      <description>&lt;h2&gt;
  
  
  SwiftUI vs. UIkit: What you need to know
&lt;/h2&gt;

&lt;p&gt;As an iOS engineer, you've likely encountered &lt;a href="https://developer.apple.com/xcode/swiftui/" rel="noopener noreferrer"&gt;SwiftUI&lt;/a&gt; and &lt;a href="https://getuikit.com/" rel="noopener noreferrer"&gt;UIkit&lt;/a&gt;, two popular tools for building iOS user interfaces. SwiftUI is the new cool kid on the block, providing a clean way to build iOS screens, while UIkit is the older and more traditional way to build screens for iOS. SwiftUI uses a declarative style where you describe how the UI should look, similar to Jetpack Compose in Android. UIkit, on the other hand, uses a drag-and-drop development style, which is relatively similar to Android XML.&lt;/p&gt;

&lt;p&gt;So, if either tool can get the job done, do you have to be concerned about choosing SwiftUI vs. UIkit?&lt;/p&gt;

&lt;p&gt;The short answer is yes. Your biggest concern is the iOS versions you'd like to support: SwiftUI only supports iOS 13 and later. If you intend to support lower versions, you're limited to UIkit. But that's not the only factor you should consider before committing to SwiftUI vs. UIkit.&lt;/p&gt;

&lt;p&gt;Let's look into a comparison of SwiftUI vs. UIkit so you can choose the optimal framework for your application. Here's an overview of the differences:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Framework-feature-comparison-of-Swift-and-UIkit.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Framework-feature-comparison-of-Swift-and-UIkit.png" alt="Framework comparison table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;An overview of SwiftUI vs. UIkit&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  UIkit: The traditional approach for building iOS user interface elements
&lt;/h2&gt;

&lt;p&gt;Let's start with UIkit. It's the oldest UI framework, but it's matured a lot along the way.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/documentation/uikit" rel="noopener noreferrer"&gt;UIkit&lt;/a&gt; was launched in 2008 to provide pre-built components for developers to handle inputs, touch events, and other user interactions on iOS apps. It was built with &lt;a href="https://sendbird.com/developer/tutorials/swift-vs-objective-c" rel="noopener noreferrer"&gt;Objective-C&lt;/a&gt;, an improvement of the C programming language, that adds support for object-oriented programming.&lt;/p&gt;

&lt;p&gt;UIkit was initially designed to build a UI for the iPhone's small touch-based screens, but it has evolved to support various devices over the years, including tvOS apps. UIkit has added numerous features over time, like auto layout, dynamic types, collection views, and drag-and-drop functionality, to make it a more powerful and user-friendly framework.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key components and design patterns
&lt;/h3&gt;

&lt;p&gt;To build high-quality and responsive user interfaces for their iOS apps, developers can utilize UIkit's wide range of UI components while following certain design patterns, as you will see below:&lt;/p&gt;

&lt;h4&gt;
  
  
  View controllers
&lt;/h4&gt;

&lt;p&gt;As the name suggests, view controllers are objects used to manage UI views by responding to user input. They handle events such as button taps, gestures, and passing data to the views. They also act as an intermediary between the app's data model and the views, as well as coordinating with other objects in the app.&lt;/p&gt;

&lt;p&gt;Here's an example of an Objective-C skeleton view controller:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Interface Builder and storyboards
&lt;/h4&gt;

&lt;p&gt;Interface Builder is a visual editor embedded into &lt;a href="https://developer.apple.com/xcode/" rel="noopener noreferrer"&gt;Xcode&lt;/a&gt; (an IDE for Apple platforms) used to create and design user interfaces for iOS apps. Storyboards are visual representations of the app's user interface, representing the screens, their order, and the transitions between them. In simpler words, Interface Builder refers to the part of Xcode that lets you view and edit storyboards, which are a collection of views and screens.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Storyboards-and-Interface-Builder.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Storyboards-and-Interface-Builder.png" alt="Storyboards and Interface Builder"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Storyboards and Interface Builder&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Delegates and data sources
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;Delegates and data sources&lt;/em&gt; is a common design pattern in UIkit for iOS app development. It entails having a data source---an object responsible for providing the data displayed in a view---and a delegate---an object responsible for handling events or actions occurring in a view.&lt;/p&gt;

&lt;h3&gt;
  
  
  3 advantages of UIkit
&lt;/h3&gt;

&lt;p&gt;The traditional approach, UIkit, has been the go-to framework for iOS developers for a long while. Its continued popularity is due to quite a few factors.&lt;/p&gt;

&lt;h4&gt;
  
  
  A mature and stable framework
&lt;/h4&gt;

&lt;p&gt;UIkit has been around since iPhoneOS 2.0, so it has had a huge head start. It has also managed to evolve well over the years, with integrations with other iOS core frameworks for graphics and animations. These steady, gradual improvements have led to a stable and reliable framework.&lt;/p&gt;

&lt;h4&gt;
  
  
  A wide range of UI components
&lt;/h4&gt;

&lt;p&gt;UIkit has gained a robust set of pre-built UI components---think of buttons, search bars, and tables---that solve most challenges developers face when building iOS UIs. This limits the need to create custom UI design elements. Most of them are simply already present.&lt;/p&gt;

&lt;h4&gt;
  
  
  Extensive documentation and community support
&lt;/h4&gt;

&lt;p&gt;UIkit's widespread adoption and its long existence have seen it gain a large and active &lt;a href="https://stackoverflow.com/questions/tagged/uikit" rel="noopener noreferrer"&gt;community of developers&lt;/a&gt;. The documentation and resources available to you are considerable, beginning with &lt;a href="https://developer.apple.com/documentation/uikit/" rel="noopener noreferrer"&gt;Apple's official documentation&lt;/a&gt; and going beyond to YouTube tutorials and other blogs.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 disadvantages of UIkit
&lt;/h3&gt;

&lt;p&gt;Still, nothing is perfect. While UIkit has been a reliable workhorse in iOS development for a long time, there are still some drawbacks to consider.&lt;/p&gt;

&lt;h4&gt;
  
  
  Verbose code
&lt;/h4&gt;

&lt;p&gt;As your app becomes more complex, the UIkit code that controls and manages the views can be harder to maintain. The more screens in your app, the harder it is to manage the app state and control flow without overusing the view controllers.&lt;/p&gt;

&lt;p&gt;However, proper code modularization and organization can help you avoid this pitfall and develop less buggy code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lack of built-in support for modern design patterns
&lt;/h4&gt;

&lt;p&gt;Modern design patterns like reactive programming and dependency injection aren't natively supported in UIkit. Developers must come up with custom solutions or depend on third-party libraries for design elements like these that are common and even expected for modern apps.&lt;/p&gt;

&lt;h2&gt;
  
  
  SwiftUI: The modern approach for iOS user interface elements
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/xcode/swiftui/" rel="noopener noreferrer"&gt;SwiftUI&lt;/a&gt; is a more recent framework built by Apple, released in 2019 with version 13 of the iOS SDK. It's particularly attractive for developers who want to create beautiful and responsive UIs in a declarative way. It's built on top of the Swift programming language and is intended for building UIs for applications across Apple's ecosystem, including iOS, macOS, tvOS, and watchOS.&lt;/p&gt;

&lt;p&gt;Because SwiftUI adopts more modern programming paradigms, such as declarative syntax, you can use simple and intuitive code syntax to define the UI without having to worry about the underlying implementation details. The framework automatically takes care of how a view should be rendered and how actions related to it can be triggered.&lt;/p&gt;

&lt;p&gt;SwiftUI is also more reactive---developers can implement UIs that automatically update when the underlying data changes without additional boilerplate code. You can add &lt;em&gt;modifiers&lt;/em&gt;, or properties, to views to change appearance and behavior when certain conditions occur.&lt;/p&gt;

&lt;p&gt;With its wide range of built-in views and layouts, SwiftUI simplifies the creation of adaptive and responsive interfaces for all devices on Apple platforms.&lt;/p&gt;

&lt;h3&gt;
  
  
  Key components and design patterns
&lt;/h3&gt;

&lt;p&gt;SwiftUI boasts a modern framework designed to make the life of an iOS developer smooth. Let's go over some key components that harness powerful features like closures, optionals, and type safety.&lt;/p&gt;

&lt;h4&gt;
  
  
  Declarative syntax
&lt;/h4&gt;

&lt;p&gt;With declarative syntax, you can describe the desired outcome of a UI rather than the specific steps for achieving it. The framework handles all the necessary actions and implementation details that your view requires, leaving you to only worry about its appearance.&lt;/p&gt;

&lt;p&gt;Have a look at the following code that displays an image and text in a column:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  State and data binding
&lt;/h4&gt;

&lt;p&gt;&lt;em&gt;State&lt;/em&gt; is a property wrapper used to store values that can change over time and whose changes need to be reflected in the UI. &lt;em&gt;Data binding&lt;/em&gt; is a method for connecting two pieces of data so that changes to one are automatically reflected in the other.&lt;/p&gt;

&lt;p&gt;Together, these powerful concepts greatly improve SwiftUI's state and data management, automatically handling storage, observation, and synchronization. This enables SwiftUI to perform automatic UI updates and keep itself reactive.&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;Binding&lt;/code&gt; property on SwiftUI and the &lt;code&gt;$&lt;/code&gt; prefix on the state variable to bind, you can easily achieve this as shown below:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h4&gt;
  
  
  Previews and live editing
&lt;/h4&gt;

&lt;p&gt;You can see changes in your app's UI in real-time as you write and modify code, thanks to SwiftUI's previews and live editing features. You don't have to run your app on an emulator or a device to see a live rendering of your UI code. This makes the development process faster and more efficient.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Previews-and-live-editing-in-XCode.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Previews-and-live-editing-in-XCode.png" alt="Previews and live editing in XCode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Previews and live editing in XCode&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  3 advantages of SwiftUI
&lt;/h3&gt;

&lt;p&gt;SwiftUI boasts a lot of features that an iOS developer wouldn't want to be without. Let's take a look at a few of the heavy hitters.&lt;/p&gt;

&lt;h4&gt;
  
  
  Simplified code and easier maintenance
&lt;/h4&gt;

&lt;p&gt;SwiftUI's declarative syntax and reactive model simplify the code needed to build responsive UIs. Since you only need to define the UI and not the implementation details, the amount of code you have to write is minimal and has an intuitive syntax.&lt;/p&gt;

&lt;p&gt;Don't forget, as already mentioned, SwiftUI handles updates on data changes automatically. That's even less code that you have to write and maintain.&lt;/p&gt;

&lt;h4&gt;
  
  
  Improved design-to-code workflow
&lt;/h4&gt;

&lt;p&gt;With preview and live editing features, there's no disconnect between the code you write and the appearance of your UI. You can validate your output in real time. SwiftUI's pre-built components make it easier and faster to implement design into code, providing a more integrated and seamless design-to-code workflow.&lt;/p&gt;

&lt;h4&gt;
  
  
  Automatic support for dark mode and accessibility
&lt;/h4&gt;

&lt;p&gt;Using SwiftUI's &lt;code&gt;colorScheme&lt;/code&gt; property, you can easily switch between light and dark colors on your app's UI. SwiftUI automatically handles the underlying heavy lifting to bring out your desired result. Remember SwiftUI's modifiers that we mentioned earlier? Don't forget that you can use those to alter the appearance of views or add more properties to ease the accessibility of the UI.&lt;/p&gt;

&lt;h3&gt;
  
  
  2 disadvantages of SwiftUI
&lt;/h3&gt;

&lt;p&gt;Even though SwiftUI is a modern framework with features that lend themselves to simple, up-to-date design, it still has a few drawbacks you should consider.&lt;/p&gt;

&lt;h4&gt;
  
  
  Limited compatibility with older iOS versions
&lt;/h4&gt;

&lt;p&gt;SwiftUI was introduced in iOS 13. It can't be used on devices running iOS 12 or earlier. That's not an insignificant concern for developers targeting older iOS versions.&lt;/p&gt;

&lt;p&gt;Fortunately, SwiftUI can still be used alongside UIkit. Using both frameworks, developers can continue supporting older versions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Less mature framework with fewer UI components
&lt;/h4&gt;

&lt;p&gt;Developers who need advanced UI components should check carefully that SwiftUI has everything they need. Even though the framework is being actively improved with new components, it's still far behind UIkit.&lt;/p&gt;

&lt;p&gt;However, it's easy to build custom components with SwiftUI. It might be easy to sidestep a missing out-of-the-box UI component on your own.&lt;/p&gt;

&lt;h2&gt;
  
  
  SwiftUI vs. UIkit: What's the verdict?
&lt;/h2&gt;

&lt;p&gt;It's time for a more detailed head-to-head comparison! Let's compare SwiftUI vs. UIkit according to factors such as device compatibility, documentation, required UI components, target iOS version, and a few others.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Framework-comparison-for-ease-of-use.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fsendbird.sfo3.digitaloceanspaces.com%2Fcms%2FTutorial-image_Framework-comparison-for-ease-of-use.png" alt="Framework comparison table"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The SwiftUI vs. UIkit frameworks&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Target iOS version and device compatibility
&lt;/h3&gt;

&lt;p&gt;As you know, UIkit has been the household name for building UI on iOS apps. Supporting version 9 and later, it basically covers all versions that any iOS app would need.&lt;/p&gt;

&lt;p&gt;SwiftUI can only support version 13 or later, which is only a handful in comparison. Still, as long as the platform is running iOS 13 or later, SwiftUI works with everything Apple, which means watchOS, tvOS, iOS, and macOS. Since you can reuse code across all platforms, development is fast and smooth.&lt;/p&gt;

&lt;p&gt;Given &lt;a href="https://developer.apple.com/support/app-store/" rel="noopener noreferrer"&gt;recent data&lt;/a&gt; that shows only 8 percent of devices connected to the Apple Store use iOS 14 or lower, SwiftUI is a strong candidate in iOS development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Project complexity and team experience
&lt;/h3&gt;

&lt;p&gt;Building simple iOS apps with only a few screens is relatively easy to accomplish with SwiftUI. However, building a complex project might require a more mature framework to reduce the risk of encountering unresolved bugs in the framework.&lt;/p&gt;

&lt;p&gt;Most experienced iOS developers are already well-versed in the UIkit framework since it's been around for a long time. It also has more educational resources than SwiftUI. However, new learners find it easy to pick up SwiftUI due to its easy-to-understand syntax and less complex code.&lt;/p&gt;

&lt;p&gt;Where you're at in your developer journey plays a significant role in your choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Required UI components and design patterns
&lt;/h3&gt;

&lt;p&gt;Depending on the complexity of your project, you might benefit from a framework that has certain UI components out of the box.&lt;/p&gt;

&lt;p&gt;UIkit has numerous UI components and works well with delegates and data sources that require extra code to manually handle updates.&lt;/p&gt;

&lt;p&gt;SwiftUI is still growing its components library, but it's a lot easier to build custom UI components and animations on SwiftUI than on UIkit. SwiftUI relies heavily on state and data binding, promoting a declarative and reactive approach to UI development.&lt;/p&gt;

&lt;p&gt;Migrating from UIkit to SwiftUI involves a slight learning curve due to the different coding practices and design patterns between the two frameworks, but it might be worth it to you. Adopting SwiftUI could also mean a huge improvement in the scalability and maintainability of your code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Interoperability between UIkit and SwiftUI
&lt;/h3&gt;

&lt;p&gt;Can't decide on one framework over the other? You also have the option of using both in a single project.&lt;/p&gt;

&lt;p&gt;To integrate SwiftUI views in UIkit projects, you can utilize UIkit's &lt;code&gt;UIHostingController&lt;/code&gt; class to manage a SwiftUI view hierarchy.&lt;/p&gt;

&lt;p&gt;Want to use UIkit components in a SwiftUI project? That's actually quite simple. Wrappers like &lt;code&gt;UIViewRepresentable&lt;/code&gt; and &lt;code&gt;UIViewControllerRepresentable&lt;/code&gt; enable you to wrap a UIkit view or view controller in SwiftUI code.&lt;/p&gt;

&lt;p&gt;This support for interoperability comes in handy if you intend to gradually migrate a UIkit project to SwiftUI. This way, you can improve your code as SwiftUI evolves while retaining UIkit's mature components. Continue to leverage UIkit's strengths and maturity on a SwiftUI project, and eliminate the need to reinvent the wheel.&lt;/p&gt;

&lt;h2&gt;
  
  
  SwiftUI vs. UIkit: Making your decision
&lt;/h2&gt;

&lt;p&gt;Depending on your application needs, you might already have an obvious winner for which UI framework you want to use to build an iOS user interface.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://developer.apple.com/xcode/swiftui/" rel="noopener noreferrer"&gt;SwiftUI's&lt;/a&gt; declarative syntax, previews, live editing, and reactive programming definitely make it the future of iOS app development. However, &lt;a href="https://developer.apple.com/documentation/uikit" rel="noopener noreferrer"&gt;UIkit&lt;/a&gt; still shines with its numerous UI components, large community, robust documentation, and support for lower iOS versions.&lt;/p&gt;

&lt;p&gt;After you've analyzed the SwiftUI vs. UIkit comparison, consider adding customer communications to your app to enhance user &lt;a href="https://sendbird.com/blog/business-communication-technology" rel="noopener noreferrer"&gt;engagement&lt;/a&gt;, &lt;a href="https://sendbird.com/blog/app-retention-rate-best-practices" rel="noopener noreferrer"&gt;retention&lt;/a&gt;, and &lt;a href="https://sendbird.com/blog/14-steps-to-improve-your-csat" rel="noopener noreferrer"&gt;CSAT&lt;/a&gt;. You can do this with &lt;a href="https://sendbird.com/" rel="noopener noreferrer"&gt;Sendbird&lt;/a&gt;, an all-in-one communications API platform for web and mobile apps. Sendbird's highly abstracted APIs empower developers to build robust and scalable communication experiences (for &lt;a href="https://sendbird.com/products/chat-messaging" rel="noopener noreferrer"&gt;chat&lt;/a&gt;, &lt;a href="https://sendbird.com/products/notifications" rel="noopener noreferrer"&gt;notifications&lt;/a&gt;, and &lt;a href="https://sendbird.com/products/voice-and-video" rel="noopener noreferrer"&gt;in-app calls&lt;/a&gt;) across web and mobile platforms, leveraging a real-time, compliant, and global infrastructure. &lt;a href="https://sendbird.com/request-a-demo" rel="noopener noreferrer"&gt;Request a demo&lt;/a&gt;, start a discussion on the &lt;a href="http://community.sendbird.com/" rel="noopener noreferrer"&gt;Sendbird Community&lt;/a&gt;, or &lt;a href="https://sendbird.com/contact-us" rel="noopener noreferrer"&gt;contact us&lt;/a&gt; to learn more!&lt;/p&gt;

</description>
      <category>swift</category>
      <category>uikit</category>
      <category>swiftui</category>
      <category>ios</category>
    </item>
    <item>
      <title>WebSocket vs. HTTP communication protocols</title>
      <dc:creator>Sendbird Devs</dc:creator>
      <pubDate>Sat, 10 Feb 2024 00:31:02 +0000</pubDate>
      <link>https://dev.to/sendbird/websocket-vs-http-communication-protocols-42p5</link>
      <guid>https://dev.to/sendbird/websocket-vs-http-communication-protocols-42p5</guid>
      <description>&lt;h2&gt;
  
  
  WebSocket vs. HTTP in a nutshell
&lt;/h2&gt;

&lt;p&gt;Many of your daily activities on the internet—from ordering food to looking up a fact to speaking to a doctor online—are enabled by WebSocket or HTTP communication protocols. As a developer, when building an app, which of these communications protocols should you use? What are the differences when we compare WebSocket vs. HTTP? In a nutshell, WebSocket, a &lt;a href="https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full_duplex"&gt;full-duplex&lt;/a&gt; communication protocol, is relatively newer and is well suited to real-time applications such as &lt;a href="https://sendbird.com/products/chat-messaging"&gt;in-app chat&lt;/a&gt;, &lt;a href="https://sendbird.com/products/notifications"&gt;notifications&lt;/a&gt;, and &lt;a href="https://sendbird.com/products/voice-and-video"&gt;voice or video calls&lt;/a&gt;. On the other hand, HTTP, a &lt;a href="https://www.geeksforgeeks.org/difference-between-simplex-half-duplex-and-full-duplex-transmission-modes/"&gt;half-duplex&lt;/a&gt; communication protocol, has been around for some time and has been the basis of websites since its debut.&lt;/p&gt;

&lt;p&gt;In this comparison, you’ll learn more about these two communication protocols, their similarities and differences, as well as understand when to choose one over the other. Let’s dive in!&lt;/p&gt;

&lt;h2&gt;
  
  
  About the WebSocket connection
&lt;/h2&gt;

&lt;p&gt;The WebSocket protocol describes how a client and server communicate in &lt;a href="https://en.wikipedia.org/wiki/Duplex_(telecommunications)#Full_duplex"&gt;full-duplex&lt;/a&gt; channels. In other words, both the client and server can send and receive data simultaneously over a long-lived connection. This type of communication has less overhead than HTTP polling, giving an application several advantages in real-time functionality.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frs4ax5y8bckv6fnsxozs.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frs4ax5y8bckv6fnsxozs.jpg" alt="WebSocket connection chart" width="800" height="389"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of a WebSocket connection
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Bidirectional communication
&lt;/h4&gt;

&lt;p&gt;Because both sides of the connection can send messages whenever they want, a WebSocket connection is an excellent choice when you need to move a lot of data back and forth quickly.&lt;/p&gt;

&lt;p&gt;Imagine a simple chat room connecting multiple clients. If a WebSocket server moderates their conversation, a client sends a message to the server, which then immediately relays it to all other connected clients. As far as the users are concerned, they can send messages to each other in real time.&lt;/p&gt;

&lt;p&gt;This is a simple version of what this looks like:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffe8bifzbxejfsuclk6rk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffe8bifzbxejfsuclk6rk.jpg" alt="Bidirectional communication flow chart" width="800" height="301"&gt;&lt;/a&gt; &lt;em&gt;Adapted from &lt;a href="https://stackoverflow.com/questions/56454187/multi-client-chat-application-in-java"&gt;Stack Overflow&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Lower latency
&lt;/h4&gt;

&lt;p&gt;A common pattern in an HTTP connection for relatively high-frequency data fetching is polling, where the client periodically requests new server data. Perhaps the biggest drawback of this communication method is latency—you have to compromise between frequent or long-running requests and high latency.&lt;/p&gt;

&lt;p&gt;With a WebSocket connection, data is sent as soon as it’s available. The client doesn’t need to keep requesting it. The result is much lower latency with a fraction of the overhead and network traffic.&lt;/p&gt;

&lt;h4&gt;
  
  
  WebSocket vs. HTTP communication diagram
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fudcgfx7asyqhewpugm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3fudcgfx7asyqhewpugm.jpg" alt="WebSocket vs. HTTP communication diagram" width="800" height="436"&gt;&lt;/a&gt; &lt;em&gt;Adapted from &lt;a href="https://ambassadorpatryk.com/2020/03/publish-web-socket-in-the-experience-layer/"&gt;source&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  Persistent connections
&lt;/h4&gt;

&lt;p&gt;With the traditional HTTP connection, the client makes a request, and after the server sends its response, the connection is closed. If the client needs more data, they have to open a new connection.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Note that although HTTP/1.1 introduced persistent connections that allow for the reuse of the TCP/IP connection, this mental model is still helpful and mostly accurate.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;With a WebSocket connection, the client can open and use a single connection for all their WebSocket communications with the server. This persistent connection allows for low-latency, bidirectional messages.&lt;/p&gt;

&lt;p&gt;This WebSocket connection can also be stateful. An HTTP connection is stateless—this means that each request is handled in isolation, with no retention of information about the requests that came before it. WebSocket, on the other hand, is stateful thanks to its persistent connection.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Whether or not an application takes advantage of stateful capability is entirely up to the developer and how they use their WebSocket connection.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  About the HTTP connection
&lt;/h2&gt;

&lt;p&gt;The HTTP protocol was designed as a request-response protocol. A client, such as a browser, would send a request to a web server, and the web server would reply with a response containing the resources corresponding to the request, such as HTML and CSS files. While HTTP connections are open, they are only &lt;a href="https://www.geeksforgeeks.org/difference-between-simplex-half-duplex-and-full-duplex-transmission-modes/"&gt;half-duplex&lt;/a&gt;, meaning communication only goes one way. Once a response has been received, the connection is often closed.&lt;/p&gt;

&lt;p&gt;HTTP/1.1 introduced &lt;a href="https://www.nginx.com/blog/http-keepalives-and-web-performance/"&gt;persistent connections&lt;/a&gt; that reuse the TCP/IP connection, which allows for some performance improvements. However, the specifics of these persistent connections vary from server to server, and in most cases, they’re closed eventually based on an inactivity timeout. So while it’s a welcome addition to HTTP connection functionality, this is still not a direct comparison to a WebSocket connection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnnzci7vcxawa37yanmp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgnnzci7vcxawa37yanmp.jpg" alt="HTTP connection chart" width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The HTTP protocol has been very good at what it was built for: responding to requests. However, it wasn’t built to handle the real-time communication use cases, such as &lt;a href="https://sendbird.com/products/chat-messaging"&gt;chat&lt;/a&gt; or &lt;a href="https://sendbird.com/products/live-streaming"&gt;live event streaming&lt;/a&gt;, that people expect today.&lt;/p&gt;

&lt;p&gt;Even so, HTTP still has several advantages over the WebSocket protocol.&lt;/p&gt;

&lt;h3&gt;
  
  
  Advantages of an HTTP connection
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Simplicity and ubiquity
&lt;/h4&gt;

&lt;p&gt;The staying power of HTTP connections comes from its widespread adoption and its straightforward accessibility. Between the three major versions of HTTP, virtually all web servers and web browsers can leverage the protocol in some form:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/1.1.&lt;/strong&gt; &lt;a href="https://w3techs.com/technologies/overview/site_element"&gt;Around 35 percent&lt;/a&gt; of sites are still using HTTP/1.1 or below.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/2.&lt;/strong&gt; &lt;a href="https://w3techs.com/technologies/details/ce-http2"&gt;Used by 39.3 percent of all sites&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;HTTP/3.&lt;/strong&gt; &lt;a href="https://w3techs.com/technologies/details/ce-http3"&gt;Used by 25.7 percent of all sites&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Stateless nature and caching support
&lt;/h4&gt;

&lt;p&gt;Because HTTP requests are stateless and self-contained, a website’s performance might benefit from caching responses, especially when dealing with static content and assets. Caching can take place at various levels:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;In the browser&lt;/strong&gt;: This eliminates the need to contact the server at all.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At the edge&lt;/strong&gt;: This uses a server closer to the user’s geographic location, as with &lt;a href="https://www.cloudflare.com/learning/cdn/what-is-a-cdn/"&gt;CDNs&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;On the server&lt;/strong&gt;: This allows the server to avoid expensive recalculations if the result is the same each time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;WebSocket messages cannot be cached as easily as HTTP responses, given that they’re stateful and usually context-sensitive. These messages would change too often for caching to be helpful in most cases.&lt;/p&gt;

&lt;h4&gt;
  
  
  Robust security mechanisms
&lt;/h4&gt;

&lt;p&gt;The HTTP protocol’s ubiquity means it has been the subject of multiple initiatives to improve its security posture.&lt;/p&gt;

&lt;h5&gt;
  
  
  HTTPS
&lt;/h5&gt;

&lt;p&gt;The original HTTP protocol is lacking in one important respect—request and response messages are not encrypted and are relatively easy for malicious actors to intercept and read.&lt;/p&gt;

&lt;p&gt;This problem is mitigated by HTTPS, a variant of HTTP that uses Transport Layer Security (TLS) or Secure Sockets Layer (SSL) to encrypt requests and responses. A malicious actor might be able to intercept your packets, but they won’t be able to read their content, thanks to this encryption.&lt;/p&gt;

&lt;h5&gt;
  
  
  HTTP Strict Transport Security
&lt;/h5&gt;

&lt;p&gt;Another HTTP-related security mechanism is HTTP Strict Transport Security (HSTS). HSTS allows servers to specify policies to help prevent common security problems, such as &lt;a href="https://www.imperva.com/learn/application-security/man-in-the-middle-attack-mitm/"&gt;MITM attacks&lt;/a&gt;, &lt;a href="https://crashtest-security.com/downgrade-attack/"&gt;protocol downgrade attacks&lt;/a&gt;, and &lt;a href="https://www.invicti.com/learn/cookie-hijacking/"&gt;cookie hijacking&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A site can leverage HSTS by returning the appropriate header over an HTTPS connection, like so:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;When configured correctly, HSTS ensures that the browser will always request the HTTPS variant of the site, even if a user has clicked a standard HTTP link. As a result, the user has a layer of security that protects them from many easy-to-mitigate attacks.&lt;/p&gt;

&lt;h2&gt;
  
  
  WebSocket vs. HTTP: Choosing the suitable protocol
&lt;/h2&gt;

&lt;p&gt;Before you rally around WebSocket or HTTP protocols, consider what you’re building and why. Note that each communication protocol excels in several areas where the other typically falls short.&lt;/p&gt;

&lt;p&gt;Technical tradeoffs between a WebSocket vs. HTTP connection&lt;br&gt;
Understanding the technical tradeoffs between these two communication protocols can give you insight as to which one is the best fit for your project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Connection setup and management
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider how you need connections to be established and managed over time.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;In the case of WebSocket, the persistent connection is established by a handshake between the client and server. It’s kept open for the duration of the session, even if there is a significant delay between messages.&lt;/p&gt;

&lt;p&gt;With HTTP, connections are established with a handshake and then used for the request-response cycle. HTTP/1.1 allows for the same TCP/IP connection to be reused for multiple request-response pairs, which reduces overhead and improves latency, but not to the same extent as WebSocket. The connection will still close in a relatively short period, ranging anywhere from a few seconds to several minutes.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hie6d1wi58cxcqcd4bn.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F9hie6d1wi58cxcqcd4bn.jpg" alt="Image description" width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Data transmission and encoding
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider how you want data to be transmitted.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;A WebSocket connection uses full-duplex two-way communication—either side of the connection can send messages whenever they want. An HTTP connection uses half-duplex communication; only one party can communicate at a time, and the server’s message is always in response to a request from a client.&lt;/p&gt;

&lt;p&gt;Both WebSocket and HTTP can send data encoded in text-based formats like JSON, XML, and plain text, as well as binary-encoded data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Error handling and recovery
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider which error handling methods would be least impactful to users.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;A WebSocket connection can fail for various reasons, including errors in your application code. Clients are sent an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/WebSocket/error_event"&gt;error event&lt;/a&gt; that they can listen for, and you can handle the error in this listener however you see fit. However, if your WebSocket server is running inside your application code, fatal errors at the application level can dramatically impact the ability of your app to implement graceful error handling.&lt;/p&gt;

&lt;p&gt;An HTTP connection can, of course, experience similar circumstances, but certain common architectures can provide benefits when it comes to error handling. HTTP specifies a range of &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status"&gt;status codes&lt;/a&gt; that servers can respond with to broadly indicate whether the request has been successful or not. The 4xx and 5xx ranges are reserved for client and server errors, respectively.&lt;/p&gt;

&lt;p&gt;Consider a web application where requests are handled through &lt;a href="https://www.nginx.com/"&gt;NGINX&lt;/a&gt; as the web server and &lt;a href="https://www.php.net/"&gt;PHP&lt;/a&gt; as the dynamic backend language. Let’s say something in the application logic results in a fatal error or process termination. This doesn’t affect NGINX’s ability to serve a response to the client, which would most likely be an &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/503"&gt;HTTP 503 - Service Unavailable&lt;/a&gt; message.&lt;/p&gt;

&lt;p&gt;Of course, this separation does depend on your application’s architecture. Consider a similar situation where your application and web server are implemented together in the same process, such as a Node.js &lt;a href="https://expressjs.com/"&gt;Express&lt;/a&gt; app. A fatal error here will also terminate the web server, limiting the usefulness of the error that the client will receive.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scalability
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider your application’s resource consumption needs.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;WebSocket connections are designed to be highly efficient at what they do. They’re event-driven—messages are only sent when there is something to send a message about.&lt;/p&gt;

&lt;p&gt;An HTTP connection can achieve something akin to real-time functionality through &lt;a href="https://www.educative.io/answers/what-is-http-long-polling"&gt;long polling&lt;/a&gt;, where requests are sent and held open until there is something to respond with. This rough approximation of real-time communication has some limitations, especially at scale. HTTP requests can’t be held open indefinitely, which means that the client will need to periodically open a new long polling request. Over time, the overhead of processing all of these long-lived HTTP requests adds up.&lt;/p&gt;

&lt;p&gt;With &lt;a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming"&gt;HTTP streaming&lt;/a&gt;, a connection is held open indefinitely to facilitate a continuous data stream. This is conceptually similar to WebSocket, but it’s still performed over HTTP and is still one-way—the client cannot send messages to the server via HTTP streaming.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance considerations of a WebSocket vs. HTTP connection
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider your application’s performance expectations.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;Thanks to persistent connections, WebSocket benefits from reduced overhead and latency. This leads to better performance, faster real-time updates, and less processing power spent on things like the HTTP &lt;a href="https://www.techopedia.com/definition/10339/three-way-handshake"&gt;three-way handshake&lt;/a&gt;, and HTTP-specific application code for managing incoming requests and authentication/authorization.&lt;/p&gt;

&lt;p&gt;Because HTTP typically has to deal with multiple connections over a session’s lifespan, it will naturally spend more time and resources compared to WebSocket.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security of a WebSocket vs. HTTP connection
&lt;/h3&gt;

&lt;h4&gt;
  
  
  &lt;em&gt;Consider which is easiest for you to secure.&lt;/em&gt;
&lt;/h4&gt;

&lt;p&gt;WebSocket and HTTP connections are similar regarding security considerations. Both have insecure and secure variants, and both can fall victim to several common attacks if not adequately secured. There are also attacks specific to each protocol that you need to be aware of, such as &lt;a href="https://portswigger.net/web-security/cross-site-scripting"&gt;cross-site scripting attacks&lt;/a&gt; for HTTP and &lt;a href="https://portswigger.net/web-security/websockets/cross-site-websocket-hijacking"&gt;cross-site WebSocket hijacking&lt;/a&gt; for WebSocket.&lt;/p&gt;

&lt;p&gt;However, if you configure them appropriately and use TLS encryption, you can mitigate most threats, making both protocols sufficiently secure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hybrid approaches to communication protocols
&lt;/h3&gt;

&lt;p&gt;Typically, the recommended approach is to use both protocols for what they’re best at within your system. That means using an HTTP connection for most of your standard web traffic and a WebSocket connection for anything that requires real-time communication, such as &lt;a href="https://sendbird.com/products/notifications"&gt;notifications&lt;/a&gt;, &lt;a href="https://sendbird.com/products/chat-messaging"&gt;messaging/chat&lt;/a&gt;, or &lt;a href="https://sendbird.com/products/voice-and-video"&gt;video calls&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You might also consider assessing complementary or alternative technologies; WebSocket and HTTP aren’t the only options when it comes to real-time communication, after all. &lt;a href="https://webrtc.org/"&gt;WebRTC&lt;/a&gt; is similar to WebSocket, with the key difference being that it’s used to implement &lt;a href="https://sendbird.com/developer/tutorials/the-basics-of-building-a-peer-to-peer-video-call"&gt;peer-to-peer connections&lt;/a&gt; without relying on a server. That can be especially helpful for video calls, allowing participants to communicate directly without introducing load to your server.&lt;/p&gt;

&lt;h2&gt;
  
  
  Communication protocols for secure, scalable, reliable in-app comms
&lt;/h2&gt;

&lt;p&gt;You should now have a solid idea now of how WebSocket and HTTP communication protocols are intended to be used. You’ve seen their strengths and weaknesses, and you can appreciate their tradeoffs.&lt;/p&gt;

&lt;p&gt;Fortunately, you don’t need to choose one over the other. The two communication protocols can, and often should, be used together, allowing each to do what it does best. If you need to implement real-time communication and streaming functionality in your applications, check out &lt;a href="https://sendbird.com/"&gt;Sendbird&lt;/a&gt;. Sendbird’s APIs and client SDKs handle the technical heavy lifting for in-app &lt;a href="https://sendbird.com/products/chat-messaging"&gt;chat&lt;/a&gt;, &lt;a href="https://sendbird.com/products/voice-and-video"&gt;calls&lt;/a&gt;, and &lt;a href="https://sendbird.com/products/live-streaming"&gt;live streaming&lt;/a&gt;. Sendbird’s chat service abstracts away the problems (such as running reliably and securely in real-time at massive scale) associated with growing and maintaining a chat system over a long period of time. This means that you can focus on the core aspects of your application.&lt;/p&gt;

&lt;p&gt;Want to try it out? &lt;a href="https://dashboard.sendbird.com/"&gt;Sign up&lt;/a&gt; for free—no commitment or credit card required.&lt;/p&gt;

&lt;p&gt;Happy in-app communications building! 📱&lt;/p&gt;

</description>
      <category>websocket</category>
      <category>http</category>
      <category>webdev</category>
      <category>developers</category>
    </item>
    <item>
      <title>How to implement map previews and location sharing on Android</title>
      <dc:creator>Sendbird Devs</dc:creator>
      <pubDate>Fri, 10 Dec 2021 17:47:07 +0000</pubDate>
      <link>https://dev.to/sendbird_devs/how-to-implement-map-previews-and-location-sharing-on-android-32fb</link>
      <guid>https://dev.to/sendbird_devs/how-to-implement-map-previews-and-location-sharing-on-android-32fb</guid>
      <description>&lt;p&gt;By Alex Preston&lt;br&gt;
Solutions Engineer | &lt;a href="https://www.sendbird.com"&gt;Sendbird&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post &lt;a href="https://sendbird.com/developer/tutorials/android-chat-location-sharing-map-preview"&gt;How to implement map previews and location sharing on Android&lt;/a&gt; appeared first on &lt;a href="https://sendbird.com"&gt;Sendbird&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;In-app location sharing and map previews offer an efficient way to communicate geolocation with friends and service providers. They remove any ambiguity about the directions to reach a location and provide peace of mind while allowing users to monitor the progress of a trip. For example, location sharing simplifies the life of delivery service personnel and improves their customer’s satisfaction when sending their location upon inquiry. &lt;/p&gt;

&lt;p&gt;Mapping and messaging are fantastic ways to coordinate live interactions. Rory Sutherland, Vice Chairman of Ogilvy &amp;amp; Mather Group and author of Alchemy: The Dark Art and Curious Science of Creating Magic in Brands, Business, and Life, reminds us why the Uber map was &lt;a href="https://www.youtube.com/watch?v=iueVZJVEmEs"&gt;magic&lt;/a&gt;. He called it: &lt;/p&gt;

&lt;p&gt;&lt;em&gt;“…a psychological moonshot, because it does not reduce the waiting time for a taxi but simply makes waiting 90% less frustrating.”&lt;/em&gt; – Rory Sutherland&lt;/p&gt;

&lt;p&gt;As you can guess, this feature is specifically relevant for apps in the industries of:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transportation and ridesharing &lt;/li&gt;
&lt;li&gt;Delivery and logistics &lt;/li&gt;
&lt;li&gt;Food or grocery delivery&lt;/li&gt;
&lt;li&gt;Other consumer product delivery&lt;/li&gt;
&lt;li&gt;Online to offline services&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This simple tutorial will walk you through the implementation of location sharing with easily digestible within-message map previews. &lt;/p&gt;

&lt;p&gt;Please note that this guide assumes you have already implemented chat using the Sendbird SDK. If you have not, check out the &lt;a href="https://sendbird.com/docs/chat/v3/android/quickstart/send-first-message"&gt;docs&lt;/a&gt; or this &lt;a href="https://sendbird.com/developer/tutorials/build-chat-uikit-android"&gt;tutorial&lt;/a&gt; to learn how to do this.&lt;/p&gt;

&lt;p&gt;Let’s begin! 💻&lt;/p&gt;
&lt;h1&gt;
  
  
  Implementing location sharing and map previews in Sendbird
&lt;/h1&gt;

&lt;p&gt;When a user presses the “Share Location” button, Android’s LocationManager class provides the user’s geographic coordinates. Sendbird sends their location in a UserMessage with the CustomType set to location. After sending the message, it is inserted into the RecyclerView through its adapter. Based on the MessageType(UserMessage) and the CustomType(location), the layoutInflater inflates a custom view containing the MapView. Finally, you add geographic coordinates to the MapView.&lt;/p&gt;

&lt;p&gt;Please note that using the Google Play Service Maps SDK, users can share their location from within the in-app chat and the recipient can open this location in Google Maps. Sendbird displays the map in an easily digestible preview for quick consumption.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Dr0HU0yP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://sendbird.com/wp-content/uploads/image3-1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Dr0HU0yP--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://sendbird.com/wp-content/uploads/image3-1.png" alt="alt text" title="Logo Title Text 1" width="800" height="648"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To implement location sharing and map previews, follow these steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Understand the prerequisites (outlined below) for location  sharing and map previews on Android&lt;/li&gt;
&lt;li&gt;Obtain permission to use the user’s location&lt;/li&gt;
&lt;li&gt;Declare your API access token and a dependency for maps&lt;/li&gt;
&lt;li&gt;Create the layout for sender and recipient&lt;/li&gt;
&lt;li&gt;Retrieve the user’s location&lt;/li&gt;
&lt;li&gt;Send the user’s location in a UserMessage&lt;/li&gt;
&lt;li&gt;Handle the received message by checking the custom type and bind it to a view&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Prerequisites for location sharing and map previews
&lt;/h3&gt;

&lt;p&gt;To reiterate, this guide assumes that you have already implemented chat using the Sendbird SDK. Check out the &lt;a href="https://sendbird.com/docs/chat/v3/android/quickstart/send-first-message"&gt;docs&lt;/a&gt; or this &lt;a href="https://sendbird.com/developer/tutorials/build-chat-uikit-android"&gt;tutorial&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Note that the code in this guide uses Sendbird’s &lt;a href="https://sendbird.com/docs/syncmanager/v1/android/getting-started/about-syncmanager#1-about-syncmanager"&gt;SyncManager SDK&lt;/a&gt; to send and receive messages.&lt;/p&gt;

&lt;p&gt;You will need:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sendbird.com/docs/chat/v3/android/quickstart/send-first-message#1-send-your-first-message"&gt;Sendbird Android SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/maps/documentation/android-sdk/start"&gt;Google Play Service Maps SDK&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/maps/documentation/android-sdk/get-api-key"&gt;A Google API access Token&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Note:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you are using Android’s built-in emulator, note that it will likely not show your location.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Other resources:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Google’s &lt;a href="https://developers.google.com/maps/documentation/android-sdk/intro"&gt;official guide on maps&lt;/a&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Google’s &lt;a href="https://github.com/googlemaps/android-samples"&gt;official sample apps&lt;/a&gt; using maps&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Step 1: Obtain permission to use the user’s location
&lt;/h2&gt;

&lt;p&gt;For location sharing to work, you need to obtain permission to use the user’s location.&lt;/p&gt;

&lt;p&gt;Request this at runtime. For the sake of brevity, this guide omits the runtime code.&lt;/p&gt;

&lt;p&gt;Instead, it shows permission as it is shown in the AndroidManifest.xml.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/50dc646a3b7236013cc4f9f54186a3e5#file-androidmanifest-xml"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Declare your API access token and add a dependency for maps
&lt;/h2&gt;

&lt;p&gt;Declare your API access token in the AndroidManifest.xml.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/4110a4386681ebc6f887d5fe2c882aee"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Add a dependency for maps in the app level build.gradle file.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/1f075eeb99b6297e47a0b8af3997965d"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Create the layout for the sender and recipient
&lt;/h2&gt;

&lt;p&gt;Create a layout for both sides of the chat, i.e. both sender and recipient. This guide differentiates between them as “me” and “other,” where “me” represents the sender and “other” represents the recipient. Both should contain a MapView.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/7fb891e7c5a88ff4bc23be71ba96a7df"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;See the full gist for each layout.&lt;/p&gt;

&lt;p&gt;Me (sender): &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/e8b8f5ef59993e689f443aa7eab1b7e5"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Other (recipient):&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/0ac419e532bc8c2cd668712bc40e6756"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note: This guide skips over the implementation for setting up the recyclerview, setting button listeners, etc. You can view the sample code in &lt;a href="https://gist.github.com/AlexPrestonSB/3ccba33a45d8bf5ee899f01d0862fb4d"&gt;this gist&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Retrieve the user’s location
&lt;/h2&gt;

&lt;p&gt;Retrieve the geographic coordinates from the LocationManager. This happens when the user decides to share their location.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/21abc8688cf807f4cd3421d3edb29a5e"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Send the user’s location in a UserMessage
&lt;/h2&gt;

&lt;p&gt;Once you obtain the longitude and latitude, send it as a UserMessage. To indicate that it is a location, set the CustomType on the individual message to “location.”&lt;/p&gt;

&lt;p&gt;Next, insert the message into the RecyclerView by adding it to the adapter.&lt;/p&gt;

&lt;p&gt;See below for the full implementation.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/230b4aca24ddea46cf07dfc48f7fc778"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Bind the view to your customer viewHolders
&lt;/h2&gt;

&lt;p&gt;After adding the messages to the adapter, check the message type before binding the view. Do this by overriding getItemViewType.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/60f0d906a2783794ab2dabb1a7f9f6a6"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Based on what getItemViewType returns, inflate the layout according to whether the message belongs to “me” (sender) or “other” (recipient).&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/02cbc77173ec335d0ad7559e19b98954"&gt;Gist&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Next, bind the views to your custom viewHolder.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/2d153f09bb5b5dc16e4f2b669e368629"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In your custom viewHolder, implement OnMapReadyCallback, and override the onMapReady function.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/2cb4d2b79b339dd3cc1f0b34c90518d4"&gt;Gist&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;You may find it useful to check out the full Adapter code.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/AlexPrestonSB/3c3405c83f0a8d28fae808fafacbee60"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;And that’s a wrap! With Sendbird’s map preview and location sharing implementation, your users will now be able to send a map showing their location, thereby improving communication with others and making their app experience a bit more magical.&lt;/p&gt;

&lt;p&gt;Happy coding! 👩‍💻&lt;/p&gt;

</description>
      <category>mappreviews</category>
      <category>android</category>
      <category>locationsharing</category>
      <category>sendbird</category>
    </item>
    <item>
      <title>How to build a chat app using React Native and Hooks</title>
      <dc:creator>Sendbird Devs</dc:creator>
      <pubDate>Fri, 08 Oct 2021 20:09:31 +0000</pubDate>
      <link>https://dev.to/sendbird_devs/how-to-build-a-chat-app-using-react-native-and-hooks-9me</link>
      <guid>https://dev.to/sendbird_devs/how-to-build-a-chat-app-using-react-native-and-hooks-9me</guid>
      <description>&lt;p&gt;By Walter Rodriguez&lt;br&gt;
Solutions Engineer | &lt;a href="https://www.sendbird.com"&gt;Sendbird&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The post &lt;a href="https://sendbird.com/developer/tutorials/react-native-chat-tutorial"&gt;How to build a chat app using React Native and Hooks&lt;/a&gt; appeared first on &lt;a href="https://sendbird.com"&gt;Sendbird&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h1&gt;
  
  
  Introduction
&lt;/h1&gt;

&lt;p&gt;This tutorial will show you how to build a messaging app using React Native. First, we’ll set the stage for this tutorial by understanding why you should use React Native in the first place. Then we’ll explain React Native Hooks functions before diving into the implementation details of how to build a chat application with Sendbird and React Native. &lt;/p&gt;

&lt;p&gt;Please note that this tutorial assumes a basic understanding of React Native.&lt;/p&gt;

&lt;p&gt;With this in mind, let’s begin.&lt;/p&gt;
&lt;h3&gt;
  
  
  Why React Native?
&lt;/h3&gt;

&lt;p&gt;Most applications today are built natively, but there are also hybrid applications developed using Webviews. The properties and features of Webviews introduce limits to applications in comparison to their native counterparts, however. Applications using Webviews are also relatively slower than native applications. React Native allows to bridge this gap by providing applications access to native functionality and properties.&lt;/p&gt;

&lt;p&gt;React Native does this by separating the JavaScript code and native code into different threads. It also enables asynchronous communication between the two, which boosts the overall app performance. Moreover, since React Native uses JavaScript, developers unfamiliar with native applications can use their existing knowledge and experience to reduce coding time.&lt;/p&gt;
&lt;h3&gt;
  
  
  Who is using React Native?
&lt;/h3&gt;

&lt;p&gt;Because of its advantages of code reusability, reliability, robustness, and the existence of a helpful community, many companies, from established Fortune 500 companies to high-growth startups, develop applications with React Native. Some well-regarded organizations using React Native include Instagram, Shopify, Tableau, Tesla, UberEats, and Skype.&lt;/p&gt;

&lt;p&gt;Now that we have understood the basics let’s move on to React Native Hooks functions. &lt;/p&gt;
&lt;h3&gt;
  
  
  What are React Native Hooks functions?
&lt;/h3&gt;

&lt;p&gt;Hooks are functions that let you “hook” into React states and lifecycle features from function components. Hooks don’t work inside classes — they let you use React without classes. (We don’t recommend rewriting your existing components overnight, but you can start using Hooks in the new ones if you’d like.)&lt;/p&gt;

&lt;p&gt;React provides a few built-in Hooks such as useState. You can also create your own Hooks to reuse stateful behavior between different components. Let’s look at the built-in Hooks first.&lt;/p&gt;

&lt;p&gt;For more information about Hooks, check out the &lt;a href="https://reactjs.org/docs/hooks-overview.html"&gt;react site&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now let’s understand how to work with Sendbird and Hooks for your chat application. This tutorial is composed of nine more parts:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Installing React Native&lt;/li&gt;
&lt;li&gt;Downloading the Sendbird sample &lt;/li&gt;
&lt;li&gt;Debugging&lt;/li&gt;
&lt;li&gt;Understanding the folder structure&lt;/li&gt;
&lt;li&gt;Building the Login component&lt;/li&gt;
&lt;li&gt;Building the Channels List component&lt;/li&gt;
&lt;li&gt;Building the Messages component&lt;/li&gt;
&lt;li&gt;Sending and receiving messages&lt;/li&gt;
&lt;li&gt;Other Sendbird features&lt;/li&gt;
&lt;/ol&gt;
&lt;h1&gt;
  
  
  Step 1. Installing React Native to build chat
&lt;/h1&gt;

&lt;p&gt;You need to have the &lt;strong&gt;React Native CLI&lt;/strong&gt; to work with this example. Please install globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g react-native-cli
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can quickly check that the installation finished correctly by showing the version number:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;react-native --version
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h1&gt;
  
  
  Step 2. Downloading the Sendbird sample
&lt;/h1&gt;

&lt;p&gt;Once you have the React Native CLI installed, you can download the sample code. First clone the repository:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git clone https://github.com/sendbird/SendBird-JavaScript.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Then, open the following folder using your favorite IDE:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;./SendBird-JavaScript/react-native-hook-sample/Sendbird
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;As the next step, let’s install all the dependencies. Run the following command: (it takes some time to download all packages)&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can run this either for Android or iOS. Open the package.json file and check the scripts we have for you to use:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqhqh2x8mhom6i2ebrhl.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fiqhqh2x8mhom6i2ebrhl.png" alt="Scripts to run the Android and iOS versions&amp;lt;br&amp;gt;
" width="652" height="122"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;center&gt;&lt;em&gt;Scripts to run the Android and iOS versions&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;To run Android, just type:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run android
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  Troubleshooting Android
&lt;/h3&gt;

&lt;p&gt;If you have problems running the Android version, you can try the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If you run on an actual device, check if everything is installed – especially Android studio.&lt;/li&gt;
&lt;li&gt;Check if your device is visible by adb devices; sometimes, it may not work or have lags. In this case, call adb kill-server and then adb start-server.&lt;/li&gt;
&lt;li&gt;You might want to build the project using react-native run-android. If it fails, you might need to run it with Android studio.&lt;/li&gt;
&lt;li&gt;Make sure your ANDROID_HOME is in the path. Something like:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export ANDROID_HOME=/Users/[your user]/Library/Android/sdk 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For iOS, you need to install Pods once:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ios
pod install
pod update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This will install all the libraries to run the iOS version.&lt;/p&gt;
&lt;h3&gt;
  
  
  Troubleshooting iOS
&lt;/h3&gt;

&lt;p&gt;If you have problems running the iOS version, you can try the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Do a pod update and then pod install from inside the ios/ folder.&lt;/li&gt;
&lt;li&gt;Delete the ios/build folder.&lt;/li&gt;
&lt;li&gt;It is better not to change any build phases, rules, or settings in XCode as this may cause further issues.&lt;/li&gt;
&lt;li&gt;It is better not to update the packages listed in the package.json file or the ones inside ios/Pods. This is because these are the versions used in our testing.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Troubleshooting for both platforms
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Make sure you are not running any VPN. Sometimes this creates problems.&lt;/li&gt;
&lt;li&gt;If you have a React Native terminal window running, try closing it and run the command above again.&lt;/li&gt;
&lt;li&gt;You can run npm run clean from the root directory. This will clean old builds.&lt;/li&gt;
&lt;li&gt;You can delete the file &lt;strong&gt;package-lock.json&lt;/strong&gt;, and try running npm i again, but we do not recommend this because of compatibility issues.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Check the list of prerequisites before running this sample. You can find them &lt;a href="https://reactnative.dev/docs/getting-started"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 3. Debugging your React Native chat app
&lt;/h1&gt;

&lt;p&gt;From your iOS simulator, you can debug the application and see console outputs to Chrome. Press &lt;strong&gt;Command + D&lt;/strong&gt; to see a screen like below:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4ktl5i51z1xr00tymcf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk4ktl5i51z1xr00tymcf.png" alt="Debugging from iOS screen" width="644" height="827"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Debugging on iOS&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;When you click Debug in Chrome, a Chrome window will open. Use the Chrome developer tools to monitor the outputs written by &lt;strong&gt;console.log()&lt;/strong&gt;.&lt;/p&gt;
&lt;h1&gt;
  
  
  Step 4. Understanding the folder structure
&lt;/h1&gt;

&lt;p&gt;The following is a description of the most important files and folders for this sample application.&lt;/p&gt;
&lt;h4&gt;
  
  
  package.json
&lt;/h4&gt;

&lt;p&gt;This file contains all the packages this project will use. Because of compatibility issues, we recommend not changing the version of these packages.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntw1zmws8i9wwvf5fbaz.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fntw1zmws8i9wwvf5fbaz.png" alt="Dependencies for this sample application&amp;lt;br&amp;gt;
" width="800" height="282"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Dependencies for this sample application&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;The file also contains the scripts you can run:&lt;br&gt;
&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38jcndcvzshh9ptkhiyi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F38jcndcvzshh9ptkhiyi.png" alt="Code showing the scripts you can run" width="800" height="302"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Scripts you can run&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;Run npm run android to launch the Android version.&lt;/p&gt;

&lt;p&gt;Run npm run ios to launch the iOS version.&lt;/p&gt;

&lt;p&gt;Run npm run clean to clear any previous build.&lt;/p&gt;
&lt;h4&gt;
  
  
  node_modules
&lt;/h4&gt;

&lt;p&gt;This folder contains all the downloaded libraries this project will use. This folder is created every time you run npm i.&lt;/p&gt;
&lt;h4&gt;
  
  
  android
&lt;/h4&gt;

&lt;p&gt;This folder contains all the files for an Android project. You can use Visual Studio to open and run the project.&lt;/p&gt;
&lt;h4&gt;
  
  
  iOS
&lt;/h4&gt;

&lt;p&gt;This folder contains all the files for the iOS project. You can open it with Xcode.&lt;/p&gt;
&lt;h4&gt;
  
  
  src
&lt;/h4&gt;

&lt;p&gt;This folder contains all the Javascript files for our demo application.&lt;/p&gt;
&lt;h4&gt;
  
  
  index.js
&lt;/h4&gt;

&lt;p&gt;This is the first file to be executed by React Native.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/99216f6e02b28cba5b014c7fc5f66508"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We define which function will process the information when we receive a Push message, for Android devices. In this example, the function &lt;strong&gt;onRemoteMessage&lt;/strong&gt; will do the work. It is inside the &lt;strong&gt;./src/utils utils.js&lt;/strong&gt; file. &lt;/p&gt;

&lt;h4&gt;
  
  
  App.js
&lt;/h4&gt;

&lt;p&gt;This file is called from the file &lt;strong&gt;index.js&lt;/strong&gt;. It shows the first screen we see when users run our application.&lt;/p&gt;

&lt;p&gt;You will see where your Sendbird application ID (you can get this from your &lt;a href="https://dashboard.sendbird.com/auth/signin"&gt;Sendbird Dashboard&lt;/a&gt;) is defined:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/4d83e7a1080c3c0e965dd301b89aca06"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We are now ready to initialize the Sendbird SDK. At this point, we are not connected.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;
 

&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/8f1f596ebb7de6a87f90c65812ba54f2"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We will use our first Hook to ask permission to receive notifications. &lt;/p&gt;

&lt;p&gt;If we already have a token from Firebase, we use the Sendbird function &lt;strong&gt;registerAPNSPushtokenForCurrentUser&lt;/strong&gt; to register it for an &lt;strong&gt;iOS&lt;/strong&gt; device and &lt;strong&gt;registerGCMPushTokenForCurrentUser&lt;/strong&gt; for an &lt;strong&gt;Android&lt;/strong&gt; device.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/1b0c544d1ff592d8b26b696e2850e0db"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;View a detailed &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/push-notifications#1-push-notifications"&gt;tutorial&lt;/a&gt; about implementing Firebase for React Native. &lt;/p&gt;

&lt;p&gt;The next step is to define our Stack Navigator. A Stack Navigator provides a way for your app to transition between screens. Each new screen can be placed on top of a stack.&lt;/p&gt;

&lt;p&gt;By default, the stack navigator offers a familiar iOS and Android look and feel. New screens slide in from the right on iOS, and the default OS animation is used on Android. You can customize the animations to match your needs.&lt;br&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/6be5418dea0d8c81625c4024dba8b9ec"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 5. Building the Login component for your React Native chat app
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mfpmhjx4taujqzrjdjf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0mfpmhjx4taujqzrjdjf.png" alt="Login window" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Login window&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;The Stack Navigator will &lt;strong&gt;Lobby&lt;/strong&gt; first. This file is in &lt;strong&gt;./src/page/lobby.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Many Hooks are applied here, and the principal actor is &lt;strong&gt;currentUser&lt;/strong&gt;. Because it depends on the user previously signed, we will show a login screen or the list of &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/channel-types"&gt;chat channels&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;This sample uses &lt;strong&gt;AsyncStorage&lt;/strong&gt; to read (and save) the value of a previously signed user. If there’s a value, we read it and define that the user as initialized.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/bff4a3458cb6be6de00fb5305685e44c"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We build the screen accordingly. If we have a signed user, we show the &lt;strong&gt;Channels&lt;/strong&gt; component. Otherwise, we show the &lt;strong&gt;Login&lt;/strong&gt; screen.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/f6170ebfc9a36c9f9f860a8d9f8e879d"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the &lt;strong&gt;Login&lt;/strong&gt; component responds, the login function executes. We save this value in the &lt;strong&gt;AsyncStorage&lt;/strong&gt; and run the token registration for iOS and/or Android to receive &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/push-notifications#1-push-notifications"&gt;push notifications&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/e772c5f8f490e09d0c4f9e77f095f112"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The login screen will paint the screen we see above and wait for the user to click on the &lt;strong&gt;Connect&lt;/strong&gt; button.&lt;/p&gt;

&lt;p&gt;When clicked, the button calls the connect function connect.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/fcc8910371ee8a1a6b566e1b5caa8be9"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Connecting to Sendbird
&lt;/h3&gt;

&lt;p&gt;As you can see, the sendbird.connect(…) function call connects the device with the Sendbird servers via Websockets. If you see any error here, it is because the user ID selected is invalid, your Sendbird application ID is incorrect, the function is not defined, or because you’re not connected to the Internet. &lt;/p&gt;

&lt;p&gt;We suggest you check for any error code and inform your users.&lt;/p&gt;

&lt;h3&gt;
  
  
  Foreground and background
&lt;/h3&gt;

&lt;p&gt;You must check if your application goes to the background, for the following screens (channels, messages, etc.). If this happens, then you should invoke setBackgroundState. You will appear as disconnected for the rest of the users. Call setForegroundState once the application returns to the front. This will make Websockets connect again and the logged user appear online again.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/09534b05533e03763e08aa24e5cec70f"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After a successful connection, we store this user’s nickname (from the input screen) and return it to the Lobby component. Once the user is set, the &lt;strong&gt;Channels&lt;/strong&gt; screen appears.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 6. Building the Channels List component
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84jogry71psko5jwp5n7.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F84jogry71psko5jwp5n7.png" alt="Channels list" width="800" height="222"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Channels list&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;Sendbird works with public &lt;strong&gt;Open Channels&lt;/strong&gt; and &lt;strong&gt;Group Channels&lt;/strong&gt;. You don’t need an invitation, any user can enter a message, for the &lt;strong&gt;Open Channels&lt;/strong&gt;. &lt;strong&gt;Group Channels&lt;/strong&gt; are the opposite. You need an invitation to join the channel and send messages.&lt;/p&gt;

&lt;p&gt;To learn more about channel types, see &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/channel-types#1-channel-types"&gt;this page&lt;/a&gt; or &lt;a href="https://sendbird.com/developer/tutorials/understanding-channels"&gt;this tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now, open the ./src/page/channels.js file and see all the essential parts that should be there.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a connection handler to receive Websocket disconnections notifications. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Customers must know when the SDK is not connected because your application should stop all requests until a connection is made. Otherwise, your users will think that your application is not working.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Add a channel handler to receive updates from Sendbird about any events. You will be able to react to channel modifications, new messages, users being added or removed from channels, etc.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A channel handler helps your application to update visually and inform the customer about any changes made by other users. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/35b9d2fc74cd822d2bffef98d1c7b752"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, remember to remove your handlers when destroying each view.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/34077cc248cf4e6d626f9bdf9d705702"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Read more about connection and channel handlers &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/event-handler#1-event-handler"&gt;here&lt;/a&gt;. &lt;/p&gt;

&lt;h3&gt;
  
  
  Listing your channels
&lt;/h3&gt;

&lt;p&gt;When listing channels, the maximum number of records you can receive from the server is 100. If you need more, you must use next(…) to call the server again:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/127b561198d8b99a511e5a2d7290499d"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the user selects a channel, our application will navigate to the chat, passing the selected channel and current signed user.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/5019d9973dbb373aefb3aa34fc9cc526"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This leads us to the messages screen.   &lt;/p&gt;

&lt;h1&gt;
  
  
  Step 7. Building the Messages components
&lt;/h1&gt;

&lt;p&gt;After selecting a channel, the application will show you a list of messages for this channel only:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1c7u2i81ttb3q3m0kli.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff1c7u2i81ttb3q3m0kli.png" alt="Messages" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Messages&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;The code for this screen is in &lt;strong&gt;./src/page/chat.js&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Naturally, the list of messages is the most important part of this screen. But let’s take a look at other parts that must be included:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;A connection handler to manage disconnections and stop customers from sending messages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A channel handler to receive any changes related to the channels (including messages added, removed, etc.), via Websockets.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/01b5a3eb6f334cb75b66bcb1a1b9f5ee"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You need to remove these handlers when this view is no longer active for users.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/7bee990398d20803a15656ffd1466b7c"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this sample application, we will take action for the following events:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onMessageReceived&lt;/strong&gt;: A new message is received via Websocket. Add this new message to the list of messages only if the channel URL informed from the event is the same channel you have active in this view.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onMessageUpdated&lt;/strong&gt;: A message has been updated. If this informed message belongs to this active channel, you must update its content from the list.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onMessageDeleted&lt;/strong&gt;: A message has been deleted. If this informed message belongs to this active channel, you must remove it from the list.&lt;/p&gt;

&lt;p&gt;You can also receive events about to this user and the channel. For example:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onUserLeft&lt;/strong&gt;: If a user left the channel, you should check if the signed user ID matches the informed user ID. If both are the same, it means that you decided to leave the channel from another device. Your action should be something like going back to the main list of channels (channels.js).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;onChannelDeleted&lt;/strong&gt;: Another critical check is the existence of the channel that contains the messages you are showing. If this channel is missing for any reason, you should also return to the main screen with the list of remaining channels (channels.js).&lt;/p&gt;

&lt;h3&gt;
  
  
  Mark channel as read
&lt;/h3&gt;

&lt;p&gt;When you enter to see the messages in a channel, you should mark all messages as read. &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/b2f1150d50cb1017883873850d30a349"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Listing your messages
&lt;/h3&gt;

&lt;p&gt;We will ask Sendbird for the list of messages in this active channel. To do this, we use createPreviousMessageListQuery&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/b2f1150d50cb1017883873850d30a349"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To view more information, see &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-load-previous-messages"&gt;this page&lt;/a&gt;. You can also check out this &lt;a href="https://sendbird.com/developer/tutorials/designing-message-objects"&gt;tutorial&lt;/a&gt; about messaging objects.&lt;/p&gt;

&lt;p&gt;For this example, we list the last 50 messages. If more messages are available to show, you should call next() to get more data.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/710552845828c264feca5468e37d57e1"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting messages according to the timestamp
&lt;/h3&gt;

&lt;p&gt;You also can request a list of messages according to a specific timestamp. Use something like new Date().getTime() and define how many previous messages you want to show. &lt;/p&gt;

&lt;p&gt;This technique will help you load previous messages if the user scrolls up to get a long history of messages. You just need to keep sending the message’s timestamp and ask for previous records to show until you reach the first message sent to the channel.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/4f204794dd661dbdaeed954e28223d0d"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To find more information, check our &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-list-messages-along-with-their-replies-3-by-timestamp"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 8. Sending and receiving messages
&lt;/h1&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1sp9ze6s91v80s1eiog.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl1sp9ze6s91v80s1eiog.png" alt="Sending a message" width="800" height="602"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Sending a message&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;

&lt;p&gt;With Sendbird, you can send a text or a file message. &lt;/p&gt;

&lt;p&gt;Note that a message for Sendbird is not just a text or a file; we have other attributes to send confidential information to your server or to the other connected users. &lt;/p&gt;
&lt;h3&gt;
  
  
  Custom type
&lt;/h3&gt;

&lt;p&gt;This attribute is part of the message object, and it specifies a custom message type for message grouping. The length is limited to 128 characters.&lt;/p&gt;

&lt;p&gt;The Sendbird &lt;a href="https://sendbird.com/docs/chat/v3/platform-api/guides/advanced-analytics"&gt;Advanced Analytics&lt;/a&gt; also uses Custom types to segment metrics. They enable the sub-classification of data views.&lt;/p&gt;
&lt;h3&gt;
  
  
  Data
&lt;/h3&gt;

&lt;p&gt;Data is another attribute you can use for your internal logic. It specifies additional message information such as custom font size, font type, or any data you want to handle with a JSON formatted string.&lt;/p&gt;

&lt;p&gt;To find a list of attributes for a message, click &lt;a href="https://sendbird.com/docs/chat/v3/platform-api/guides/messages#4-list-of-properties-for-text-message"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To get more information about sending a message via the SDK and Javascript, see &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-send-a-message"&gt;this page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Below is the code to send a message.  &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h3&gt;
  
  
  File messages
&lt;/h3&gt;

&lt;p&gt;With Sendbird, you can also send file messages. In this application, we allow users to select the file from the device and then send it.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/01c7073f281d7d3962ef637d077922ac"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;span&gt;&lt;strong&gt;&lt;em&gt;Remember to request permission.&lt;/em&gt;&lt;/strong&gt;&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;When working with Android and iOS, you must request permission from users before using a file picker.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/ca0d119667480ef0e6b2cf2258fcddd7"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important&lt;/strong&gt;: Sendbird requires a Javascript &lt;strong&gt;File&lt;/strong&gt; object as the file to upload. You may receive errors or have a failed upload if trying to send another format. Sometimes, the custom file pickers used from public repositories don’t deliver the proper object type.&lt;/p&gt;

&lt;p&gt;Remember that when sending file messages, you cannot send text along with it. However, you can use other message object attributes to send a text and display it on the chat list. Check out the list of available attributes for a file message:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/7ed1bc74c3e2ff5724ea8698b998bda4"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;More information is in the &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-send-a-message"&gt;docs&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Thumbnails for image files
&lt;/h3&gt;

&lt;p&gt;When uploading image files, you can ask Sendbird to generate a thumbnail automatically. Enable this from your &lt;a href="https://dashboard.sendbird.com/auth/signin"&gt;dashboard&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86lcev65sopbq3chnwnk.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86lcev65sopbq3chnwnk.png" alt="A screenshot of enabling the auto thumbnail generator" width="800" height="476"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;&lt;em&gt;Enable auto thumbnail generator&lt;/em&gt;&lt;/center&gt;
&lt;br&gt;
&lt;h3&gt;
  
  
  Voice messages
&lt;/h3&gt;

&lt;p&gt;You can send voice messages with file messages. Your frontend application should implement a voice recording function and save the result as a file. Then you just upload that file, along with any of the custom attributes we provide for the message object, indicating that this is a voice message file. When drawing this message in the channel, analyze the information and show it properly.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qxjtl11ywrsyww3ts2f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2qxjtl11ywrsyww3ts2f.png" alt="Screenshot depicting a voice message" width="800" height="264"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;center&gt;Formatting a file message as a voice message&lt;/center&gt;
&lt;br&gt;
&lt;h3&gt;
  
  
  Reply to messages
&lt;/h3&gt;

&lt;p&gt;Sendbird supports message threading so you can respond to messages. &lt;/p&gt;

&lt;p&gt;To do this, you must indicate the parent message ID when sending a response.&lt;/p&gt;

&lt;p&gt;You can respond with a text message:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/ae8804a26a9dd49a262a8b0b74cf8bde"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Or with a file message:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/6747e2828741e505a84f2975130b75c0"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To learn more about messages, check out the &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-reply-to-a-message"&gt;docs&lt;/a&gt; and this &lt;a href="https://sendbird.com/developer/tutorials/designing-message-objects"&gt;tutorial&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Step 9. Other Sendbird features
&lt;/h1&gt;

&lt;p&gt;Sendbird offers a variety of features for your chat experience.&lt;/p&gt;

&lt;h3&gt;
  
  
  Typing indicators
&lt;/h3&gt;

&lt;p&gt;In this example, you can see the use of startTyping() and endTyping() to send events to all members in the channel.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;a href="https://gist.github.com/warodri-sendbird/a3071a18a82f594fdee524fbdd598dde"&gt;Gist&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This event triggers the onTypingStatusUpdated function from the &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/event-handler#4-list-of-open-channel-events"&gt;channel handler&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The rest is to show a label saying that user XXX is typing a message.&lt;/p&gt;

&lt;h3&gt;
  
  
  Moderation
&lt;/h3&gt;

&lt;p&gt;Sendbird provides powerful tools for moderation. You can use the Sendbird &lt;a href="https://dashboard.sendbird.com/auth/signin"&gt;Dashboard&lt;/a&gt; to moderate messages and users. You may also &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-register-operators"&gt;register&lt;/a&gt; or &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-cancel-the-registration-of-operators"&gt;unregister&lt;/a&gt; channel members as &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/user-types#2-operator"&gt;Operators&lt;/a&gt; so that they can &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-freeze-and-unfreeze-a-channel"&gt;freeze&lt;/a&gt; channels, &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-ban-and-unban-a-user"&gt;block&lt;/a&gt;, or &lt;a href="https://sendbird.com/docs/chat/v3/javascript/guides/group-channel#2-mute-and-unmute-a-user"&gt;mute&lt;/a&gt; users. &lt;/p&gt;

&lt;p&gt;To review all the features that Sendbird offers, check out our JavaScript &lt;a href="https://sendbird.com/docs/chat/v3/javascript/quickstart/send-first-message"&gt;docs&lt;/a&gt; and this tutorial for &lt;a href="https://sendbird.com/developer/tutorials/reporting-api-best-practice"&gt;moderation best practices&lt;/a&gt;.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;So that’s a wrap! Many more features are available in the JavaScript SDK, so make sure to check out &lt;a href="https://sendbird.gitbooks.io/sendbird-javascript-sdk/content/"&gt;the documentation&lt;/a&gt; to build an even more advanced messaging app.&lt;/p&gt;

&lt;p&gt;This tutorial gave you a taste for building a React Native chat app with the &lt;a href="https://sendbird.com/docs/chat/v3/javascript/quickstart/send-first-message"&gt;Sendbird JavaScript SDK&lt;/a&gt;. To learn more about React Native, refer to the &lt;a href="https://reactnative.dev/docs/getting-started.html"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you have any questions regarding this tutorial or using Sendbird in general, please drop us a note on our &lt;a href="https://community.sendbird.com/"&gt;community page&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thanks, and happy React Native chat building!&lt;/p&gt;

</description>
      <category>reactnative</category>
      <category>chat</category>
      <category>api</category>
      <category>sdk</category>
    </item>
  </channel>
</rss>
