How to update existing object in Core Data? - objective-c

When I insert new object I do with following code:
NSManagedObjectContext *context = [appDelegate managedObjectContext];
Favorits *favorits = [NSEntityDescription insertNewObjectForEntityForName:#"Favorits" inManagedObjectContext:context];
favorits.title = #"Some title";
NSError *error;
if (![context save:&error]) {
NSLog(#"Whoops");
}
How can I update existing object in core data?

Updating is simple as creating a new one.
To update a specific object you need to set up a NSFetchRequest. This class is equivalent to a SELECT statetement in SQL language.
Here a simple example:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Favorits" inManagedObjectContext:moc]];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
// error handling code
The array results contains all the managed objects contained within the sqlite file. If you want to grab a specific object (or more objects) you need to use a predicate with that request. For example:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title == %#", #"Some Title"];
[request setPredicate:predicate];
In this case results contains the objects where title is equal to Some Title. Setting a predicate is equal to put the WHERE clause in a SQL statement.
For further info I suggest you to read the Core Data programming guide and NSFecthRequest class reference.
Core Data Programming Guide
NSFecthRequest Class Reference
Hope it helps.
EDIT (snippet that can be used to update)
// maybe some check before, to be sure results is not empty
Favorits* favoritsGrabbed = [results objectAtIndex:0];
favoritsGrabbed.title = #"My Title";
// save here the context
or if you are not using a NSManagedObject subclass.
// maybe some check before, to be sure results is not empty
NSManagedObject* favoritsGrabbed = [results objectAtIndex:0];
[favoritsGrabbed setValue:#"My title" forKey:#"title"];
// save here the context
In both cases if you do a save on the context, data will be updated.

You have to fetch the object from the context, change the properties you desire, then save the context as you are in your example.

I hope this will help u. as it works for me.
NSMutableArray *results = [[NSMutableArray alloc]init];
int flag=0;
NSPredicate *pred;
if (self.txtCourseNo.text.length > 0) {
pred = [NSPredicate predicateWithFormat:#"courseno CONTAINS[cd] %#", self.txtCourseNo.text];
flag=1;
} else {
flag=0;
NSLog(#"Enter Corect Course number");
}
if (flag == 1) {
NSLog(#"predicate: %#",pred);
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]initWithEntityName:#"Course"];
[fetchRequest setPredicate:pred];
results = [[self.context executeFetchRequest:fetchRequest error:nil] mutableCopy];
if (results.count > 0) {
NSManagedObject* favoritsGrabbed = [results objectAtIndex:0];
[favoritsGrabbed setValue:self.txtCourseName.text forKey:#"coursename"];
[self.context save:nil];
[self showData];
} else {
NSLog(#"Enter Corect Course number");
}
}

if you are a swift programmer this can help you :
if you want to delete a NSManagedObject
in my case ID is a unique attribute for entity STUDENT
/** for deleting items */
func delete(identifier: String) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "STUDENT")
let predicate = NSPredicate(format: "ID = '\(identifier)'")
fetchRequest.predicate = predicate
do
{
let object = try context.fetch(fetchRequest)
if object.count == 1
{
let objectDelete = object.first as! NSManagedObject
context.delete(objectDelete)
}
}
catch
{
print(error)
}
}
if you want to update a NSManagedObject :
/** for updating items */
func update(identifier: String,name:String) {
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let fetchRequest:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest.init(entityName: "STUDENT")
let predicate = NSPredicate(format: "ID = '\(identifier)'")
fetchRequest.predicate = predicate
do
{
let object = try context.fetch(fetchRequest)
if object.count == 1
{
let objectUpdate = object.first as! NSManagedObject
objectUpdate.setValue(name, forKey: "name")
do{
try context.save()
}
catch
{
print(error)
}
}
}
catch
{
print(error)
}
}

I saw an answer in Objective-C which helped me. I am posting an answer for Swift users -
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let updateCont = appDelegate?.persistentContainer.viewContext
let pred = NSPredicate(format: "your_Attribute_Name = %#", argumentArray : [your_Arguments])
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "your_Entity_Name")
request.predicate = pred
do {
let resul = try updateCont?.fetch(request) as? [NSManagedObject]
let m = resul?.first
m?.setValue(txtName.text, forKey: "your_Attribute_Name_Whose_Value_Should_Update")
try? updateCont?.save()
} catch let err as NSError {
print(err)
}

Related

Objective-C converting to Swift 3.1 getting error 'Any' is not convertible

I'm finally attempting to convert one of my Objective-C apps to Swift 3.1. I'm also taking a tutorial on Swift to help me out. However, I'm running into the following error when trying to convert a 'for in' loop to Swift that worked successfully in Obj-C. I've posted both the Swift and Objective-C code below and commented the line in Swift where I am getting the error. I am getting the error with
for managedObject: NSManagedObject in myResults{
The error states
'Any' is not convertible to 'MSManageObject'
Any help pointing me in the right direction is greatly appreciated.
//IN SWIFT 3.1
let context: NSManagedObjectContext? =
CoreDataHelper.shared().context
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
let entity = NSEntityDescription.entity(forEntityName:
"Exhibitors", in: context!)
fetchRequest.entity = entity
var myResults : NSArray = try!
CoreDataHelper.shared().context.fetch(fetchRequest) as NSArray
self.objects = myResults as! [Any]
if !(myResults != nil) || !((myResults.count) != nil) {
print("No Exhibitor objects found to be deleted!")
}
else {
//****Getting error 'Any' is not convertible to 'NSManagedObject'
for managedObject: NSManagedObject in myResults {
if !(managedObject.value(forKey: "fav") == "Yes") {
context?.deleteObject(managedObject)
var error: Error? = nil
// Save the object to persistent store
if !context?.save(error) {
print("Can't Save! \(error) \
(error?.localizedDescription)")
}
print("Exhibitor object deleted!")
}
}
}
//IN OBJECTIVE-C
NSManagedObjectContext *context = [[CoreDataHelper sharedHelper]
context];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc]
init];
NSEntityDescription *entity = [NSEntityDescription
entityForName:#"Exhibitors" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *myResults = [[[CoreDataHelper sharedHelper]
context] executeFetchRequest:fetchRequest error:nil];
self.objects = myResults;
if (!myResults || !myResults.count){
NSLog(#"No Exhibitor objects found to be deleted!");
}
else{
for (NSManagedObject *managedObject in myResults) {
if (![[managedObject valueForKey:#"fav"]
isEqualToString:#"Yes"]) {
[context deleteObject:managedObject];
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error,
[error localizedDescription]);
}
NSLog(#"Exhibitor object deleted!");
}
}
}
The main issue is that your are annotating worse types than the compiler infers.
Don't do that. Don't annotate types unless the compiler tells you to do.
For example the managed object context is supposed to be non-optional
let context = CoreDataHelper.shared().context
Your fetch returns [NSManagedObject], never use NSArray and never cast distinct types up to more unspecified like [Any]
Simply write
let fetchRequest = NSFetchRequest<NSFetchRequestResult>()
let entity = NSEntityDescription.entity(forEntityName: "Exhibitors", in: context)
fetchRequest.entity = entity
do { // its always recommended to do a good error handling !!
self.objects = try CoreDataHelper.shared().context.fetch(fetchRequest)
for managedObject in self.objects {
...
}
} catch { print(error) }
If objects is empty the loop will be skipped.
Instead of this:
var myResults : NSArray = try! CoreDataHelper.shared().context.fetch(fetchRequest) as NSArray
Do this:
let myResults : [NSManagedObject] = try! CoreDataHelper.shared().context.fetch(fetchRequest)
You should also use less ! operators, as they may crash your app, try using the guard let pattern or ? operators.

Uploading multiple files to a single row parse.com

So I'm using the following code to upload multiple files to a single row of a class.
for (NSString* currentString in directoryContents){
NSLog(#"%#",currentString);
NSString *temp2 = [temp stringByAppendingPathComponent:currentString];
PFFile *file = [PFFile fileWithName:currentString contentsAtPath:temp2];
[file saveInBackground];
PFObject *obj = [PFObject objectWithClassName:#"DreamBits"];
if ([currentString isEqualToString:#"index.html"]) {
[obj setObject:file forKey:#"index"];
}
else {
count += 1;
NSString *filen = [NSString stringWithFormat:#"file%i",count];
NSLog(#"%#",filen);
[obj setObject:file forKey:filen];
}
[obj saveInBackground];
}
The issue is I'm getting the files in different rows for some reason. Any idea how I can correct this?
I am modified your code little bit. I am not run this code but hope it helps you.
PFObject *obj = [PFObject objectWithClassName:#"DreamBits"];
for (NSString* currentString in directoryContents){
NSLog(#"%#",currentString);
NSString *temp2 = [temp stringByAppendingPathComponent:currentString];
PFFile *file = [PFFile fileWithName:currentString contentsAtPath:temp2];
if ([currentString isEqualToString:#"index.html"]) {
[obj setObject:file forKey:#"index"];
}
else {
count += 1;
NSString *filen = [NSString stringWithFormat:#"file%i",count];
NSLog(#"%#",filen);
[obj setObject:file forKey:filen];
}
}
[obj saveInBackground];
Create the PFObject outside the loop.Set all the PFFile object to the PFObject inside the loop.
After loop, save the PFObject. It is better to use the method :
[obj saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error)
{
//Check whether the upload is succeeded or not
}];
I have used this method for upload profile and thumb image in a row in the Parse Server table. Using swift 4 and Parse SDK 1.17.1. Hope this technic will help.
func uploadImage(profileImage: UIImage, profileImageName: String, thumbImage: UIImage, thumbImageName: String) {
if let profileImagefile = PFFile.init(name: profileImageName, data: profileImage.jpegData(compressionQuality: 1)!) {
let fileObject = PFObject(className:"ProfileImage")
fileObject.setValue(profileImagefile, forKey: "profile_image")
fileObject.saveInBackground { (success, error) in
if error == nil {
print("thumb image path: \(profileImagefile.url ?? "")")
if let thumbImage = PFFile.init(name: thumbImageName, data: thumbImage.jpegData(compressionQuality: 0.5)!) {
fileObject.setValue(thumbImage, forKey: "thumb_image")
fileObject.saveInBackground(block: { (result, fileError) in
if fileError == nil {
print("thumb image path: \(thumbImage.url ?? "")")
}else {
print("error on thumb upload: \(result)")
}
})
}
}else {
print("error on file upload: \(error.debugDescription)")
}
}
}
}

How to NSFetchedResultsController coding in Swift

can't figure out how to rewrite the following method in swift
for a better learning curve, so i tried to translate this code. so lets select a more difficult method to do so. it has error handling, object init and parameter settings, an array of object pointers, selectors, nil, and self..
Objective-C:
-(NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
return _fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Event" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:20];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"timeStamp" ascending:NO];
NSArray *sortDescriptors = #[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *frC = [[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:self.managedObjectContext
sectionNameKeyPath:nil
cacheName:#"Master"];
frC.delegate = self;
self.fetchedResultsController = frC;
NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error]) {
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
abort();
}
return _fetchedResultsController;
}
specially can't figure out how to call NSEntityDescription *entity.
while interpreting the specs i could not rewrite this correct..
swift:
var fetchedResultsController: NSFetchedResultsController {
var _fetchedResultsController: NSFetchedResultsController? = nil //??
var fetchRequest: NSFetchRequest? = nil // ??
var entity: NSEntityDescription = NSEntityDescription( /*. . .*/ ) //??
fetchRequest.entity(entity) //?? sure this is wrong
...
return _fetchedResultsController
}
This looks like the code you get when you set up a master-detail project with CoreData.
You can do the same, in Xcode 6, but choosing Swift as the language. In MasterViewController, you get :
var fetchedResultsController: NSFetchedResultsController {
if _fetchedResultsController != nil {
return _fetchedResultsController!
}
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext)
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = [sortDescriptor]
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext, sectionNameKeyPath: nil, cacheName: "Master")
aFetchedResultsController.delegate = self
_fetchedResultsController = aFetchedResultsController
var error: NSError? = nil
if !_fetchedResultsController!.performFetch(&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.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
return _fetchedResultsController!
}
var _fetchedResultsController: NSFetchedResultsController? = nil
This looks like a line-to-line translation, I hope it helps.
try lazy:
lazy var fetchedResultsController: NSFetchedResultsController = {
let fetchRequest = NSFetchRequest()
// Edit the entity name as appropriate.
let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: self.managedObjectContext())
fetchRequest.entity = entity
// Set the batch size to a suitable number.
fetchRequest.fetchBatchSize = 20
// Edit the sort key as appropriate.
let sortDescriptor = NSSortDescriptor(key: "timeStamp", ascending: false)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = [sortDescriptor]
// Edit the section name key path and cache name if appropriate.
// nil for section name key path means "no sections".
let aFetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.managedObjectContext(), sectionNameKeyPath: nil, cacheName: "Master")
aFetchedResultsController.delegate = self
var error: NSError? = nil
if !aFetchedResultsController.performFetch(&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.
//println("Unresolved error \(error), \(error.userInfo)")
abort()
}
return aFetchedResultsController
}()

assign value from NSDictionary to NSManagedObject

My app requires to get data from a .Net WCF service when the device is connected to WiFi.If there's a new row added on the server,it should add it to its CoreData database. I am using a NSDictionary for comparing the local objects with the remote objects. The code is:
-(void)handleGetAllCategories:(id)value
{
if([value isKindOfClass:[NSError class]])
{
NSLog(#"This is an error %#",value);
return;
}
if([value isKindOfClass:[SoapFault class]])
{
NSLog(#"this is a soap fault %#",value);
return;
}
NSMutableArray *result = (NSMutableArray*)value;
NSMutableArray *remoteObj = [[NSMutableArray alloc]init];
for (int i = 0; i < [result count]; i++)
{
EDVCategory *catObj = [[EDVCategory alloc]init];
catObj = [result objectAtIndex:i];
[remoteObj addObject:catObj];
}
NSArray *remoteIDs = [remoteObj valueForKey:#"categoryId"];
NSFetchRequest *request = [[[NSFetchRequest alloc] init]autorelease];
request.predicate = [NSPredicate predicateWithFormat:#"categoryId IN %#", remoteIDs];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
[request setEntity:entity];
NSMutableArray *results = [[NSMutableArray alloc]initWithArray:[__managedObjectContext executeFetchRequest:request error:nil]];
NSArray *existingIDs = [results valueForKey:#"categoryId"];
NSDictionary *existingObjects = [NSDictionary dictionaryWithObjects:results forKeys:existingIDs];
for (NSDictionary *remoteObjectDic in remoteObj)
{
Categories *existingObject = [existingObjects objectForKey:[remoteObjectDic valueForKey:#"categoryId"]];
if (existingObject)
{
NSLog(#"object exists");
}
else
{
NSLog(#"create new local object");
// Categories *newCategory;
// newCategory = [NSEntityDescription insertNewObjectForEntityForName:#"Categories" inManagedObjectContext:__managedObjectContext];
// [newCategory setCategoryId:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"categoryId"]intValue]]];
// [newCategory setCategoryName:[remoteObjectDic objectForKey:#"categoryName"]];
// [newCategory setDocCount:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"docCount"]intValue]]];
// [newCategory setCategoryType:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"categoryType"]intValue]]];
// [newCategory setSubCategoryId:[NSNumber numberWithInt:[[remoteObjectDic objectForKey:#"subCategoryId"]intValue]]];
// [__managedObjectContext insertObject:newCategory];
}
}
[my_table reloadData];
}
The problem is,I am not able to extract values from the remote object and assign it to the NSManagedObject.I have commented the code which (according to me) should save the values in new object to the managed object. Can someone please help me achieve this?
Thanks
Here is an example of a save I did in a recent project. I have somethings in wrappers so fetching a managed object and saving look a little weird on my end. Really the only major difference I see is the act of saving. Are you saving the new NSManagedObject elsewhere in the code?
dict = (NSDictionary*)data;
#try {
if (dict) {
CaretakerInfo* info = [GenericDataService makeObjectWithEntityName:NSStringFromClass([CaretakerInfo class])];
[info setName:[dict valueForKey:#"name"]];
[info setImageURL:[dict valueForKey:#"photo"]];
[info setCaretakerID:[dict valueForKey:#"id"]];
[GenericDataService save];
}
else {
theError = [Error createErrorMessage:#"No Data" Code:-42];
}
}
#catch (NSException *exception) {
//return an error if an exception
theError = [Error createErrorMessage:#"Exception Thrown While Parsing" Code:-42];
}
If not it should looks something like this...
NSError *error = nil;
[context save:&error];
If you have anymore information about what's happening when you extract or assigning data that would be helpful (error/warning/log messages).

Cocoa Core Data efficient way to count entities

I read much about Core Data.. but what is an efficient way to make a count over an Entity-Type (like SQL can do with SELECT count(1) ...). Now I just solved this task with selecting all with NSFetchedResultsController and getting the count of the NSArray! I am sure this is not the best way...
I don't know whether using NSFetchedResultsController is the most efficient way to accomplish your goal (but it may be). The explicit code to get the count of entity instances is below:
// assuming NSManagedObjectContext *moc
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:entityName inManagedObjectContext:moc]];
[request setIncludesSubentities:NO]; //Omit subentities. Default is YES (i.e. include subentities)
NSError *err;
NSUInteger count = [moc countForFetchRequest:request error:&err];
if(count == NSNotFound) {
//Handle error
}
[request release];
To be clear, you aren't counting entities, but instances of a particular entity. (To literally count the entities, ask the managed object model for the count of its entities.)
To count all the instances of a given entity without fetching all the data, the use -countForFetchRequest:.
For example:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity: [NSEntityDescription entityForName: entityName inManagedObjectContext: context]];
NSError *error = nil;
NSUInteger count = [context countForFetchRequest: request error: &error];
[request release];
return count;
Swift
It is fairly easy to get a count of the total number of instances of an entity in Core Data:
let context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest(entityName: "MyEntity")
let count = context.countForFetchRequest(fetchRequest, error: nil)
I tested this in the simulator with a 400,000+ object count and the result was fairly fast (though not instantaneous).
I'll just add that to make it even more efficient... and because its just a count, you don't really need any property value and certainly like one of the code examples above you don't need sub-entities either.
So, the code should be like this:
int entityCount = 0;
NSEntityDescription *entity = [NSEntityDescription entityForName:#"YourEntity" inManagedObjectContext:_managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:entity];
[fetchRequest setIncludesPropertyValues:NO];
[fetchRequest setIncludesSubentities:NO];
NSError *error = nil;
NSUInteger count = [_managedObjectContext countForFetchRequest: fetchRequest error: &error];
if(error == nil){
entityCount = count;
}
Hope it helps.
I believe the easiest and the most efficient way to count objects is to set NSFetchRequest result type to NSCountResultType and execute it with NSManagedObjectContext countForFetchRequest:error: method.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:entityName];
fetchRequest.resultType = NSCountResultType;
NSError *fetchError = nil;
NSUInteger itemsCount = [managedObjectContext countForFetchRequest:fetchRequest error:&fetchError];
if (itemsCount == NSNotFound) {
NSLog(#"Fetch error: %#", fetchError);
}
// use itemsCount
I wrote a simple utility method for Swift 3 to fetch the count of the objects.
static func fetchCountFor(entityName: String, predicate: NSPredicate, onMoc moc: NSManagedObjectContext) -> Int {
var count: Int = 0
moc.performAndWait {
let fetchRequest: NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: entityName)
fetchRequest.predicate = predicate
fetchRequest.resultType = NSFetchRequestResultType.countResultType
do {
count = try moc.count(for: fetchRequest)
} catch {
//Assert or handle exception gracefully
}
}
return count
}
It's really just this:
let kBoat = try? yourContainer.viewContext.count(for: NSFetchRequest(entityName: "Boat"))
"Boat" is just the name of the entity from your data model screen:
What is the global yourContainer?
To use core data, at some point in your app, one time only, you simply go
var yourContainer = NSPersistentContainer(name: "stuff")
where "stuff" is simply the name of the data model file.
You'd simply have a singleton for this,
import CoreData
public let core = Core.shared
public final class Core {
static let shared = Core()
var container: NSPersistentContainer!
private init() {
container = NSPersistentContainer(name: "stuff")
container.loadPersistentStores { storeDescription, error in
if let error = error { print("Error loading... \(error)") }
}
}
func saveContext() {
if container.viewContext.hasChanges {
do { try container.viewContext.save()
} catch { print("Error saving... \(error)") }
}
}
}
So from anywhere in the app
core.container
is your container,
So in practice to get the count of any entity, it's just
let k = try? core.container.viewContext.count(for: NSFetchRequest(entityName: "Boat"))
In Swift 3
static func getProductCount() -> Int {
let moc = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Product")
let count = try! moc.count(for: fetchRequest)
return count
}
If you want to find count for specific predicated fetch, i believe this is the best way:
NSError *err;
NSUInteger count = [context countForFetchRequest:fetch error:&err];
if(count > 0) {
NSLog(#"EXIST");
} else {
NSLog(#"NOT exist");
}
Swift 5 solution:
var viewContext: NSManagedObjectContext!
do {
let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "insertName")
let count = try viewContext.count(for: fetchRequest)
print("Counted \(count) objects")
}
catch {
print("Error")
}