I'm trying to update single entity in swift with help of batch request. It works perfect to update all the entities. Is it possible to update single entity using it's objectID?
Here is the example code:
let appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let batchRequest = NSBatchUpdateRequest(entityName: "Outlays")
batchRequest.propertiesToUpdate = ["purchase": self.purchase.text!]
batchRequest.resultType = .UpdatedObjectsCountResultType
do {
let results = try managedContext.executeRequest(batchRequest) as! NSBatchUpdateResult
print(" \(results.result) results changed")
} catch {
print(error)
}
Thanks in advance!
No, there is not need updating a single entity (NSManagedObject) in a batch request.
The easiest way is just to set the new value on your Outlays objects. Of course they have to be of type NSManagedObject. Call saveContext on your NSManagedObjectContext afterwards:
myOutlay.text = "changed"
let managedContext = appDelegate.managedObjectContext
var error: NSError? = nil
managedContext.save(&error)
If you only have the NSManagedObjectID of your NSManagedObject, it's required to get it from the Datastore first:
let managedContext = appDelegate.managedObjectContext
var myOutlay: Outlays = managedObjectContext.existingObjectWithID(outlayManagedID, error: nil) as? Outlays
myOutlay.text = "changed"
let managedContext = appDelegate.managedObjectContext
var error: NSError? = nil
managedContext.save(&error)
Related
func saveName(name: String){
//1
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext!
//2
let person = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
//3
person.setValue(name, forKey: "name")
//4
var error: NSError?
if !managedContext.save(&error) {
print("Could not save \(error!), \(String(describing: error?.userInfo))");
}
//5
people.append(person)
}
I can't get this program working correctly. I was trying save to CoreData.
In Swift 3, you access the context object like this:-
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
As the managed object context is used frequently add a lazy instantiated property in AppDelegate
lazy var managedObjectContext : NSManagedObjectContext = {
return self.persistentContainer.viewContext
}()
Both entity and managedObjectContext are supposed to be non-optional.
Change your second line in your code to access the managed object context
let managedContext = appDelegate.persistantContainer.Viewcontext
How to delete all data for example from an attribute <name>, not Entity, from attribute. I have an entity name - Users, attribute - name and I don't know how to delete all data from an attribute.
for delete the all data you can use this function
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)
print("Deleted")
}
} catch let error as NSError {
print(error)
}
}
and after that call the function like this
deleteAllData(entity: "your Entity name")
You have to set that attibute to nil and save the context. This is how you have to remove the attribute from entity. You can't delete it like how an entity is deleted from coreData.
I just renewed Rahuld and Piet.t code for Swift and it works.
func deleteAllData(entity: String) {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let managedObjectContext = appDelegate.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: entity)
fetchRequest.returnsObjectsAsFaults = false
do
{
let results = try managedObjectContext.fetch(fetchRequest)
for managedObject in results
{
let managedObjectData:NSManagedObject = managedObject
managedObjectContext.delete(managedObjectData)
print("Deleted")
}
} catch let error as NSError {
print(error)
}
try? managedObjectContext.save()
self.fetch(entity: "ListItem")
}
and after that call the function like this
deleteAllData(entity: "your Entity name")
in addition after you need to show the result so you will fetch your data again.
the below function can be used for it
func fetch(entity: String) {
//Veritabanındaki bilginin ekrana gelmesi için veriyi çekme işlemi
let appDelegate = UIApplication.shared.delegate as? AppDelegate
let managedObjectContext = appDelegate?.persistentContainer.viewContext
let fetchRequest = NSFetchRequest<NSManagedObject>.init(entityName: entity)
data = try! managedObjectContext!.fetch(fetchRequest)
tableView.reloadData()
}
use it like:
self.fetch(entity: "your entity name")
or like this:
fetch(entity: "your entity name")
referring to my previous question: Unique value of object to use in section Swift
my problem now is core data. this is code to save data following the previous code to populate section and table:
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let entity = NSEntityDescription.entityForName("Movie", inManagedObjectContext: context)!
let movie = Movie(entity: entity, insertIntoManagedObjectContext: context)
movie.title = title.text
movie.plot = plot.text
movie.genre = genre.text
context.insertObject(movie)
do {
try context.save()
} catch {
print("Could not save movie")
}
and fetch data is:
let app = UIApplication.sharedApplication().delegate as! AppDelegate
let context = app.managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "Movie")
do {
let results = try context.executeFetchRequest(fetchRequest)
self.loadMovie = results as! [Movie]
} catch let err as NSError {
print(err.debugDescription)
}
}
but nothing I receive the error on loadMovie Line..
where am I wrong?
First of all, delete the line
context.insertObject(movie)
because the object has already been inserted in the let movie = line.
To load the movies you need to recreate the data structure using the insertMovie(movie : Movie) function.
let movies = try context.executeFetchRequest(fetchRequest) as! [Movie]
loadMovie.removeAll()
for movie in movies {
insertMovie(movie)
}
As the answer of your previous question suggested, the self.loadMovie now has type [String:[Movie]], so you should probably try casting results as [String:[Movie]].
Try self.loadMovie = results as! [String:[Movie]] instead.
I have code, which fetches core data
var appDelegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var managedContext : NSManagedObjectContext = appDelegate.managedObjectContext!
let request = NSFetchRequest(entityName: "QuestionDB")
request.returnsObjectsAsFaults = false
if let results = managedContext.executeFetchRequest(request, error: nil)
it returns array of AnyObject
I need it to return array of objects with type of [Question]
when i cast
var appDelegate : AppDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
var managedContext : NSManagedObjectContext = appDelegate.managedObjectContext!
let request = NSFetchRequest(entityName: "QuestionDB")
request.returnsObjectsAsFaults = false
if let results = managedContext.executeFetchRequest(request, error: nil) as? [Question] {
println("This is result of loadFromDb \(results)")
}
it returns nil
How can i fix it ?
Check class name in data model inspector of Entity in data model by
select your app's .xcdatamodeld -> select Entity and in data model inspector
Try this:
let fetchRequest = NSFetchRequest(entityName:"QuestionDB")
var error: NSError?
let fetchedResults = managedObjectContext.executeFetchRequest(fetchRequest, error: &error) as! [NSManagedObject]?
if let results = fetchedResults {
return results as! [QuestionDB]
} else {
fatalError("Could not fetch \(error), \(error!.userInfo)")
}
If your class name is Question you have to set it in the model inspector.
Here's how I'm saving the data
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
let entity = NSEntityDescription.entityForName("Theme", inManagedObjectContext: managedContext)
let themeObj = NSManagedObject(entity: entity!, insertIntoManagedObjectContext:managedContext)
themeObj.setValue(num, forKey: "themeNumber")
var error: NSError?
if !managedContext.save(&error)
{
println("Could not save \(error), \(error?.userInfo)")
}
And then loading it
let appDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let managedContext = appDelegate.managedObjectContext!
let fetchRequest = NSFetchRequest(entityName:"Theme")
var resultArr = [NSManagedObject]()
var error: NSError?
let fetchedResults = managedContext.executeFetchRequest(fetchRequest, error: &error) as [NSManagedObject]?
if let results = fetchedResults
{
resultArr = results
}
else
{
println("Could not fetch \(error), \(error!.userInfo)")
}
theme = resultArr[0].valueForKey("themeNumber") as Int
My data model is just the entity Theme with one attribute, themeNumber which is an Integer 16. If I delete the app from the simulator, it loads the correct theme. However, if I change it and run it again... nothing. Any ideas?
You don't need to use setValue. Typically you would do something like this:
themeObj.themeNumber = num
So to fix your problem, you need to actually update the core data object. I just realized that you probably didn't set the themeNumber by the property because you don't have the NSManagedObject subclass setup for your entity. I'll write try to write the fix for how you have it setup.
theme = resultArr[0] as NSManagedObject
theme.setValue(num, forKey: "themeNumber")
if !managedContext.save(&error)
{
println("Could not save \(error), \(error?.userInfo)")
}
After you save it, see if it has the new value that you are looking for.