When building a chat application, it's not uncommon to see the list of friends and the status of Friends. Apps like WhatsApp have this feature, it's very useful to check the status of your friends and know if it's wise to send them a message at that time.
We'll build a similar feature in a fictitious iOS chat app. We'll use pusher to implement real-time functionality for your application so that when someone publishes a new status update, you can see it change in real time.
Here is the screen record after we complete the application.
To follow this article, you must have the following requirements:
- Have some knowledge about Swift 3?
- Knowledge of how to use Xcode?
- Basic JavaScript knowledge----NPM and Cocoapods installed on your computer.
- Basic knowledge of the terminal (command line)?
- Pusher application (you will need the application's ID, secret, key, and cluster). If you do not currently have an account, please create a pusher account.
I am an iOS developer and intend to get in-depth knowledge of this industry's friends and can follow me or private messages to me.
iOS Learning Exchange Group: 638302184, the group has a systematic learning course and learning route and detailed planning, hope to help developers less detours.
Get ready for our project
To get started, we need to create an iOS project and then install some of the dependencies required for the application to function properly. Let's get started.
Set up our project in Xcode start Xcode on your machine and create a new project. Create an application project and follow the wizard until you reach the main storyboard. Once you're there, quit Xcode.
In your terminal, CD into the Xcode project directory, and then run the following command:
$ pod Init
This will podfile create an interior at the root of your application. Podfile is where we will define cocoapods dependencies. Open in a text editor and replace with the following:
Platform:ios, ' 8.4 '
Target ' project_name ' do
use_frameworks!
Pod ' pusherswift ', ' ~> 4.0 '
Pod ' Alamofire ', ' ~> 4.4 '
End
Above, we have just specified the dependencies we want Cocoapods to install into our application. Don't forget to replace PROJECT_NAME with your actual project name.
Now go to the terminal and run the command:
$ pod Install
This should install all of the dependencies and library Podfile we have specified. Open the project directory and double-click the. xcworkspace file in the catalog to start the project workspace in Xcode.
Create a user interface for our live iOS app
Now that we've created the project in Xcode and successfully installed all of the dependencies, what we're going to do is create the user interface for the iOS app. Main.storyboard Open the file in Xcode, let's start designing the UI.
This is what we want at the end of this section:
Add a navigation controller to the canvas and set it as the root view controller. After you do this, you need to update the Tableviewcontroller attachment to the navigation controller.
First, create a new class with Xcode CTRL + N; The class name should be Friendsviewcontroller, and it should extend Uitableviewcontroller. Then, in the Main.storyboard file, make sure that you tableviewcontroller use it friendsviewcontroller as its custom class.
Configure a prototype cell?
Now that we have created the table view controller, we need to configure its cells to match the target we are trying to achieve.
Click "Prototype Cells" on the main storyboard file and make the property inspector look close to the image below.
The last thing we can do (completely optional) is to change the navigation bar color of our app. Let's do that.
Open appdelegate the class and in the application (_ Application:uiapplication, didfinishlaunchingwithoptions launchOptions: [ Uiapplicationlaunchoptionskey:any]?) method, paste the following content:
Uinavigationbar.appearance (). Bartintcolor = Uicolor (red:18.0/255.0, green:140.0/255.0, blue:126.0/255.0, alpha:1.0)
Uinavigationbar.appearance (). Tintcolor = Uicolor.white
Uinavigationbar.appearance (). Titletextattributes = [NSForegroundColorAttributeName:UIColor.white]
With this, you've finished creating the UI for your application, and all that's left is the ability to support it. Now let's do it.
The ability to create our live iOS app
For the function, we divide it into two parts. The first section will focus on adding functionality to update the status, and the second part will focus on real-time updates.
To create the initial function: U * * * * pdate?status? Allow Friendsviewcontroller to open and make some modifications. The first modification is to add an Update status button to the upper-right corner of the navigation bar.
In the method of the Viewdidload controller, add the following code:
Navigationitem.title = "Friends List"
Navigationitem.rightbarbuttonitem = Uibarbuttonitem (
Title: "Status",
Style:. Plain,
Target:self,
Action: #selector (ShowPopup (_:))
)
The above code simply sets the controller's title in the navigation bar and adds a button to the right of the navigation bar.
If you notice that in the action argument it points to a method, ShowPopup so let's create this method. Add this method to the controller:
Public Func ShowPopup (_ Sender:any) {
Let Alertcontroller = Uialertcontroller (
Title: "Update Your Status",
Message: "What would your status to say?",
Preferredstyle:. Alert
)
alertController.addTextField(configurationHandler: {(_ textField: UITextField) -> Void in textField.placeholder = "Status" }) alertController.addAction(UIAlertAction(title: "Update", style: .default, handler: {(_ action: UIAlertAction) -> Void in let status = (alertController.textFields?[0].text)! as String self.postStatusUpdate(message: status) })) alertController.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil)) present(alertController, animated: true, completion: nil)}
So what we're doing here is that when the operation is invoked and the method is showpopup called, the application displays a popup that asks the user to enter its state.
Now, the popup calls a method that Poststatusupdate does not exist in our application. Now let's create this method.
In the view controller, add the following method:
public func poststatusupdate (message:string) {
Let params:parameters = ["username": username, "status": Message]
Alamofire.request(FriendsViewController.API_ENDPOINT + "/status", method: .post, parameters: params).validate().responseJSON { response in switch response.result { case .success: _ = "Updated" case .failure(let error): print(error) } }}
In this approach, we are using the Alamofire library to make a request to the endpoint Friendsviewcontroller.api_endpoint + "/status" (not yet present). Now, because we did not import the Alamofire library, nor did we define friendsviewcontroller.api_endpoint we would get the error.
At the top of the view controller, import the Alamofire library:
Import ' Alamofire '
Also, inside the class, after the class definition, add the following to declare Api_endpoint which will point to the remote HTTP server.
static Let Api_endpoint = "http://localhost:4000";
The endpoint we are using now is the local server, which will be created later in this article. If you use a remote server, you need to replace this value with the server's URL.
So now, when you run the application and click the Status button, it pops up a dialog box where you can enter an update. However, since we have not created the backend to respond to this call, it will fail and will not take any action. We'll talk about it in a later article.
Update default table View Controller method by default, table View Controller? With some methods, we will quickly change them to fit our application.
Open the View controller and update the method numberofsections. Sets the return value of 1. This ensures that the first and only parts are displayed.
Next, update the TableView (Tableview:uitableview, Numberofrowsinsection:section) method and create the return value Friends.count. This will ensure that you create an appropriate amount of rows for each entry in the Friends list.
To make the cell display details for each friend, TableView (Tableview:uitableview, Cellforrowat Indexpath:indexpath) uses the following code to update the contents of the method:
Let cell = Tableview.dequeuereusablecell (withidentifier: "Friends", For:indexpath)
var status = friends[indexPath.row]["status"]if status == "" { status = "User has not updated status!"}cell.detailTextLabel?.textColor = UIColor.graycell.imageView?.image = UIImage(named: "avatar.png")cell.textLabel?.text = friends[indexPath.row]["username"]cell.detailTextLabel?.text = statusreturn cell
The above code simply gets the current cell and updates the desired cell label with the status, user name, and image (in case you want to add another image).
Finally, add a new method to the View controller:
Override Func TableView (_ Tableview:uitableview, Heightforrowat indexpath:indexpath), CGFloat {
Return 75.0
}
This will only increase the row height of the table to equal 75.0. This will make it easier to adapt to the contents of the cell.
Add real-time update status to our iOS app using pusher
Now, before we add the live online status update using pusher, we want to add some sort of pseudo-friends list.
We will use pusher to make friends list. We will do this by creating a non-persistent class property, and in this variable, we will store the details of any person who is online.
Add a list of pseudo friends? In the view controller, add some new properties:
var friends: [[string:string]] = []
var username:string = ""
var pusher:pusher!
The Friends property stores all online users, and the Username property stores a random user name for the current user, and the Pusher property stores the pusher library instance.
Now, in the Viewdidload method, add the following code:
Username = "Anonymous" + String (Int (arc4random_uniform (1000)))
listenForRealtimeEvents()// --- Update online presence at intervals --- //let date = Date().addingTimeInterval(0)let timer = Timer(fireAt: date, interval: 1, target: self, selector: #selector(postOnlinePresence), userInfo: nil, repeats: true)RunLoop.main.add(timer, forMode: RunLoopMode.commonModes)
In line 1th, we simply use the Username property random string as the user name.
In line 3rd, we call a method that listenforrealtimeevents does not yet exist (we'll create it later).
And on the 第6-8 line, we just basically added a loop call to Postonlinepresence (which doesn't exist yet). This phone will update your online status every second.
Listenforrealtimeevents Now let's create the method. Add the following code to the view controller:
Private Func listenforrealtimeevents () {
Pusher = Pusher (key: "Pusher_key", Options:pusherclientoptions (Host:. Cluster ("Pusher_cluster")))
let channel = pusher.subscribe("new_status") let _ = channel.bind(eventName: "online", callback: { (data: Any?) -> Void in if let data = data as? [String: AnyObject] { let username = data["username"] as! String let index = self.friends.index(where: { $0["username"] == username }) if username != self.username && index == nil { self.friends.append(["username": username, "status": "No Status"]) self.tableView.reloadData() } } }) pusher.connect()}
In the method we just created, we instantiated the pusher library using the pusher key and the application cluster. Then we subscribed to a pusher channel named New_status, and on that channel we started listening to events called online.
In the callback, when the event listener is triggered, we get the user name from the event. We then check to see if there is a user name in the Friends match list. If not, we attach it to the Friends List and reload the tabular data.
So, all in all, each time someone goes online, the name is appended to the Friends list and re-loaded into the table view.
Next, we'll create a way for postonlinepresence to periodically publish the current user's online status so that others can select it. Add the following code to the view controller:
public func postonlinepresence () {
Let params:parameters = ["username": Username]
Alamofire.request(FriendsViewController.API_ENDPOINT + "/online", method: .post, parameters: params).validate().responseJSON { response in switch response.result { case .success: _ = "Online" case .failure(let error): print(error) } }}
The code above simply clicks on an endpoint to mark the user as online.
Use pusher to add status updates to your application? The last part of our iOS app adds an updated listener so that updates are added every time someone updates their state.
To do this, open the Listenforrealtimeevents method and add the following after instantiating the push variable:
Let channel = Pusher.subscribe ("Newstatus")
let = Channel.bind (eventName: "Update", Callback: {(data:any?)-Void in
If let data = data as? [String:anyobject] {
Let username = data["username"] as! String
let status = data["status"] as! String let index = self.friends.index(where: { $0["username"] == username }) if index != nil { self.friends[index!]["status"] = status self.tableView.reloadData() } }})
The above code creates a listener for the update event for the New_status channel. When an event is triggered, the callback checks to see if the user name is part of the list of friends. If it is, the state of the entry is updated and the table view data is re-loaded.
We have now successfully added real-time functionality to our applications. The next thing we do is create a backend to help us actually trigger the pusher event that can be picked up by our iOS app.
Create Nodejs backend for our live iOS status update application
Create a directory for your Web application, and then create some new files:
Index.js
------------------------------------------------------//Import all required packages and files//----------------- -------------------------------------Let pusher = require (' pusher '), let Express = require (' Express '), let app = Express (); Let Bodyparser = require (' body-parser ') let pusher = new pusher (Require ('./config.js '));//--------------- ---------------------------------------//Set up Express middlewares//-------------------------------------------- ----------App.use (Bodyparser.json ()); App.use (bodyparser.urlencoded ({extended:false}));//---------------------- --------------------------------//Define routes and logic//------------------------------------------------------ App.post ('/status ', (req, res, next) = {Let payload = {username:req.body.username, status:req.body.status}; Pusher.trigger (' New_status ', ' Update ', payload); Res.json ({success:200});}); App.post ('/online ', (req, res, next) = {Let payload = {Username:req.body.username}; Pusher.Trigger (' new_status ', ' online ', payload); Res.json ({success:200});}); App.get ('/', (req, res) = {Res.json ("It works!"); /------------------------------------------------------//Catch errors//---------------------------------------- --------------App.use (req, res, next) = {Let err = new Error (' Not Found: '); Err.status = 404; Next (err);}); /------------------------------------------------------//Start application//----------------------------------- -------------------App.listen (4000, () = Console.log (' app listening on port 4000! '));
In this file, we created a basic Express application. The application has two important endpoints: Post/online and Post/status. They all trigger the pusher event and are picked up by the listener in our iOS app.
Next, create the Config.js file:
Module.exports = {
AppId: ' pusher_id ',
Key: ' Pusher_key ',
Secret: ' Pusher_secret ',
Cluster: ' Pusher_cluster ',
};
This is our pusher configuration file. Here, replace the empty string with the voucher provided in your fader dashboard.
Finally, create a Package.json file:
{
"Main": "Index.js",
"Dependencies": {
"Body-parser": "^1.16.0",
"Express": "^4.14.1",
"Pusher": "^1.5.1"
}
}
This file contains all the node packages that are required by the node application to function properly.
Finally, in the directory of the node application, run the following command:
$ NPM Install && node index.js
The first command installs all the dependencies, and the second command launches an express server in the node. When you see the message "?" the application listens on port 4000! "? * * when you know your back-end application is ready.
Test our real-time status update application
Once the local node Web server is running, you need to make some changes so that your application can communicate with the local Web server. In the Info.plist file, make the following changes:
With this change, you can build and run your application, and you can speak directly to your local Web application.
Conclusion
In the article, we've been able to create an iOS app with real-time user status updates, similar to WhatsApp's current application.
How to build status updates for real-time users in iOS