How to write current date into Cell of UITableView through NSUserDefaults? - ios

I want the user to save the current date (like dd.mm.yyyy) to the NSUserDefaults by clicking a button and load it back in another ViewController to display it as a cell in UITableView. But it won't work. I don't know how to get the date right but this is what I tried:
#IBAction func saveButtonTapped (sender:AnyObject){
let userDefaults = NSUserDefaults.standardUserDefaults()
if var timeList = userDefaults.objectForKey("timeList") as? [NSDate]
{
timeList.append(NSDate())
userDefaults.setObject(timeList, forKey: "timeList")
}
else
{
userDefaults.setObject([NSDate()], forKey: "timeList")
}
userDefaults.synchronize()
}
...
#IBOutlet weak var tableView: UITableView!
var time:NSMutableArray = NSMutableArray();
override func viewDidLoad() {
super.viewDidLoad()
var timecopy = NSMutableArray(array: time)
var userDefaults:NSUserDefaults = NSUserDefaults.standardUserDefaults()
var timeListFromUserDefaults:NSMutableArray? = userDefaults.objectForKey("timeList") as? NSMutableArray
if ((timeListFromUserDefaults) != nil){
time = timeListFromUserDefaults!
}
self.tableView.reloadData()
}

There you go.
class ViewController: UIViewController, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
let userDefaults = NSUserDefaults.standardUserDefaults()
let timeListKey = "TimeList" // Key in user defaults
var timeList: [NSDate] = [NSDate]() {
didSet {
userDefaults.setObject(self.timeList, forKey: timeListKey)
self.tableView.reloadData()
}
}
//MARK: Actions
#IBAction func saveButtonTapped(sender: UIButton) {
self.timeList.append(NSDate())
}
//MARK: TableView DataSource
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return 1
}
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.timeList.count
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "TimeListCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as UITableViewCell
cell.textLabel?.text = "\(timeList[indexPath.row])"
return cell
}
//MARK: View Lifecycle
override func viewDidLoad() {
super.viewDidLoad()
// Get NSArray from userDefaults
let timeListFromUserDefaults = userDefaults.objectForKey(timeListKey) as? NSArray
// Check if it is an array of NSDate, else set timeList to empty array
self.timeList = (timeListFromUserDefaults as? [NSDate]) ?? [NSDate]()
}
}

Everything you put in NSUserDefaults is saved as immutable. Thus you will get back an NSArray not an NSMutableArray. This may cause your conditional casting to fail and return nil.
By the way, consider that NSUserDefaults is not intended to be some sort of DataBase for your app, but just a small PropertyList of preferenses and stuff like that.
If you are going to have lot of dates to save, delete etc., you should probably consider CoreData or other solutions.

Related

Implementing Favourites Section Of Table View Using UserDefaults

