Coredata in swift - ios

Hello I am having an issue with core data in Swift, this doesn't show an error but also doesn't print anything when I believe it should be returning 'Joe' + 'pass' in console. Could anyone help please?
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
var appDel:AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var context:NSManagedObjectContext = appDel.managedObjectContext
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
newUser.setValue("Joe", forKey: "username")
newUser.setValue("pass", forKey: "password")
do {
try context.save()
} catch let error {
print("Couldn't save user data")
print(error)
}
let request = NSFetchRequest(entityName: "Users")
request.returnsObjectsAsFaults = false
do {
var results = try context.executeFetchRequest(request)
results = results as! [NSManagedObject]
if results.count > 0 {
for results in results {
print(results)
}}
} catch let error as NSError {
print(error)
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}

You should create your own coredata class (as a subclass of NSManagedObject) and then create the array out of that class.
specify exactly what you want to print. In your case
newUser.username

I finally realised what my issue was, I hadn't actually renamed by Entity to 'Users' I'd kept it as 'Entity' so when I was doing
let newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
let request = NSFetchRequest(entityName: "Users")
I should have actually have replaced both Users with 'Entity' which now fixes my issue, thanks I guess for your help anyway!

Related

Getting nil after delete an object in Coredata Swift

I tried to store some data using CoreData.
I created Entity Name Users and some attributes namely age, username, password.
Successfully loading, retrieving.
When I delete some object in that entity using context.delete(user), It will be deleted but show nil after I retrieving again.
Showing nil for deleted object
Note: I write the code for predicate which format is "Username!=nil".
Is this the right way? or how to overcome without nil in core data?
import UIKit
import CoreData
class CoreDataVC: UIViewController {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
var context:NSManagedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
}
#IBAction func addAction(_ sender: Any){
if let newUser = openDatabse(){
saveData(UserDBObj:newUser)
}
_ = fetchData()
}
#IBAction func deleteAction(_ sender: Any){
if let newUser = openDatabse(){
deleteData(UserObj: newUser)
}
_ = fetchData()
}
// MARK: Methods to Open, Store and Fetch data
func openDatabse() -> NSManagedObject?{
context = appDelegate.persistentContainer.viewContext
guard let entity = NSEntityDescription.entity(forEntityName: "Users", in: context) else {
print("Invalid Entity")
return nil
}
let newUser = NSManagedObject(entity: entity, insertInto: context)
return newUser
}
func deleteData(UserObj: NSManagedObject){
let result = self.fetchData()
if let data = result.last{
context.delete(data)
}
do {
try context.save()
}
catch{
print("Error on saving context")
}
_ = fetchData()
}
func saveData(UserDBObj:NSManagedObject)
{
UserDBObj.setValue("RDC1", forKey: "username")
UserDBObj.setValue("12341", forKey: "password")
UserDBObj.setValue("22", forKey: "age")
print("Storing Data..")
do {
try context.save()
} catch {
print("Storing data Failed")
}
_ = fetchData()
}
func fetchData() -> [Users]
{
var users : [Users] = []
print("Fetching Data..")
let request = Users.fetchRequest()
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
users = result
for data in result {//as! [NSManagedObject] {
print("Username: ",data.username ?? "nil",", Age : ",data.age ?? "nil")
}
} catch {
print("Fetching data Failed")
}
return users
}
}
Thanks in Advance.

Swift 3 Core Data

I am getting the following error while trying to do NSFetchRequest in Swift 3
Generic parameter 'ResultType' could not be inferred
i checked lots of links and i have not been able to figure how to solve it.
this is what am doing
ViewController.swift
func loadData(){
let request = NSFetchRequest(entityName: "Grocery") //Error occurs here(Generic parameter 'ResultType' could not be inferred)
do{
let results = try manageObjectContext.execute(request)
groceries = results as! [NSManagedObject]
tableView.reloadData()
}catch{
fatalError("Error is retriving Gorcery items")
}
}
Try this:
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Grocery")
It should work :)
Therefore your code should Look like:
func loadData(){
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Grocery")
do{
let results = try manageObjectContext.execute(request)
groceries = results as! [NSManagedObject]
tableView.reloadData()
}catch{
fatalError("Error is retriving Gorcery items")
}
}
Credits: Nitesh Patil https://medium.com/#imnitpa/swift-3-core-data-7b00b50f5782
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .white
let appDelegate = UIApplication.shared.delegate as!AppDelegate
let context = appDelegate.persistentContainer.viewContext
//adding new user and saving in database...
let newUser = NSEntityDescription.insertNewObject(forEntityName: "Users", into: context)
newUser.setValue("Batman", forKey: "username")
newUser.setValue("Robin", forKey: "password")
do {
try context.save()
print("saved")
} catch {
print("Error occured...")
}
// restoring data back from database
let request = NSFetchRequest < NSFetchRequestResult > (entityName: "Users")
request.returnsObjectsAsFaults = false
do {
let results =
try context.fetch(request)
if results.count > 0 {
for result in results as![NSManagedObject] {
if let username = result.value(forKey: "username") as ? String {
print(username)
}
}
}
else {
print("No results")
}
} catch {
print("Couldn't fetch results")
}
}
}
you can use this too:
let request : NSFetchRequest<Grocery> = Grocery.fetchRequest()
and you get results of the type [Grocery] when you execute the request:
let results : [Grocery] = try manageObjectContext.execute(request)
or
let results = try manageObjectContext.execute(request)

