Parse : is it possible to follow progress of PFObject upload - objective-c

I have a PFObject containing a text and a PFFile.
PFObject *post = [PFObject objectWithClassName:#"Posts"];
post[#"description"] = self.Photodescription.text;
NSData *picture = UIImageJPEGRepresentation(self.capturedPicture, 0.5f);
post[#"picture"] = [PFFile fileWithName:#"thumbnailPicture.png" data:picture];
I would like to get progress of upload in order to display a progression bar. The following function only works for PFFile.
[post[#"picture"] saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error) {
}progressBlock:^(int percentDone) {
// Update your progress spinner here. percentDone will be between 0 and 100.
NSLog(#"%i", percentDone);
}];
Is there a way to do the same for a PFObject?

Are you uploading a single object or an array of objects? Right now there is no progress for a single PFObject. For very large arrays of PFObjects I did create a category for uploading a series of PFObjects in the background with progress feedback, it works like the normal saveAlInBackground: except you specific the chunkSize (How many PFObjects to save at a time until complete) and give it a progress block handler which is calls each time a chunk is completed:
+(void)saveAllInBackground:(NSArray *)array chunkSize:(int)chunkSize block:(PFBooleanResultBlock)block progressBlock:(PFProgressBlock)progressBlock
{
unsigned long numberOfCyclesRequired = array.count/chunkSize;
__block unsigned long count = 0;
[PFObject saveAllInBackground:array chunkSize:chunkSize block:block trigger:^(BOOL trig) {
count++;
progressBlock((int)(100.0*count/numberOfCyclesRequired));
}];
}
+(void)saveAllInBackground:(NSArray *)array chunkSize:(int)chunkSize block:(PFBooleanResultBlock)block trigger:(void(^)(BOOL trig))trigger
{
NSRange range = NSMakeRange(0, array.count <= chunkSize ? array.count:chunkSize);
NSArray *saveArray = [array subarrayWithRange:range];
NSArray *nextArray = nil;
if (range.length<array.count) nextArray = [array subarrayWithRange:NSMakeRange(range.length, array.count-range.length)];
[PFObject saveAllInBackground:saveArray block:^(BOOL succeeded, NSError *error) {
if(!error && succeeded && nextArray){
trigger(true);
[PFObject saveAllInBackground:nextArray chunkSize:chunkSize block:block trigger:trigger];
}
else
{
trigger(true);
block(succeeded,error);
}
}];
}

Related

Implementing Progress Bar While Uploading the Image

I am uploading the image and some string to server , it is working fine ,now i am want to implement the Progress bar,if i am sending 5 images means ,i want to show the progress bar and i want to show the count of images sended successfully ,like 2 /5 ,Please anyone help me to do this.
The follwoing method is for uploading image ,dictionary , and string
-(void)uploadImage
{
NSString *userCategory = self.UserCategory;
NSDictionary *dict = [self.arrayWithImages objectAtIndex:self.currentIndex];
NSString *notes = [dict objectForKey:#"string"];
UIImage *sample = [dict objectForKey:#"image"];
NSData *sampleData = UIImageJPEGRepresentation(sample, 1.0);
NSMutableDictionary *FinalDict = [self.dictMetaData mutableCopy];
[FinalDict setObject:userCategory forKey:#"user_category"];
if (notes.length > 0) {
[FinalDict setObject:notes forKey:#"note"];
}
for (int i = 0; i<self.arrayWithImages.count; i++) {
[ServerUtility uploadImageWithAllDetails:FinalDict noteResource:sampleData andCompletion:^(NSError *error,id data)
{
if (!error) {
NSString *strResType = [data objectForKey:#"res_type"];
if ([strResType.lowercaseString isEqualToString:#"success"]) {
NSLog(#"Upload Successfully");
self.currentIndex++;
}
else if ([strResType.lowercaseString isEqualToString:#"error"])
{
NSString *strMsg = [data objectForKey:#"msg"];
[self.view makeToast:strMsg duration:1.0 position:CSToastPositionCenter];
}
}
else{
[self.view makeToast:error.localizedDescription duration:1.0 position:CSToastPositionCenter];
}
}];
}

Get int value out of pfquery to change settings objective-c

Im trying to work with a script thats in objective c i want to make an int i can access throughout view did load to change settings or the viewcontroller but it doesn't work like swift and i get a null out of the pfquery so i tried to make an array and couldn't get anything out of the query with that as well
what is the best way to set up and int variable and set it in the pfquery then use if statements later on
here is some of my code
__block int setting = 0;
PFQuery *query = [PFQuery queryWithClassName:#"test"];
[query whereKey:#"testActive" equalTo:[NSNumber numberWithBool:YES]];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error) {
if (!error) {
// The find succeeded.
NSLog(#"Successfully retrieved %lu scores.", (unsigned long)objects.count);
// Do something with the found objects
for (PFObject *object in objects) {
NSLog(#"%#", object.objectId);
setting = [[object objectForKey:#"testSetting"] intValue];
// When checked in the loop i get all the right data
}
} else {
// Log details of the failure
NSLog(#"Error: %# %#", error, [error userInfo]);
}
}];
// When checked here i get settings = 0 when it should be 1
if (setting == 0) {
self.segmentedControl.selectedSegmentIndex = 0;
} else if (setting == 1) {
self.segmentedControl.selectedSegmentIndex = 1;
}
if (setting == 3) {
[self.segmentedControl setEnabled:YES];
}else {
[self.segmentedControl setEnabled:NO];
}
But when i check the setting int its always 0 but if i log in the loop is gives me the correct number
thanks for your help
Thanks for your help but i figured it out..
findObjectsInBackgroundWithBlock was not completing before i did the if statements
so i moved the code into a new function which i ran when the PFQuery was completed giving me the correct int

NSProgressIndicator within the NSTableViewCell not update

There is a NSTableView which contains several cells. There are a NSTextField and NSProgressIndicator in the cell. Each cell has its own progress indicator which represent its own uploading percentage.
Now, I need to update the progress indicator according the uploading percentage so that we could know the progress of uploading.
- (void)startUploading:(NSArray *)filePathArray
{
if (self.QNToken) {
NSString *token = self.QNToken;
NSUInteger count = [filePathArray count];
// We may have multiple files to upload.
for (int i = 0; i < count; i ++) {
NSString *filePath = filePathArray[i];
NSData *fileData = [NSData dataWithContentsOfFile:filePath];
NSString *key = [fileData md5String];
// Upload option
QNUploadOption *option = [[QNUploadOption alloc] initWithMime:nil
progressHandler:^(NSString *key, float percent) {
QNUploadDetailCell *cell = [self.tableView viewAtColumn:0 row:i makeIfNecessary:NO];
[cell.progress.animator setDoubleValue:percent];
[cell.progress displayIfNeeded];
}
params:nil
checkCrc:NO
cancellationSignal:nil];
// Let's upload!
[self.uploadManager putFile:filePath
key:key
token:token
complete: ^(QNResponseInfo *info, NSString *key, NSDictionary *resp) {
NSLog(#"%#", info);
NSLog(#"%#", resp);
} option:option];
}
}
}
However, the progress indicator will never be animated.
I also print out the percent of the progressHandler: the percentage just keep increasing from 0 to 1.0
But the progress bar still keep stopping.
Any ideas?

How to add a number in Parse (Measuring popularity of a tag)

I am trying to implement a method to measure popularity of a certain tag. Therefore, I wrote a method in which a user can add a new tag when there is no preexisting tag. I also wanted to create a column which displays the number of times that certain tag was used. However, when I try to add 1 to to that counter in an object, counter in another object gets increased. I have no idea how to solve this problem. Any help is appreciated.
PFQuery *query = [PFQuery queryWithClassName:#"TagTrend"];
NSMutableArray *preexistingTags = [NSMutableArray array];
NSMutableArray *preexistingTagId = [NSMutableArray array];
NSMutableArray *numPostsArray = [NSMutableArray array];
[query findObjectsInBackgroundWithBlock:^(NSArray *objects, NSError *error){
if (error == nil) {
int count = (int)objects.count;
for (PFObject *object in objects){
NSString *tagName = [NSString stringWithFormat:#"%#", [object objectForKey:#"TagName"]];
[preexistingTags addObject:tagName];
NSLog(#"tagname %#", tagName);
NSNumber *numPostsNSNUM = [object objectForKey:#"NumberOfPosts"];
//int numPosts = [numPostsStr intValue];
[numPostsArray addObject:numPostsNSNUM];
NSLog(#"tagNum %#", numPostsNSNUM);
//NSLog(#"number of posts %i", numPosts);
NSString *objectId = [NSString stringWithFormat:#"%#", [object objectId]];
[preexistingTagId addObject:objectId];
NSLog(#"tagId %#", objectId);
count --;
if (count == 0) {
for (int i = 0; i < miscTagArray.count; i++) {
NSString *tagName = [miscTagArray objectAtIndex:i];
NSString *tagObjectId = [preexistingTagId objectAtIndex:i];
NSNumber *numPosts = [numPostsArray objectAtIndex:i];
BOOL sameTag = [preexistingTags containsObject:tagName];
if (sameTag == NO){
PFObject* tagPop = [PFObject objectWithClassName:#"TagTrend"];
NSLog(#"NO %#",tagName);
// NSString *numPostsStr = #"1";
NSNumber *numPosts = #1;
tagPop[#"NumberOfPosts"] = numPosts;
tagPop[#"TagName"] = tagName;
[tagPop saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
if (!error) {
NSLog(#"success");
}else{
NSLog(#"failure");}
}];
}else{
PFObject* tagPop = [PFObject objectWithoutDataWithClassName:#"TagTrend" objectId: tagObjectId];
NSLog(#"YES %#",tagName);
int tempNumPosts = [numPosts intValue];
tempNumPosts ++;
tagPop[#"NumberOfPosts"] = [NSNumber numberWithInt:tempNumPosts];
[tagPop saveInBackgroundWithBlock:^(BOOL succeeded, NSError *error){
if (!error) {
NSLog(#"success");
}else{
NSLog(#"failure");}
}];
}
}
}}}}];
Make sure the tag indices in miscTagArray correspond with the objectID/numPosts indices. I'm suspecting that these are not lining up and is causing the wrong objects counter increase. Hope that kind of helps.

How to save data in Core Data?

I created an entity named House. This entity has two attributes which are street (of type string) and numOfStories (of type integer 32). I was able to successfully save and NSLog data in my AppDelegate.m didFinishLaunchingWithOptions method. However, when I try to make 2 textfields and show the User's input, and make a button to save, the result is SIGABRT.
Here is all the code I'm using in my MainViewController.m:
- (BOOL)createNewHouseWithStreet:(NSString *)paramStreet numOfStories: (NSUInteger)paramNumOfStories
{
BOOL result = NO;
if ([paramStreet length] == 0)
{
NSLog(#"Street name is mandatory");
return NO;
}
House *newHouse = [NSEntityDescription insertNewObjectForEntityForName:#"House" inManagedObjectContext:self.managedObjectContext];
if (newHouse == nil)
{
NSLog(#"Failed to create the new House");
return NO;
}
newHouse.street = paramStreet;
newHouse.numOfStories = #(paramNumOfStories);
NSError *savingError = nil;
if ([self.managedObjectContext save:&savingError])
{
return YES;
}
else
{
NSLog(#"Failed the save the new House. Error = %#", savingError);
}
return result;
}
and below this I have
- (IBAction)save:(id)sender {
[self createNewHouseWithStreet:#"10 WYOMING" numOfStories:2];
[self createNewHouseWithStreet:#"6 WYOMING" numOfStories:3];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"House"];
NSError *requestError = nil;
NSArray *houses = [self.managedObjectContext executeFetchRequest:fetchRequest error:&requestError];
if ([houses count] > 0)
{
NSUInteger counter = 1;
for (House *thisHouse in houses)
{
NSLog(#"House %lu Street Name = %#", (unsigned long)counter, thisHouse.street);
NSLog(#"House %lu number of stories = %ld", (unsigned long)counter, (unsigned long)[thisHouse.numOfStories unsignedIntegerValue]);
counter++;
}
}
else
{
NSLog(#"Could not find any House entities in the context.");
}
}
So what's weird is that this code ends up resulting in sigabrt whenever I tap the save button, but when I put the code from the save method into my AppDelegate.m didFinishLaunchingWithOptions method it works great.
All help is appreciated, thanks.