1

I am making an application that allows the user to keep order at usernames and passwords. Currently, I am having a problem when the user quit the app, the data or TableViewCell is not stored or showing up. I am using an array.

I assume because the data is not getting stored after. Is CoreData or UserDefaults a simple solution for this? I want to avoid Firebase.

Can someone explain or show, how to implement CoreData/UserDefaults into the code? I have searched a lot but I simply find it hard to understand how to apply it in my code, especially with arrays and TableViewCell. Help is deeply appreciated.

Pictures are below.

Here is my code:

MainViewController:

class MainViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {
@IBOutlet weak var tableView:UITableView?


override func viewDidLoad() {
    super.viewDidLoad()


    // 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 {
    return informasjoner.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "InformasjonTableViewCell") as! InformasjonTableViewCell

    let informasjon:Informasjon = informasjoner[indexPath.row];

    if(informasjon.image != nil){
        cell.imageViewInfo?.image = informasjon.image
    } else {
        cell.imageViewInfo?.image = UIImage(named: informasjon.imageName!)
    }

    cell.epostLabel?.text = informasjon.labelEpost
    cell.passordLabel?.text = informasjon.labelPassord
    cell.applikasjonLabel?.text = informasjon.labelApplikasjon

    return cell
}

// EDIT / UPDATE CELL

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
    let informasjon = informasjoner[indexPath.row]

    let deleteAction = UITableViewRowAction(style: .default, title: "Delete"){
        (action, indexPath) in
        self.deleteAction(informasjon: informasjon, indexPath: indexPath)
    }
        //call delete action
    deleteAction.backgroundColor = .red;
    return [deleteAction]
    }
private func deleteAction(informasjon: Informasjon, indexPath: IndexPath){
let alert = UIAlertController(title: "Delete",
                              message: "Are u sure?",
                              preferredStyle: .alert)

    let deleteAction = UIAlertAction(title: "Yes",
                                     style: .default){ (action) in
        informasjoner.remove(at: indexPath.row)
        self.tableView?.deleteRows(at: [indexPath], with: .automatic)

    }
    let cancelAction = UIAlertAction(title: "No",
                                     style: .default,
                                     handler: nil);
    alert.addAction(deleteAction);
    alert.addAction(cancelAction);
    present(alert, animated: true);

}
}

InformasjonTableViewCell:

 import UIKit

 class InformasjonTableViewCell: UITableViewCell {


@IBOutlet weak var imageViewInfo: UIImageView?
@IBOutlet weak var epostLabel: UILabel?
@IBOutlet weak var passordLabel: UILabel?
@IBOutlet weak var applikasjonLabel: UILabel!




override func awakeFromNib() {
    super.awakeFromNib()
    // Initialization code
}

override func setSelected(_ selected: Bool, animated: Bool) {
    super.setSelected(selected, animated: animated)


}

}

AddInfoVC:

import UIKit

class AddInfoVC: UIViewController, UITextFieldDelegate, UINavigationControllerDelegate, UIImagePickerControllerDelegate {

@IBOutlet weak var txtEpost:UITextField?
@IBOutlet weak var ImageInfo:UIImageView?
@IBOutlet weak var txtPassord:UITextField?
@IBOutlet weak var txtApplikasjon: UITextField!


var newInfo = Informasjon()

@IBAction func btnSave(sender:UIButton){
print("Press Save!")
    if(newInfo.image == nil || newInfo.labelEpost?.count == 0 || newInfo.labelPassord?.count == 0 || newInfo.labelApplikasjon?.count == 0){
        let alertController = UIAlertController(title: "Alert", message: "Please set", preferredStyle: .alert)
        let okAction = UIAlertAction(title: "OK", style: .default){
            (action) in
        }
        alertController.addAction(okAction)
        self.present(alertController, animated: true, completion: nil);

    } else{
        informasjoner.append(newInfo);
        navigationController?.popViewController(animated: true)
        let mainViewController = self.navigationController?.topViewController as? MainViewController
        mainViewController?.tableView?.reloadData()
    }
}

override func viewDidLoad() {
    super.viewDidLoad()
    //Tap to ImageView
    let tapGestureToImageView = UITapGestureRecognizer(target: self, action: #selector(tapToImageView(sender:)))
    tapGestureToImageView.numberOfTapsRequired = 1
    ImageInfo?.isUserInteractionEnabled = true;
    ImageInfo?.addGestureRecognizer(tapGestureToImageView);

    self.txtEpost?.delegate = self;
    self.txtPassord?.delegate = self;
    self.txtApplikasjon?.delegate = self;


}

Models

Informasjon.swift:

import Foundation
import UIKit

class Informasjon {
var imageName: String?
var image: UIImage?
var labelEpost: String?
var labelPassord: String?
var labelApplikasjon: String?
convenience init(imageName:String, labelEpost:String, labelPassord:String,labelApplikasjon:String ) {
    self.init()
    self.imageName = imageName
    self.labelEpost = labelEpost
    self.labelPassord = labelPassord
    self.labelApplikasjon = labelApplikasjon
}
}

Picture 1 -> How the Application looks from the Storyboard.

Picture 2 -> How the Application looks from Simulator.

Alexander
  • 2,803
  • 5
  • 13
  • 21

2 Answers2

0

UserDefaults usually is the simplest database to use. If you have only one array to store/retrieve then stick with it. If you have much more information go with something bigger like CoreData/Realm.

let array = []()
let defaults = UserDefaults.standard
defaults.set(array, forKey: "SavedStringArray")

Feel free to check out following answer and tutorial.

how to save and read array of array in NSUserdefaults in swift? https://medium.com/@nimjea/userdefaults-in-swift-4-d1a278a0ec79

If it's still hard to understand I would recommend to check the Objective-C version of UserDefaults - NSUserDefaults. Even if you are not familiar with Objective-C syntax it's probably easier to understand.

Save string to the NSUserDefaults?

Now the question comes where to use these methods when working with UITableView.

Whenever you want to change or retrieve the data from the store (UserDefaults in our case).

For the instance you can change the stored array calling tableView(:cellForRowAt:) methods in the tableView(:didSelectRowAt:), or you can retrieve the data in tableView(_:cellForRowAt:)

For using Realm check the official website https://realm.io/docs/swift/latest

Alexander
  • 2,803
  • 5
  • 13
  • 21
0

You should use NSUserDefaults to store preferences only – just preferences for your app’s functionality and nothing else. Anything else like user data should be stored someplace else. Especially if said that is sensitive and you don’t want to risk your user’s data as the plist file is directly available in the apps directory.

One more disadvantage for using UserDefaults to store app data is all data will be stored as a property list file. The entire file is read in and written out as a whole, so if you use UserDefaults to store a large amount of data that only changes in parts, you will be wasting a lot of time doing unnecessary I/O.

Rather, CoreData/Realm is always a better option to persist app data.

To learn how to store in CoreData -

To learn how to store in Realm -

Abhishek729
  • 327
  • 5
  • 14