Trouble Saving with CoreData and Swift 2.0

Problem
I'm trying to simply save a record and then fetch it but I think I'm doing something wrong here as my record isn't saving. The output window just shows an empty array.
I'm using the boiler-plate AppDelegate CoreData stack in Xcode 7 beta 5. [See Gist Here]
Attempt
Entity
Model
import Foundation
import CoreData
// #func(Person) edit: removed
class Person: NSManagedObject {
#NSManaged var firstName: String?
#NSManaged var lastName: String?
}
View Controller
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
seedPerson()
fetch()
}
func seedPerson() {
let managedContext = AppDelegate().managedObjectContext
let entity = NSEntityDescription.entityForName("Person", inManagedObjectContext: managedContext)
let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
// add our data
person.setValue("Dan", forKey: "firstName")
person.setValue("Beaulieu", forKey: "lastName")
// save it
do {
try AppDelegate().managedObjectContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
func fetch() {
let moc = AppDelegate().managedObjectContext
let personFetch = NSFetchRequest(entityName: "Person")
do {
let fetchedPerson = try moc.executeFetchRequest(personFetch) as! [Person]
print(fetchedPerson.first!.firstName)
} catch {
fatalError("Failed to fetch person: \(error)")
}
}
}
Desired Behavior
What I'm trying to return is my first name from the data store, however I don't think my record is ever saved which is why I'm getting is an empty array.
So my specific question is, how do I save using the boiler plate core data stack?
The problem was that I was creating a new instance of managedObjectContext and trying to save to it which obviously wouldn't work because I was working with the managed context that I created at the top of my method.
func seedPerson() {
let managedContext = AppDelegate().managedObjectContext
//let entity = NSEntityDescription.entityForName("Person", inManagedObjectContext: managedContext)
//let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: managedContext)
let person = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: managedContext)
// add our data
person.setValue("Dan", forKey: "firstName")
person.setValue("Beaulieu", forKey: "lastName")
// save it
do {
// this was the problem ///////////////
try managedContext.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
Video
I've uploaded a video tutorial on how to setup core data in swift 2 : https://www.youtube.com/watch?v=WcQkBYu86h8

Retrieving Core Data With Swift

Problem
I am new to IOS development, and have been struggling with Core Data. I am trying to create a settings page with a switch. I need to remember if this switch is turned on or off. I created a core data application, and have managed to figure out how to save the value of the switch to the attribute. The code below does this, I just can't figure out how to get the saved value of the switch back as on or off. How would I do this? Thanks!
Picture of Core Data
Code:
import UIKit
import CoreData
class preferencesStuff: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Settings")
request.returnsObjectsAsFaults = false;
var results:NSArray = context.executeFetchRequest(request, error: nil)!
if(results.count > 0){
if results[results.count-1] as NSObject == 1 {
println("ON")
}
}else{
println("NO RESULTS")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
#IBOutlet weak var fractSwitchValue: UISwitch!
#IBAction func fractSwitch(sender: AnyObject) {
if fractSwitchValue.on == true {
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var newSetting = NSEntityDescription.insertNewObjectForEntityForName("Settings", inManagedObjectContext: context) as NSManagedObject
newSetting.setValue(true, forKey: "fractionOnOff")
context.save(nil)
//println(newSetting)
}
else {
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var newSetting = NSEntityDescription.insertNewObjectForEntityForName("Settings", inManagedObjectContext: context) as NSManagedObject
newSetting.setValue(false, forKey: "fractionOnOff")
context.save(nil)
//println(newSetting)
}
}
}
I just did your example with CoreData. I just happened to store an NSString instead of a Bool. It's not optimized, but it should get you going.
import UIKit
import CoreData
class ViewController: UIViewController {
var state: NSString = ""
#IBOutlet weak var fractSwitchValue: UISwitch!
#IBAction func fractSwitch(sender: AnyObject) {
if fractSwitchValue.on == true {
state = "On"
save(state)
}
else {
state = "Off"
save(state)
}
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
var appDel = UIApplication.sharedApplication().delegate as AppDelegate
var context = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Settings")
var error: NSError?
var results = context.executeFetchRequest(request, error: &error) as [NSManagedObject]?
if let fetchedResults = results {
state = fetchedResults[fetchedResults.count - 1].valueForKey("fractionOnOff") as String!
} else {
println("Could not fetch \(error), \(error!.userInfo)")
}
if state == "On" {
fractSwitchValue.setOn(true, animated: true)
} else {
fractSwitchValue.setOn(false, animated: true)
}
}
override func viewDidLoad() {
super.viewDidLoad()
}
func save(string: NSString) {
let appDel = UIApplication.sharedApplication().delegate as AppDelegate
let context = appDel.managedObjectContext!
let entity = NSEntityDescription.entityForName("Settings", inManagedObjectContext: context)
let setting = NSManagedObject(entity: entity!, insertIntoManagedObjectContext: context)
setting.setValue(string, forKey: "fractionOnOff")
println(string)
var error: NSError?
if !context.save(&error) {
println("Could not save \(error), \(error?.userInfo)")
}
}
}
I would use NSUserDefaults for this case. It's much easier to use than Core Data when storing user preferences. For example, you would store the property using
NSUserDefaults.standardUserDefaults().setBool(value, forKey: "fractionPreference")
and retrieve it using
let value = NSUserDefaults.standardUserDefaults().boolForKey("fractionPreference")

