The Presentation Model

Ben Sandofsky
Nov 20, 2017 · 8 min read

Preface: What Is and Isn’t MVC?

Our MVC Design

class InboxViewController:UIViewController, UITableViewDataSource {
var conversations:[Conversation] = []
var messageStore:MessageStore!
var tableView:UITableView!
func conversationsDidUpdate(_ notification:Notification){
conversations = messageStore.fetchAllConversations()
tableView.reloadData()
}
override viewDidLoad(){
super.viewDidLoad()
// Set up subscribers, etc
}
}

Problem 1: Complex Display Rules

Problem 2: Display State

Problem 3: Testing

Introducing the Presentation Model

class ConversationPresentation {
private var conversation:Conversation
init(_ conversation:Conversation){
self.conversation = conversation
}
var previewText:String {
guard let lastMessage = conversation.messages.last else {
return ""
}
if lastMessage.isPhoto {
return "Attachment: 1 Image"
} else {
return lastMessage.text
}
}
}
class InboxPresentation {
private var store:MessageStore
var conversations:[ConversationPresentation] = []
init(_ store:MessageStore){
self.store = store
self.refreshConversations()
self.subscribeToNotifications()
}
private func refreshConversations(){
self.conversations = store.conversations.map { conv in
return ConversationPresentation(conv)
}
postInboxNotification()
}
func messageStoreUpdated(_ notification:Notification){
self.refreshConversations()
}
}
var searchText:String? {
didSet {
refreshConversations()
}
}
private func refreshConversations(){
let filteredPresentations:Conversation
if let searchText = self.searchText {
filteredPresentations = store.conversations.filter { conv in
return conv.bodyContains(searchText)
}
} else {
filteredPresentations = store.conversations
}
self.conversations = filteredPresentations.map { conv in
ConversationPresentation(conv)
}
postInboxNotification()
}
func searchFieldDidUpdate(_ sender:Any){
self.inbox.searchText = self.searchField.text
}

What about MVVM?

Do these semantics matter?

The Trade Offs

class TaskPresentation {
var task:Task
init(_ task:Task){
self.task = task
}
var text:String {
return self.task.text
}
var important:Bool {
return self.task.important
}
}

Ben Sandofsky

Written by

Developer half of @halidecamera.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade