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

Swift India Conf 2019: Building engaging tips for non tech savvy users

Swift India Conf 2019: Building engaging tips for non tech savvy users

Speaker: Abhishek Pandey, Senior iOS Engineer, Flipkart

LinkedIn: https://www.linkedin.com/in/abhishek-pandey-25432746/

Bio: I am senior iOS developer in Flipkart. Being a big Apple fan I love Apple’s app development ecosystem. I have written many apps for Mac, iPhone and Apple Watch. I have been part of App development team which are featured by Apple on macOS and iOS. I have been working on swift since its inception and have seen its evolution into the powerhouse it is today. Recently I have been doing a lot of cross-platform development also. Ironically, doing a lot of cross-platform development made me love swift even more. Being a foodie, cooking is my second love after coding. When I am not coding, I am probably in a cricket ground or in my kitchen.

Abstract: With the easy availability of mobile devices and the Internet, we now have many users who are not very used to apps. They come to our app with some intent like 'buy shoes', 'cancel order' etc but get overwhelmed by the complexity of the app. These are first-time mobile apps users and they are not aware of common interaction of apps like 'scroll', 'swipe', 'tap' etc. I will like to talk about how we are trying to tackle this problem with our Guided Navigation framework in Flipkart.


Swift India

July 28, 2019


  1. Building engaging tips for non tech savvy users Abhishek Pandey

    iOS Engineer @ Flipkart
  2. Confusion! /kənˈfjuːʒ(ə)n/ uncertainty about what is happening, intended, or required.

  3. Traditional tips

  4. Problems with tips Can’t work with dynamic content. Can’t be

    flexible. Can’t be engaging.
  5. Why static tips won’t work with apps like Flipkart? Completely

    dynamic Content. Reusable ui components and recycling. Configurability and A/B support. Widgets
  6. Attempt 1 With dynamic content, deliver dynamic tips also. Add

    some more variety of tips like animating point, audio support etc.
  7. How can it be more engaging? Remember user’s interaction history,

    and deliver tips on the fly while he/she interacts with App.
  8. Triggering and dismissal rules Events - Tap, Pan, KeyStroke, Activation

    etc Operators - AND, OR, NOT. Operands - Events Rules - Any valid expression with Operator and Operands. Ex- (Tap AND Activation) OR Scroll
  9. Basic rule evaluator based on expression tree //Expression tree node.

    protocol ExpTreeNode { //Operand or Operator var type: String { get } //truth value based on event history var truthValue: Bool { get } //math events from users and update truth value func match(withEvent: GNEvents) }
  10. Expression tree evaluator protocol ExpressionTreeEvaluator { //root node var rootNode:

    ExpTreeNode { get } //recursively evaluate truth value of expression tree func eval() -> Bool }
  11. class GNExpressionTreeEvaluator: ExpressionTreeEvaluator { let rootNode: ExpTreeNode init(rootNode: ExpTreeNode) {

    self.rootNode = rootNode } func eval() -> Bool { //Evaluate truth value based on history return rootNode.truthValue } func consume(event: GNEvents) { //cosume events and distribute in the tree self.rootNode.match(withEvent: event) } }
  12. //Simple task example which consumes events and build event history.

    It evaluates trigger and dismissal rules class GNTask: Task { private let invocationExpEval: GNExpressionTreeEvaluator private let dismissalExpEval: GNExpressionTreeEvaluator init(invocationExpEval: GNExpressionTreeEvaluator, dismissalExpEval: GNExpressionTreeEvaluator) { self.invocationExpEval = invocationExpEval self.dismissalExpEval = dismissalExpEval } func consumeEvent(event: GNEvents) { self.invocationExpEval.consume(event: event) let isInvocationSatisfied = invocationExpEval.eval() self.dismissalExpEval.consume(event: event) isDismissalSatisfied = dismissalExpEval.eval() } }
  13. A basic context aware tips delivery system Tip task Consume

    and build history Evaluate and trigger or dismiss Events Trigger Or Dismissal
  14. Guided Navigation framework Tasks [taskID: Task] Renderer S c h

    e d ul er Observes state Containers Events Building history and evaluating rules
  15. A basic task class Task: NSObject { open var taskID:

    String //maintain a state with task. State changes based on expression-tree’s truth value @objc open dynamic var state: Int = TaskState.waiting.rawValue init(taskID: String) { self.taskID = taskID } }
  16. Basic task scheduler class TaskScheduler: NSObject { var activeTasks =

    [String: Task]() var pausedTasks = [String: Task]() var waitingTasks = [String: Task]() private var listOfObservations = [String: NSKeyValueObservation]() //Add task and observe state. func addTask(task: Task) { let observation = task.observe(\Task.state, options: [.new, .old, .initial]) { [weak self] (task, change) in guard let strongSelf = self else { return } if let oldState = change.oldValue, let newValue = change.newValue { strongSelf.taskStatusChanged(forTask: task, oldState: TaskState(rawValue: oldState)!, newState: TaskState(rawValue: newValue)!) } } listOfObservations[task.taskID] = observation } }
  17. switch newState { //Call respective run() pause() resume() or kill()

    based on tasks observed state. case .active: activeTasks[task.taskID] = task if oldState == .paused { task.resume() } else { task.run() } case .paused: pausedTasks[task.taskID] = task task.pause() case .waiting: waitingTasks[task.taskID] = task case .finished: self.listOfObservations[task.taskID]?.invalidate() self.listOfObservations[task.taskID] = nil task.kill() } Task state management
  18. Demo of flipkart home page with rule based tip delivery

    Demo of rules and evaluation. Demo of pause and resuming. Demo if trigger and dismissal rule evaluation and trigger.
  19. What did we achieve? All the tips, help content can

    be stored on server. Configured anytime and delivered anytime with all the trigger and dismissal rules. Hardcoding - Removed!!
  20. What did we achieve? Context aware, more engaging tips. They

    don’t act dumb, they guided you when you need them most. Boring, non engaging tips - Removed!!
  21. What’s pending? • Support for more accents. AVSpeechSynthesizer doesn’t support

    many vernacular languages. • More variety of tips to drive more confidence in users.
  22. Thank you Suggestions? Questions?