I'm currently developing an application for IOS that has 2 tabs. A home view, which consists of a table of images with actions when you click on them, and a favourites view which allows users to view their favourite images and actions. I'm currently trying to figure out a way to save this favourites data once the application has been closed. It seems to simple for core data, yet I can't seem to get my head around UserDefaults.
I have a favourite button inside of a view that appears when the user clicks the favourite button, it adds the image title to a list and reloads the table using that list inside of the favourites tab. This is working fine with a normal array variable. When I try implementing UserDefaults, it doesn't seem to reload the table when I click on the favourites tab, however when I close the app and restart it using multitasking (swipe up) and restart the app the table forms and all the data is remembered and set up. Is there any way for the data to be remembered and stored in the UserDefaults variable when the app closes and when the app restarts use that variable, and while the app is running use the normal variable to reload the table from?
Here's my favourites tab code for the table:
import UIKit
var favRow = 0
class FavouritesViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
let favouritesavedimages = userDefaults.object(forKey: "Data") as? [String] ?? [String]()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
tableView.reloadData()
super.viewDidLoad()
tableView.delegate = self
tableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return favouritesavedimages.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "imageCell2") as? FavouritesImageCellTableViewCell {
cell.configureCellFavourites(image: UIImage(named: favouritesavedimages[indexPath.row])!)
return cell
} else {
return FavouritesImageCellTableViewCell()
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
favRow = indexPath.row
}
override func viewWillAppear(_ animated: Bool) {
let favouritesavedimages = userDefaults.object(forKey: "Data") as? [String] ?? [String]()
super.viewWillAppear(animated)
tableView.reloadData()
}
}
Here's my code for the page with the favourite button:
import UIKit
let userDefaults = UserDefaults.standard
var favouriteImages: [String] = []
var isFavourite = [false,false,false,false,false,false,false,false,false,false,false,false,false,f alse,false,false,false,false,false,false,false,false,false,false,false]
class SecondViewController: UIViewController {
let favourites = userDefaults.object(forKey: "FavData") as? [Bool] ?? [Bool]()
override func viewDidLoad() {
super.viewDidLoad()
if !isFavourite[row]
{
favouriteButton.image = UIImage(named: "favourite")
} else {
favouriteButton.image = UIImage(named: "defavourite")
}
secondImageView.image = secondImages[row]
secondTitle.text = tutorialTitles[row]
secondTutorialText.text = tutorialText[row]
}
#IBAction func favouriteButtonTapped(_ sender: Any) {
if !isFavourite[row] {
setOnFavourite()
} else {
setOnDeFavourite()
}
}
#IBOutlet weak var favouriteButton: UIBarButtonItem!
#IBOutlet weak var secondTutorialText: UITextView!
#IBOutlet weak var secondTitle: UILabel!
#IBOutlet weak var secondImageView: UIImageView!
func setOnFavourite()
{
isFavourite[row] = true
favouriteButton.image = UIImage(named: "defavourite")
favouriteImages.append(String(row + 1))
userDefaults.set(favouriteImages, forKey: "Data")
userDefaults.set(isFavourite, forKey: "FavData")
}
func setOnDeFavourite()
{
isFavourite[row] = false
favouriteButton.image = UIImage(named: "favourite")
favouriteImages = favouriteImages.filter{$0 != String(row)}
userDefaults.set(favouriteImages, forKey: "Data")
userDefaults.set(isFavourite, forKey: "FavData")
}
}
Thanks, any help would be appreciated.

NSManagedObject Array becomes nil when UITableView is scrolled

