To Force Fully Stop Background thread running in parse - iphone

I am using this method to fetch objects from the parse in back ground
PFQuery *query = [PFQuery queryWithClassName:#"UserInfo" predicate:predicate];
NSPredicate *predicate; = [NSPredicate predicateWithFormat:#"useremail == %#",[dict objectForKey:#"form"]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error)
{
}];
Its producing the results but what i have to do is i have to stop the thread when i pop over from this class where i have implemented this code.

It sounds like you want to cancel a query in progress if you are about to navigate away from the current view controller. There is - (void)cancel method of PFQuery that will take care of this:
https://www.parse.com/docs/ios/api/Classes/PFQuery.html#//api/name/cancel
Just make sure you keep a reference to this query and call it's cancel method in your UIViewController's - (void)viewWillDisappear:(BOOL)animated.

Related

How to update a property of a ViewController from data retrieved asynchronously?

I would like to update a property of my ViewController self.matchedUsers, which takes data from a query that I run asynchronously through a block.
Then somewhere later When I retrieve the count via [self.matchedUsers count], I still get 0, despite knowing that multiple objects was added to my property. My question is, how do I ensure that my property gets updated even when I am retrieving data asynchronously through a block? Thanks!
Update:
For context, here is the block:
//Way earlier in an initializer:
self.matchedUsers = [[NSMutableArray alloc] init];
//In a method much later
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error){
//Code that updates self.matchedUsers with the NSArray objects
dispatch_async(dispatch_get_main_queue(), ^{
[self.matchedUsers addObjectsFromArray: objects];
});
//Question relates to ensure how property could be updated
}
}];
This should work provided you didn't forget to initialize matchedUsers, you check for its value after it's been changed and array does not lose its elements between the time you schedule and execute the block.
However, I would prefer to write a method that can be called from any thread, say
- (void)addUser ...
#synchronized(self.usersToAdd) {
[self.usersToAdd addObjectsFromArray: array];
Enqueue on main thread {
NSArray *addingNow;
#synchronized(self.usersToAdd) {
addingNow = [self.usersToAdd copy];
[self.usersToAdd removeObjects...
}
if (addingNow.count) {
[self.users addObjectsFromArray: addingNow;
[self.tableView insertRowsWithIndexPaths...
}
}
}
}
As others have written the problem could be missing initialization of matchedUsers but...
...the problem could also be due to your main thread being blocked. You write that you "somewhere later retrieve the count". If that is within the same method as the one that made the first dispatch you will be in trouble. Consider this code
NSMutableArray *collection = [[NSMutableArray alloc] init];
dispatch_async(dispatch_get_global_queue(0, 0), ^{
NSArray *array = [[NSArray alloc] initWithObjects:#"1", nil];
dispatch_async(dispatch_get_main_queue(), ^{
for (NSString *item in array){
[collection addObject:item];
}
NSLog(#"A");
});
});
[NSThread sleepForTimeInterval:5];
NSLog(#"B");
If this is running on the main thread it will output first B on then A (no matter the sleep time), because the block is not run until the method finishes executing. If you on the other hand dispatch to another global queue instead of the main queue it will be A and then B.

How to use PFQuery in ios for beginner

I am searching about "How to implement PFquery in ios ?"
I am getting followings links. I am fresher in ios field and I don't understand that..
this link for discription of PFquery
this link for discription of PFquery
Please Help me any one know any tutorial for learning and implementing in iphone app.
PFQuery *query = [PFQuery queryWithClassName:#"UserInfo"];
[query selectKeys:#[#"FirstName"]];
NSArray *results = [query findObjects:nil];
NSLog(#"%#",[results description]);
And Check this link its all about PFQuery
Example:
PFQuery *query = [PFQuery queryWithClassName:#"tempClass"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded. The first 100 objects are available in objects
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
Good starter: Parse with TableView

Parse.com + iOS Avoid simultaneous calls of PFQuery to avoid NSInternalInconsistencyException error crash

Duplicate of :
https://stackoverflow.com/questions/17037149/ios-parse-com-app-crashes-while-retrieve-data-from-cache-nsinternalinconsiste
have implemented an iOS App using Parse.com
Trying to retrieve from cache.
While retrieve data from cache i got an error like this:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'This query has an outstanding network connection. You have to wait until it's done.'
When i browse for the issues i found that:
Some suggested that it may happens due to making two query calls on the same query object without waiting for the first to complete.
how to avoid these simultatanius calls in this app
query setLimit: limit];
[query setSkip: skip];
//RETRIEVING FROM CACHE
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error)
{
[allObjects removeAllObjects]; //Added regarding cache ******
// The find succeeded. Add the returned objects to allObjects
[allObjects addObjectsFromArray:objects];
if (objects.count == limit) {
// There might be more objects in the table. Update the skip value and execute the query again.
skip += limit;
[query setSkip: skip];
// Go get more results
weakPointer();
}
else
{
// We are done so return the objects
block(allObjects, nil);
}
}
else
{
block(nil,error);
}
}];
To avoid simultaneous calls of a PFQuery, call [query cancel] before findObjects is called:
query.cachePolicy = kPFCachePolicyCacheThenNetwork;
[query cancel]; //cancels the current network request being made by this query (if any)
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
//do stuff
}];
Careful:
[query cancel];
Does not work if you're expecting the callback.
Solution:
#property (nonatomic) BOOL isCurrentlyFetching; // Makes sure Parse is called only
-(void)myQuery
{
if (_isCurrentlyFetching) { return; } // Bails if currently fetching
_isCurrentlyFetching = YES;
//RETRIEVING FROM CACHE
query.cachePolicy = kPFCachePolicyCacheThenNetwork; // Whatever your cache policy is
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error){
// Your code...
}
else{
// Your code...
}
_isCurrentlyFetching = NO;
}];
}

