简体   繁体   English

CoreData Swift:如何保存和加载数据?

[英]CoreData Swift: How to save and load data?

I'm writing an iOS game in Swift, and I wanted to include a highscore label at the end.我正在用 Swift 编写一个 iOS 游戏,我想在最后包含一个高分标签。 I think that the saving function is correct, but the load one is the one which is giving me problems.我认为保存功能是正确的,但加载功能是给我带来问题的功能。 I already created an entity ("BestScores") and the attributes ("classicBestScoreTF"):我已经创建了一个实体(“BestScores”)和属性(“classicBestScoreTF”):

To save the highscore:保存高分:

var bestscore25 = 1000
var score: int

func savescore() {    
    var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    var context:NSManagedObjectContext = appDel.managedObjectContext!
    var score25: AnyObject! = NSEntityDescription.insertNewObjectForEntityForName("BestScores", inManagedObjectContext: context) as NSManagedObject
    score25.setValue(score, forKey: "classicBestScoreTF")
    context.save(nil)
}

func loadscore() {
    var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
    var context:NSManagedObjectContext = appDel.managedObjectContext!
    bestScore25 = valueForKey("classicBestScoreTF") as Int
}

func endgame() {

    if score > bestScore25 {
        savescore()
        loadscore()
        bestScoreLabel.text = "Best Score: \(bestScore25)"
    }

    if score < bestscore {            
        loadscore()
        bestScoreLabel.text = "Best Score: \(bestScore25)"
    }    
}

It's not working :( Please help!它不起作用:(请帮忙!

Saving data: 保存数据:

var person = NSEntityDescription.insertNewObjectForEntityForName("Person", 
inManagedObjectContext: self.managedObjectContext!) as Person
person.name = "Mary"
person.age = Float(arc4random() % 100)

var error : NSError? = nil
if !self.managedObjectContext!.save(&error) {
    NSLog("Unresolved error \(error), \(error!.userInfo)")
    abort()
}

Loading data: 加载数据中:

var error: NSError? = nil
var fReq: NSFetchRequest = NSFetchRequest(entityName: "Frases")    
fReq.predicate = NSPredicate(format: "id contains[c] %@", String(day))
var sorter: NSSortDescriptor = NSSortDescriptor(key: "id" , ascending: false)
fReq.sortDescriptors = [sorter]
fReq.returnsObjectsAsFaults = false
let result : [AnyObject] = self.managedObjectContext!.executeFetchRequest(fReq, error:&error)!

For saving data, you should be using: 为了保存数据,您应该使用:

context.insertNewObjectForEntityForName(...)

And the same when you are loading data, it should be: 在加载数据时也一样,它应该是:

context.valueForKey(...) context.valueForKey(...)

However, I am not sure if that is even the correct syntax, as you may need to get an array of the entities and then get the object at index 0. On that note why are you using core data for high scores? 但是,我不确定这是否是正确的语法,因为您可能需要获取实体数组,然后在索引0处获取对象。那么为什么您使用核心数据获得高分? You might want to look into user defaults or icloud, Core data is designed more for databases 您可能希望查看用户默认值或icloud,Core数据是针对数据库设计的

Updated for swift: 更新为swift:

used below simple code for load, insert, delete date; 用于加载,插入,删除日期的简单代码;