I have a ViewController in my app where I have to show Settings to the user and user can turn the Settings on or off using UISwitch. I have to store the settings in the local db and based on that display data to user in app.
I am using SugarRecord for Core Data Management. Initially all the settings are turned on.
SugarRecordManager.swift
import Foundation
import SugarRecord
import CoreData
class SugarRecordManager
{
static let sharedInstance = SugarRecordManager()
private init(){
}
// Initializing CoreDataDefaultStorage
func coreDataStorage() -> CoreDataDefaultStorage {
let store = CoreDataStore.named("db")
let bundle = Bundle(for: type(of: self))
let model = CoreDataObjectModel.merged([bundle])
let defaultStorage = try! CoreDataDefaultStorage(store: store, model: model)
return defaultStorage
}
//MARK:- User Settings methods
//update local settings
func updateSettingsModel(userSettings: [UserSetting]){
let db = self.coreDataStorage()
for localSetting in userSettings{
try! db.operation { (context, save) -> Void in
if let settingObjectToUpdate = try! context.request(UserSetting.self).filtered(with: "groupName", equalTo: localSetting.groupName!).fetch().first{
settingObjectToUpdate.groupId = localSetting.groupId! as String
settingObjectToUpdate.groupName = localSetting.groupName! as String
settingObjectToUpdate.isGroupActive = localSetting.isGroupActive
try! context.insert(settingObjectToUpdate)
save()
}
}
}
}
//retrieve settings from storage
func getAllSettings() -> [UserSetting] {
let db = self.coreDataStorage()
var userSettings : [UserSetting]
do {
userSettings = try db.fetch(FetchRequest<UserSetting>())
} catch {
userSettings = []
}
return userSettings
}
//initialise settings for the first time
func initialiseUserSettings(){
let db = self.coreDataStorage()
var groupNameArray = UserDefaults.standard.value(forKey: "groupNamesArrayKey") as? [String]
var groupIdArray = UserDefaults.standard.value(forKey: "groupIdsArrayKey") as? [String]
for i in 0 ..< groupIdArray!.count {
try! db.operation { (context, save) -> Void in
let settingObject: UserSetting = try! context.new()
settingObject.groupId = groupIdArray?[i];
settingObject.groupName = groupNameArray?[i];
settingObject.isGroupActive = true;
try! context.insert(settingObject)
save()
}
}
}
}
SettingsViewController.swift
class SettingsViewController: BaseViewController, UITableViewDataSource, UITableViewDelegate, SettingsCellDelegate {
#IBOutlet weak var btnSideNav: UIBarButtonItem!
#IBOutlet weak var settingsTable: UITableView!
var userSetting = [UserSetting]() //array to hold settings from storage
override func viewDidLoad() {
super.viewDidLoad()
self.automaticallyAdjustsScrollViewInsets = false;
btnSideNav.target = revealViewController();
btnSideNav.action = #selector(SWRevealViewController.revealToggle(_:));
userSetting = SugarRecordManager.sharedInstance.getAllSettings() //here userSetting contains data and I have checked it
self.settingsTable.reloadData()
self.settingsTable.dataSource = self;
self.settingsTable.delegate = self;
// Do any additional setup after loading the view.
}
//MARK:- Table View Methods
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print("Count of cells = \(self.userSetting.count)") //prints 18 which is good
return self.userSetting.count
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 60;
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let settingsCell : SettingsCell? = tableView.dequeueReusableCell(withIdentifier: "SettingsCell") as? SettingsCell;
settingsCell?.setUpWithModel(model: self.userSetting[indexPath.row], cell: settingsCell!)
settingsCell?.delegate = self as SettingsCellDelegate;
return settingsCell!
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
tableView.deselectRow(at: indexPath, animated: true)
}
func didTappedSwitch(cell: SettingsCell) {
let indexPath = settingsTable.indexPath(for: cell);
userSetting[(indexPath?.row)!].isGroupActive? = cell.isGroupActive.isOn as NSNumber
}
#IBAction func btnSaveTapped(_ sender: UIButton) {
// code to save settings
}
}
SettingsCell.swift
protocol SettingsCellDelegate {
func didTappedSwitch(cell: SettingsCell)
}
class SettingsCell: UITableViewCell {
#IBOutlet weak var groupName: UILabel!
#IBOutlet weak var lblGroupId: UILabel!
#IBOutlet weak var isGroupActive: UISwitch!
var delegate: SettingsCellDelegate!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
func setUpWithModel(model: UserSetting, cell: SettingsCell)
{
cell.groupName.text = model.groupName;
cell.lblGroupId.text = model.groupId;
isGroupActive.setOn((model.isGroupActive?.boolValue)!, animated: false)
}
#IBAction func isGroupActiveValueChanged(_ sender: UISwitch) {
delegate.didTappedSwitch(cell: self)
}
}
Now, initally the TableView is populated and all arrays are working fine but as soon as I scroll the TableView all data is gone. Even the userSetting array is nill. I know it's something to do with context but can't figure out what. Any help would be greatly appreciated.
Change your func coreDataStorage() -> CoreDataDefaultStorage like this
// Initializing CoreDataDefaultStorage
lazy var coreDataStorage: CoreDataDefaultStorage = {
let store = CoreDataStore.named("db")
let bundle = Bundle(for: type(of: self))
let model = CoreDataObjectModel.merged([bundle])
let defaultStorage = try! CoreDataDefaultStorage(store: store, model: model)
return defaultStorage
}()
you have this problem because you re-init CoreDataDefaultStorage each time when you do any request.
After you made it lazy - you will have only one CoreDataDefaultStorage for all app life
Basically, it will be good to make coreDataStorage as singleton

Populate the data saved on core data on a tableView

