Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Tech Stack to Build a Customizable Chat App for...

Tech Stack to Build a Customizable Chat App for iOS

Building a chat app wraps most of the functionalities provided by a smartphone, so it is essential to get your technology stack right. This presentation show what you can use to create your own.

Bruno Guerios
github.com/brunoguerios
facebook.com/brunoguerios

Cheesecake Labs

March 21, 2017
Tweet

More Decks by Cheesecake Labs

Other Decks in Technology

Transcript

  1. Agenda • Intro • Motivation • Tech Stack ◦ MongooseIM

    ◦ XMPPFramework ◦ JSQMessagesViewController ◦ NSFetchedResultsController • Conclusion • Reference
  2. Intro • Chat messages ◦ Push notification • Media messages

    ◦ Camera and microphone • Location messages ◦ Core Location and Maps • Persist messages ◦ Core Data • Backup ◦ Cloud Kit • Save Media ◦ Photos framework • Contacts ◦ Contacts Framework • ... Building a chat app wraps most of the functionalities provided by a smartphone:
  3. Intro Payed • https://sendbird.com/ • https://quickblox.com/ • http://layer.com/ • ...

    Open Source • http://chatsdk.co/ • https://actor.im • ... There are several solutions to implement a chat service:
  4. Tech Stack • XMPP Server ◦ MongooseIM • XMPP Client

    (iOS) ◦ XMPPFramework • Chat UI ◦ JSQMessagesViewController • Data source performance ◦ NSFetchedResultsController
  5. XMPPFramework • XMPPFramework provides a core implementation of the XMPP

    standard ◦ XMPP - eXtensible Messaging and Presence Protocol • It is massively parallel and thread-safe • It has a modular architecture with multiple popular extensions - XEP's ◦ XMPPRoster ◦ XMPPMessage ◦ XMPPMessageArchiving (XEP-0136) ◦ XMPPLastActivity (XEP-0012) ◦ XMPPBlocking (XEP-0191) ◦ XMPPMUCLight ◦ ... • Relies on MulticastDelegate
  6. XMPPFramework • XXMPP Stanzas ◦ Example - Sending a message

    <message from='romeo@forza' to='juliet@pronto'> <body>M'lady, I would be pleased to make your acquaintance.</body> </message> ◦ Example - Replying a message <message from='juliet@pronto' to='romeo@forza'> <body>Art thou not Romeo, and a Montague?</body> </message>
  7. XMPPFramework • Example - XMPPRoster class XMPPClientManager: NSObject { ...

    func setupRoster() { self.xmppRoster = XMPPRoster(rosterStorage: self.xmppRosterStorage) self.xmppRoster.autoClearAllUsersAndResources = false self.xmppRoster.activate(self.xmppStream) self.xmppRoster.addDelegate(self, delegateQueue: DispatchQueue.main) } ... }
  8. XMPPFramework • Example - XMPPRoster extension XMPPClientManager: XMPPRosterDelegate { func

    xmppRoster(_ sender: XMPPRoster!, didReceivePresenceSubscriptionRequest presence: XMPPPresence!) { } func xmppRoster(_ sender: XMPPRoster!, didReceiveRosterPush iq: XMPPIQ!) { } func xmppRosterDidBeginPopulating(_ sender: XMPPRoster!, withVersion version: String!) { } func xmppRosterDidEndPopulating(_ sender: XMPPRoster!) { } func xmppRoster(_ sender: XMPPRoster!, didReceiveRosterItem item: DDXMLElement!) { } }
  9. JSQMessagesViewController (UI) • Easily customizable • Easily extensible • Very

    well documented • Large community to help • Widely adopted ◦ +10k stars on Github
  10. NSFetchedResultsController (Performance) • Efficient way to load hundreds of items

    into a table view • Seamless integration between Core Data and UITableViewDataSource • Seamless integration between Core Data and UICollectionViewDataSource • Infinite scroll for free
  11. NSFetchedResultsController (Performance) NSFetchedResultsControllerDelegate func controllerWillChangeContent(controller: NSFetchedResultsController) { } func controllerDidChangeContent(controller:

    NSFetchedResultsController) { } func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) { } func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { }
  12. NSFetchedResultsController (Performance) func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex:

    Int, forChangeType type: NSFetchedResultsChangeType) { switch type { case .Insert: tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) case .Delete: tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: .Fade) case .Move: break case .Update: break } }
  13. NSFetchedResultsController (Performance) func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath:

    NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) { switch type { case .Insert: tableView.insertRowsAtIndexPaths([newIndexPath!], withRowAnimation: .Fade) case .Delete: tableView.deleteRowsAtIndexPaths([indexPath!], withRowAnimation: .Fade) case .Update: // Update cell content case .Move: tableView.moveRowAtIndexPath(indexPath!, toIndexPath: newIndexPath!) } }
  14. NSFetchedResultsController (Performance) UITableViewController var fetchedResultsController: NSFetchedResultsController! override func tableView(tableView: UITableView,

    cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCellWithIdentifier("cellIdentifier", forIndexPath: indexPath) // Set up the cell return cell } override func numberOfSectionsInTableView(tableView: UITableView) -> Int { return fetchedResultsController.sections?.count ?? 0 } override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return fetchedResultsController.sections?[section].numberOfObjects ?? 0 }
  15. Conclusion • XMPPFramework ◦ Only go with XMPPFramework if you

    need a customized behavior ◦ Powerful, but time consuming • Tips ◦ Make sure you know your tools ▪ Study them before using in a project ◦ Careful when binding the behavior of a framework with your app ▪ Add an interface to make them work independently
  16. Reference • Open source chat apps ◦ https://github.com/dkhamsing/open-source-ios-apps#communication • Libs/frameworks

    ◦ https://github.com/vsouza/awesome-ios#messaging • MongooseIM ◦ https://github.com/esl/MongooseIM • XMPPFramework ◦ https://github.com/robbiehanson/XMPPFramework • JSQMessagesViewController ◦ https://github.com/jessesquires/JSQMessagesViewController • UITableView + NSFetchedResultsController ◦ https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/CoreData/nsf etchedresultscontroller.html