import UIKit
import CoreData

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate{

    // MARK:- Variable Declarations

    @IBOutlet weak var mTableView: UITableView!
    var manageObjectContext: NSManagedObjectContext!
    var eventArray = [Event]()

    // MARK:- ViewController LifeCycle Methods

    override func viewDidLoad() {
        super.viewDidLoad()
        self.title = "Event Reminder"
        manageObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
        self.loadSaveData()
    }

    override func viewWillAppear(_ animated: Bool) {
        // Remove empty cell from tableview
        mTableView.tableFooterView = UIView(frame: .zero)
    }

    // MARK:- TableView DataSource and Delegate Methods

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return eventArray.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        let cell = tableView.dequeueReusableCell(withIdentifier: "ViewControllerTableViewCell")! as! ViewControllerTableViewCell
        cell.layer.cornerRadius = 05

        let eventArrayItem = eventArray[indexPath.row]

        if let eventImage = UIImage(data: (eventArrayItem.event_image! as Data)){
            cell.mImageView.image = eventImage
        }

        cell.mEventHeadingLabel.text = eventArrayItem.event_heading
        cell.mShortDescriptionLabel.text = eventArrayItem.event_description

        return cell
    }

    // To delete Particular cell/row from tableview
    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

        let eventArrayItem = eventArray[indexPath.row]

        if editingStyle == .delete {
            manageObjectContext.delete(eventArrayItem)

            do {
                try manageObjectContext.save()
            } catch let error as NSError {
                print("Error While Deleting Note: \(error.userInfo)")
            }
        }
        self.loadSaveData()
    }

    // MARK:- IBAction Methods

    @IBAction func actionOnPlusButton(_ sender: Any) {
        let imagePicker = UIImagePickerController()
        imagePicker.sourceType = .photoLibrary
        imagePicker.delegate = self
        self.present(imagePicker, animated: true, completion: nil)
    }

    // MARK:- ImagePicker Delegate Methods

    func imagePickerControllerDidCancel(_ picker: UIImagePickerController) {
        picker.dismiss(animated: true, completion: nil)
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        if let mImage = info[UIImagePickerControllerOriginalImage] as? UIImage{
            picker.dismiss(animated: true, completion: { 
                self.createEventItemWith(selectedImage: mImage)
            })
        }
    }

    // MARK:- Instance Methods

    func createEventItemWith(selectedImage: UIImage)  {

        let eventItem = Event(context: manageObjectContext)

        let alertController = UIAlertController(title: "Add Event", message: "Enter event and it's description", preferredStyle: .alert)

        let saveAction = UIAlertAction(title: "Save", style: .default, handler: {
            alert -> Void in

            let eventNameTextField = alertController.textFields![0] as UITextField
            let descriptionTextField = alertController.textFields![1] as UITextField

            print("firstName \(String(describing: eventNameTextField.text)), secondName \(String(describing: descriptionTextField.text))")

            if eventNameTextField.text != "" || descriptionTextField.text != ""{

                eventItem.event_heading = eventNameTextField.text
                eventItem.event_description = descriptionTextField.text
                eventItem.event_image = NSData(data: UIImageJPEGRepresentation(selectedImage, 0.3)!)

                do{
                    try self.manageObjectContext.save()
                    self.loadSaveData()
                }catch{
                    print("Could not save data: \(error.localizedDescription)")
                }

            }else{
                self.showAlertMessageToUser(title: "Alert", messageToUser: "Fields should not be empty, Please enter given info...")
            }
        })

        let cancelAction = UIAlertAction(title: "Cancel", style: .default, handler: {
            (action : UIAlertAction!) -> Void in
                self.manageObjectContext.reset()
        })

        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Enter event Name"
        }
        alertController.addTextField { (textField : UITextField!) -> Void in
            textField.placeholder = "Enter event description in short"
        }

        alertController.addAction(saveAction)
        alertController.addAction(cancelAction)

        self.present(alertController, animated: true, completion: nil)
    }

    func showAlertMessageToUser(title: String, messageToUser: String)  {
        let alert = UIAlertController(title: title, message: messageToUser, preferredStyle: UIAlertControllerStyle.alert)
        alert.addAction(UIAlertAction(title: "Ok", style: UIAlertActionStyle.default, handler: nil))
        self.present(alert, animated: true, completion: nil)
    }

    func loadSaveData()  {
        let eventRequest: NSFetchRequest<Event> = Event.fetchRequest()
        do{
            eventArray = try manageObjectContext.fetch(eventRequest)
            self.mTableView.reloadData()
        }catch
        {
            print("Could not load save data: \(error.localizedDescription)")
        }
    }
}

在此输入图像描述

Swift 5 斯威夫特5

Step 1. Create Simple app with CoreData option 步骤1.使用CoreData选项创建简单应用程序

在此输入图像描述

Step 2. Open .xcdatamodeld file and add Entity , Attributes this way 步骤2.打开.xcdatamodeld文件并以这种方式添加实体属性

在此输入图像描述

Step 3. your AppDelegate should have Core Data stack methods 第3步。您的AppDelegate应该具有Core Data堆栈方法

Step 4. Make sure you have swift code snipe as following 步骤4.确保您有快速代码狙击如下

import UIKit
import CoreData

class ViewController: UIViewController {

    // MARK: Variables declearations
    let appDelegate = UIApplication.shared.delegate as! AppDelegate //Singlton instance
    var context:NSManagedObjectContext!

    // MARK: View Controller life cycle methods
    override func viewDidLoad() {
        super.viewDidLoad()

        openDatabse()
    }