PFQuery not returning results in iPhone app

I am using parse for my iPhone app, and I am trying to fetch a PFObject using PFQuery. My query and other related code is as follows:
PFQuery *query = [PFQuery queryWithClassName:#"UserInfo"];
[query whereKey:#"userId" equalTo:#"89b7eb8801b24ace16b35b927ef01d4f"];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %d users.", objects.count);
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
I tried using this method but I am getting 0 results in NSArray objects. While you can see in my data browser that there is one object matching the userId. I am able to add data in that class, but I am not able to retrieve it. Am I missing something? I am new at using Parse.
I got it. It was the anonymous user being created from my appDidFinishLaunching method.
This code was running which I wasn't aware of:
[PFUser enableAutomaticUser];
PFACL *defaultACL = [PFACL ACL];
// Optionally enable public read access by default.
[defaultACL setPublicReadAccess:YES];
[PFACL setDefaultACL:defaultACL withAccessForCurrentUser:YES];
Now, initially the [defaultACL setPublicReadAccess:YES]; line was commented. I studied a bit about users and anonymous users being created and uncommented this line, and it worked just fine exactly as I wanted. The PFQuery has started returning results. So, I am assuming the defaultACL value was the issue. Please correct me if wrong.

Core Data deleting problem when closing app completely

Hi I do have a problem with my Core Data storage!
I delete it the following way like I found it here an stack overflow:
NSFetchRequest * allFriends = [[NSFetchRequest alloc] init];
[allFriends setEntity:[NSEntityDescription entityForName:#"Friend" inManagedObjectContext:self.managedObjectContext]];
[allFriends setIncludesPropertyValues:NO]; //only fetch the managedObjectID
NSError * error = nil;
NSArray * friends = [self.managedObjectContext executeFetchRequest:allFriends error:&error];
[allFriends release];
//error handling goes here
for (NSManagedObject * Friend in friends) {
[self.managedObjectContext deleteObject:Friend];
}
this seams to work perfect at runtime!
my tableview (which I manage with NSFetchedResultsController) clears and all is fine it looks!
Also when I hit the home button and start it back up it works.
BUT if I even close it from the multitasking list (so completely close it) and start it back up all is back in the tableView again!
could anybody help me out with this?
Your code is fine but you have forgotten to commit all changes (objects were removed) made to database. So, you should add following lines to your code and after reopening the app your db will not contain that objects:
NSError *error;
if (![self.managedObjectContext save:&error])
{
// Update to handle the
NSLog(#"Unresolved error %#", error);
exit(-1); // Fail
}
Because all changes are stored in memory, don't forget to save the managed object context after some important or critical changes were made. Before you commit your changes, the database/presistent-store file will be in the previously saved state.
Are you saving the managedObjectContext at any point before quitting? Normally you would save the context when the application enters the background or terminates.