0

Let's say I have class with Date property

class SomeModel {
    ..some properties
    let date: Date = Date(timeIntervalSince1970: 1505050)
    ..more properties
}

and I need to display it using this transformation (or any other, just example)

func createString(from date: Date) -> String {
     let formatter = DateFormatter()
     formatter.dateFormat = "MM dd yyyy HH:mm:ss"
     let stringifyDate = formatter.string(from: model.applicationDate)
     let monthSymbols = formatter.shortMonthSymbols
     let monthIndex = Calendar.current.component(.month, from: model.applicationDate)
     let monthName = monthSymbols![monthIndex-1]
     return monthName + String(stringifyDate.dropFirst(2))
}

Using Model-View-Presenter pattern, should I pass SomeModel to View and perform transformation there, what would be easier since other properties are String/Int and it is easy to display them. Or should I create properties for each SomeModel field

var someText: String {
    return model.someText
}

var stringDate: String {
    return createString(from: model.date)
}

..other properties

and then call updateUI like

func updateUI() {
    someLabel.text = presenter.someText
    dateLabel.text = presenter.stringDate
    ..other properties
}

Or even it is ok to combine both, but it sounds like bad idea since View gets Date property anyway.

JuicyFruit
  • 2,638
  • 2
  • 18
  • 35

2 Answers2

2

The view shouldn't be responsible for any transformation and manipulation of data. There are two possible way to overcome this problem:

  1. Create computed properties or methods in the model and use them in the view. I prefer computed properties because the code is more clean and understandable.
  2. Manage all the transformation and manipulation in the Presenter class. The aim of this class in the MVP Pattern is to take the model, do some stuff, and pass the final data to be presented at the view.

Both ways are correct, it depends on the context. Maybe the second way is more close to the pattern but it depends.

For some documentation about computed properties: https://developer.apple.com/library/content/documentation/Swift/Conceptual/Swift_Programming_Language/Properties.html#//apple_ref/doc/uid/TP40014097-CH14-ID259

Fab
  • 816
  • 8
  • 17
  • so you pass model having 2 properties `date: Date` and `stringDate: String {return ""}`? – JuicyFruit Jan 31 '18 at 11:22
  • 1
    Yes, A correct way is to have a private variable in the model (your Date) and all the public computed properties for accessing or modified the value from outside classes. – Fab Jan 31 '18 at 11:34
0

With MVP you want your Presenter layer doing all the custom display logic for the View layer and you don't want to do anything to your Model layer, it should just be a plain representation of how object is defined in the database).

Firstly I would create a custom init in a string extension file e.g.

extension String {

   init(from date: Date) {
       // custom logic goes here
   }
}

Then in your relevant Presenter just have a have a property that calls this extension class to do the data manipulation, this way other presenters can also use this logic e.g.

public class Presenter {

    public var customProperty: String {

       return String.init(from: model.date)        
    }
}
kd02
  • 422
  • 5
  • 14