Get values from CoreData in Swift

I am attempting to pull out and print two values from CoreData. One is speed, the other is degrees. However things don't go as planned. First up, here's part of the code:
// Start fetching from CoreData
request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result: AnyObject in results! {
println(result)
println(result.speed)
println(result.degrees)
}
}
else {
println("No data")
}
When I simply print results I get the values:
<NSManagedObject: 0x7f944a734e80> (entity: WindData; id: 0xd000000000740000 <x-coredata://762EB8C2-DDCF-43F5-8DFC-FAB9A29532E1/WindData/p29> ; data: {
degrees = 190;
speed = 8; })
println(result.speed) writes in the consol: 2.34181e-38
and println(result.degrees) won't allow me to compile and tells me that AnyObject does not have a member named degrees (although it clearly does)
Sorry for any rookie mistakes, this is my first time posting on Stackoverflow.
Here is the full code:
//
// ViewController.swift
// KitesurfioApp
//
// Created by Lasse Kristensen on 24/10/14.
// Copyright (c) 2014 Lasse Kristensen. All rights reserved.
//
import UIKit
import CoreData
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
// Set logo in nav bar
navigationItem.titleView = UIImageView(image: UIImage(named: "logo"))
// Global save values
var appDel: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
var context: NSManagedObjectContext = appDel.managedObjectContext!
// JSON Fetching
let urlPath = "http://api.openweathermap.org/data/2.5/weather?lat=55.564120&lon=12.568605"
let url = NSURL(string: urlPath)
let session = NSURLSession.sharedSession()
let task = session.dataTaskWithURL(url!, completionHandler: {data, response, error -> Void in
if (error != nil) {
println(error)
}
else {
// Delete old entries in CoreData
var request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
for result in results! {
context.deleteObject(result as NSManagedObject)
context.save(nil)
}
// Start fetching JSON
let jsonResult = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary
var item = jsonResult["wind"] as NSDictionary
var degrees:Int = item["deg"] as NSInteger
var speed:Float = item["speed"] as Float
// Start saving JSON
var newItem = NSEntityDescription.insertNewObjectForEntityForName("WindData", inManagedObjectContext: context) as NSManagedObject
var speedValue:NSNumber = speed as NSNumber
var degreesValue:NSNumber = degrees as NSNumber
newItem.setValue(speedValue, forKey: "speed")
newItem.setValue(degreesValue, forKey: "degrees")
context.save(nil)
}
})
task.resume()
// Start fetching from CoreData
var request = NSFetchRequest(entityName: "WindData")
request = NSFetchRequest(entityName: "WindData")
request.returnsObjectsAsFaults = false
var results = context.executeFetchRequest(request, error: nil)
if results!.count > 0 {
for result: AnyObject in results! as [WindData] {
println(result)
println(result.speed)
}
}
else {
println("No data")
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
You need to cast the AnyObject to your class which have properties degree etc.AnyObject does not know about your class properties you need to downcast the array [AnyObject] to your class array
for result in results! as [NSManagedObject] {
println(result)
println(result.valueForKey("speed")!)
println(result.valueForKey("degrees")!)
}

Resources