SwiftUI is a very new framework and currently has some bugs. However, building the same interface requires five times less code than would be written in any other environment. That’s exactly what I’ll show you in this tutorial.

1. Development environment

First, you must download the latest XCode 11.0 and macOS 10.15.

2. Create a new project in XCode

Create the first View

When you create a new project, you will see a completely new code structure. Don’t be afraid of the unknown. You have to learn it once, and then you can use it anywhere: on iOS, the new iPad OS, watchOS, even MacOS! The latest features on display at WWDC2019 show that if you can build an application for iOS, you can easily convert it to any other Apple platform with no additional knowledge.

Building applications in SwiftUI actually reminds me of creating websites using HTML editors from the early 21st century.

4. Add your first message to View

Ok, so let’s add some messages to this view. Replace your code with the code below and read all my comments carefully.

import SwiftUI

// let's create a structure that will represent each message in chat struct ChatMessage : Hashable { var message: String var avatar: String } struct ContentView : View { // let's add some dummy values to the messages
    // suppose, there are only two messages in the chat room sent by two users: A and B
    // A sent "Hello world" with a red message bubble color
    // B sent "Hi" with a blue message color
    var messages = [
        ChatMessage(message: "Hello world", avatar: "A"),
        ChatMessage(message: "Hi", avatar: "B")
    ]
    
    var body: some View {
      
        // I've removed the text line from here and replaced it with a list // List is the way you should create any list in SwiftUI  List { // we have several messages so we use the For Loop ForEach(messages.identified(by: \.self)) { // then we just show the avatars of the users and their messages // by using these two Text functions Text($0.avatar) Text($0.message) } } } } #if DEBUG struct ContentView_Previews : PreviewProvider { static var previews: some View { ContentView() } } #endifCopy the code

Now, what do you see

5. Add design to the information list

Now, let’s make these messages look like real message bubbles. To do this, we must add color var to the ChatMessage structure:

Struct ChatMessage: Hashable {var message: String var avatar: String var color: color} then we need to populate the message list with the color parameter:Copy the code

Var messages = [ChatMessage(message: “Hello world”, avatar: “A”, color:.red), ChatMessage(message: “Hi”, avatar: “B”, color: blue)]

Copy the code

List { ForEach(messages.identified(by: .self)) { Text($0.avatar) Text($0.message) .bold() .foregroundColor(Color.white) .padding(10) .background($0.color, cornerRadius: 10) } }

Isn't that cool? Guys, look, we made a message bubble in an iOS app by writing a few lines of code. Now let's line up the name with the message. To keep the contents of the For loop from getting too cluttered, let's take advantage of how easily code is formatted in SwiftUI. Create a new structure and place the text there:Copy the code

// ChatRow will be a view similar to a Cell in standard Swift struct ChatRow : View {

// we will need to access and represent the chatMessages here
var chatMessage: ChatMessage

// body - is the body of the view, just like the body of the first view we created when opened the project
var body: some View {
    // HStack - is a horizontal stack. We let the SwiftUI know that we need to place 
    // all the following contents horizontally one after another
    HStack {
        Text(chatMessage.avatar)
        Text(chatMessage.message)
            .bold()
            .foregroundColor(Color.white)
            .padding(10)
            .background(chatMessage.color, cornerRadius: 10)
    }
}
Copy the code

}

Copy the code

ForEach(messages.identified(by: .self)) { ChatRow(chatMessage: $0) }

! [](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/6/24/16b877a9cfa02743~tplv-t2oaga2asx-image.image ) You can use the avatar and style it if you wish. Bridge with the Swift UI using the old Swift file with network requests We have learned how to display messages in the message dictionary. But how do we get messages from other places, such as standard Swift files, where we can use old popular libraries and frameworks to handle all parts of the network? And... How do we send our own messages? First, let's create a standard Swift file without SwiftUI support:! [](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2019/6/24/16b877d418784b02~tplv-t2oaga2asx-image.image Name it ChatController.swift and put it in the SwiftUI Chat folder. We will use this file as a bridge between the old Swift code and the new code written with SwiftUI. This means that you can use the ChatController file to connect to your database using Google FireBase. The data is then extracted and sent to SwiftUI View. To make it work, we will have to import the Combine and SwiftUI frameworks.Copy the code

import Combine import SwiftUI

// ChatController needs to be a BindableObject in order // to be accessible by SwiftUI class ChatController : BindableObject { // didChange will let the SwiftUI know that some changes have happened in this object // and we need to rebuild all the views related to that object var didChange = PassthroughSubject<Void, Never>()