The code of my first UIViewController looks like this and basically I want to save the data whatever I type on the UITextField and retrieve it and populate on a UITableView. code as below. (I think my issue is in the cellForRow method)
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet weak var textField1: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBAction func nxtbuttonpressed(_ sender: AnyObject) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
//Lets save data
let newUser = NSEntityDescription.insertNewObject(forEntityName: "Expenses", into: context)
newUser.setValue(textField1.text, forKey: "expenseName")
do {
try context.save ()
print("data saved successfully")
}catch{
print("There was an error")
}
performSegue(withIdentifier: "ShowNxtVC", sender: nil)
}
}
This is where I retrieve the data that I saved in the above VC (as the code bellow). However even though I can print all the data on the console, only the last data item I saved will populate to the UITableViewCell. How can i overcome this as to populate all the data that I've saved before instead the one that i saved last.
import UIKit
import CoreData
class TableViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
var myArray : Array? = []
override func viewDidLoad() {
super.viewDidLoad()
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest <NSFetchRequestResult> (entityName: "Expenses")
request.returnsObjectsAsFaults = false
do {
let results = try context.fetch(request)
// check data existance
if results.count>0 {
print(results.count)
for resultGot in results as! [NSManagedObject]{
if let expName = resultGot.value(forKey:"expenseName") as? String{
myArray = [expName]
print("my array is : \(myArray)")
}
}
}
}catch{
print("No Data to load")
}
// Do any additional setup after loading the view.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
print(myArray?.count)
return myArray!.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell ()
cell.textLabel?.text = myArray? [indexPath.row] as! String?
return cell
}
}
first off all you have to change this:
myArray = [newValue] because that resets your array with just one value every time it finds a new expense in core data.
var array = [String]()
array = ["hello"]
array = ["joe"]
print(array)
// returns: ["joe"]
use:
myArray.append(newExpense)
and you get:
var array2 = [String]()
array2.append("hello")
array2.append("joe")
print(array2)
// returns: ["hello", "joe"]
After the FOR loop you add:
tableView.reloadData()
Now you should be up and running
There is another thing you should do:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ExpCell", for: indexPath)
cell.textLabel?.text = myArray?[indexPath.row] as! String
return cell
}
In your Storyboard you need to put ExpCell as reuse identifier into the TableViewCell. The dequeReusableCell command loads only the cells you can see on your device and reuses those cells after you scrolled them out of sight. This way your app uses much less memory and will be faster.
update table view with data, after myArray = [expName] use
DispatchQueue.main.async { [unowned self] in
self.tableView.reloadData()
}
change the tableview cell for row at index path function that will solve your problem
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier identifier: String,
for indexPath: IndexPath)
if(!cell){
cell = tableView.register(tableViewCellClass,forCellReuseIdentifier identifier: String)
}
return cell
}

App not deleting a row from .plist file

