Reputation: 1793
I'm writing an iOS game in Swift, and I wanted to include a highscore label at the end. 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"):
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!
Upvotes: 20
Views: 64433
Reputation: 31
import UIKit
class tblviewAViewController: UIViewController,UITableViewDelegate,UITableViewDataSource {
@IBOutlet weak var tablviwREA: UITableView!
var context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var studentarry:[StudentsFR] = []
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return studentarry.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "tblCA", for: indexPath)as! tblcellATableViewCell
let onrecord = studentarry[indexPath.row]
//cell.textLabel?.text =
cell.lblREA.text = onrecord.st_name!
cell.LBLREB.text = onrecord.st_address!
cell.lblREC.text = onrecord.st_email!
cell.lblRED.text = onrecord.st_department!
cell.lblREE.text = onrecord.st_course!
cell.lblREF.text = onrecord.st_school!
return cell
}
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
return 100
}
func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete{
let std = studentarry[indexPath.row]
context.delete(std)
(UIApplication.shared.delegate as! AppDelegate).saveContext()
do{
studentarry = try context.fetch(StudentsFR.fetchRequest())
}catch{
print("error")
}
}
tableView.reloadData()
}
func fetchdata(){
do{
studentarry = try context.fetch(StudentsFR.fetchRequest())
}catch{
print("error")
}
}
override func viewDidLoad() {
super.viewDidLoad()
self.fetchdata()
self.tablviwREA.reloadData()
// Do any additional setup after loading the view.
}
}
Upvotes: -1
Reputation: 34175
Operations with 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.
Also fetchRequest.sortDescriptors
is mandatory
Upvotes: 0
Reputation: 536
import UIKit import CoreData
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
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, 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) {
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()
}
Upvotes: 2
Reputation: 35783
Swift 5
Step 1. Create Simple app with CoreData option
Step 2. Open .xcdatamodeld file and add Entity, Attributes this way
Step 3. your AppDelegate should have Core Data stack methods
Step 4. Make sure you have swift code snipe as following
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
Upvotes: 11
Reputation: 3317
Updated for 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)")
}
}
}
Upvotes: 4
Reputation: 2725
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)!
Upvotes: 31
Reputation: 161
For saving data, you should be using:
context.insertNewObjectForEntityForName(...)
And the same when you are loading data, it should be:
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? You might want to look into user defaults or icloud, Core data is designed more for databases
Upvotes: 3