    // MARK: Methods to Open, Store and Fetch data
    func openDatabse()
    {
        context = appDelegate.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "Users", in: context)
        let newUser = NSManagedObject(entity: entity!, insertInto: context)
        saveData(UserDBObj:newUser)
    }

    func saveData(UserDBObj:NSManagedObject)
    {
        UserDBObj.setValue("RDC", forKey: "username")
        UserDBObj.setValue("1234", forKey: "password")
        UserDBObj.setValue("21", forKey: "age")

        print("Storing Data..")
        do {
            try context.save()
        } catch {
            print("Storing data Failed")
        }

        fetchData()
    }

    func fetchData()
    {
        print("Fetching Data..")
        let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")
        request.returnsObjectsAsFaults = false
        do {
            let result = try context.fetch(request)
            for data in result as! [NSManagedObject] {
                let userName = data.value(forKey: "username") as! String
                let age = data.value(forKey: "age") as! String
                print("User Name is : "+userName+" and Age is : "+age)
            }
        } catch {
            print("Fetching data Failed")
        }
    }
}

Step 5. Run on Device and see log for core data results 步骤5.在设备上运行并查看核心数据结果的日志

import UIKit import CoreData 导入UIKit导入CoreData

class ViewController: UIViewController { class ViewController:UIViewController {

let nameTxt: UITextField = {

    let td = UITextField()
    td.translatesAutoresizingMaskIntoConstraints = false
    td.placeholder = "Enter Id"
    td.borderStyle = .line
    td.layer.borderWidth = 1
    td.layer.borderColor = UIColor.lightGray.cgColor
    return td
}()

let doneBt: UIButton = {

    let bt = UIButton()
    bt.translatesAutoresizingMaskIntoConstraints = false
    bt.setTitle("DONE", for: .normal)
    bt.setTitleColor(.white, for: .normal)
    bt.addTarget(self, action: #selector(handleDoneBt), for: .touchUpInside)
    bt.backgroundColor = UIColor.blue
    return bt
}()

@objc func handleDoneBt() {

     saveData()
}

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    view.backgroundColor = .white

    setupView()
    setupLayout()

}


func saveData() {

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}

    let manageContent = appDelegate.persistentContainer.viewContext

    let userEntity = NSEntityDescription.entity(forEntityName: "Users", in: manageContent)!

    let users = NSManagedObject(entity: userEntity, insertInto: manageContent)

    users.setValue(1, forKeyPath: "id")
    users.setValue(nameTxt.text, forKeyPath: "name")
    users.setValue(123, forKeyPath: "mobile")


    do{
        try manageContent.save()
    }catch let error as NSError {

        print("could not save . \(error), \(error.userInfo)")
    }

    fetchData()
}

func fetchData() {

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
     let manageContent = appDelegate.persistentContainer.viewContext
     let fetchData = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")

    do {

        let result = try manageContent.fetch(fetchData)

        for data in result as! [NSManagedObject]{

             print(data.value(forKeyPath: "id") as Any)
             print(data.value(forKeyPath: "name") as Any)
        }
    }catch {
        print("err")
    }
}

func setupView() {

    view.addSubview(nameTxt)
    view.addSubview(doneBt)
}
func setupLayout(){

    NSLayoutConstraint.activate([

            nameTxt.centerXAnchor.constraint(equalTo: view.centerXAnchor),
            nameTxt.centerYAnchor.constraint(equalTo: view.centerYAnchor),
            nameTxt.widthAnchor.constraint(equalToConstant: 160),
            nameTxt.heightAnchor.constraint(equalToConstant: 30),

            doneBt.topAnchor.constraint(equalTo: nameTxt.bottomAnchor,constant: 6),
            doneBt.leftAnchor.constraint(equalTo: nameTxt.leftAnchor,constant: 8),
            doneBt.widthAnchor.constraint(equalToConstant: 120),
            doneBt.heightAnchor.constraint(equalToConstant: 36)
        ])
}

} }

DISPLAY IN TABLEVIEW 在TABLEVIEW中显示

func fetchData() { func fetchData(){

    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}
    let manageContent = appDelegate.persistentContainer.viewContext
    let fetchData = NSFetchRequest<NSFetchRequestResult>(entityName: "Users")        
    do {

        let result = try manageContent.fetch(fetchData)
        allData = result as! [NSManagedObject]
        tbl.reloadData()
    }catch {
        print("err")
    }
}

