CoreData only updates after I restart the app? - swift

Hi I'm saving my data using the saveContext() that is generated with the AppDelegate template. My app records sets of locations when in background mode, and then when the app enters foreground I take those locations and store them in core data. Everything is saved and it stores but when I go to my view controller where I display them it doesn't show unless I RESTART the app and come back to it.
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
if self.myLocations.count > 0 {
let context = persistentContainer.viewContext
let logEntity = NSEntityDescription.insertNewObject(forEntityName: "PostureLog", into: context)
logEntity.setValue(self.errors, forKey: "logError")
// populate log
logEntity.setValue(Date(), forKey: "logDate")
for i in 0...myLocations.count - 1 {
let locationEntity = NSEntityDescription.insertNewObject(forEntityName: "Location", into: context)
// populate address
locationEntity.setValue(myLocations[i].coordinate.latitude, forKey: "latitude")
locationEntity.setValue(myLocations[i].coordinate.longitude, forKey: "longitude")
// create relationship Location -> Log
locationEntity.mutableSetValue(forKey: "log").add(logEntity)
}
self.saveContext()
self.myLocations.removeAll()
self.errors = 0
}
}
save context function
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}

You are probably not refreshing your ViewController so it is still showing the old data until you restart.

Related

Knowing when lightweight migration finished

