ios - How to record date, time, and score in swift -


i creating simple quiz app. planning show kind of "history" user can see following:

  1. date , time of playing
  2. score particular session

how do that?

as of date , time of playing, saw thread on so: how current time datetime however, how "record" date(s) , time(s) user played game?

regarding score data, using:

nsuserdefaults.standarduserdefaults().setinteger(currentscore, forkey: "score") 

however, able current score. how record score(s) user got each session on different date(s) , time(s)?

please note have no problem in getting user's current score. need in storing or recording user's score(s) in multiple sessions.

for instance, wanted display this:

date: 2/7/16 time: 7:00 score: 70/100 

nsuserdefaults isn't right trying do. recommend using nscoding simple data storing. core data may complicated simple. however, if plan on saving large data model relationships, core data way go.

nscoding

nscoding has 2 parts:

  1. encoding , decoding
  2. archiving , unarchiving

nshipster explains perfectly:

nscoding simple protocol, 2 methods: -initwithcoder: , encodewithcoder:. classes conform nscoding can serialized , deserialized data can either archived disk or distributed across network.

that archiving performed nskeyedarchiver , nskeyedunarchiver.

session

even without nscoding, suggested represent data objects. in case, can use creative name session represent session in history.

class session: nsobject, nscoding {      let date: nsdate // stores both date , time     let score: int      init(date: nsdate, score: int) { // initialize new session          self.date = date         self.score = score          super.init()      }      required init?(coder adecoder: nscoder) { // decodes existing session          if let decodeddate = adecoder.decodeobjectforkey("date") as? nsdate {              self.date = decodeddate         } else {              self.date = nsdate() // placeholder // case shouldn't happen, clearing compiler errors         }          self.score = adecoder.decodeintegerforkey("score")      }      func encodewithcoder(acoder: nscoder) {          acoder.encodeobject(date, forkey: "date")         acoder.encodeinteger(score, forkey: "score")      }  } 

the above code in english, in order top bottom:

  • defining class, conforming nscoding
  • the properties of session: date (+ time) , score
  • the initializer new session - takes date , score , creates session it
  • the required initializer existing session - decodes date , score saved
    • decodeobjectforkey: says (decodes object using key), , returns anyobject?
    • decodeintegerforkey:, however, returns int. if none exists on file, returns 0, why isn't optional. case of decoding methods except decodeobjectforkey:
  • the required method encoding existing session - encodes date , score
    • the encoding methods straightforward decoding methods.

that takes care of session class, properties ready nscoding. of course, add more properties , methods.

sessionhistory

while sessions nice, object manage array of sessions needed, , needs conform nscoding. add code existing class.

class sessionhistory: nsobject, nscoding {      var sessions = [session]()      required init?(coder adecoder: nscoder) {          if let decodedsessions = adecoder.decodeobjectforkey("sessions") as? [session] {              self.sessions = decodedsessions         } else {              self.sessions = [] // compiler error clearer         }      }      func encodewithcoder(acoder: nscoder) {          acoder.encodeobject(sessions, forkey: "sessions")      }      override init() { // used convenience         super.init()     }  } 

english translation:

  • defining manager, conforming nscoding
  • add property array of sessions
  • next 2 nscoding methods same thing session. except time, array.
  • initializer new manager, used below.

nscoding looks @ manager class , sees needs encode array of sessions, nscoding looks @ session class see encode sessions.

nskeyedarchiver/nskeyedunarchiver , singletons

while nscoding set now, final step incorporate nskeyedarchiver , nskeyedunarchiver save , load data.

the 2 important methods nskeyedarchiver.archiverootobject(_, tofile:) , nskeyedunarchiver.unarchiverootobjectwithfile:

note both methods need file. automagically creates file you, need set location. add sessionhistory:

static var datapath: string {      let urls = nsfilemanager.defaultmanager().urlsfordirectory(.documentdirectory, indomains: .userdomainmask)     let url = urls[0]     return url.urlbyappendingpathcomponent("savehistory").path! // put want string  } 

that finds location file. could, of course, find somewhere else put file.

with data path ready, can use 2 methods mentioned earlier. use modified version of singleton manager class make sure i'm using same array of objects. in sessionhistory class:

private static var history: sessionhistory!  static func apphistory() -> sessionhistory {      if history == nil {         if let data = nskeyedunarchiver.unarchiveobjectwithfile(datapath) as? sessionhistory {             history = data         } else {             history = sessionhistory()         }     }      return history  } 

this creates private static property store 1 session history of app. static method checks if session history nil. if so, returns current history on file , loads file history property. otherwise, creates new empty session history. after that, or if history property stores something, returns history property.

usage

all setup nscoding , nskeyedarchiver done. how use code?

each time want access session history, call

sessionhistory.apphistory() 

wherever want save session history, call

nskeyedarchiver.archiverootobject(sessionhistory.apphistory(), tofile: sessionhistory.datapath) 

sample usage work this:

let session = session(date: somerandomdate, score: somerandomscore) sessionhistory.apphistory().sessions.append(session) nskeyedarchiver.archiverootobject(sessionhistory.apphistory(), tofile: sessionhistory.datapath) 

the session history automatically loaded file when accessed via sessionhistory.apphistory().

you don't need "link" classes per se, need append sessions sessions array of session history.

further reading


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

json - Gson().fromJson(jsonResult, Myobject.class) return values in 0's -