Code:
+(id)loadJSONDataFromURL:(NSString *)urlString{
MsgsHelper *msg=[[MsgsHelper alloc]init];
// This function takes the URL of a web service, calls it, and either returns "nil", or a NSDictionary,
// describing the JSON data that was returned.
NSError *error;
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
// Call the web service, and (if it's successful) store the raw data that it returns
NSURLResponse *response = nil; //
NSData *data = [ NSURLConnection sendSynchronousRequest:request returningResponse: &response error:&error ];
//here we get the respond from NSURLResponse and then we check for the statusCode //1
//200 is ok,, 0 is no internet connection else is server error //2
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;//1
//any warning like this one with integers shuold add the casting (int)
int statCode = (int)[httpResponse statusCode];//2
if(statCode == 200){
if (!data)
{
//NSLog(#"Download Error: %#", error.localizedDescription);
return nil;
}
// Parse the (binary) JSON data from the web service into an NSDictionary object
id dictionary = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
if (dictionary == nil) {
//NSLog(#"JSON Error: %#", error);
return nil;
}
return dictionary;
}else if(statCode == 0){
[msg alertStatus:NSLocalizedString(#"No internet", #"Message") :#"" :0 ];
return nil;
}else{
//Server Error
//NSLog(#"Server Error");
[msg alertStatus:NSLocalizedString(#"Server Error", #"Message") :#"" :0 ];
return nil;
}}
the problem on result as below:
results: (
{
"Name" = "\U0633\U0639\U0648\U062f \U0639\U0628\U062f\U0627\U0644\U0639\U0632\U064a\U0632 \U064a\U0646 \U062c\U062f\U064a\U062f";
"location" = CENTER;
}
)
maybe need to dataUsingEncoding to read arabic string, but how do it.
Thanks,
Related
I use this type of function to call my Web Services from my iOS App:
-(NSData *)getMainMenuJsonData{
NSString *urlAsString = [NSString stringWithFormat:#"%#%#/%#/%#",[configs valueForKey:#"wsURL"], [configs valueForKey:#"clientToken"], [configs valueForKey:#"appToken"], [CommonsUtils getCommonUtil].getAppLanguage];
NSString* webStringURL = [urlAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:webStringURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.5];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
NSUInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
if (statusCode == 200 && error == Nil) {
if (error != Nil) {
return Nil;
} else {
return data;
}
}
else {
return Nil;
}
}
As far as I understand, I'm sending something like:
http://myserver.com/WSFunction/Parameter1/Parameter2 and so on.
This is a problem for me because if I need to add 1 parameter I have to create another service with almost the same functionality but using the new parameter i.e:
http://myserver.com/WSFunction/Parameter1/Parameter2/Parameter3
My idea is to call always the same Web Service but passing the version of the Service and a JSON with all the parameters that I need, but as far as I know, I have to warp the JSON in the message (maybe this is not the right word, and that is maybe why I can't find anything in Google), so at the end I will finish with something like:
http://myserver.com/WSVersionNumber/[SerializedJSON]
And in the server I will have a logic like this:
Case:"Version 1"
Deserialize JSON and use Parameter1 and Parameter2
Case:"Version 2"
Deserialize JSON and use Parameter1 and Parameter2 and Parameter3
At the end what I want is to do something like this in iOS:
-(NSData *)getMainMenuJsonData{
NSString *urlAsString = #"http://myserver.com/WSVersionNumber/"
NSURLRequest * urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:webStringURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.5];
[urlRequest setParameterName:#"SerializedJSON" withValue:SerializedJSONVar];
NSURLResponse * response = nil;
NSError * error = nil;
NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
NSUInteger statusCode = ((NSHTTPURLResponse *)response).statusCode;
if (statusCode == 200 && error == Nil) {
if (error != Nil) {
return Nil;
} else {
return data;
}
}
else {
return Nil;
}
}
Is there a way to do something like this in iOS?, I'm not interested in doing this with a third party library because is the enterprise policy.
Thanks in advance.
Please check, may be this link will helps you,
This example use ASIHTTPRequest, very easy and effective way to deal with JSON.
https://stackoverflow.com/a/7928734/4852079
Thanks to the answer posted by Tejas Patel that lead me to the right information.
The code ended like this:
-(NSData *)getLogin:(NSMutableDictionary *)pData {
NSString *tUrlAsString = [NSString stringWithFormat:#"%#%#/%#/%#/GetLogin",[_Configs valueForKey:#"wsURL"], [_Configs valueForKey:#"wsVersion"], [_Configs valueForKey:#"clientToken"], [CommonsUtils getCommonUtil].getAppLanguage];
NSString* tWebStringURL = [tUrlAsString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest * tUrlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:tWebStringURL] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:2.5];
[tUrlRequest setHTTPMethod:#"POST"];
[tUrlRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSData *tJsonData;
if ([NSJSONSerialization isValidJSONObject:pData]) {
NSError *tError;
tJsonData = [NSJSONSerialization dataWithJSONObject:pData options:NSJSONWritingPrettyPrinted error:&tError];
if (!tJsonData) {
NSLog(#"json Data %#",tError.description);
return Nil;
} else {
NSString *tJSONString = [[NSString alloc] initWithBytes:[tJsonData bytes] length:[tJsonData length] encoding:NSUTF8StringEncoding];
NSLog(#"JSON String %#",tJSONString);
[tUrlRequest setHTTPBody:tJsonData];
NSURLResponse * tResponse = nil;
NSData * tData = [NSURLConnection sendSynchronousRequest:tUrlRequest returningResponse:&tResponse error:&tError];
NSUInteger tStatusCode = ((NSHTTPURLResponse *)tResponse).statusCode;
if (tStatusCode == 200 && tError == Nil) {
if (tError != Nil) {
return Nil;
} else {
return tData;
}
} else {
return Nil;
}
}
} else {
NSLog(#"This Data can't be serialized");
return Nil;
}
}
At the end you just have to add a JSON inside the setHTTPBody, so in your REST service you have to receive all the nodes of your JSON with the same name for the variables.
I hope this helps someone in the future.
Regards.
I have created a method that uses NSMutableURLRequest to request and receive JSON from a RESTful API running on a remote machine. The request successfully returns some JSON, but the returned sub-arrays in the JSON (see tasks: []) are empty.
The JSON returned from the API is:
{
"error":false,
"tasks":[
{
"id":1,
"task":"Get Milk",
"status":0,
"createdAt":"2014-08-09 12:29:15"
},
{
"id":2,
"task":"Call Mom",
"status":0,
"createdAt":"2014-08-09 12:46:52"
},
{
"id":3,
"task":"Call Dad",
"status":0,
"createdAt":"2014-08-09 12:47:04"
},
{
"id":4,
"task":"Study",
"status":0,
"createdAt":"2014-08-09 12:47:08"
}
]
}
The method that utilizies NSMutableURLRequest (proper parameters being passed is assumed) is:
-(NSDictionary *) apiRequestWithEndpoint:(NSString *) endpoint
withParams:(NSDictionary *) params
withHTTPHeaders:(NSDictionary *) headers
withHTTPMethod:(NSString *) method
{
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:endpoint]];
[request setValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request setHTTPMethod:method];
//set headers
for (id key in headers) {
[request setValue:[headers valueForKey:key] forHTTPHeaderField:key];
}
//set paramaters in request body
NSMutableString *requestBody = [[NSMutableString alloc] init];
int keyIndex = 0;
for (id key in params) {
if (keyIndex == 0) {
[requestBody appendFormat:#"%#=%#", key, [params valueForKey:key]];
} else {
[requestBody appendFormat:#"&%#=%#", key, [params valueForKey:key]];
}
keyIndex++;
}
[request setHTTPBody:[requestBody dataUsingEncoding:NSUTF8StringEncoding]];
NSURLResponse *response;
NSError *NSURLError = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&NSURLError];
if (NSURLError) {
NSLog(#"Error: %# Cancelling operation.", NSURLError);
return nil;
}
NSError *NSJSONSerializationError = nil;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&NSJSONSerializationError];
if (NSJSONSerializationError) {
NSLog(#"Error: %# Cancelling operation.", NSJSONSerializationError);
return nil;
}
NSLog(#"Data: %#",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
return responseJSON;
}
Notice the 4th last line that logs the returned NSData from the NSMutableURLRequest, the output is:
Data: {"error":false "tasks":[]}
The code that calls the above method:
NSString *getAllTasksEndpoint = #"http://developmentVPS.com/TaskList-API/v1/tasks";
NSString *apiKey = #"A Valid API Key";
NSDictionary *headers = [[NSDictionary alloc] initWithObjectsAndKeys:apiKey, #"Authorization", nil];
NSDictionary *responseJSON = [self apiRequestWithEndpoint:getAllTasksEndpoint
withParams:nil
withHTTPHeaders:headers
withHTTPMethod:#"GET"];
It is my understanding that the entire data returned from the request should be logged in that NSLog call, but "tasks" is empty. I am new to iOS development, so I may be missing something simple. Does anybody see anything I am missing here?
I have a NSURLConnection (two of them), and they're running in the wrong order.
Here's my method:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
}
}
else {
NSLog(#"error: %#", error);
}
}];
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[request setHTTPMethod:#"POST"];
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
- (NSString *)percentEscapeString:(NSString *)string
{
NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
(CFStringRef)string,
(CFStringRef)#" ",
(CFStringRef)#":/?#!$&'()*+,;=",
kCFStringEncodingUTF8));
return [result stringByReplacingOccurrencesOfString:#" " withString:#"+"];
}
So, it's two NSURLConnection's that are added to the [NSOperationQueue mainQueue]. What my output is showing me is that the second NSURLConnection is running before the first one. So it tries to go to the page where I download data before I'm logged in, so it (obviously) returns a "You're not logged in" error.
How do I schedule them one after another?
The issue, as I suspect you have realized, is that you're doing asynchronous network requests (which is good; you don't want to block the main queue), so there's no assurance of the order they'll finish.
The quickest and easiest answer is to simply put the call to the second request inside the completion block of the first one, not after it. You don't want to be making that second one unless the first one succeeded anyway.
To keep your code from getting unwieldy, separate the login from the request for main page. And you can use the completion block pattern which is common with asynchronous methods. You add a parameter to loginToMistarWithPin that specifies what it should do when the request finishes. You might have one completion block handler for success, and one for failure:
- (void)loginToMistarWithPin:(NSString *)pin password:(NSString *)password success:(void (^)(void))successHandler failure:(void (^)(void))failureHandler {
NSURL *url = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/Login"];
//Create and send request
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *postString = [NSString stringWithFormat:#"Pin=%#&Password=%#",
[self percentEscapeString:pin],
[self percentEscapeString:password]];
NSData * postBody = [postString dataUsingEncoding:NSUTF8StringEncoding];
[request setHTTPBody:postBody];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *error)
{
// do whatever with the data...and errors
if ([data length] > 0 && error == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
// assuming you validated that everything was successful, call the success block
if (successHandler)
successHandler();
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *loggedInPage = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from login), it was = %#", loggedInPage);
if (failureHandler)
failureHandler();
}
}
else {
NSLog(#"error: %#", error);
if (failureHandler)
failureHandler();
}
}];
}
- (void)requestMainPage {
//Now redirect to assignments page
NSURL *homeURL = [NSURL URLWithString:#"https://mistar.oakland.k12.mi.us/novi/StudentPortal/Home/PortalMainPage"];
NSMutableURLRequest *requestHome = [[NSMutableURLRequest alloc] initWithURL:homeURL];
[requestHome setHTTPMethod:#"GET"]; // this looks like GET request, not POST
[NSURLConnection sendAsynchronousRequest:requestHome queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *homeResponse, NSData *homeData, NSError *homeError)
{
// do whatever with the data...and errors
if ([homeData length] > 0 && homeError == nil) {
NSError *parseError;
NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:homeData options:0 error:&parseError];
if (responseJSON) {
// the response was JSON and we successfully decoded it
NSLog(#"Response was = %#", responseJSON);
} else {
// the response was not JSON, so let's see what it was so we can diagnose the issue
NSString *homePage = [[NSString alloc] initWithData:homeData encoding:NSUTF8StringEncoding];
NSLog(#"Response was not JSON (from home), it was = %#", homePage);
}
}
else {
NSLog(#"error: %#", homeError);
}
}];
}
Then, when you want to login, you can do something like:
[self loginToMistarWithPin:#"1234" password:#"pass" success:^{
[self requestMainPage];
} failure:^{
NSLog(#"login failed");
}];
Now, change those successHandler and failureHandler block parameters to include whatever data you need to pass back, but hopefully it illustrates the idea. Keep your methods short and tight, and use completion block parameters to specify what an asynchronous method should do when it's done.
Can you check the below link. It is about forcing one operation to wait for another.
NSOperation - Forcing an operation to wait others dynamically
Hope this helps.
I'm working on an iPad app that requests data from a server, changes and submits it, and then re-requests the data from the server, displaying it to the user. The app updates the data just fine (the equivalent web app sees the update happening), but the data that the iPad app gets back is the old data. I thought maybe it was the caching flag on the NSURLRequest, but it doesn't look like it.
Here is my sequence of calls:
NSString* currentStuff = self.fCurrentIndex.currentStuff;
NSError* err = nil;
[self.fCurrentIndex approve:currentStuff withUsername:username andPassword:password error:&err];
if (err == nil)
{
// rebuild the case list (grab the data from the URL again first)
[self getCaseListViaURL]; // grab the updated data
[self setupUIPanel]; // display it
}
Here's the code that grabs the data (the 'getCaseListViaURL' call):
NSURLResponse* response;
NSError* err = nil;
NSMutableDictionary * jsonObject = nil;
NSString * urlRequestString;
urlRequestString = [method to get the URL string];
NSURL * url = [NSURL URLWithString:urlRequestString];
NSURLRequest * request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:60];
NSData * data = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&err];
if (err == nil)
{
jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&err];
}
if (err && error) {
*error = err;
}
return jsonObject;
Is there any way to force the server to serve up the updated data?
Thanks in advance.
EDIT: Per comments, I'm adding the sequence of update to the server and subsequent pull:
This does the push to the server:
NSString* currentStuff = self.fCurrentIndex.currentStuff;
NSError* err = nil;
[self.fCurrentPatient approveStuff:currentStuff withUsername:username andPassword:password error:&err];
Where 'approveStuff' eventually calls:
__block NSData * jsonData;
__autoreleasing NSError * localError = nil;
if (!error) {
error = &localError;
}
// Serialize the dictionary into JSON
jsonData = [NSJSONSerialization dataWithJSONObject:data
options:NSJSONWritingPrettyPrinted
error:error];
if (*error) return nil;
NSURLResponse* response;
NSString * urlRequestString;
urlRequestString = [self urlStringForRelativeURL:relativeURL
withQueryParams:params];
NSURL * url = [NSURL URLWithString:urlRequestString];
NSMutableURLRequest * request;
request = [NSMutableURLRequest requestWithURL:url
cachePolicy:self.cachePolicy
timeoutInterval:self.timeOutInterval];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:jsonData];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
jsonData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&localError];
NSMutableDictionary * jsonObject;
if (localError == nil)
{
jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData
options:NSJSONReadingMutableContainers
error:&localError];
}
if (error && localError) {
*error = localError;
}
return jsonObject;
Right after this, I call the aforementioned get call and rebuild the UI. Now, if I stick a breakpoint when I do the get, and check on the web server if the data is updated after the push, I see the data is there. However, when I let the get operation continue, it gives me the old data.
So it looks like the issue was on the server. There were some data structures on the server side that weren't being refreshed when the data was being posted.
I get an self.usersArray with 2 elements in the format:
(
{
userCreated = "2012-01-05 12:27:22";
username = Simulator;
},
{
userCreated = "2013-01-01 14:27:22";
username = "joey ";
}
)
This is gotten in a completion block after which I call another method to fetch points for these 2 users through a helper class:
-(void)getPoints{
self.usersPointsArray = [[NSMutableArray alloc] init];
for (NSDictionary *usersDictionary in self.usersArray) {
[SantiappsHelper fetchPointsForUser:[usersDictionary objectForKey:#"username"] WithCompletionHandler:^(NSArray *points){
if ([points count] > 0) {
[self.usersPointsArray addObject:[points objectAtIndex:0]];
}
NSLog(#"self.usersPointsArray %#", self.usersPointsArray);
}];
}
}
The final self.usersPointsArray log looks like:
(
{
PUNTOS = 5;
username = Simulator;
},
{
PUNTOS = 2;
username = joey;
}
)
But the problem is that the way the call for points is structured, the self.usersPointsArray is returned twice, each time with an additional object, due to the for loop, I know.
Here is the Helper class method:
+(void)fetchPointsForUser:(NSString*)usuario WithCompletionHandler:(Handler2)handler{
NSURL *url = [NSURL URLWithString:#"http://myserver.com/myapp/readpoints.php"];
NSDictionary *postDict = [NSDictionary dictionaryWithObjectsAndKeys:usuario, #"userNa", nil];
NSData *postData = [self encodeDictionary:postDict];
// Create the request
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPMethod:#"POST"];
[request setValue:[NSString stringWithFormat:#"%d", postData.length] forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:postData];
__block NSArray *pointsArray = [[NSArray alloc] init];
dispatch_async(dispatch_get_main_queue(), ^{
// Peform the request
NSURLResponse *response;
NSError *error = nil;
NSData *receivedData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&response
error:&error];
if (error) {
if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse*)response;
NSLog(#"HTTP Error: %d %#", httpResponse.statusCode, error);
return;
}
return;
}
NSString *responseString = [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding];
pointsArray = [NSJSONSerialization JSONObjectWithData:[responseString dataUsingEncoding:NSASCIIStringEncoding] options:0 error:nil];
if (handler)
handler(pointsArray);
});
}
I cannot use the self.usersPointsArray with the initial objects, only with the finalized object. It wont always be 2 elements, i actually dont know how many it will be.
What would be the way to structure it so I get a final call when the self.usersPointsArray is complete and then I reload my tableview?
I think of your problem as a standard consumer-producer problem. You can create a queue count for the amount of items that will be processed (int totalToProcess=self.usersArray.count). Each time the completion handler is hit, it will do totalToProcess--. When totalToProcess reaches 0 you have processed all of the elements in your queue and can refresh your table.
If I understand your question correctly I believe this solves your problem. If not, hopefully I can with a bit more information.