var allData = [NSObject]()

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { return allData.count } func tableView(_ tableView:UITableView,numberOfRowsInSection section:Int) - > Int {return allData.count}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! tblCell
    cell.lbl.text = allData[indexPath.row].value(forKey: "name") as? String
    return cell
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { func tableView(_ tableView:UITableView,commit editingStyle:UITableViewCell.EditingStyle,forRowAt indexPath:IndexPath){

    if editingStyle == .delete {
        let task = allData[indexPath.row]
        guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {return}

        let manageContent = appDelegate.persistentContainer.viewContext

        manageContent.delete(task as! NSManagedObject)
        (UIApplication.shared.delegate as! AppDelegate).saveContext()

        do {
            try manageContent.save()
        } catch {
            print("Fetching Failed")
        }
    }
    fetchData()
}

Operations with CoreData使用 CoreData 操作

import CoreData


public class ItemCoreDataStorage {
    
    let context: NSManagedObjectContext
    
    init(context: NSManagedObjectContext) {
        self.context = context
    }
    
    func save(_ items: [Item]) {
        
        cashbackItems.forEach({ item in
            let moItem = MOCashback(context: context)
            moItem.a = item.a
            moItem.b = item.b
        })
        
        do {
            try context.save()
        } catch {
            //Error handling
        }
        
    }
    
    func fetch() -> [MOItem] {
        do {
            let moItems: [MOItem] = try context.fetch(MOItem.fetchRequest())
            return moItems
        } catch {
            //Error handling
        }
    }
    
    func fetchedResultsController() -> NSFetchedResultsController<MOItem> {
        
        let fetchRequest: NSFetchRequest< MOItem > = MOCashback.fetchRequest()
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "a", ascending: true)]
        let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
        
        return frc
    }
    
    func delete() {

        self.fetch()
            .forEach({ context.delete($0)})
        do {
            try context.save()
        }
        catch {
            //Error handling
        }

    }
}
  • Please note that you can for example use bunch for delete items but it will not be managed by FRC.请注意,例如您可以使用 bundle 来删除项目,但它不会由 FRC 管理。

  • Also fetchRequest.sortDescriptors is mandatory此外fetchRequest.sortDescriptors是强制性的

import UIKit import CoreData导入 UIKit 导入 CoreData

class ViewController: UIViewController {类视图控制器:UIViewController {

@IBOutlet weak var nameREA: UITextField!

@IBOutlet weak var emailREA: UITextField!
@IBOutlet weak var addressREA: UITextField!



@IBOutlet weak var schoolREA: UITextField!


@IBOutlet weak var departmentREA: UITextField!
@IBOutlet weak var coursREA: UITextField!

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext



override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
}
@IBAction func saveA(_ sender: Any) {
    
    let stdA = NSEntityDescription.insertNewObject(forEntityName: "StudentsFR", into: context)
    stdA.setValue(self.nameREA.text, forKey: "st_name")
    stdA.setValue(self.emailREA.text, forKey: "st_email")
    stdA.setValue(self.addressREA.text, forKey: "st_address")
    stdA.setValue(self.schoolREA.text, forKey: "st_school")
    stdA.setValue(self.departmentREA.text, forKey: "st_department")
    stdA.setValue(self.coursREA.text, forKey: "st_course")
    do{
        try context.save()
        self.nameREA.text = ""
        self.emailREA.text = ""
        self.addressREA.text = ""
        self.schoolREA.text = ""
        self.departmentREA.text = ""
        self.coursREA.text = ""
    } catch{
        print("error")
    }
    
}
@IBAction func showA(_ sender: Any) {
    
    let storybd = UIStoryboard(name: "Main", bundle: nil)
    let stdA = storybd.instantiateViewController(withIdentifier: "tblA")as!tblviewAViewController
    self.navigationController?.pushViewController(stdA, animated: true)
        }

} }

import UIKit导入 UIKit

class tableviewAViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {类 tableviewAViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {

@IBOutlet weak var tablREA: UITableView!
var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

var studentarray:[Studentsdet] = []

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return studentarray.count
}

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: "tblA", for: indexPath)
    let onrecord = studentarray[indexPath.row]
    cell.textLabel?.text = onrecord.name_std! + "" + onrecord.age_std! + "" + onrecord.department_std! + "" + onrecord.course_std!
    
    return cell
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete{
        let std = studentarray[indexPath.row]
        context.delete(std)
        (UIApplication.shared.delegate as! AppDelegate).saveContext()
        do{
            studentarray = try context.fetch(Studentsdet.fetchRequest())
            
        }catch
        {
            print("error")
            
        }
   }
    
    
    tableView.reloadData()
}
func fetchdata()
{
    do{
        studentarray = try context.fetch(Studentsdet.fetchRequest())
    }catch{
        print("error")
    }
}

override func viewDidLoad() {
    super.viewDidLoad()

    self.fetchdata()
    self.tablREA.reloadData()
    
    
    // Do any additional setup after loading the view.
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM