class Event {
var name : String?
var FullDate : NSDate?
var date: String? {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEEE MMM dd"
return dateFormatter.stringFromDate(FullDate!)
}
init ()
}
class EventsViewController: UIViewController, UITableViewDelegate , UITableViewDataSource
{
let Event1 = Event()
override func viewDidLoad() {
super.viewDidLoad()
Event1.date = "10.01.16" // here is the issue
Event2.date = "12.11.16" // "" "" "" ""
}
I dont understand why I can use the FullDate variable from my custom class Event but not the date variable. thanks for your help
Your date is actually a computed property
that only has a getter
So it can only be read, not written too.
In contrast your FullDate
is a stored property
.
computed properties
are often used to hide functionality from other classes or expose buried data in a convenient way.
Below there is some illustration in the SomeClass
object.
stored properties
are just regular old propertiescomputed properties
are getters
and maybe also setters
. A good example is height
and width
of CGRect
, these are actually from CGRect.size
but are implemented as convenience getters
property observers
are functions executed when stored properties
change value. didSet
and willSet
access control
on get
and set
allows you to create stored properties
that are read or write only depending on access.class SomeClass {
// just a variable
var storedProperty : Int = 10
// just a variable but the setter is hidden from other "files"
private(set) var storedPropertyWithPartialAccessControl : Int = 0
// only calculates when set
var derivedProperty : Int = 0 {
didSet {
storedProperty = doStuffs(derivedProperty)
}
}
// calculates every get and set
var computedProperty : Int {
get { // get is needed
return doStuffs(storedProperty)
}
set(value) { // set is not needed, using only get gives you a read only property
storedProperty = doReverseStuffs(value)
}
}
// hidden functions that are used in the computed property
private func doStuffs(value:Int) -> Int {
return value * 10
}
private func doReverseStuffs(value:Int) -> Int {
return value / 10
}
}
Because NSDateFormatter
is very inefficient, it is very bad to use it in a computed property
. One will be created every get. A lot of time and energy will be wasted because the resulting value might be the same most of the time.
Best practice :
computed properties
to get
stored properties
and set
to do calculations.NSDateFormatter
A much much better way to go:
class SomeEvent {
// Store calculated results.
// This is private to make the class cleaner in use.
private var storedDate : NSDate?
private var storedFormattedDate : String = ""
// get returns stored values without calculations
// set updates both stored values after calculations
var date : NSDate? {
get {
return storedDate
}
set(value) {
storedFormattedDate = format(date: value)
storedDate = value
}
}
var formattedDate : String {
get {
return storedFormattedDate
}
set(value) {
storedDate = readDateFrom(dateString: value)
storedFormattedDate = format(date: storedDate)
}
}
// hidden functions, again to make the class cleaner in use.
private func format(date maybeDate:NSDate?) -> String {
guard let date = maybeDate else {
return ""
}
guard let dateFormatter = MyDateFormatter.shared().dateFormatter else {
return ""
}
return dateFormatter.stringFromDate(date)
}
private func readDateFrom(dateString string:String) -> NSDate? {
// get detector
if let detector = MyDateFormatter.shared().dateReader {
// results
let matches = detector.matchesInString(string, options: [], range: NSRange(location: 0, length: string.characters.count))
// first result
if let match = matches.first, let date = match.date {
return date
}
}
// just format if there is no detector
if let dateFormatter = MyDateFormatter.shared().dateFormatter {
if let date = dateFormatter.dateFromString(string) {
return date
}
}
// everything failed
return nil
}
}
Singleton to store the NSDateFormatter
and NSDataDetector
:
Google: Swift Singleton
class MyDateFormatter {
private static var privateShared : MyDateFormatter?
var dateFormatter : NSDateFormatter?
var dateReader : NSDataDetector?
class func shared() -> MyDateFormatter {
guard let uwShared = privateShared else {
privateShared = MyDateFormatter()
return privateShared!
}
return uwShared
}
class func destroy() {
privateShared = nil
}
private init() {
dateReader = try? NSDataDetector(types: NSTextCheckingType.Date.rawValue)
dateFormatter = NSDateFormatter()
dateFormatter!.dateFormat = "EEEE MMM dd"
}
}
Tests:
let event = SomeEvent()
event.formattedDate = "tomorrow"
event.formattedDate // "Friday Dec 04"
event.formattedDate = "25/02/2010"
event.formattedDate // "Thursday Feb 25"
event.formattedDate = "Sunday Mar 13"
event.formattedDate // "Sunday Mar 13"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With