Nothing happens after calling [table reloadData] when called with dispatch_async - ios

- (void) setRooms:(NSArray *)newRooms
{
NSLog(#"Main thread(cp3)... %d", [rooms count]);
rooms = newRooms;
[table reloadData];
NSLog(#"Main thread(cp4)... %d", [rooms count]);
}
- (void) parseJSONWithURL:(NSURL *)jsonURL
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
NSLog(#"Main thread(cp1)...%d", [rooms count]);
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSLog(#"Background thread(cp1)...%d", [rooms count]);
NSError *error = nil;
// Request the data and store in a string.
NSString *resp = [NSString stringWithContentsOfURL:jsonURL
encoding:NSASCIIStringEncoding
error:&error];
// Convert the String into an NSData object.
NSData *data = [resp dataUsingEncoding:NSASCIIStringEncoding];
// Parse that data object using NSJSONSerialization without options.
NSDictionary *json = [[NSDictionary alloc] init];
json = [NSJSONSerialization JSONObjectWithData:data
options:kNilOptions
error:&error];
// Return to the main thread to update the UI elements
dispatch_sync(dispatch_get_main_queue(), ^{
NSLog(#"Main thread(cp2)...%d", [rooms count]);
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
[self setRooms:[json valueForKey:#"Rooms"]];
});
NSLog(#"Background thread(cp2)...%d", [rooms count]);
});
NSLog(#"Main thread(cp5)...%d", [rooms count]);
}

Try this
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
NSError *error = nil;
// Request the data and store in a string.
NSString *resp = [NSString stringWithContentsOfURL:jsonURL
encoding:NSASCIIStringEncoding
error:&error];
if (error == nil) {
// Convert the String into an NSData object.
NSData *data = [resp dataUsingEncoding:NSASCIIStringEncoding];
// Parse that data object using NSJSONSerialization without options.
NSDictionary *json = [[NSDictionary alloc] init];
json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
dispatch_sync(dispatch_get_main_queue(), ^{
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
_rooms = [json valueForKey:#"Rooms"];
[_table reloadData];
});
}
});
or try
[self performSelectorOnMainThread:#selector(udpateAfterFetch:) withObject: [json valueForKey:#"Rooms"] waitUntilDone:YES];
-(void)udpateAfterFetch:(NSArray or whatever *) yourObject
{
_rooms = yourObject;
[_table reloadData];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
The table is not being reloaded because any UI update should happen in the main thread and it is not happening so in ur lines of code.

Related

How to add activity indicator to image load

I want to add activity indicator to image load on image view. How it possible please help, Thank You
My code
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSLog(#"Error in receiving data %#",error);
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSLog(#"response data %#",json);
NSArray* results = [json objectForKey:#"status"];
NSArray *imageUrlArray = [results valueForKey:#"slider_image_path"];
NSLog(#"images %#",imageUrlArray);
NSMutableArray *arrayImages = [[NSMutableArray alloc] init];
for (NSString *strImageUrl in imageUrlArray) {
[arrayImages addObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strImageUrl]]]];
}
self.imageview.animationImages = arrayImages;
_imageview.animationDuration = 10;
_imageview.animationRepeatCount = 0;
[_imageview startAnimating];
}
Do like following :
UIActivityIndicatorView *indctr = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indctr startAnimating];
[indctr setCenter:self.imageView.center];
[self.contentView addSubview:indctr];
Use this Code
UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
[indicator startAnimating];
[indicator setCenter:self.imageView.center];
[self.contentView addSubview:indicator];
Remove the indicator from the superview in the block's succes method.
[_imageView setImageWithURL:[NSURL URLWithString:anURL]
success:^(UIImage *image) {
[indicator removeFromSuperview];
}
failure:^(NSError *error) {
}];
}
You Can use the MBProgress HUD class:https://github.com/jdg/MBProgressHUD
download it and in your code set this:
-(void)viewDidLoad{
MBProgressHUD *HUD = [[MBProgressHUD alloc]initWithView:self.view];
[self.view addSubview:HUD];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSError *error;
NSLog(#"Error in receiving data %#",error);
[HUD show: YES];
NSMutableDictionary *json = [NSJSONSerialization JSONObjectWithData:response options:NSJSONReadingMutableLeaves error:&error];
NSLog(#"response data %#",json);
NSArray* results = [json objectForKey:#"status"];
NSArray *imageUrlArray = [results valueForKey:#"slider_image_path"];
NSLog(#"images %#",imageUrlArray);
NSMutableArray *arrayImages = [[NSMutableArray alloc] init];
for (NSString *strImageUrl in imageUrlArray) {
[arrayImages addObject:[UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:strImageUrl]]]];
}
self.imageview.animationImages = arrayImages;
_imageview.animationDuration = 10;
_imageview.animationRepeatCount = 0;
[_imageview startAnimating];
[HUD hide: YES];
}

Getting delay to see next view controller ,see detail in post?

I have one login screen after that it will move to next view controller which have i have used some networks like http,json to get data from server. when i enter login username/password then if i click login button its getting delay to 8 seconds after that only it moving to next view controller.Still that my login screen alone showing for 8 seconds and then only it move to next view controller.
Here my login controller.m:
#implementation mainViewController
- (void)viewDidLoad {
[super viewDidLoad];
_username.delegate = self;
_password.delegate = self;
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if (![defaults boolForKey:#"reg"]) {
NSLog(#"no user reg");
_logBtn.hidden = NO;
}
}
- (void)viewWillAppear:(BOOL)animated
{
[self.navigationController setNavigationBarHidden:YES animated:animated];
[super viewWillAppear:animated];
_username.text = nil;
_password.text = nil;
}
- (IBAction)LoginUser:(id)sender {
if ([_username.text isEqualToString:#"sat"] && [_password.text isEqualToString:#"123"]) {
NSLog(#"Login success");
[self performSegueWithIdentifier:#"nextscreen" sender:self];
}
else {
NSLog(#"login was unsucess");
// Alert message
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:#"wrong"
message:#"Message"
preferredStyle:UIAlertControllerStyleAlert];
UIAlertAction *actionOk = [UIAlertAction actionWithTitle:#"Ok"
style:UIAlertActionStyleDefault
handler:nil];
[alertController addAction:actionOk];
[self presentViewController:alertController animated:YES completion:nil];
}
}
Here my nextcontroller.m
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
// here only i am getting data from server
[self getdata];
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
}
Help me out. If my question din't understand.I can tell more about my post. And in my nextcontroller.m [self getdata] is i am getting data from server url.Thanks
My get data:
-(void)getdata {
NSString *userName = #“users”;
NSString *password = #“images”;
NSData *plainData = [password dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [plainData base64EncodedStringWithOptions:0];
base64String=[self sha256HashFor: base64String];
NSString *urlString = #"https://porterblog/image/file”;
NSMutableURLRequest *request= [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"GET"];
NSString *authStr = [NSString stringWithFormat:#"%#:%#", userName, base64String];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat:#"Basic %#", [authData base64EncodedStringWithOptions:0]];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *str = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
NSError * error;
self->arrayPDFName = [[NSMutableArray alloc]init];
NSDictionary *jsonResults = [NSJSONSerialization JSONObjectWithData:returnData options:NSJSONReadingMutableContainers error:nil];
NSDictionary *dictOriginal = jsonResults[#“birds”];
[titleArray addObject:[NSString stringWithFormat:#" birds(%#)”, dictOriginal[#"count"]]];
NSDictionary *dictOriginal2 = jsonResults[#"owl”];
[titleArray addObject:[NSString stringWithFormat:#" Owl(%#)”, dictOriginal2[#"count"]]];
NSDictionary *dictOriginal3 = jsonResults[#"pensq”];
[titleArray addObject:[NSString stringWithFormat:#" Pensq(%#)”, dictOriginal3[#"count"]]];
NSDictionary *dictOriginal4 = jsonResults[#“lion”];
[titleArray addObject:[NSString stringWithFormat:#" lion(%#)”, dictOriginal4[#"count"]]];
NSArray *arrayFiles = [NSArray arrayWithObjects: dictOriginal, dictOriginal2, dictOriginal3, dictOriginal4, nil];
NSLog(#"str: %#", titleArray);
for (NSDictionary *dict in arrayFiles) {
NSMutableArray *arr = [NSMutableArray array];
NSArray *a = dict[#"files"];
for(int i=0; i < a.count; i ++) {
NSString *strName = [NSString stringWithFormat:#"%#",[[dict[#"files"] objectAtIndex:i] valueForKey:#"name"]];
[arr addObject:strName];
}
[arrayPDFName addObject:arr];
}
NSString *errorDesc;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory1 = [paths objectAtIndex:0];
NSString *plistPath = [documentsDirectory1 stringByAppendingPathComponent:#"SampleData.plist"];
NSString *error1;
returnData = [ NSPropertyListSerialization dataWithPropertyList:jsonResults format:NSPropertyListXMLFormat_v1_0 options:0 error:&error];
if(returnData ) {
if ([returnData writeToFile:plistPath atomically:YES]) {
NSLog(#"Data successfully saved.");
}else {
NSLog(#"Did not managed to save NSData.");
}
}
else {
NSLog(#"%#",errorDesc);
}
NSDictionary *stringsDictionary = [NSDictionary dictionaryWithContentsOfFile:plistPath];
}
EDITED:
`- (void)viewDidLoad {
[super viewDidLoad];
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
self.dataSourceForSearchResult = [NSArray new];
titleArray = [NSMutableArray array];
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
[self.collectionView reloadData];
self.navigationItem.hidesBackButton = YES;
});
});
}`
You're getting your data using main thread you need do to that in background then invoke the code you need (as i see is reload collectionView)
I assume that because you didn't show the getdata method code
If that the case you can use this code:
dispatch_async(dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
It's mean that your VC will show immediately but the collectionView fill after you finish load the data, you can put some old data while loading like Facebook app (you see latest retrieved posts until finish loading].
Edit:
In your code you replace viewdidload method in nextController with next code:
- (void)viewDidLoad {
[super viewDidLoad];
//for search label data
self.dataSourceForSearchResult = [NSArray new];
//collection of array to store value
titleArray = [NSMutableArray array];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){
//Background Tasks
[self getdata];
dispatch_async(dispatch_get_main_queue(), ^(void){
//Run UI Updates
[self.collectionView reloadData];
});
});
self.collectionView.dataSource = self;
self.collectionView.delegate = self;
}

How to use google Api for find places around me

I am working on app which use Google API. I am trying to find places around me by it. I am using below code for fetch data,
-(void)fetchedData:(NSData *)responseData {
//this is to parse out the json data
NSError *error = nil; //create some error handling here
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
//I'm told the returned results from Google will be an array obtained from the NSDictionary object with the key "results"
NSArray *places = [json objectForKey:#"results"];
//display the data to the console for review
NSLog(#" Google data:\n%#", places);
}
But it shows json status = Request Denied.
Any help will appreciated.
Vishal,
You can do it using the following block of Code:
- (void) queryGooglePlaces: (NSString *) googleType
{
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?location=%f,%f&radius=%#&types=%#&sensor=true&key=%#&language=%#", appDelegate.currentLatitude, appDelegate.currentLongitude, [radiusValueArray objectAtIndex:[[NSUserDefaults standardUserDefaults] integerForKey:#"selectedDistance"]], googleType, kGOOGLE_API_KEY, appDelegate.selectedLanguageCode];
//Formulate the string as URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
if(data == nil)
{
[placeTableView reloadData];
[SVProgressHUD dismiss];
}
else
{
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
}
});
}
- (void) queryGooglePlaces_WithNextPage
{
// Build the url string we are going to sent to Google. NOTE: The kGOOGLE_API_KEY is a constant which should contain your own API key that you can obtain from Google. See this link for more info:
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/search/json?pagetoken=%#&location=%f,%f&radius=%#&sensor=true&key=%#", nextPageToken, appDelegate.currentLatitude, appDelegate.currentLongitude, [radiusValueArray objectAtIndex:[[NSUserDefaults standardUserDefaults] integerForKey:#"selectedDistance"]], kGOOGLE_API_KEY];
//Formulate the string as URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
if(data == nil)
{
[placeTableView reloadData];
[SVProgressHUD dismiss];
}
else
{
[self performSelectorOnMainThread:#selector(fetchedData:) withObject:data waitUntilDone:YES];
}
});
}
- (void)fetchedData:(NSData *)responseData
{
//parse out the json data
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
//The results from Google will be an array obtained from the NSDictionary object with the key "results".
if(isNextPageAvailable == FALSE)
[appDelegate.placesArray removeAllObjects];
NSArray *placesTemp = [json objectForKey:#"results"];
if([json valueForKey:#"next_page_token"] != nil)
{
nextPageToken = [json valueForKey:#"next_page_token"];
isNextPageAvailable = TRUE;
}
else
{
nextPageToken = #"";
isNextPageAvailable = FALSE;
}
for(int i=0;i<[placesTemp count];i++)
{
NSMutableDictionary *placeDictionary = [[NSMutableDictionary alloc] initWithDictionary:[placesTemp objectAtIndex:i]];
double lat1 = appDelegate.currentLatitude;
double long1 = appDelegate.currentLongitude;
double lat2 = [[[[placeDictionary objectForKey:#"geometry"] objectForKey:#"location"] valueForKey:#"lat"] doubleValue];
double long2 = [[[[placeDictionary objectForKey:#"geometry"] objectForKey:#"location"] valueForKey:#"lng"] doubleValue];
CLLocation *location1 = [[CLLocation alloc] initWithLatitude:lat1 longitude:long1];
CLLocation *location2 = [[CLLocation alloc] initWithLatitude:lat2 longitude:long2];
[placeDictionary setValue:[NSString stringWithFormat:#"%f",[location1 distanceFromLocation:location2]] forKey:#"distance"];
[appDelegate.placesArray addObject:placeDictionary];
}
NSSortDescriptor *sortDescriptor;
sortDescriptor = [[NSSortDescriptor alloc] initWithKey:#"distance" ascending:YES comparator:^NSComparisonResult(id obj1, id obj2) {
if ([obj1 floatValue] < [obj2 floatValue])
return NSOrderedAscending;
else
return NSOrderedDescending;
}];
NSArray *sortedArray = [appDelegate.placesArray sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
[appDelegate.placesArray removeAllObjects];
[appDelegate.placesArray addObjectsFromArray:sortedArray];
[self showPoweredbyGoogle];
[placeTableView reloadData];
[SVProgressHUD dismiss];
// [NSTimer scheduledTimerWithTimeInterval:0.001 target:self selector:#selector(reloadTableNow) userInfo:nil repeats:NO];
//Plot the data in the places array onto the map with the plotPostions method.
// [self plotPositions:placesArray];
}
- (void) queryGooglePlaceDetail
{
NSString *url = [NSString stringWithFormat:#"https://maps.googleapis.com/maps/api/place/details/json?reference=%#&sensor=false&key=%#&language=%#", [[appDelegate.placesArray objectAtIndex:selectedPlaceIndex] valueForKey:#"reference"], kGOOGLE_API_KEY, appDelegate.selectedLanguageCode];
//Formulate the string as URL object.
NSURL *googleRequestURL=[NSURL URLWithString:url];
// Retrieve the results of the URL.
dispatch_async(kBgQueue, ^{
NSData* data = [NSData dataWithContentsOfURL: googleRequestURL];
if(data == nil)
{
[SVProgressHUD dismiss];
}
else
{
[self performSelectorOnMainThread:#selector(fetchedDetailPlaceData:) withObject:data waitUntilDone:YES];
}
});
}
- (void)fetchedDetailPlaceData:(NSData *)responseData
{
//parse out the json data
NSError* error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:responseData
options:kNilOptions
error:&error];
NSDictionary *detailTempDic = [[NSMutableDictionary alloc] initWithDictionary:[json objectForKey:#"result"]];
[detailTempDic setValue:[[appDelegate.placesArray objectAtIndex:selectedPlaceIndex] valueForKey:#"distance"] forKey:#"distance"];
[SVProgressHUD dismiss];
[self performSegueWithIdentifier:#"Detail_Place_Push" sender:detailTempDic];
}
Here you have to pass different types of objects from Google Places such as atm, airport, restaurant, bank, hospital, school.
[self queryGooglePlaces:[googlePlaceTypeArray objectAtIndex:SharedManager.selectedPlaceCategoryIndex]];
Thanks,
Best Regards,
Gurprit

dispatch_async UITableView ReloadData

I have a problem, when start the viewDidLoad method, the data is loaded and displayed correctly in UITableView but when I have to reload the data by clickPopular method, the TableView is not updated.
Any ideas on how I can do this?
viewDidLoad Method
-(void)viewDidLoad
{
Name = [[NSMutableArray alloc] init];
slug = [[NSMutableArray alloc] init];
Immagine = [[NSMutableArray alloc] init];
visite = [[NSMutableArray alloc] init];
categorie = [[NSMutableArray alloc] init];
[[NSUserDefaults standardUserDefaults] setObject:#"recent" forKey:#"settings_home_filter"];
[[NSUserDefaults standardUserDefaults] synchronize];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self LoadJson];
dispatch_async(dispatch_get_main_queue(), ^{
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[tableView reloadData];
[self StopCaricamento];
});
});
}
Popular Method
-(IBAction)clickPopular:(id)sender{
[tableView reloadData];
[[NSUserDefaults standardUserDefaults] setObject:#"popular" forKey:#"settings_home_filter"];
[[NSUserDefaults standardUserDefaults] synchronize];
[self StartCaricamento];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self LoadJson];
dispatch_async(dispatch_get_main_queue(), ^{
[tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationNone];
[tableView reloadData];
[self StopCaricamento];
});
});
}
LoadJson Method
-(void)LoadJson
{
NSString *filtro = [[NSUserDefaults standardUserDefaults] objectForKey:#"settings_home_filter"];
NSString *stringachiamata = [NSString stringWithFormat:#"https://www.mywebsite.com/videos/latest?count=100&ln=en&result_type=%#", filtro];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:stringachiamata]];
[request setHTTPMethod:#"GET"];
[request setValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"content-type"];
NSError *err;
NSURLResponse *response;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
if(err != nil)
{
NSLog(#"Error Parsing JSON: %#", err);
}
else
{
NSDictionary *jsonArray = [NSJSONSerialization JSONObjectWithData:responseData options: NSJSONReadingMutableContainers error: &err];
array = [jsonArray objectForKey:#"videos"];
NSLog(#"%d", [array count]);
for (int i = 0; i < [array count]; i++)
{
[Name addObject:[[array objectAtIndex:i] objectForKey:#"name"]];
[slug addObject:[[array objectAtIndex:i] objectForKey:#"slug_video"]];
[Immagine addObject:[[array objectAtIndex:i] objectForKey:#"thumbnail_video_original"]];
[visite addObject:[[array objectAtIndex:i] objectForKey:#"views_video"]];
[categorie addObject:[[array objectAtIndex:i] objectForKey:#"category_name_video"]];
}
}
}
StartCaricamento and Stop Caricamento Methods
-(void)StartCaricamento{
activityImageView.hidden = NO;
[activityImageView startAnimating];
}
-(void)StopCaricamento{
[activityImageView stopAnimating];
activityImageView.hidden = YES;
}
you never clear the array when reloading...
meaning old entries remain upon reloading BEFORE you dispatch_async
[Name removeAllObjects];
[slug removeAllObjects];
[Immagine removeAllObjects];
[visit eremoveAllObjects];
[categorie removeAllObjects];
actually.. do it as FIRST line of -(IBAction)clickPopular:(id)sender{

Update the UI of the View Controller and then dismiss it

I have a view controller, that loads some an array. While everything is loading, I need to present another view controller (with the UIProgressView) and update it's UI (the progress property of a UIProgressView) and then dismiss and present first vc with downloaded data. I'm really struggling on it and I've tried delegation, but nothing worked for me.
- (void)viewDidLoad
{
[super viewDidLoad];
if ([[NSUserDefaults standardUserDefaults] boolForKey:#"downloaded"]) {
} else {
NSLog(#"First time Launched");
ProgressIndicatorViewController *progressVC = [ProgressIndicatorViewController new];
progressVC.modalPresentationStyle = UIModalPresentationFullScreen;
[self syncContacts];
[self presentViewController:progressVC animated:YES completion:nil];
[[NSUserDefaults standardUserDefaults] setBool:YES forKey:#"downloaded"];
[progressVC release];
}
}
sync contacts method:
- (void)syncContacts
{
NSLog(#"Sync data");
NSMutableArray *allContacts = [ContactsOperations getAllContactsFromAddressBook];
NSInteger allContactsCount = [allContacts count];
if (allContactsCount > 0) {
for (ContactData *contact in allContacts) {
NSMutableArray *phoneNumbersArray = [[NSMutableArray alloc] init];
NSString *nospacestring = nil;
for (UserTelephone *tel in [contact.abonNumbers retain]) {
NSArray *words = [tel.phoneNumber componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceCharacterSet]];
NSString *nospacestring = [words componentsJoinedByString:#""];
[phoneNumbersArray addObject:nospacestring];
}
contact.abonNumbers = phoneNumbersArray;
if (phoneNumbersArray != nil) {
NSLog(#"NOT NULL PHONENUMBERS: %#", phoneNumbersArray);
}
NSDictionary *dataDictionary = [[NSDictionary alloc] initWithObjectsAndKeys:contact.abonNumbers, #"phoneNumbers", contact.contactName, #"fullName", [NSNumber numberWithBool:contact.isBlackList], #"blacklist", [NSNumber numberWithBool:contact.isIgnore], #"ignore", contact.status, #"status", nil];
NSLog(#"dictionary: %#", dataDictionary);
NSError *error;
NSData *postData = [NSJSONSerialization dataWithJSONObject:dataDictionary options:0 error:&error];
NSLog(#"POST DATA IS : %#", postData);
NSMutableURLRequest *newRequest = [self generateRequest:[[NSString stringWithFormat:#"%#c/contacts%#%#", AVATATOR_ADDR, SESSION_PART, [[ServiceWorker sharedInstance] SessionID]] stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding] withHTTPMethod:#"POST"];
[newRequest setHTTPBody:postData];
[newRequest setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
//__block NSMutableData *newData;
[NSURLConnection sendAsynchronousRequest:newRequest queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
if (!connectionError) {
NSDictionary *allData = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"alldata from contacts: %#", allData);
//NSInteger errorCode = [[allData objectForKey:#"CommandRes"] integerValue];
//if (errorCode == 0) {
NSInteger remoteId = [[allData objectForKey:#"contactId"] integerValue];
contact.remoteId = remoteId;
NSLog(#"remote id is from parse content : %d", remoteId);
[[AvatatorDBManager getSharedDBManager]createContactWithContactData:contact];
} else {
NSLog(#"error");
}
}];
//Somewhere here I need to update the UI in another VC
[phoneNumbersArray release];
[dataDictionary release];
}
} else {
}
}
generate request method:
- (NSMutableURLRequest *)generateRequest:(NSString *)urlString withHTTPMethod:(NSString *)httpMethod
{
NSLog(#"url is :%#", urlString);
NSURL *url = [NSURL URLWithString:urlString];
request = [NSMutableURLRequest requestWithURL:url];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
[request setHTTPMethod:httpMethod];
return request;
}
ProgressViewController is just an empty VC with the progress bar. No code yet.
In the view controller that will display the progress view expose a method like this...
- (void)updateProgress:(float)progress;
Its implementation will look like this...
- (void)updateProgress:(float)progress {
[self.progressView setProgress:progress animated:YES];
}
On the main view controller you need to execute the long-running process on a background thread. Here's viewDidLoad for the main view controller. This example code uses a property for the progress view controller (you may not require this) and assumes your are in a navigation controller...
- (void)viewDidLoad {
[super viewDidLoad];
// Create and push the progress view controller...
self.pvc = [[ProgressViewController alloc] init];
[self.navigationController pushViewController:self.pvc animated:YES];
// Your long-running process executes on a background thread...
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// Your long-running process goes here. Wherever required you would
// call updateProgress but that needs to happen on the main queue...
dispatch_async(dispatch_get_main_queue(), ^{
[self.pvc updateProgress:progress];
});
// At the end pop the progress view controller...
dispatch_async(dispatch_get_main_queue(), ^{
[self.navigationController popViewControllerAnimated:YES];
});
});
}

Resources