In a project that I am working on I have note-esque function that is acting as an Exercise/Training Log. This Training Log is made up of 5 files: Note.swift, NotesTableViewController.swift, NoteDetailViewController.swift, NoteDetailTableViewCell.swift, and NoteStore.swift. The class for this table is NotesTableViewController, which is a UIViewController with UITableViewDelegate, and UITableViewDataSource. This note taking feature works decently, populating the tableview, but fails to delete a note from the .plist file and continues to retrieve it when the app is reopened. I do not know if this is actually failure to save/load, or if something is going wrong somewhere else. I would appreciate any help at all. The files are as follows:
Note.swift
import Foundation
class Note : NSObject, NSCoding {
var title = ""
var text = ""
var date = NSDate() // Defaults to current date / time
// Computed property to return date as a string
var shortDate : NSString {
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "MM/dd/yy"
return dateFormatter.stringFromDate(self.date)
}
override init() {
super.init()
}
// 1: Encode ourselves...
func encodeWithCoder(aCoder: NSCoder) {
aCoder.encodeObject(title, forKey: "title")
aCoder.encodeObject(text, forKey: "text")
aCoder.encodeObject(date, forKey: "date")
}
// 2: Decode ourselves on init
required init(coder aDecoder: NSCoder) {
self.title = aDecoder.decodeObjectForKey("title") as! String
self.text = aDecoder.decodeObjectForKey("text") as! String
self.date = aDecoder.decodeObjectForKey("date") as! NSDate
}
}
NotesTableViewController.swift
import UIKit
class NotesTableViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {
#IBOutlet weak var tableView: UITableView!
#IBOutlet weak var OpenButton: UIBarButtonItem!
override func viewDidLoad() {
super.viewDidLoad()
// Leverage the built in TableViewController Edit button
self.navigationItem.leftBarButtonItem = self.editButtonItem()
OpenButton.target = self.revealViewController()
OpenButton.action = Selector("revealToggle:")
self.view.addGestureRecognizer(self.revealViewController().panGestureRecognizer())
self.tableView.reloadData()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
// ensure we are not in edit mode
editing = false
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Here we pass the note they tapped on between the view controllers
if segue.identifier == "NoteDetailPush" {
// Get the controller we are going to
var noteDetail = segue.destinationViewController as! NoteDetailViewController
// Lookup the data we want to pass
var theCell = sender as! NoteDetailTableViewCell
// Pass the data forward
noteDetail.theNote = theCell.theNote
}
}
#IBAction func saveFromNoteDetail(segue:UIStoryboardSegue) {
// We come here from an exit segue when they hit save on the detail screen
// Get the controller we are coming from
var noteDetail = segue.sourceViewController as! NoteDetailViewController
// If there is a row selected....
if let indexPath = tableView.indexPathForSelectedRow() {
// Update note in our store
NoteStore.sharedNoteStore.updateNote(theNote: noteDetail.theNote)
// The user was in edit mode
tableView.reloadRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
} else {
// Otherwise, add a new record
NoteStore.sharedNoteStore.createNote(theNote: noteDetail.theNote)
// Get an index to insert the row at
var indexPath = NSIndexPath(forRow: NoteStore.sharedNoteStore.count()-1, inSection: 0)
// Update tableview
tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: UITableViewRowAnimation.Automatic)
}
}
// MARK: - Table view data source
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// Just return the note count
return NoteStore.sharedNoteStore.count()
}
func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
// Fetch a reusable cell
let cell = tableView.dequeueReusableCellWithIdentifier("NoteDetailTableViewCell", forIndexPath: indexPath) as! NoteDetailTableViewCell
// Fetch the note
var rowNumber = indexPath.row
var theNote = NoteStore.sharedNoteStore.getNote(rowNumber)
// Configure the cell
cell.setupCell(theNote)
return cell
}
// Override to support editing the table view.
func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
// Delete the row from the data source
NoteStore.sharedNoteStore.deleteNote(indexPath.row)
// Delete the note from the tableview
tableView.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
}
}
}
NoteDetailViewController
import UIKit
class NoteDetailViewController: UIViewController {
var theNote = Note()
#IBOutlet weak var noteTitleLabel: UITextField!
#IBOutlet weak var noteTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// The view starts here. By now we either have a note to edit
// or we have a blank note in theNote property we can use
// Update the screen with the contents of theNote
self.noteTitleLabel.text = theNote.title
self.noteTextView.text = theNote.text
// Set the Cursor in the note text area
self.noteTextView.becomeFirstResponder()
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Whenever we leave the screen, update our note model
theNote.title = self.noteTitleLabel.text
theNote.text = self.noteTextView.text
}
#IBAction func CancelNote(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
NoteDetailTableViewCell
import UIKit
class NoteDetailTableViewCell : UITableViewCell {
// The note currently being shown
weak var theNote : Note!
// Interface builder outlets
#IBOutlet weak var noteTitleLabel : UILabel!
#IBOutlet weak var noteDateLabel : UILabel!
#IBOutlet weak var noteTextLabel : UILabel!
// Insert note contents into the cell
func setupCell(theNote:Note) {
// Save a weak reference to the note
self.theNote = theNote
// Update the cell
noteTitleLabel.text = theNote.title
noteTextLabel.text = theNote.text
noteDateLabel.text = theNote.shortDate as String
}
}
and finally, NoteStore
import Foundation
class NoteStore {
// Mark: Singleton Pattern (hacked since we don't have class var's yet)
class var sharedNoteStore : NoteStore {
struct Static {
static let instance : NoteStore = NoteStore()
}
return Static.instance
}
// Private init to force usage of singleton
private init() {
load()
}
// Array to hold our notes
private var notes : [Note]!
// CRUD - Create, Read, Update, Delete
// Create
func createNote(theNote:Note = Note()) -> Note {
notes.append(theNote)
return theNote
}
// Read
func getNote(index:Int) -> Note {
return notes[index]
}
// Update
func updateNote(#theNote:Note) {
// Notes passed by reference, no update code needed
}
// Delete
func deleteNote(index:Int) {
notes.removeAtIndex(index)
}
func deleteNote(withNote:Note) {
for (i, note) in enumerate(notes) {
if note === withNote {
notes.removeAtIndex(i)
return
}
}
}
// Count
func count() -> Int {
return notes.count
}
// Mark: Persistence
// 1: Find the file & directory we want to save to...
func archiveFilePath() -> String {
let paths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)
let documentsDirectory = paths.first as! NSString
let path = documentsDirectory.stringByAppendingPathComponent("NoteStore.plist")
return path
}
// 2: Do the save to disk.....
func save() {
NSKeyedArchiver.archiveRootObject(notes, toFile: archiveFilePath())
}
// 3: Do the reload from disk....
func load() {
let filePath = archiveFilePath()
let fileManager = NSFileManager.defaultManager()
if fileManager.fileExistsAtPath(filePath) {
notes = NSKeyedUnarchiver.unarchiveObjectWithFile(filePath) as! [Note]
} else {
notes = [Note]()
}
}
}
it look's like you're not calling the save method after changing creating,deleting or updating notes
you could add for example :
func deleteNote(index:Int) {
notes.removeAtIndex(index)
save()
}
or call the save methods on vievWillDisappear if you don't want to write a new plist after every change

