My code is trying to delete a elememnt from a set via button. When the button is pressed a runtime error occurs. The error states "Thread 1: Fatal error: Index out of range" at let date = users[indx]. All I am doing is trying to delete a element from the core data set. I save the code in one class and iand display it through another. Link to git https://github.com/redrock34/core-Data-Delete.
extension ViewController : datacollectionProfotocol {
func deleteData(indx: Int) {
users.remove(at: indx)
block.reloadData()
let date = users[indx]
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
request.predicate = NSPredicate(format:"atBATS = %#", date as CVarArg)
let result = try? context.fetch(request)
let resultData = result as! [NSManagedObject]
for object in resultData {
context.delete(object)
}
do {
try context.save()
print(" saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
}
Related
**this is to how to create a login validation form to move from login to next view controller **
**fetching the data from database**
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
**it stores the data**
let managedContext = appDelegate.persistentContainer.viewContext
//it fetches the data
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Details")
**validation code to check it but the condition fails**
do {
let result = try managedContext.fetch(fetchRequest)
for data in result as! [NSManagedObject] {
if ([emailid.text].count != 0 && [password.text].count != 0){
if (emailid.text == data.value(forKey: "emailId") as? String) && (password.text == data.value(forKey: "passWord") as? String){
let secondvc = storyboard?.instantiateViewController(withIdentifier: "loginVcID") as! loginVc
self.navigationController?.pushViewController(secondvc, animated: true)
}
in this condition it is not moving to next view controller
to check another condition
}
else {
self.label.text = "enter a valid data"
}
}
}
**when it fails it goes to catch to show that**
catch
{
print("Failed")
}
}
}
**this code is for registration to save into database**
**to create a database and store the value**
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }
let managedContext = appDelegate.persistentContainer.viewContext
let detailEntity = NSEntityDescription.entity(forEntityName: "Details", in: managedContext)!
** creation of database**
let detail = NSManagedObject(entity: detailEntity, insertInto: managedContext)
detail.setValue(username.text, forKeyPath: "userName")
detail.setValue(emailid.text, forKey: "emailId")
detail.setValue(password.text, forKey: "passWord")
detail.setValue(city.text, forKey: "city")
**saving the data**
do {
try managedContext.save()
}
** it display whatever in that method**
catch let error as NSError
{
its shows error when it fails
print("Could not save. (error), (error.userInfo)")
}
Go to you appDelegate, you will find a line // MARK: - Core Data stack & // MARK: - Core Data Saving support, remove the saveContext() function & also remove persistentContainer.. Then
Add this class to your project
final class PersistenceManager {
private init() {}
static let shared = PersistenceManager()
// 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: "ProjectNAME")
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
}()
lazy var context = persistentContainer.viewContext
// MARK: - Core Data Saving support
func save() {
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)")
}
}
}
func fetch<T: NSManagedObject>(_ objectType: T.Type) -> [T] {
let entityName = String(describing: objectType)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
do {
let fetchedObjects = try context.fetch(fetchRequest) as? [T]
return fetchedObjects ?? [T]()
} catch {
return [T]()
}
}
func deleteAll<T: NSManagedObject>(_ objectType: T.Type) {
let entityName = String(describing: objectType)
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: entityName)
let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
do {
try persistentContainer.persistentStoreCoordinator.execute(deleteRequest, with: context)
} catch {
print(error.localizedDescription)
}
}
func delete(_ object: NSManagedObject) {
context.delete(object)
save()
}
}
To fetch data
PersistenceManager.shared.fetch(User.self)
To delete data
PersistenceManager.shared.delete(user)
To create user
let newUser = Users(context: PersistenceManager.shared.context)
newUser.name = "Zero Cool"
newUser.password = "qwerty"
PersistenceManager.shared.save()
My code is trying to delete a element from a set via button. When the user presses the button the set is deleted from that page but if it is reloaded the code is still there. So it is not permanently deleted. All I am doing is trying to delete a element from the core data set. I save the code in one class and iand display it through another. Link to git https://github.com/redrock34/core-Data-Delete/blob/master/photography%202.zip.
extension ViewController : datacollectionProfotocol {
func deleteData(indx: Int) {
block.reloadData()
let date = users[indx]
users.remove(at: indx)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Item")
request.predicate = NSPredicate(format:"atBATS = %#", date as CVarArg)
let result = try? context.fetch(request)
let resultData = result as! [NSManagedObject]
for object in resultData {
context.delete(object)
}
do {
try context.save()
print(" saved!")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}}
Using this function to sort my cells in my table view. I am getting an error in my fetch request. The line inside of the do loop, notes = try context.fetch(request) is causing the error , the request is underlined
The error says "Cannot convert value of type 'NSFetchRequest' to expected argument type 'NSFetchRequest'"
My TableViewController file
import UIKit
import CoreData
class noteTableViewController: UITableViewController {
var notes = [Note]()
var managedObjectContext: NSManagedObjectContext? {
return (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
}
func loadDataFromDatabase() {
let settings = UserDefaults.standard
let sortPriority = settings.string(forKey: Constants.kPriority)
let context = appDelegate.persistentContainer.viewContext
let request = NSFetchRequest<NSManagedObject>(entityName: "Note")
let sortDescriptor = NSSortDescriptor(key: sortPriority)
let sortDescriptorsArray = [sortDescriptor]
request.sortDescriptors = sortDescriptorsArray
do {
notes = try context.fetch(request)
} catch let errer as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
}
Try this:
func loadDataFromDatabase() {
...
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Note")
...
do {
notes = try context.fetch(request) as? [Note] ?? []
} catch let errer as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
Of course, I'm assuming your Note class is a subclass of NSManagerObject.
You need to cast it as an array of Notes
do {
notes = try context.fetch(request) as? [Note] ?? []
} catch let errer as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
I'm having trouble fetching my object from core data. Object looks like this:
class cilj: NSObject {
var imeCilja: String
var slikaCilja: String }
My entity is called Entity and has two Attributes "tekst" and "slika", both of type String. My save func is this:
func saveImage(goalName:String, imageName:String) {
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entityDescription = NSEntityDescription.entityForName("Entity", inManagedObjectContext:managedContext)
let thingToSaveToCD = NSManagedObject(entity: entityDescription!, insertIntoManagedObjectContext: managedContext)
thingToSaveToCD.setValue(globalGoalTitle, forKey: "tekst")
thingToSaveToCD.setValue(globalGoalImagePath, forKey: "slika")
do {
try managedContext.save()
print("managed to save to core data")
//5
// listaObjekata.append(cilj5) as! [cilj]
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
}
I use an alertController to pick up the text, and imagePicker to pick up image that I then store in documents and get the path. I store both of these in a global variables visible in the code above.
My fetch function is :
func coreDataFetch(){
//core data fetch
//1
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
//2
let fetchRequest = NSFetchRequest(entityName: "Entity")
do {
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest) as! [cilj]
listaObjekata = fetchedResults
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
}
I have been through ray wenderlich's article on Core Data, Apple's documentation, a couple of YT videos but I still seem to be missing something. I would greatly appreciate any help. Thanks !
EDIT - here is my cellForRowAtIndexPath
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("myCell") as! cellController
let ciljZaPrikaz = listaObjekata[indexPath.item]
cell.labelText.text = ciljZaPrikaz.imeCilja ?? "no text found"
let path = getDocumentsDirectory().stringByAppendingPathComponent(ciljZaPrikaz.slikaCilja)
cell.imageToShow.image = UIImage(contentsOfFile: path)
return cell
}
You are doing correct but just missing type casting to your model. Try below:
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest)
if let results = fetchResults where results.count > 0 {
let entityModel = results[0] as? Entity
let tekst = entityModel.tekst
}
I would also like to add how I iterate through my return objects from core data:
do {
let fetchedResults = try managedContext.executeFetchRequest(fetchRequest)
listaObjekata.removeAll()
for i in 0...(fetchedResults.count-1) {
let enityModel = fetchedResults[i] as? Entity
let thisToArray = cilj(imeCilja: (enityModel?.tekst!)!, slikaCilja: (enityModel?.slika!)!)
listaObjekata.append(thisToArray)
}
} catch let error as NSError {
print("Could not fetch \(error), \(error.userInfo)")
}
I make my fetch request like so :
let pageFetchRequest = NSFetchRequest(entityName: "Page")
let results = try managedObjectContext.executeFetchRequest(pageFetchRequest)
Here, results will return 0 results {}.
But I do this by itself :
managedObjectContext.executeFetchRequest(pageFetchRequest)
I get all 192 results. So long as I don't assign it to a variable such as results. Why is that? Does assigning it or using the method try prevent this from working?
Update
This is the full post. Notice how I'm using managedObjectContext twice for two different related requests. Maybe that's what is botching my results up?
let managedObjectContext = self.managedObjectContext
for item in items {
let word = Word(chapter: Int(item.chapter)!, verse: Int(item.verse)!, sanskrit: item.sanskrit, english: item.english, insertIntoManagedObjectContext: managedObjectContext)
// Assign the Page
let pageFetchRequest = NSFetchRequest(entityName: "Word")
let chapterPred = NSPredicate(format: "(chapter = %d)", Int(item.chapter)!)
let versePred = NSPredicate(format: "(verse = %d)", Int(item.verse)!)
pageFetchRequest.fetchLimit = 1
pageFetchRequest.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [chapterPred, versePred])
do {
let results = try managedObjectContext.executeFetchRequest(pageFetchRequest)
if let page = results.first as? NSManagedObject {
word.setValue(page, forKey: "page")
}
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
do {
try managedObjectContext.save()
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
So evidently the answer.. I think.. was to create a separate managedObjectContext that wouldn't be confused with the parent one.. Like so :
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let secondManagedContext = appDelegate.managedObjectContext
let pageFetchRequest = NSFetchRequest(entityName: "Page")Int(item.verse)!)
pageFetchRequest.fetchLimit = 1
pageFetchRequest.predicate = NSCompoundPredicate(type: .OrPredicateType, subpredicates: [chapterPred, versePred])
And then I had to also write this :
do {
var results:[NSManagedObject]
results = try secondManagedContext.executeFetchRequest(pageFetchRequest) as! [Page]
if let page = results.first {
word.setValue(page, forKey: "page")
}