Swift 4, Хранение и отображение данных с использованием Array и TableViewCell - PullRequest
0 голосов
/ 10 мая 2018

Я делаю приложение, которое позволяет пользователю следить за порядком имен пользователей и паролей. В настоящее время у меня возникает проблема, когда пользователь выходит из приложения, данные или TableViewCell не сохраняются или не отображаются. Я использую массив.

Я предполагаю, потому что данные не сохраняются после. Является ли CoreData или UserDefaults простым решением для этого? Я хочу избежать Firebase.

Может кто-нибудь объяснить или показать, как внедрить CoreData / UserDefaults в код? Я много искал, но мне просто трудно понять, как применить его в моем коде, особенно с массивами и TableViewCell. Помощь высоко ценится.

Фотографии ниже.

Вот мой код:

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;


}

Модель

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
}
}

Рисунок 1 -> Как выглядит приложение с раскадровки.

Рисунок 2 -> Как выглядит приложение из симулятора.

Ответы [ 2 ]

0 голосов
/ 10 мая 2018

Вы должны использовать NSUserDefaults только для хранения настроек - только настройки для функциональности вашего приложения и ничего больше. Все остальное, например пользовательские данные, должно храниться где-то еще. Особенно, если вы говорите, что это деликатный вопрос, и вы не хотите рисковать данными своего пользователя, поскольку файл plist непосредственно доступен в каталоге приложений.

Еще один недостаток использования UserDefaults для хранения данных приложения - все данные будут сохранены в виде файла списка свойств. Весь файл считывается и записывается как единое целое, поэтому, если вы используете UserDefaults для хранения большого объема данных, которые изменяются только по частям, вы будете тратить много времени на ненужные операции ввода-вывода.

Скорее, CoreData / Realm всегда является лучшим вариантом для сохранения данных приложения.

Чтобы узнать, как хранить в CoreData -

Чтобы узнать, как хранить в Realm -

0 голосов
/ 10 мая 2018

UserDefaults обычно является самой простой базой данных для использования.Если у вас есть только один массив для хранения / извлечения, придерживайтесь его.Если у вас есть гораздо больше информации, зайдите с чем-то большим, например CoreData / Realm .

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

Не стесняйтесь проверить следующий ответ и учебное пособие.

howсохранить и прочитать массив массива в NSUserdefaults в swift? https://medium.com/@nimjea/userdefaults-in-swift-4-d1a278a0ec79

Если это все еще трудно понять, я бы рекомендовал проверить Objective-C версию UserDefaults - NSUserDefaults .Даже если вы не знакомы с синтаксисом Objective-C , его, вероятно, легче понять.

Сохранить строку в NSUserDefaults?

Теперь вопросприходит, где использовать эти методы при работе с UITableView .

Всякий раз, когда вы хотите изменить или извлечь данные из хранилища ( UserDefaults в нашем случае).

Для экземпляра вы можете изменить сохраненный массив, вызывая методы tableView (: cellForRowAt :) в tableView (: didSelectRowAt :), или вы можете получить данные в tableView (_: cellForRowAt :)

Для использования Realm проверьте официальный сайт https://realm.io/docs/swift/latest

...