Swift label not displaying what the selected cell says

I have a tableview that is populated with information from a JSON array. I want to make each selected cell segue into a viewController, and in that viewController I have a label the should display what the selected cell says. For example if my cell says California, when I click on the cell it'll open up my viewController and the label would say California.
Seems simple enough, and I've done this before successfully, however this time I'm using JSON to populate my tableView and I'm guessing I'm doing something wrong. With the code posted below, when I click on a cell the titleLabel doesn't even show up.
(My tableView file and DetailsViewController file are posted below, any other swift file I used can be found in my previous question populating Tableview with a function that uses SwiftyJSON)
import UIKit
class EarthTableViewController: UITableViewController {
var info = [AppModel]()
func getEarthquakeInfo(completion: (results : NSArray?) ->Void ){
DataManager.getEarthquakeDataFromFileWithSuccess {
(data) -> Void in
let json = JSON(data: data)
if let JsonArray = json.array {
for appDict in JsonArray {
var ids: String? = appDict["id"].stringValue
var title: String? = appDict["title"].stringValue
var time: String? = appDict["time"].stringValue
var information = AppModel(idEarth: ids, title: title, time: time)
self.info.append(information)
completion(results: self.info)
}
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
getEarthquakeInfo { (info) in
self.tableView.reloadData()
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("reuseIdentifier", forIndexPath: indexPath) as UITableViewCell
let infoArray = self.info
cell.textLabel!.text = self.info[indexPath.row].title
return cell
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "SEGUE" {
let vc = segue.destinationViewController as DetailsViewController
let cell = (sender as UITableViewCell)
let title = cell.textLabel!.text
vc.titleData = title
}
}
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
// #warning Incomplete method implementation.
// Return the number of rows in the section.
return info.count
}
}
My DetailsViewController file:
import UIKit
class DetailsViewController: UIViewController {
#IBOutlet weak var titleLabel: UILabel!
#IBOutlet weak var idLabel: UILabel!
#IBOutlet weak var timeLabel: UILabel!
var titleData: String!
var idData: String!
var timeData: String!
override func viewDidLoad() {
super.viewDidLoad()
var earthInfo = EarthTableViewController()
var getEarthInfo: () = earthInfo.getEarthquakeInfo { (info) in
println("\(info)")
}
titleLabel.text = titleData
idLabel.text = idData
timeLabel.text = timeData
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}

Resources