2017-06-29 4 views
0

Ich habe einen ViewController in meiner App, wo ich Einstellungen für den Benutzer anzeigen muss und Benutzer kann die Einstellungen mit UISwitch ein- oder ausschalten. Ich muss die Einstellungen in der lokalen Datenbank speichern und basierend auf dieser Anzeige Daten für Benutzer in der App.NSManagedObject Array wird Null, wenn UITableView gescrollt wird

Ich verwende SugarRecord für Core Data Management. Anfangs sind alle Einstellungen aktiviert.

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) 

} 

} 

Nun initally die Tableview bestückt ist und alle Arrays arbeiten gut, aber so bald Während ich das TableView scrolle, sind alle Daten verschwunden. Selbst das userSetting-Array ist null. Ich weiß, dass es etwas mit Kontext zu tun hat, aber nicht herausfinden kann, was. Jede Hilfe würde sehr geschätzt werden.

+0

Könnten Sie SugarRecordManager Klasse bieten zu machen? –

+0

Ich habe die Frage bearbeitet und den Code für SugarRecordManager.swift –

Antwort

1

dieses Ihr func coreDataStorage() -> CoreDataDefaultStorage wie

ändern
// 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 
    }() 

Sie dieses Problem haben, weil Sie wieder init CoreDataDefaultStorage jedes Mal, wenn Sie eine Anfrage machen.

Nachdem Sie es lazy gemacht - Sie

Grundsätzlich nur eine CoreDataDefaultStorage für alle App Leben haben wird, wird es gut sein coreDataStorage als singleton

+0

hinzugefügt. Erstens können Sie nicht Lazy mit berechneter Eigenschaft verwenden. Zweitens, selbst wenn ich coreDataStorage eine berechnete Eigenschaft mache oder es Singleton mache, hat es keinen Einfluss. –

+0

Machen Sie es nicht eine berechnete Eigenschaft, aber machen Sie es faulen Eigenschaft mit Initialisierung wie in meinem Beispiel: 'lazy var coreDataStorage: CoreDataDefaultStorage = {// Init-Code hier)()' Eigentlich können Sie einfach kopieren-fügen Sie mein Beispiel –

+0

Arbeitete wie ein Zauber: D Vielen Dank! –

Verwandte Themen