I am working on an app that uses CoreData.
I am strong numbers and retrieving them, but when i store more than one field it only shows the last field with the number but a 0 in all the others. below is my codes.
to store them...
let CWConvert = Double(CWeight.text!)
storeTranscription18CW(pageText: (CWConvert)!, textFileUrlString: "cWeight")
savePlus += 1
let TWConvert = Double(TWeight.text!)
storeTranscription18TW(pageText: (TWConvert)!, textFileUrlString: "tWeight")
and...
func getContext () -> NSManagedObjectContext {
_ = UIApplication.shared.delegate as! AppDelegate
return DataController().managedObjectContext
}
func storeTranscription18CW (pageText: Double, textFileUrlString: String) {
let context = getContext()
//retrieve the entity that we just created
let entity = NSEntityDescription.entity(forEntityName: "TextInputs", in: context)
let transc = NSManagedObject(entity: entity!, insertInto: context)
// set the entity values
transc.setValue(pageText, forKey: "cWeight")
//save the object
do {
try context.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
func storeTranscription18TW (pageText: Double, textFileUrlString: String) {
let contexta = getContext()
//retrieve the entity that we just created
let entitya = NSEntityDescription.entity(forEntityName: "TextInputs", in: contexta)
let transc = NSManagedObject(entity: entitya!, insertInto: contexta)
// set the entity values
transc.setValue(pageText, forKey: "tWeight")
//save the object
do {
try contexta.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
and to retrive.
func getTranscriptions18CW () {
//create a fetch request, telling it about the entity
let fetchRequesta: NSFetchRequest<TextInputs> = TextInputs.fetchRequest()
do {
//go get the results
let searchResults18CW = try getContext().fetch(fetchRequesta)
for transa in searchResults18CW as [NSManagedObject] {
if let resulta = transa.value(forKey: "cWeight") {
if let stra = resulta as? String {
CWeight.text = stra
}else {
CWeight?.text = "\(resulta)"
}
}
}
//get the Key Value pairs (although there may be a better
}catch {
print("Error with request: \(error)")
}
}
func getTranscriptions18TW () {
//create a fetch request, telling it about the entity
let fetchRequest: NSFetchRequest<TextInputs> = TextInputs.fetchRequest()
do {
//go get the results
let searchResults18TW = try getContext().fetch(fetchRequest)
for trans in searchResults18TW as [NSManagedObject] {
if let result = trans.value(forKey: "tWeight") {
if let str = result as? String {
TWeight.text = str
}else {
TWeight?.text = "\(result)"
}
}
//get the Key Value pairs (although there may be a better way to do that...
}
}catch {
print("Error with request: \(error)")
}
}
i have tried different names but get the same it only shows the last one as the real number if i moment out the last one then the first shows the real value.
Try something more like this to save so that you are saving both in the same row.
func storeTranscription18TW () {
let contexta = getContext()
//retrieve the entity that we just created
let entitya = NSEntityDescription.entity(forEntityName: "TextInputs", in: contexta)
let transc = NSManagedObject(entity: entitya!, insertInto: contexta)
// set the entity values
transc.setValue(CWConvert, forKey: "cWeight") // Note the change from pageText
transc.setValue(TWConvert, forKey: "tWeight") // Note the change from pageText
//save the object
do {
try contexta.save()
print("saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
} catch {
}
}
Then when you do a get they would both be done in the same function as well.
Related
I'm trying to save a string array to core data, but every time I try to read the array a get an empty one(I'm using NSString because of an answer I've read here, but it doesn't seem to work). Here is the code I use for saving :
let i = UserDefaults.standard.integer(forKey: "Index")
let fetchRequest: NSFetchRequest<PersonalTask> = PersonalTask.fetchRequest()
do {
let tasks = try PersistanceService.context.fetch(fetchRequest)
self.personalTasks = tasks
} catch {
print("Error")
}
let pTask = personalTasks[i]
var subtasks = pTask.subtasks
print(subtasks as Any)
let subtask = textView!.text as NSString
subtasks?.append(subtask)
print(subtasks)
PersistanceService.saveContext()
Here is the function saveContext() :
static var context: NSManagedObjectContext {
return persistentContainer.viewContext
}
static var persistentContainer: NSPersistentCloudKitContainer = {
let container = NSPersistentCloudKitContainer(name: "Tasks")
guard let description = container.persistentStoreDescriptions.first else {
fatalError("No descriptions found")
}
description.setOption(true as NSObject, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
container.viewContext.automaticallyMergesChangesFromParent = true
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
return container
}()
// MARK: - Core Data Saving support
static func saveContext () {
if context.hasChanges {
do {
try context.save()
} catch {
let nserror = error as NSError
print("Unresolved error \(nserror), \(nserror.userInfo)")
}
}
}
And here I am reading the data and getting an empty array :
let i = UserDefaults.standard.integer(forKey: "Index")
let fetchRequest: NSFetchRequest<PersonalTask> = PersonalTask.fetchRequest()
do {
let tasks = try PersistanceService.context.fetch(fetchRequest)
self.personalTasks = tasks
} catch {
print("Error")
}
let pTask = personalTasks[i]
print(pTask.title)
print(pTask.notes)
print(pTask.subtasks)
subtasks = pTask.subtasks as [String]? ?? [NSString]() as [String]
print(subtasks)
What should I do to fix this?
My function below when called is not saving whatever is on the textfield to core data. When appearing in the debugg area what appears is "". THis code when used in the view did load function it does work but when I call it it does not work.
func timTebow(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let entity = NSEntityDescription.entity(forEntityName: "Item", in: context)
let newUser = NSManagedObject(entity: entity!, insertInto: context)
newUser.setValue(playName.text, forKey: "atBATS")
do {
try context.save()
} catch {
print("Failed saving")
}
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
for data in result as! [NSManagedObject] {
print(data.value(forKey: "atBATS") as? String)
}
} catch {
print("Failed")
}
}
I have 2 functions, one which should save the string to a CoreData attribute and another to fetch it. And this was written by copying working code from elsewhere in the project, so I can't figure out why when I print the contents of 'currentSetting' I get nil.
The save function is called from didSelectRowAtIndexPath and it sends in indexPath.row as the parameter and this fetches a String from an array.
func getImageSetting() {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Settings")
do {
let fetcher = try context.fetch(fetchRequest)
let data = fetcher as? [NSManagedObject]
if let results = data {
let settingResult = results[0]
currentSetting = settingResult.value(forKey: "imageQuality") as? String
print(currentSetting as Any)
} else { print ("error") }
}
catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
func saveSetting(selection: Int) {
let coreSelection = choices[selection]
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.persistentContainer.viewContext
let itemEntity = NSEntityDescription.entity(forEntityName: "Settings", in: managedContext)!
let item = NSManagedObject(entity: itemEntity, insertInto: managedContext)
item.setValue(coreSelection, forKey: "imageQuality")
do {
try managedContext.save()
} catch let error as NSError {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
}
I created a table: key, value.
It's just for save some params, when the key doesn't exist, I do an insert but when it exist I update the value.
In my case, when the key already exist it does an another insert in ma table with key equal to nil:
public static func insertValueWithKey(context: NSManagedObjectContext, key:String, value:String){
let fetchRequest : NSFetchRequest<NSFetchRequestResult>
if #available(iOS 10.0, *) {
fetchRequest = Params.fetchRequest()
} else {
fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Params")
}
let predicate = NSPredicate(format: "key=%#", key)
fetchRequest.predicate = predicate
do {
let results = try context.fetch(fetchRequest)
if(results.count != 0){
let paramsDescription = NSEntityDescription.entity(forEntityName: "Params", in: context)
let params = NSManagedObject(entity: paramsDescription!, insertInto: context) as! Params
params.value = value
do {
try context.save()
} catch let error as NSError {
print ("Error first demande insertion \(error)")
}
} else if (results.count == 0) {
let params = NSEntityDescription.insertNewObject(forEntityName: "Params", into: context) as! Params
params.key = key
params.value = value
context.insert(params)
do {
try context.save()
} catch let error as NSError {
print ("Error first demande insertion \(error)")
}
}
} catch {
let fetchError = error as NSError
print(fetchError)
}
}
I don't understand why because it work as well on simulator but not on device...
replace:
let params = NSManagedObject(entity: paramsDescription!, insertInto: context) as! Params
with
let params = results.last as! Params
NSManagedObject(entity: insertInto:) is functionally the same as NSEntityDescription.insertNewObject(forEntityName:into:)
So I have this code which works fine, but I want a much better one.
func deleteCoreDataObjects() {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
//where groupData is an Array of an Entity
for i in 0..<self.groupData.count {
context.delete(groupData[i])
}
(UIApplication.shared.delegate as! AppDelegate).saveContext()
}
Currently I'm deleting the objects one by one via for loop.
You can try this:
func deleteAllData(entity: String)
{
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: entity)
fetchRequest.returnsObjectsAsFaults = false
do
{
let results = try managedContext.executeFetchRequest(fetchRequest)
for managedObject in results
{
let managedObjectData:NSManagedObject = managedObject as! NSManagedObject
managedContext.deleteObject(managedObjectData)
}
} catch let error as NSError {
print("Detele all data in \(entity) error : \(error) \(error.userInfo)")
}
}
Usage:
self.deleteAllData("your_entityName")
Already seen in: https://stackoverflow.com/a/33931528/2894160
Best is delete the persistence storage and then add new one instead of looping each entity (if you want to delete all entities from coredata).
func deletePersistentStoreCoordinator () {
do {
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("YourDatabaseName.sqlite")
try self.persistentStoreCoordinator.destroyPersistentStoreAtURL(url, withType: NSSQLiteStoreType, options: nil)
try self.persistentStoreCoordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
}
catch{
}
}
Here is the code for deleting records from Core Data :
//Delete user info from local db
func deleteUserInfo() {
let context = appdelegate.managedObjectContext
let coord = appdelegate.persistentStoreCoordinator
let fetchRequest = NSFetchRequest(entityName: "User")
if #available(iOS 9.0, *) {
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
//let predicate = NSPredicate(format: "id == %#", key)
//fetchRequest.predicate = predicate
do {
try coord.executeRequest(deleteRequest, withContext: context)
}
catch let error as NSError {
//Error handling
}
catch {}
} else {
// Fallback on earlier versions
do {
let users: NSArray = try appdelegate.managedObjectContext.executeFetchRequest(fetchRequest)
for user in users {
appdelegate.managedObjectContext.delete(user)
}
try appdelegate.managedObjectContext.save()
} catch let error as NSError {
//Error handling
}
catch {}
}
}