// We've relocated the messages from the main SwiftUI View. Now, if you wish, you can handle the networking part here and populate this array with any data from your database. If you do so, please share your code and let's build the first global open-source chat app in SwiftUI together
var messages = [
    ChatMessage(message: "Hello world", avatar: "A", color: .red),
    ChatMessage(message: "Hi", avatar: "B", color: .blue)
]

// this function will be accessible from SwiftUI main view
// here you can add the necessary code to send your messages not only to the SwiftUI view, but also to the database so that other users of the app would be able to see it
func sendMessage(_ chatMessage: ChatMessage) {
    // here we populate the messages array
    messages.append(chatMessage)
    // here we let the SwiftUI know that we need to rebuild the views
    didChange.send(())
}
Copy the code

}

Copy the code

var window: UIWindow? var chatController = ChatController()

Copy the code

let window = UIWindow(frame: UIScreen.main.bounds) window.rootViewController = UIHostingController(rootView: ContentView().environmentObject(chatController)) self.window = window

In the main SwiftUI view file called ContentView.swift, we should also add the new environmentObject to Debug to make it accessible by preview:Copy the code

#if DEBUG struct ContentView_Previews : PreviewProvider { static var previews: some View { ContentView() .environmentObject(ChatController()) } } #endif

### 7. Add a TextField and a button to send messagesDon't lose your energy! We're almost done. Now we need to add a TextField and a Button to send the message. Check the current version of the contentView.swift file for changes and comments:Copy the code

import SwiftUI

// let’s create a structure that will represent each message in chat struct ChatMessage : Hashable { var message: String var avatar: String var color: Color // isMe will be true if We sent the message var isMe: Bool = false }

struct ContentView : View {

// @State here is necessary to make the composedMessage variable accessible from different views @State var composedMessage: String = "" @EnvironmentObject var chatController: ChatController var messages = [ ChatMessage(message: "Hello world", avatar: "A", color: .red), ChatMessage(message: "Hi", avatar: "B", color: .blue) ] var body: some View { // the VStack is a vertical stack where we place all our substacks like the List and the TextField VStack { // I've removed the Hello World text line from here and replaced it with a list // List is the way you should create any  list in SwiftUI List { ForEach(chatController.messages.identified(by: \.self)) { // we have several messages so we use the For Loop ChatRow(chatMessage: $0) } } // TextField are aligned with the Send Button in the same line so we put them in HStack HStack { // this textField generates the value for the composedMessage @State var TextField($composedMessage, placeholder: Text("Message..." )).frame(minHeight: 30) // the button triggers the sendMessage() function written in the end of current View Button(action: sendMessage) { Text("Send") } }.frame(minHeight: 50).padding() // that's the height of the HStack } } func sendMessage() { chatController.sendMessage(ChatMessage(message: composedMessage, avatar: "C", color: .green, isMe: true)) composedMessage = "" }Copy the code

}

// ChatRow will be a view similar to a Cell in standard Swift struct ChatRow : View { var chatMessage: ChatMessage

// body - is the body of the view, just like the body of the first view we created when opened the project var body: some View { Group { // if the message is sent by the user, // show it on the right side of the view if ! chatMessage.isMe { // HStack - is a horizontal stack. We let the SwiftUI know that we need to place // all the following  contents horizontally one after another HStack { Text(chatMessage.avatar) Text(chatMessage.message) .bold() .foregroundColor(Color.white) .padding(10) .background(chatMessage.color, cornerRadius: 10) // Spacer fills the gaps of the Horizontal stack between the content and the borders Spacer() } } else { // else show the message on the left side HStack { Spacer() Text(chatMessage.message) .bold() .foregroundColor(Color.white) .padding(10) .background(chatMessage.color, cornerRadius: 10) Text(chatMessage.avatar) } } } }Copy the code

}

#if DEBUG struct ContentView_Previews : PreviewProvider { static var previews: some View { ContentView() .environmentObject(ChatController()) } } #endif

For this to work, you should run the application on the iOS emulator: You will then see the message from the ChatController along with the new TextField and "Send" button. To send a message, click TextField and then press Cmd + K to display the keyboard (the new XCode still has some bugs with the hardware keyboard, so we had to switch the software keyboard). Enter the message "What are up guys?" . Press Cmd + K again to hide the emulator's keyboard, then press the "Send" button.# # #SwiftUI is a new framework that helps us create more features and write less code. Still, it's new and there isn't much documentation on how to do what you want to do, so I've tried to be very informative in this article and describe each step as clearly as possible.Copy the code