Decrypting core data - objective-c

Warning: I don't know obj C but was handed this project for this one task
I am successfully encrypting the fields which lay in core data (sqlite) but I cannot decrypt them using a similar method. Below is my code which is causing the app to break during the fetch of core data:
NSManagedObjectContext *context = [self getContext];
NSEntityDescription *entityDesc = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entityDesc];
[request setReturnsObjectsAsFaults:NO];
if (predicate != nil) {
[request setPredicate:predicate];
}
NSError *error;
//the code that breaks
NSMutableDictionary *theFetch = [[context executeFetchRequest:request error:&error] mutableCopy];
return [[self decryptDictionaryData:theFetch withUserId:entityDesc.propertiesByName[#"theUnlockKey"]] mutableCopy];
decryptDictionaryData goes through each key in the dictionary and decrypts as follows:
decryptedResult = [RNDecryptor decryptData:[[NSData alloc] initWithBase64EncodedString:value options:0]
withSettings:kRNCryptorAES256Settings
password:key
error:&error];

Related

How can i replace Object in NSManagedObjectContext

How i can replace object with managedObject in core data object.Please help me how i can out from this problem.
XMPPMessageArchivingCoreDataStorage *storage = [XMPPMessageArchivingCoreDataStorage sharedInstance];
NSManagedObjectContext *moc = [storage mainThreadManagedObjectContext];
NSEntityDescription *entityDescription = [NSEntityDescription entityForName:#"XMPPMessageArchiving_Contact_CoreDataObject"
inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc]init];
NSSortDescriptor *sortDescriptor1 = [NSSortDescriptor sortDescriptorWithKey:#"mostRecentMessageTimestamp" ascending:NO];
[request setEntity:entityDescription];
[request setSortDescriptors:#[sortDescriptor1]];
NSError *error;
NSArray *data = [moc executeFetchRequest:request error:&error];
for (XMPPMessageArchiving_Contact_CoreDataObject *managedObject in data) {
if ([managedObject.bareJid isEqual:_user.jabberId]) {
// [moc deleteObject:managedObject];**//Here i want to replace object to managed object never delete**
}
}

call method from NSManagedObject from uiviewController (MVC pattern)

My question is simple. How to communicate between my model and my controller ?
Code into controller
NSEntityDescription *entity = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:manageContext];
album = [[Album alloc] initWithEntity:entity insertIntoManagedObjectContext:manageContext];
NSArray *arrayListAlbums = [album returnAllAlbums];
Method into NSManagedObject
(NSArray *) returnAllAlbums
{
NSEntityDescription *entitydescription = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:managedObjContextAlbum];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entitydescription];
NSError *error;
NSArray *arrayListAlbums = [managedObjContextAlbum executeFetchRequest:request error:&error];
return arrayListAlbums;
}
From the code you provided, you have added a convenience method in your NSManagedObject subclass and then you create an instance of the NSManagedObject to call that convenience method. This is not a good design.
You are creating an empty data object to call a fetch method. Perhaps you should have a class method "somewhere" that looks like this:
+ (NSArray *)returnAllAlbums:(NSManagedObjectContext*)moc
{
NSEntityDescription *entitydescription = [NSEntityDescription entityForName:#"Album" inManagedObjectContext:moc];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entitydescription];
NSError *error;
NSArray *arrayListAlbums = [managedObjContextAlbum executeFetchRequest:request error:&error];
if (arrayListAlbums == nil) {
NSLog(#"Failed to fetch: %#\n%#", [error localizedDescription], [error userInfo]);
}
return arrayListAlbums;
}
Which you can then access without creating an empty data object:
NSArray *arrayListAlbums = [MyClassWithFetchMethods returnAllAlbums:myLocalContextReference];

to set default value when core data fetch result is null

I am using simple core data fetch request code.
- (NSMutableArray *) read_cd
{
NSError *error = nil;
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#"List_CD" inManagedObjectContext:cd_Context];
[request setEntity:entity];
NSSortDescriptor *sd = [[NSSortDescriptor alloc] initWithKey:#"last_date" ascending:NO];
NSArray *sortDescriptor = [[NSArray alloc] initWithObjects:sd, nil];
[request setSortDescriptors:sortDescriptor];
NSMutableArray *mutableFetchResults = [[cd_Context executeFetchRequest:request error:&error] mutableCopy];
if(mutableFetchResults == nil){
//Handle the error
}
return mutableFetchResults;
}
and I'm using return value like this
MSMutableArray *now_cd = self.read_cd;
cell output for {
cell.label1.text = [[now_cd objectAtIndex:i] cd_title];
cell.label2.text = [[now_cd objectAtIndex:i] cd_auth];
}
I want to set default value when executeFetchRequest is null.
so I can continue to use an existing output module.
I don't know how to make a method like that
[[object objectAtIndex:i] instance]

Does CoreData always respect returnObjectsasFaults?

In the following code, I explicitly set returnObjectsasFaults as false. Then RIGHT after the request I check to see if objects are fault or not. NSAssert fail.
Perhaps it's because the object is an imageBlob. Perhaps I am missing something? I just want to make sure.
This is a minor issue. If I get rid the nsassert, then my programs will run anyway. Still it sucks.
+(NSFetchRequest * )fetchRequestInContext:(NSString*) entityName:(NSPredicate *) predicate:(NSString*) sortKey:(BOOL) sortAscending
{
//NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:[BGMDCRManagedObjectContextThreadHandler managedObjectContext]];
[request setEntity:entity];
if(predicate != nil)
{
[request setPredicate:predicate];
}
if(sortKey != nil)
{
NSMutableArray * sortDescriptorArray =[self getMoreSearchDescriptorsForEntity:entityName];
[request setSortDescriptors:sortDescriptorArray];
}
//request.fetchLimit = 200; //can be overridden somewhere else
request.returnsObjectsAsFaults = false;
if (entityName == BusinessString)
{
request.relationshipKeyPathsForPrefetching = arrayRelationship;
}
//[request setIncludesSubentities:<#(BOOL)#>
return request;
}
+(NSArray *) searchObjectsInContextEntityName:(NSString*) entityName Predicate:(NSPredicate *) predicate SortKEy:(NSString*) sortKey Booelan:(BOOL) sortAscending
{
NSManagedObjectContext * moc =[BGMDCRManagedObjectContextThreadHandler managedObjectContext];
NSFetchRequest *request = [self fetchRequestInContext:entityName:predicate:sortKey:sortAscending];
NSError *error;
if (entityName==BusinessString)
{
error=nil; //Some code for breakpoint
}
NSArray *fetchedObjects = [moc executeFetchRequest:request error:&error];
for (NSManagedObject * mo in fetchedObjects) {
NSAssert(!mo.isFault, #"For some reason mo is fault");
}
return fetchedObjects;
}
I've encountered the same problem while operating on a child NSManagedObjectContext. I create one as follows
NSManagedObjectContext *workerMOC = nil;
workerMOC = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
workerMOC.parentContext = self.moc; // this is my main NSManagedObjectContext
Now after that if I do:
[workerMOC performBlock:^{
NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Company"];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSArray *allCompanies = [workerMOC executeFetchRequest:fetchRequest error:nil];
}];
I get faults in allCompanies. Which of course, just to clarify, does not happen if I execute the fetch request on self.moc.
However, I get appropriate pre-fetched results if I use the approach below:
[workerMOC performBlock:^{
NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
fetchRequest.entity = [NSEntityDescription entityForName:#"Company" inManagedObjectContext:workerMOC];
[fetchRequest setReturnsObjectsAsFaults:NO];
NSArray *allCompanies = [workerMOC.persistentStoreCoordinator executeRequest:fetchRequest
withContext:workerMOC
error:nil];
}];
So it seems to be the case, that fetching on NSManagedObjectContexts tied directly to the NSPersistentStoreCoordinator works just fine. But in case of child NSManagedObjectContexts, which are not tied directly to the store, but rather to the parent context, do not behave as expected.
I could not find anything related to this matter in the Apple docs, but still, I don't think it's a bug.

How to Update and Delete the required recored of a table usning Core Data

I am learning the core data
How to delete and update the data using core data. I have worked on upload and fetch. I need to write the methods for delete and update. Please tell me how to update and delete a recode using core data.
Below I have written code for upload and fetch data from table using core data.
-(void)uploadData
{
Employee *empObj=(Employee *)[NSEntityDescription insertNewObjectForEntityForName:#"Employee" inManagedObjectContext:self.managedObjectContext];
empObj.empId=[NSNumber numberWithInt:12345];
empObj.empSalary=[NSNumber numberWithInt:25000];
empObj.empName=#"Venu";
empObj.empDesignation=#"Programmer";
empObj.empExp=#"2 Years";
if ([self.managedObjectContext hasChanges] )
{
[self.managedObjectContext save:nil];
}
}
-(void)fetchData
{
NSEntityDescription *empEntity = [NSEntityDescription entityForName:#"Employee" inManagedObjectContext:self.managedObjectContext];
// Setup the fetch request
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:entity];
NSArray *fatherArray=[self.managedObjectContext executeFetchRequest:request error:nil];
[request setEntity:empEntity];
NSArray *empArray=[self.managedObjectContext executeFetchRequest:request error:nil];
for (int i=0; i<[empArray count]; i++)
{
printf("\n=================================Recored== %d==================================== ",i);
Employee *empObj=[empArray objectAtIndex:i];
printf("\n obj.empName========= %s",[empObj.empName UTF8String]);
printf("\n obj.empDesignation========= %s",[empObj.empDesignation UTF8String]);
printf("\n obj.empExp========= %s",[empObj.empExp UTF8String]);
printf("\n obj.empId========= %d",[empObj.empId intValue]);
printf("\n obj.empSalary========= %d",[empObj.empSalary intValue]);
printf("\n============================================================================= ");
}
}
I am doing a project which involved in Core Data, and I would
like to share something with you about it.
It is a clear that before you delete or update a record you need
to retrieve that record.
Use the employee with empId 12345 as an example,
a)Delete
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#:#"Employee"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"empId = %d", 12345]];
[request setPredicate:pred];
NSArray *empArray=[self.managedObjectContext executeFetchRequest:request error:nil];
[request release];
if ([empArray count] > 0){
Employee *employee = [empArray objectAtIndex:0];
[self.managedObjectContext deleteObject:employee];
[self.managedObjectContext save:nil];
}
b) update
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:#:#"Employee"
inManagedObjectContext:self.managedObjectContext];
[request setEntity:entity];
NSPredicate *pred = [NSPredicate predicateWithFormat:[NSString stringWithFormat:#"empId = %d", 12345]];
[request setPredicate:pred];
NSArray *empArray=[self.managedObjectContext executeFetchRequest:request error:nil];
[request release];
if ([empArray count] > 0){
Employee *employee = [empArray objectAtIndex:0];
employee.empSalary=[NSNumber numberWithInt:45000];
employee.empName=#"John";
employee.empDesignation=#"Analysist";
employee.empExp=#"4 Years";
[self.managedObjectContext save:nil];
}
After a successful fetch-request, you can delete your objects simply by asking the managed objectcontext to delete them:
for (NSManagedObject *managedObject in items) {
[self.managedObjectContext deleteObject:managedObject];
DebugLog(#"%# object deleted",entityDescription);
}
if (![self.managedObjectContext save:&error]) {
DebugLog(#"Error deleting %# - error:%#",entityDescription,error);
}
Updating is done in a similar way, fetch the object desired, change the value, and save the context.