Setup:
I'm trying to do a lightweight Core Data migration in my app. I added a new Core Data model version and added the new improvements (added 9 attributes to existing entities, 2 new entities, relationships between the new and existing entities).
Issue:
Switching from a build with the old database to the new one causes the app to have no data. But once I quit the app and come back, the data is all there (I'm assuming it was just being migrated).
Question:
Is there a way to know when the Core Data is starting a migration (to let the users know) and when the migration is finished (to refresh their view with the new data)? I've done so much searching this past couple of weeks and have not come with much.
Thank you in advance!
Code:
This is how I set up Core Data (specifically the setupContainer() code):
final class CoreDataManager {
static let sharedManager = CoreDataManager()
lazy var persistentContainer: NSPersistentContainer = {
setupContainer()
}()
private func setupContainer() -> NSPersistentContainer {
useCloudSync = UserDefaults.standard.bool(forKey: UserDefaults.Keys.useCloudSync)
let containerToUse: NSPersistentContainer?
if useCloudSync {
containerToUse = NSPersistentCloudKitContainer(name: "appName")
} else {
containerToUse = NSPersistentContainer(name: "appName")
}
//check if we have a container
guard let container = containerToUse else {
fatalError("Hey Listen! Could not get a container!!")
}
// Enable history tracking and remote notifications
guard let description = container.persistentStoreDescriptions.first else {
fatalError("Hey Listen! ###\(#function): Failed to retrieve a persistent store description.")
}
//be notified of change
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
description.setOption(true as NSNumber, forKey: NSMigratePersistentStoresAutomaticallyOption)
description.setOption(true as NSNumber, forKey: NSInferMappingModelAutomaticallyOption)
//set tracking history if we're using local container
if !useCloudSync {
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Hey Listen! Couldn't load persistent store. Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
container.viewContext.transactionAuthor = appTransactionAuthorName
container.viewContext.automaticallyMergesChangesFromParent = true
//Remote changes notification
NotificationCenter.default.addObserver(
self, selector: #selector(type(of: self).storeRemoteChange(_:)),
name: .NSPersistentStoreRemoteChange, object: container.persistentStoreCoordinator)
return container
}//end of setup container
}
Presumably you're calling loadPersistentStores on your NSPersistentContainer. That method accepts a completion handler (closure). That's where you'll get the callback that the migration has finished (or has failed). And you can tell when the migration is about to begin by adding a call just before loadPersistentStores.
If you create your own NSPersistentStoreDescription instance and add it to the NSPersistentContainer, you can control whether the migration happens and whether it runs synchronously or asynchronously.
See Enabling core data lightweight migration in Swift 3 (particularly answer https://stackoverflow.com/a/53607127/719690) for an example of using the completion handler.
Does the completionHandler of loadPersistentStores of NSPersistentContainer run synchronously? is also useful to understanding the flow.
Working from your code sample, you might revise it to (and I've switch to shortened closure syntax):
container.loadPersistentStores { storeDescription, error in
if let error = error as NSError? {
// error path, but should be nicer than just crashing
fatalError("Hey Listen! Couldn't load persistent store. Unresolved error \(error), \(error.userInfo)")
} else {
// happy path
print("unicorns and rainbows, migration succeeded, load the tableview")
}
}
(typed in browser, beware typos)
A Swiftier version would use a guard let on the error checking, but I wanted to minimize changes I made to your sample.

Swift - Core Data student info storage app errors

EDIT - i've played around with the code; still having issues.
i've been trying to modify the app in this tutorial so that i can enter student information and store it using core data. Ideally, i would like to be able to display that information on a label; but i haven't gotten that far yet. This is my first time working with core data and currently, i've hit a wall and need some assistance figuring out where in my code i've gone wrong and what to do to get it working.
So my questions are, how do i fix these errors.
and How would i got about displaying all the data after it's saved on a label.
Updated Screenshot
Updated Error Screenshot
Thanks in advance!
Code :
import UIKit
import CoreData
class ViewController: UIViewController {
#IBOutlet var name: UITextField!
#IBOutlet var address1: UITextField!
#IBOutlet var address2: UITextField!
#IBOutlet var city: UITextField!
#IBOutlet var state: UITextField!
#IBOutlet var zip: UITextField!
#IBOutlet var grade: UITextField!
#IBOutlet var status: UILabel!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
func getContext () -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
#IBAction func insertStudent(_ sender: AnyObject) {
let context = getContext()
let entityDescription = NSEntityDescription.entity(forEntityName: "Contacts", in: context)
let contact = NSManagedObject(entity: entityDescription!, insertInto: context) as! Contacts
contact.student_name = name.text
contact.address1 = address1.text
contact.address2 = address2.text
contact.city = city.text
contact.grade = grade.text
contact.state = state.text
contact.zip = zip.text
var error: NSError?
//save the object
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Looks like you are trying to mix Swift versions. See code examples below and see if this helps clear up the issue.
AppDelegate
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(_ application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
}
func applicationDidEnterBackground(_ application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(_ application: UIApplication) {
// Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(_ application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(_ application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: - Core Data stack
lazy var persistentContainer: NSPersistentContainer = {
/*
The persistent container for the application. This implementation
creates and returns a container, having loaded the store for the
application to it. This property is optional since there are legitimate
error conditions that could cause the creation of the store to fail.
*/
let container = NSPersistentContainer(name: "CDTest")
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
/*
Typical reasons for an error here include:
* The parent directory does not exist, cannot be created, or disallows writing.
* The persistent store is not accessible, due to permissions or data protection when the device is locked.
* The device is out of space.
* The store could not be migrated to the current model version.
Check the error message to determine what the actual problem was.
*/
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
return container
}()
// MARK: - Core Data Saving support
func saveContext () {
let context = persistentContainer.viewContext
if context.hasChanges {
do {
try context.save()
} catch {
// Replace this implementation with code to handle the error appropriately.
// fatalError() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
let nserror = error as NSError
fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
}
Functions to save and get data from CoreData in Swift 3.
func storeTranscription() {
let context = getContext()
//retrieve the entity that we just created
let entity = NSEntityDescription.entity(forEntityName: "ItemList", in: context)
let transc = NSManagedObject(entity: entity!, insertInto: context) as! ItemList
//set the entity values
transc.itemID = Double(itemid)
transc.productname = nametext
transc.amount = Double(amountDouble)
transc.stock = stockStatus
transc.inventoryDate = inventoryDate
//save the object
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
func getTranscriptions () {
//create a fetch request, telling it about the entity
let fetchRequest: NSFetchRequest<ItemList> = ItemList.fetchRequest()
do {
//go get the results
let searchResults = try getContext().fetch(fetchRequest)
fetchedStatsArray = searchResults as [NSManagedObject]
//I like to check the size of the returned results!
print ("num of results = \(searchResults.count)")
//You need to convert to NSManagedObject to use 'for' loops
for trans in searchResults as [NSManagedObject] {
//get the Key Value pairs (although there may be a better way to do that...
print("\(trans.value(forKey: "productname")!)")
let mdate = trans.value(forKey: "inventoryDate") as! Date
print(mdate)
}
} catch {
print("Error with request: \(error)")
}
}
Your Code converted Swift 3
func getContext () -> NSManagedObjectContext {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}
#IBAction func insertStudent(_ sender: AnyObject) {
let context = getContext()
let entityDescription = NSEntityDescription.entity(forEntityName: "Contacts", in: context)
let contact = NSManagedObject(entity: entityDescription!, insertInto: context) as! Contacts
contact.student_name = name.text
contact.address1 = address1.text
contact.address2 = address2.text
contact.city = city.text
contact.grade = grade.text
contact.state = state.text
contact.zip = zip.text
var error: NSError?
//save the object
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}

Using background location to keep NSTimer running

I'm trying to keep a NSTimer running in the background for a long period of time (multiple hours) but ofc Apple has strict rules about background execution (10 mins), but they do allow certain things such as audio and location to play in the background.
I was wondering how I could use location manager to keep a NSTimer running, basically the user sets an 'alarm' and i need it to go off at that time, so the location manager keeps the timer alive or something similar
Not sure how to approach I have this so far in my app delegate
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, CLLocationManagerDelegate{
var window: UIWindow?
var locationManager = CLLocationManager()
func update() {
var backgroundMusic:AVAudioPlayer
backgroundMusic = self.setupAudioPlayerWithFile("music", type:"mp3")
backgroundMusic.volume = 1
backgroundMusic.prepareToPlay()
backgroundMusic.play()
println("we made!")
}
func setupAudioPlayerWithFile(file:NSString, type:NSString) -> AVAudioPlayer {
//1
AVAudioSession.sharedInstance().setCategory(AVAudioSessionCategoryPlayback, error: nil)
var path = NSBundle.mainBundle().pathForResource(file as String, ofType: type as String)
var url = NSURL.fileURLWithPath(path!)
//2
var error: NSError?
//3
var audioPlayer:AVAudioPlayer?
audioPlayer = AVAudioPlayer(contentsOfURL: url, error: &error)
//4
return audioPlayer!
}
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
if NSUserDefaults.standardUserDefaults().boolForKey(kLoadedOnceKey) == false {
NSUserDefaults.standardUserDefaults().setBool(true, forKey: kLoadedOnceKey)
NSUserDefaults.standardUserDefaults().setBool(false, forKey: kShouldCapitalizeTaskKey)
NSUserDefaults.standardUserDefaults().setBool(false, forKey: kShouldCompleteNewTodoKey)
NSUserDefaults.standardUserDefaults().synchronize()
}
application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: UIUserNotificationType.Sound | UIUserNotificationType.Alert |
UIUserNotificationType.Sound, categories: nil
))
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
self.locationManager.delegate = self
self.locationManager.startUpdatingLocation()
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "KashishGoel.Photo_Alarm" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1] as! NSURL
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("Photo_Alarm", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("Photo_Alarm.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
func locationManager(manager: CLLocationManager!, didUpdateToLocation newLocation: CLLocation!, fromLocation oldLocation: CLLocation!) {
self.sendBackgroundLocationToServer(newLocation);
}
func sendBackgroundLocationToServer(location: CLLocation) {
var bgTask = UIBackgroundTaskIdentifier()
bgTask = UIApplication.sharedApplication().beginBackgroundTaskWithExpirationHandler { () -> Void in
UIApplication.sharedApplication().endBackgroundTask(bgTask)
}
println(location.coordinate.latitude)
if (bgTask != UIBackgroundTaskInvalid)
{
UIApplication.sharedApplication().endBackgroundTask(bgTask);
bgTask = UIBackgroundTaskInvalid;
}
}
}
I want to be able to call the update function when the NSTimer goes off, any advice on how to set this NSTimer?
Using the NSTimer for an alarm probably isn't the best choice. As you are finding out, you can't keep it running forever not to mention if the user terminates your app. Also, Apple is very strict on what apps get approved when it comes to running location updates in the background. I have first hand experience with this. I would recommend you look at using Local Notifications instead to set your alarm then you will not have to worry about keeping a timer running and it will be much more reliable.

Swift Core Data NSFetchRequest no results

I've encountered a problem when working with Core Data. I have this Core Data Model named 'Test.xcdatamodeld' and it contains only one entity named 'Data'. This Data entity contains one attribute named 'currCount' of type Int32.
What I'm trying to do is to read the value of 'currCount' but when I try to fetch something out of my entity 'Data' there are no results.
This is my fetching code:
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Data")
request.returnsObjectsAsFaults = false
var results: NSArray = context.executeFetchRequest(request, error: nil)!
var currCount:Int32 = 0
if results.count > 0 {
var res = results[0] as NSManagedObject
currCount = Int32(res.valueForKey("currCount") as Int)
println("Local Count: \(currCount)")
return currCount
}
else {
println("firstTime no Questions")
return 0
}
I always end up in the else-statement. I don't understand what I'm doing wrong. I've been going this way in another project and it works fine.
My AppDelegate.swift is as follows:
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication!, didFinishLaunchingWithOptions launchOptions: NSDictionary!) -> Bool {
return true
}
func applicationWillResignActive(application: UIApplication!) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication!) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication!) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication!) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication!) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "com.jqsoftware.MyLog" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1] as NSURL
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("Test", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("Test.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
coordinator = nil
// Report any error we got.
var dict = [String: AnyObject]()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
}
EDIT
Even if I save something to currCount before fetching it again, I get 0 results. This is the code I use for saving (which comes before the code above):
var appDel:AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context:NSManagedObjectContext = appDel.managedObjectContext!
var request = NSFetchRequest(entityName: "Data")
request.returnsObjectsAsFaults = false
var results: NSArray = context.executeFetchRequest(request, error: nil)!
var currentCount:Int32 = 5
var newCount = NSEntityDescription.insertNewObjectForEntityForName("Data", inManagedObjectContext: context) as NSManagedObject
newHp.setValue(currentCount, forKey: "currCount")
Once you have inserted something on your context, you should save it to make changes permanent (I suppose you are using a SQLite store).
In other words, you need to run a context.save(&error) method.
Update 1
var error: NSError?
if !context.save(&error) {
println("Error saving context: \(error?.localizedDescription)\n\(error?.userInfo)")
}

Could not save data in core data

I am new to core data , in order to add data
in xcode 6.1.1 using swift
this button function should take username and password from two text fields and save them
#IBAction func save(sender: AnyObject) {
var appDel: AppDelegate = (UIApplication.sharedApplication().delegate as AppDelegate)
var context: NSManagedObjectContext = appDel.managedObjectContext!
var newUser = NSEntityDescription.insertNewObjectForEntityForName("Users", inManagedObjectContext: context) as NSManagedObject
newUser.setValue(""+username.text, forKey: "username")
newUser.setValue(password.text, forKey: "password")
context.save(nil)
println(newUser)
println("Object Saved")
}
this code compile, how ever it has a run time error
ones I click on it I see this error
2015-01-26 21:40:55.160 cordatafirst[2104:1324567] CoreData: error: -addPersistentStoreWithType:SQLite configuration:(null)
MY AppDelegate.swift file
//
// AppDelegate.swift
// cordatafirst
//
// Created by Mustafa on 1/26/15.
// Copyright (c) 2015 Rashwan. All rights reserved.
//
import UIKit
import CoreData
#UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
var window: UIWindow?
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
// Override point for customization after application launch.
return true
}
func applicationWillResignActive(application: UIApplication) {
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
func applicationDidEnterBackground(application: UIApplication) {
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
func applicationWillEnterForeground(application: UIApplication) {
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
func applicationDidBecomeActive(application: UIApplication) {
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
func applicationWillTerminate(application: UIApplication) {
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
// Saves changes in the application's managed object context before the application terminates.
self.saveContext()
}
// MARK: - Core Data stack
lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file. This code uses a directory named "edu.self.cordatafirst" in the application's documents Application Support directory.
let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
return urls[urls.count-1] as NSURL
}()
lazy var managedObjectModel: NSManagedObjectModel = {
// The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model.
let modelURL = NSBundle.mainBundle().URLForResource("cordatafirst", withExtension: "momd")!
return NSManagedObjectModel(contentsOfURL: modelURL)!
}()
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator? = {
// The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail.
// Create the coordinator and store
var coordinator: NSPersistentStoreCoordinator? = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("cordatafirst.sqlite")
var error: NSError? = nil
var failureReason = "There was an error creating or loading the application's saved data."
if coordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil, error: &error) == nil {
coordinator = nil
// Report any error we got.
let dict = NSMutableDictionary()
dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
dict[NSLocalizedFailureReasonErrorKey] = failureReason
dict[NSUnderlyingErrorKey] = error
error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)
// Replace this with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
return coordinator
}()
lazy var managedObjectContext: NSManagedObjectContext? = {
// Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail.
let coordinator = self.persistentStoreCoordinator
if coordinator == nil {
return nil
}
var managedObjectContext = NSManagedObjectContext()
managedObjectContext.persistentStoreCoordinator = coordinator
return managedObjectContext
}()
// MARK: - Core Data Saving support
func saveContext () {
if let moc = self.managedObjectContext {
var error: NSError? = nil
if moc.hasChanges && !moc.save(&error) {
// Replace this implementation with code to handle the error appropriately.
// abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development.
NSLog("Unresolved error \(error), \(error!.userInfo)")
abort()
}
}
}
}
thanks in advance
It seems like your persistent store is not added. Does your AppDelegate look like THIS ? (I've got this file from THIS tutorial, but it's essentially the same among most apps)