Pass data fetched from Cloudkit from one viewcontroller to another - ios

I have a button that calls this function and also calls performSegueWithIdentifier. Segue occurs before the data is the two query returns data. How do i get round this?
-(void)recommendSomeone {
NSString *currentUserID = [NSString stringWithFormat:#"%#%#",#"KU",self.liaResponse[#"id"]];
CKContainer *myContainer = [CKContainer defaultContainer];
CKDatabase *publicDatabase = [myContainer publicCloudDatabase];
CKRecordID *currentUserRecordID = [[CKRecordID alloc] initWithRecordName:currentUserID];
CKReference *recordToMatch = [[CKReference alloc] initWithRecordID:currentUserRecordID action:CKReferenceActionNone];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"contactList CONTAINS %#",recordToMatch];
CKQuery *query = [[CKQuery alloc] initWithRecordType:#"knotworkGhostUsers" predicate:predicate];
[publicDatabase performQuery:query inZoneWithID:nil completionHandler:^(NSArray *results, NSError *error) {
if (error) {
// Error handling for failed fetch from public database
NSLog(#"error querying knotwork users %#", error);
}
else {
// Display the fetched records
self.randomGhostUser = results[arc4random_uniform([results count])];
NSLog(#"this is the first name %#", self.randomGhostUser[#"firstname"]);
NSLog(#"knotwork ghost users for current user data returned ordinary title %#",results);
NSString* searchQuery = #" ";
NSString *kuTitle = [self.randomGhostUser[#"title"] lowercaseString];
NSArray *keyWords = #[#"developer",#"networking",#"sales manager",#"engineer",#"doctor",#"facility manager"];
for(NSString* keyWord in keyWords){
NSRange checkResult = [kuTitle rangeOfString:keyWord];
if(checkResult.location != NSNotFound){
searchQuery = [NSString stringWithFormat:#"%#%#%#",searchQuery,#" ",keyWord];
}
}
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"allTokens tokenmatches[cdl] %# AND contactList CONTAINS %#",searchQuery,recordToMatch];
CKQuery *query2 = [[CKQuery alloc] initWithRecordType:#"knotworkGhostUsers" predicate:predicate];
[publicDatabase performQuery:query2 inZoneWithID:nil completionHandler:^(NSArray *response, NSError *error) {
if (error) {
// Error handling for failed fetch from public database
NSLog(#"error querying knotwork users %#", error);
}
else {
// Display the fetched records
self.recommendedGhostUser = response;
NSLog(#"knotwork users data returned after recom %#", self.recommendedGhostUser);
}
}];
}
[self performSegueWithIdentifier:#"Recommend" sender:nil];
}];
}
emphasized text

You have to replace your segue and put it inside your second completion-block.
Because otherwise your completion-block will be called after you already have pushed the segue.
[publicDatabase performQuery:query2 inZoneWithID:nil completionHandler:^(NSArray *response, NSError *error) {
if (error) {
// Error handling for failed fetch from public database
NSLog(#"error querying knotwork users %#", error);
}
else {
// Display the fetched records
self.recommendedGhostUser = response;
NSLog(#"knotwork users data returned after recom %#", self.recommendedGhostUser);
//Put it in here
[self performSegueWithIdentifier:#"Recommend" sender:nil];
}
}];
Also you could use prepareForSegue to pass your value to the second controller:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// Set Segue name from storyboard
if ([[segue identifier] isEqualToString:#"seguename"])
{
// Get reference to the destination view controller
YourViewController *vc = [segue destinationViewController];
// Pass any objects to the view controller here, like...
[vc setMyObjectHere:object];
}
}
(Link to segue-answer)

Related

Delete PFUser with Cloud Code Parse.com iOS

I succeed to add friend with Cloud Code and Parse.com.
Now I would like to delete friend relation with Cloud Code in didSelectRowAtIndexPath
My error is "attempt to insert nil object from objects[0]'"
But I don't know what parameters I need to configure, I found the cloud code for main.js :
Parse.Cloud.define("removeFriend", function(request, response)
{
// here's how to get the client's user making the request
var user = request.user;
// consider checking that user && request.params.friend are valid
// if not, return response.error("missing user or friend id")
getUser(request.params.friend).then(function(friend) {
// your code prematurely called response.success() here, thereby canceling any further steps
friend.relation("friendsRelation").remove(user);
// return the promise returned by save() so we can chain the promises
return friend.save();
}).then(function(result) {
// only now that the save is finished, we can claim victory
response.success(result);
}, function (error) {
response.error(result);
});
});
// EDIT - the OP once referred to a getUser function that we assume to be something like this:
// return a promise to get a user with userId
function getUser(userId) {
var userQuery = new Parse.Query(Parse.User);
return userQuery.get(userId);
}
Here is my code EditFriends.m :
- (void)viewDidLoad
{
[super viewDidLoad];
PFQuery *query = [PFUser query];
[query orderByAscending:#"name"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (error) {
NSLog(#"Error: %# %#", error, [error userInfo]);
}
else {
self.allUsers = objects;
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:NO];
}
}];
self.currentUser = [PFUser currentUser];
[self loadFriends];
}
-(void) loadFriends{
self.friendsRelation = [[PFUser currentUser] objectForKey:#"friends"];
PFQuery *query = [self.friendsRelation query];
[query orderByAscending:#"username"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
if (error) {
NSLog(#"Error %# %#", error, [error userInfo]);
}
else {
self.friends = objects;
[self.tableView reloadData];
}
}];
}
- (BOOL)isFriend:(PFUser *)user {
for(PFUser *friend in self.friends) {
if ([friend.objectId isEqualToString:user.objectId]) {
return YES;
}
}
return NO;
}
CellForRowAtIndexPath :
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
PFUser *user = [self.allUsers objectAtIndex:indexPath.row];
NSString *name = [[self.allUsers objectAtIndex:indexPath.row] valueForKey:#"username"];
cell.textLabel.text = name;
if ([self isFriend:user]) {
cell.accessoryType = UITableViewCellAccessoryCheckmark;
} else {
cell.accessoryType = UITableViewCellAccessoryNone;
}
return cell;
}
didSelectRowAtIndexPath :
PFUser *selected = [self.allUsers objectAtIndex:indexPath.row];
if ([self isFriend:selected]) {
NSLog(#"déjà amis");
// PFObject *friendRequest = [self.friendRequests objectAtIndex:indexPath.row];
[PFCloud callFunctionInBackground:#"removeFriend" withParameters:#{#"friendRequest" : selected.objectId} block:^(id object, NSError *error) {
if (!error) {
//add the fromuser to the currentUsers friends
//save the current user
[self.currentUser saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
} else {
}
}];
}
else {
}
}];
}
else{
PFUser *selectedUser = [self.allUsers objectAtIndex:indexPath.row];
//request them
PFObject *friendRequest = [PFObject objectWithClassName:#"FriendRequest"];
friendRequest[#"from"] = self.currentUser;
friendRequest[#"fromUsername"] = [[PFUser currentUser] objectForKey:#"username"];
//selected user is the user at the cell that was selected
friendRequest[#"to"] = selectedUser;
// set the initial status to pending
friendRequest[#"status"] = #"pending";
[friendRequest saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (succeeded) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Yay" message:#"Friend request sent" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
} else {
// error occurred
}
}];
}
The iOS code looks okay, and only needs to be sure it sends the correct user objectId.
The cloud code is close, but must be improved a little:
Parse.Cloud.define("removeFriend", function(request, response)
{
// here's how to get the client's user making the request
var user = request.user;
// consider checking that user && request.params.friend are valid
// if not, return response.error("missing user or friend id")
getUser(request.params.friendRequest).then(function(friend) {
// your code prematurely called response.success() here, thereby canceling any further steps
console.log("relation is:" + JSON.stringify(friend.relation("friends")));
friend.relation("friends").remove(user);
// return the promise returned by save() so we can chain the promises
return friend.save();
}).then(function(friend) {
// friendship goes both ways, so remove the friend from user's friends
user.relation("friends").remove(friend);
return user.save();
}).then(function(result) {
// only now that the save is finished, we can claim victory
console.log("relation is:" + JSON.stringify(result.relation("friends")));
response.success(result);
}, function (error) {
response.error(error);
});
});
// EDIT - the OP once referred to a getUser function that we assume to be something like this:
// return a promise to get a user with userId
function getUser(userId) {
var userQuery = new Parse.Query(Parse.User);
return userQuery.get(userId);
}
EDIT - to call:
PFUser *selected = [self.allUsers objectAtIndex:indexPath.row];
if ([self isFriend:selected]) {
NSLog(#"déjà amis");
[PFCloud callFunctionInBackground:#"removeFriend" withParameters:#{#"friendRequest" : selected.objectId} block:^(id object, NSError *error) {
// etc.

Login functionality in iOS

I am trying to implement a login functionality. I am using core data to achieve this and am able to register a new user successfully. The details such as username and password are stored in the entity. I now want to compare these values with the user input in the login detail page.
Here is the code for the signup.
//first we grab the managed obj context
managedObjectContext = self.managedObjectContext;
//creating an instance
//getting the entity in which the data is to be stored and store the new obj with the data in it
NSManagedObject *pplAcc = [NSEntityDescription insertNewObjectForEntityForName:#"Person" inManagedObjectContext:managedObjectContext];
//populating the obj with the data stored in the text fields
[pplAcc setValue:nameTxt.text forKey:#"name"];
[pplAcc setValue:paswordTxt.text forKey:#"password"];
[pplAcc setValue:radioLbl forKey:#"radio"];
//saving the img in binary format
NSData *imgData = UIImagePNGRepresentation(profImg.image);
[pplAcc setValue:imgData forKey:#"image"];
//saving
NSError *error;
if (![managedObjectContext save:&error]) {
NSLog(#"Error in saving %#", [error localizedDescription]);
}
else{
NSLog(#"User registration successful");
LoginViewController *lvc = [self.storyboard instantiateViewControllerWithIdentifier:#"login"];
[self.navigationController pushViewController:lvc animated:YES];
}
Here is the code for the login.
-(IBAction)btnLogin:(id)sender{
managedObjectContext = self.managedObjectContext;
//fetching the result
NSFetchRequest *fetch = [[NSFetchRequest alloc]initWithEntityName:#"Person"];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:#"name = %#",nameTxt.text];
NSPredicate *passwordPredicate = [NSPredicate predicateWithFormat:#"password = %#", passwordTxt.text];
NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[namePredicate, passwordPredicate]];
[fetch setPredicate:compoundPredicate];
NSError *error = nil;
//excuting the fetch result
NSArray *arrayFetch = [managedObjectContext executeFetchRequest:fetch error:&error];
//checking to see if the user input equals the fetched managedobj in coredata
if (
[nameTxt.text isEqual:[arrayFetch valueForKey:#"name"]] &&
[passwordTxt.text isEqual:[arrayFetch valueForKeyPath:#"password"]] &&
[radioLbl isEqual:[arrayFetch valueForKey:#"radio"]]
) {
if ([radioLbl isEqual: #"Student"]) {
StudentViewController *student = [self.storyboard instantiateViewControllerWithIdentifier:#"student"];
[self.navigationController pushViewController:student animated:YES];
}
else if ([radioLbl isEqual: #"Instructor"]){
InstructorViewController *instructor = [self.storyboard instantiateViewControllerWithIdentifier:#"instructor"];
[self.navigationController pushViewController:instructor animated:YES];
}
}
else{
UIAlertView *error = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Incorrect username/password" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[error show];
}
}
The problem is that I am getting the alert view of "Incorrect username/password" whenever I try to login.
How many objects are in arrayFetch ? Your're making a request in CoreData for all Person entries so you have all of them. I suggest to you to make a request with a predicate
NSPredicate *predicate = [NSPredicate predicatewithformat:"name = %#",nameTxt.text];
If you get any result, then check the password with That person.
I have solved the problem and I am posting the updated code here for anyone else who needs help. The changes are made in the login code.
-(IBAction)btnLogin:(id)sender{
managedObjectContext = self.managedObjectContext;
//fetching the result
NSFetchRequest *fetch = [[NSFetchRequest alloc]initWithEntityName:#"Person"];
NSPredicate *namePredicate = [NSPredicate predicateWithFormat:#"name = %#",nameTxt.text];
NSPredicate *passwordPredicate = [NSPredicate predicateWithFormat:#"password = %#", passwordTxt.text];
NSCompoundPredicate *compoundPredicate = [NSCompoundPredicate andPredicateWithSubpredicates:#[namePredicate, passwordPredicate]];
[fetch setPredicate:compoundPredicate];
NSManagedObject *object = nil;
NSError *error = nil;
//excuting the fetch result
NSArray *arrayFetch = [managedObjectContext executeFetchRequest:fetch error:&error];
if ([arrayFetch count] > 0) {
object = [arrayFetch objectAtIndex:0];
//checking to see if the user input equals the fetched managedobj in coredata
if ([nameTxt.text isEqualToString:[object valueForKey:#"name"]] || [passwordTxt.text isEqualToString:[object valueForKey:#"password"]]){
if ([radioLbl isEqualToString:#"Student"]) {
StudentViewController *student = [self.storyboard instantiateViewControllerWithIdentifier:#"student"];
[self.navigationController pushViewController:student animated:YES];
}
else{
InstructorViewController *instructor = [self.storyboard instantiateViewControllerWithIdentifier:#"instructor"];
[self.navigationController pushViewController:instructor animated:YES];
}
nameTxt.text = #"";
passwordTxt.text = #"";
}
}
else{
UIAlertView *error = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Incorrect username/password" delegate:self cancelButtonTitle:#"Ok" otherButtonTitles:nil, nil];
[error show];
}
}
What I was missing in the above code was NSManagedObject. Basic mistake!

iOS to Parse.com - SaveInBackground Object ID is null

I am struggling to find why I am getting a null value when using SaveInBackgroundWithBlock to Parse.com. I am sure I am missing something, have tried both if (!error) and if(succeeded) with same result which is that the object is created but eventID (the objectID) is null... Any suggestions?
Thanks in advance!
[event saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
if (!error) {
[CommonHelper hideBusyView];
EventObj *obj = [[EventObj alloc] init];
obj.eventID = event.objectId;
obj.eventName = strNameEvent;
obj.eventDateTime = self.dateEvent;
obj.eventAddress = strAddress;
NSLog(#"EventID: %#",self.eventObj.eventID);
PreviewInvite *invitepreview =[[PreviewInvite alloc] init];
invitepreview.eventObj = self.eventObj;
[self.navigationController pushViewController:invitepreview animated:YES];
}
else
{
NSString *errorString = [error userInfo][#"error"];
[CommonHelper showAlert:errorString];
[CommonHelper hideBusyView];
}
}]

Challenging Online Database Persistence w/ Core Data?

This is my first time doing any work with database persistence/maintenance online, so I apologize in advance for my sloppy code. My app consists of the user creating a bunch of athletes and having their data save online so they can be accessed from any device. This works fantastically, except the athletes each get saved twice online, and it's making me want to rip my hair out. I've checked my code several hundred times, but I just can't seem to find why athletes are being saved twice on the server, resulting in 2 locally as well. I'm utilizing the Parse.com framework. Am I missing something?
The following method gets called from a pull down to refresh on a table view controller.
- (void)getParseData {
NSLog(#"GET PARSE DATA WAS CALLED");
if(self.syncing != TRUE){
NSLog(#"GET PARSE DATA RAN");
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateStyle = NSDateFormatterLongStyle;
PFQuery *query = [PFQuery queryWithClassName:#"Athlete"];
[self populateAthleteArray];
if (self.athleteArray.count == 0) {
NSLog(#"ATHLETE ARRAY IS EMPTY");
// If the athlete array has no objects, download all objects from the database.
[query findObjectsInBackgroundWithBlock: ^(NSArray *objects, NSError *error) {
self.syncing = TRUE;
if (!error) {
self.syncing = FALSE;
for (PFObject * object in objects) {
Athlete *newAthlete = [NSEntityDescription insertNewObjectForEntityForName:#"Athlete" inManagedObjectContext:_managedObjectContext];
newAthlete.first = object[#"first"];
newAthlete.last = object[#"last"];
newAthlete.updatedAt = [dateFormatter stringFromDate:[object updatedAt]];
newAthlete.objectId = [object objectId];
[_managedObjectContext save:nil];
}
self.syncing = FALSE;
}
else {
self.syncing = FALSE;
NSLog(#"Error: %# %#", error, [error userInfo]);
}
if(self.needToUploadArray.count > 0){
[PFObject saveAllInBackground:self.needToUploadArray target:nil selector:#selector(emptyUploadArray)];
}
}];
[self populateAthleteArray];
[self.tableView reloadData];
}
else {
NSLog(#"ATHLETE ARRAY HAS ATHLETES ALREADY");
// Athlete array has athletes already
NSMutableArray *athletesToUpload = [NSMutableArray array];
// Placeholder array for athletes that aren't in the database.
for (Athlete *athlete in athleteArray) {
if (athlete.objectId.length == 0 || athlete.objectId == nil) {
// If the objectId is nil, it wasn't uploaded to the database. Add to placeholder array.
[athletesToUpload addObject:athlete];
}
}
[query findObjectsInBackgroundWithBlock: ^(NSArray *objects, NSError *error) {
self.syncing = TRUE;
if (!error) {
// Downloaded all athletes successfully
self.syncing = FALSE;
BOOL found = FALSE;
[self populateAthleteArray];
NSMutableArray *athletesToDelete = [NSMutableArray array];
for (Athlete * athlete in athleteArray) {
for (PFObject * object in objects) {
// Check to see each local athlete exists in the online database
if ([object.objectId isEqualToString:athlete.objectId]) {
// Athlete was find in the online database
found = TRUE;
break;
}
}
if (found != TRUE) {
NSLog(#"%# was not found online.",athlete.first);
if(athlete.objectId.length > 0){
NSLog(#"%# was deleted online. delete them locally",athlete.first);
[athletesToDelete addObject:athlete];
}
else{
// No athlete in the local database matched any of the athletes online
PFObject *onlineAthlete = [PFObject objectWithClassName:#"Athlete"];
onlineAthlete[#"first"] = athlete.first;
onlineAthlete[#"last"] = athlete.last;
PFFile *imageFile = [PFFile fileWithName:[NSString stringWithFormat:#"%#%#MedicalRelease.jpg", athlete.first, athlete.last] data:athlete.medical_release_image];
onlineAthlete[#"medical_release_image"] = imageFile;
[onlineAthlete saveInBackgroundWithBlock: ^(BOOL succeeded, NSError *error) {
self.syncing = TRUE;
if (succeeded) {
NSLog(#"SAVED SUCCESSFULLY");
self.syncing = FALSE;
PFQuery *query = [PFQuery queryWithClassName:#"Athlete"];
[query orderByDescending:#"createdAt"];
[query getFirstObjectInBackgroundWithBlock: ^(PFObject *object, NSError *error) {
Athlete *athleteToChange = [self findAthlete:athlete.objectId];
[athleteToChange setObjectId:[object objectId]];
[_managedObjectContext save:nil];
}];
}
}];
}
}
found = FALSE;
}
if(athletesToDelete.count > 0){
for(id athlete in athletesToDelete){
NSManagedObject *eventToDelete = athlete;
[_managedObjectContext deleteObject:eventToDelete];
[athleteArray removeObjectAtIndex:[athleteArray indexOfObject:athlete]];
[self.tableView reloadData];
NSError *error = nil;
if (![_managedObjectContext save:&error]) {
NSLog(#"there is an error: %#", error);
}
}
}
for (PFObject *object in objects) {
// Loop through every athlete downloaded
for (Athlete * athlete in athleteArray) {
// For every object downloaded, compare it to every athlete in the local database.
if ([object.objectId isEqualToString:athlete.objectId]) {
// If the object's id matches the local athletes id, we found the object
if ([object updatedAt] >= [dateFormatter dateFromString:athlete.updatedAt]) {
// If the object has been updated more recently than the athlete, update the local athlete
Athlete *sameAthlete = [self findAthlete:athlete.objectId];
sameAthlete.first = object[#"first"];
sameAthlete.last = object[#"last"];
sameAthlete.updatedAt = [dateFormatter stringFromDate:[object updatedAt]];
sameAthlete.address = object[#"address"];
sameAthlete.objectId = [object objectId];
[_managedObjectContext save:nil];
}
found = TRUE;
// The athlete was found in the database
break;
}
}
if (found != TRUE) {
// We looped through all the local athletes, the object downloaded isn't in the local database; add them.
Athlete *athlete = [NSEntityDescription insertNewObjectForEntityForName:#"Athlete" inManagedObjectContext:_managedObjectContext];
athlete.first = object[#"first"];
athlete.last = object[#"last"];
athlete.objectId = [object objectId];
athlete.address = object[#"address"];
athlete.updatedAt = [dateFormatter stringFromDate:[object updatedAt]];
[_managedObjectContext save:nil];
}
// Reset flag var
found = FALSE;
}
}
else {
self.syncing = FALSE;
NSLog(#"Error: %# %#", error, [error userInfo]);
}
self.syncing = FALSE;
}];
if (athletesToUpload.count > 0) {
for (Athlete *athlete in athletesToUpload) {
PFObject *upload = [PFObject objectWithClassName:#"Athlete"];
upload[#"first"] = athlete.first;
upload[#"last"] = athlete.last;
PFFile *imageFile = [PFFile fileWithName:[NSString stringWithFormat:#"%#%#MedicalRelease.jpg", athlete.first, athlete.last] data:athlete.medical_release_image];
upload[#"medical_release_image"] = imageFile;
[upload saveInBackgroundWithBlock: ^(BOOL succeeded, NSError *error) {
if (succeeded) {
PFQuery *uploadQuery = [PFQuery queryWithClassName:#"Athlete"];
[uploadQuery orderByDescending:#"createdAt"];
[uploadQuery getFirstObjectInBackgroundWithBlock: ^(PFObject *object, NSError *error) {
[athlete setObjectId:[object objectId]];
}];
}
}];
}
}
[self populateAthleteArray];
[self.tableView reloadData];
}
}
}
In the branch marked by the comment // No athlete in the local database matched any of the athletes online you are creating a new PFObject and saving it to Parse. In my understanding, this should not be correct, since the athlete is not in the local db but online.

Core data how update a record?

I have some object that is image that is in relation with object user mani-to-one like that Image <<---> User. Now that i want to do, when the user is login i display a button to each images for add to favourites, when i click this button is run this code:
User * user = [[UserController sharedInstance] currentUser];
Image * image = (Image*)[user.managedObjectContext objectWithID:[self.yacht objectID]];
yacht.whoLiked = user
the problem is not i the same controller but in the Main Controller before, because what i do is load al the image's thumb in a collection view (and in this controller load all the data from the DB) then when i press the thumb i go in another controller that show me the big image and the button for add favourites, when i press it and then come back to the old controller in the viewDidAppear of the old controller i reload every time the data from the db but i can't see any change, if i change section (controller) and i come back to see i see the data update
this is how I call the Db from Main Controller:
- (void)fetchImages
{
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:#"Image"];
request.predicate = [NSPredicate predicateWithFormat:#"ANY whichCategories.name =[cd] %#", self.category.name];
NSSortDescriptor *sortName = [[NSSortDescriptor alloc] initWithKey:#"headline" ascending:YES selector:#selector(localizedCaseInsensitiveCompare:)];
request.sortDescriptors = [NSArray arrayWithObject:sortName];
NSError * error = nil;
self.images = [self.database.managedObjectContext executeFetchRequest:request error:&error];
[self.collectionView reloadData];
}
- (void)useDocument
{
if (![[NSFileManager defaultManager] fileExistsAtPath:[self.database.fileURL path]]) {
// CREATE
[self.database saveToURL:self.database.fileURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) {
[self fetchImages];
}];
} else if (self.database.documentState == UIDocumentStateClosed) {
// OPEN
[self.database openWithCompletionHandler:^(BOOL success) {
[self fetchImages];
}];
} else if (self.database.documentState == UIDocumentStateNormal) {
// USE
[self fetchImages];
}
}
- (void)setDatabase:(UIManagedDocument *)database
{
if (_database != database) {
_database = database;
[self useDocument];
}
}
-(void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
[self useDocument];
//[self.collectionView reloadData];
[UIView beginAnimations:#"" context:nil];
[UIView setAnimationDuration:0.5];
self.collectionView.alpha = 1;
[UIView commitAnimations];
}
Why if i come back and return the code work else is like that I didn't call the server for refresh the array?
Triy with this code:
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"Favorits" inManagedObjectContext:moc]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"title == %#", #"Some Title"];
[request setPredicate:predicate];
NSError *error = nil;
NSArray *results = [moc executeFetchRequest:request error:&error];
YourObject *object = [results objectAtIndex:0];
object.title = #"Bla bla bla";
//save changes
[moc save:&error];
if (error) {
//Do something
}
this 2 link is helpful:
http://developer.apple.com/library/iOS/#documentation/Cocoa/Conceptual/CoreData/cdProgrammingGuide.html
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/CoreDataFramework/Classes/NSFetchRequest_Class/NSFetchRequest.html
If I didn't misunderstand you, the problem is that when you refresh the array, your data is not updated.
If you reload from the DB and you haven't saved your changes, then you will get the values are in the DB. You should do:
NSError *saveError = nil;
[user.managedObjectContext save:&saveError];
if (error) {
//Do whatever
}
You should use this code before call again the function to reload the array from the DB. The place it's up to you, but if you only call to refresh the array from DB when you are loading the viewcontroller, you can save the data when you are leaving the viewController.

Resources