SplitViewController reference logic - ios

I read allot about the SplitViewControllers but i am walking in circles because i dont understand something.
You have a masterviewcontroller and a popoverview as a bar button item (filter)
lets say masterviewcontroller is a tableview and in the popoverview is a uiview controller
On the iphone i always alloced the masterviewcontroller and update the reference after some modifications, when you hit the button "search", it pushed a new controller with new data (come to think of it,maybe this wasnt the best idea) now that logic doesnt work anymore.
I have read you have to reference the controllers to each other, so i did it like this.
in the filtercontroller (this is the popoverview)
.h
#property (strong, nonatomic) MasterViewController *masterviewController;
#property (weak, nonatomic) IBOutlet UISlider *filterPrice;
- (IBAction)filterSearch:(id)sender;
.m
- (IBAction)filterSearch:(id)sender {
self.masterviewController.filterSearchPrice = [NSNumber numberWithInt:self.filterPrice.value];
[self.masterviewController performFilterSearch];
}
the performFilterSearch checks the fields, makes a call to an url with the filternames and json objects come back,parse and reload data happens..
Now i expect the masterviewcontroller to show new data but that doesnt happen, in fact nothing happens...
Update this is FilterSearch:
-(void)performFilterSearch
{
[queue cancelAllOperations];
[[AFImageCache sharedImageCache] removeAllObjects];
[[NSURLCache sharedURLCache] removeAllCachedResponses];
isLoading =YES;
[self.tableView reloadData];
searchResults = [NSMutableArray arrayWithCapacity:10];
NSURL *url = [self urlFilterWithSearchPrice:filterSearchPrice];
NSLog(#"%#",url);
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation
JSONRequestOperationWithRequest:request
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
[self parseDictionary:JSON];
isLoading = NO;
[self.tableView reloadData];
}
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
[self showNetworkError];
isLoading = NO;
[self.tableView reloadData];
}];
operation.acceptableContentTypes = [NSSet setWithObjects:#"application/json", #"text/json", #"text/javascript",#"text/html", nil];
[queue addOperation:operation];
}
btw when i Nslog in filterSearch to check if its updated:
NSLog(#"%d",self.masterviewController.filterSearchPrice);
NSLog(#"%d",[self.filterTypeSegmentedControl selectedSegmentIndex]);
the first one never gets updated the second one gets updated off course
Update 2: (how do i launch the popview):
I added a bar button item on the masterviewcontrollers navigation that has an action.
I added a popover segue from the masterviewcontroller -> filtercontroller
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
filterPopOver = [(UIStoryboardPopoverSegue *)segue popoverController];
}
- (IBAction)filterPopButton:(id)sender {
if (filterPopOver){
[filterPopOver dismissPopoverAnimated:YES];
}
else{
[self performSegueWithIdentifier:#"showFilterPopover" sender:sender];
}
}

When you launch your filterController, you need to pass in a reference to the MasterViewController. You have a property for it in the filter controller, but you never assign a value to that property.
After Edit:
Your prepareForSegue method should look like this:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
FilterController *fc = (FilterController *)segue.destinationViewController;
fc.masterViewController = self;
}
Make sure that you've imported MasterViewController.h into you FilterController.m

Related

iOS objective c passing data between view controllers

I am new to iOS and I am not able to pass data from one controller to another. I am not able to access the variable in the second view controller
this is my method for passing I have created a delegate in .h file of receiving view controller
.h file of first view controller (sending)
#interface OtpViewController : UIViewController
#property (nonatomic,strong) NSString *str;
#property (strong,nonatomic) NSString *tmp;
#property(weak,nonatomic) NSString *requestReply ;
.m file of first view controller(sending)
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender{
VerifyViewController *loadCtr = (VerifyViewController *)segue.destinationViewController;
loadCtr.delegate = self;
loadCtr.tmpStr = self.tmp;
NSLog(#"--%#",self.tmp);
[loadCtr setotp:self.tmpdict withMobile:_mobiletf.text];
//NSLog(#"otp:%#",[tmpdict valueForKey:#"otp"]);
NSLog(#"mobile:%#",_mobiletf.text);
}
.m file of second view controller(receiving)
-(void)setotp:(NSDictionary *)dic withMobile:(NSString *)str{
self.stri=[tmpdict valueforkey:#"otp"];
self.stri1=_mobiletf.text;
OtpViewController.[tmpdict valueforkey:#"otp"]=self.stri;
NSLog(#"%#----%#",self.stri,self.stri1);
}
.h file of second view controller(receiving)
#protocol VerifyViewControllerDelegate <NSObject>
#end
#interface VerifyViewController : UIViewController
#property (nonatomic,strong) NSString *otpStr;
#property(nonatomic,strong) NSString *mobileStr;
#end
actually I am trying to get otp from server and I have extracted the otp in the first view controller and now I have to pass otp and the mobile number from the text field to second view controller for verification of the otp please help!!
NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding]; // this is json string
// NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; // you need to convert to dictionary object
NSLog(#"requestReply: %#", jsonDict);
self.tmp=[jsonDict valueForKey:#"otp"] ;
self.str=self.tmp;
NSLog(#"tmp storage inside block:%#",self.tmp);
}] resume];
[ self performSegueWithIdentifier:#"b1" sender:self];
NSLog(#" storage:%#",self.str);
NSLog(#"tmp storage:%#",self.tmp);
}
at log whatever is printed which is out of resume gives me null
this is my log data
2017-06-01 12:26:45.803 MenuBar[2652:124758] 9047038606
2017-06-01 12:26:45.809 MenuBar[2652:124758] storage:(null)
2017-06-01 12:26:45.810 MenuBar[2652:124758] tmp storage:(null)
2017-06-01 12:26:48.422 MenuBar[2652:124804] requestReply: {
otp = 325106;
success = 1;
}
2017-06-01 12:26:48.422 MenuBar[2652:124804] tmp storage inside block:325106
Use Below code:
#interface VerifyViewController : UIViewController
#property (nonatomic,strong) NSString *otpStr;
#property(nonatomic,strong) NSString *mobileStr;
Then pass values:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(nullable id)sender
{
VerifyViewController *loadCtr = (VerifyViewController *)segue.destinationViewController;
loadCtr.otpStr = [tmpdict valueForKey:#"otp"];
loadCtr.mobileStr = _mobiletf.text;
}
You can access these 2 values in ViewDidLoad method of VerifyViewController.
self.otpStr and self. mobileStr
(As of Xcode Version 9.4.1 (9F2000) - iOS 11.4 - Objective C) 
Most will need to call several storyboard segue calls from a single UIViewController. Here is how to handle the different segue string identifiers within the preparForSegue delegate call.
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
if ([segue.identifier isEqualToString: #“CallerViewController_ToMusicPlayerViewController_Segue"])
{
MusicPlayerViewController * targetVC = (MusicPlayerViewController *)segue.destinationViewController;
targetVC.listName = #“Music Hits”;
}
if ([segue.identifier isEqualToString: #“CallerViewController_ToMusicListViewController_Segue"])
{
MusicListViewController * targetVC = (MusicListViewController *)segue.destinationViewController;
// if you need to manage a protocol delegate with caller VC
targetVC.savefolderChoiceDelegate = self;
}
}
The actual call to invoke the segue looks like:
-(void)buttonAction:(id)sender{
[self performSegueWithIdentifier:#“CallerViewController_ToMusicPlayerViewController_Segue" sender:sender];
}
Here is an example of Interface Builder Segue. the identifier is different, but imagine #“CallerViewController_ToMusicPlayerViewController_Segue" is actually #"ProtData_Add_Segue" in this image.

Hidden button action won't change issue

I'm trying to disable the navigation bar button when I start the app and after I finish the process(fetching data), I enable it back but unfortunately it won't enable.
Please where would be my issue? While I'm putting enable to YES and when I debug it I can see that it enabling it to YES.
- (void)viewDidLoad {
UIImage *searchBtn = [UIImage imageNamed:#"search_icon.png"];
barButtonSearch = [[UIBarButtonItem alloc] initWithImage:[searchBtn imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:#selector(searchButton)];
UIImage *menuBtn = [UIImage imageNamed:#"menu_icon.png"];
barButtonMenu = [[UIBarButtonItem alloc] initWithImage:[menuBtn imageWithRenderingMode:UIImageRenderingModeAlwaysOriginal] style:UIBarButtonItemStylePlain target:self action:#selector(menuButton)];
self.navigationItem.rightBarButtonItem = barButtonMenu;
self.navigationItem.leftBarButtonItem = barButtonSearch;
barButtonMenu.enabled = NO;
barButtonSearch.enabled = NO;
}
- (void)unhide{
if (!(barButtonSearch.enabled && barButtonMenu.enabled)) {
barButtonMenu.enabled = YES;
barButtonSearch.enabled = YES;
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
ViewController *theInstance = [[ViewController alloc] init];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
_dic = (NSDictionary *)responseObject;
[theInstance unhide];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Err");
}];
[operation start];
return YES;
}
}
Well there it is!
You are initializing your ViewController but that doesn't call your viewDidLoad: method. The viewDidLoad: method gets called when your ViewController is either Pushed or Presented! That is the time when the view gets loaded into the memory.
Therefore, the barButtons are never created and you are unable to see them.
So either make your network call inside the viewDidLoad: method of your ViewController
OR
Push the instance of your ViewController and then call the method unhide.
Edit
Since you are using Storyboards and not pushing any ViewController from AppDelegate, you need to use reference of your ViewController.
replace this in your - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions method
ViewController *theInstance = (ViewController *)[(UINavigationController*)self.window.rootViewController topViewController];
You are calling [theInstance unhide] from the completion block of the AFHTTPOperation - this will almost certainly be executed on a background queue.
All UI operations must be performed on the main queue.
You should use -
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
_dic = (NSDictionary *)responseObject;
dispatch_async(dispatch_get_main_queue(),^{
[theInstance unhide];
});
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Err");
}];
Update
Your main problem is that theInstance points to an instance of your view controller that isn't on the screen - It is just an instance you have allocated but not actually presented.
Assuming this view controller is the initial view controller loaded by your application you can get a reference to the correct instance using [UIApplication sharedApplication].keyWindow.rootViewController
Remove this method from the completion block of app delegate.
[theInstance unhide];
And add some delegate function which will be activated after the asynchronous call completes its task. And add that unhide method there (In your view controller may be).

Bool value not being sent to destination ViewController

I want to send a bool value, didAddNewItem, from my SearchViewController to MatchCenterViewController, and then run a function depending on the state of the bool value. I attempt to send a didAddNewItem value of YES to my destination, MatchCenterViewController, but it doesn't seem to send correctly, as the function below never runs.
Here's how I'm sending it from SearchViewController (edited to reflect Rob's answer):
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([segue.identifier isEqualToString:#"ShowMatchCenterSegue"]) {
_didAddNewItem = YES;
MatchCenterViewController *controller = (MatchCenterViewController *) segue.destinationViewController;
NSLog(#"we're about to set controller values before segueing to MC");
// Send over the matching item criteria
controller.itemSearch = self.itemSearch.text;
controller.matchingCategoryId = self.matchingCategoryId1;
controller.matchingCategoryMinPrice = self.matchingCategoryMinPrice1;
controller.matchingCategoryMaxPrice = self.matchingCategoryMaxPrice1;
controller.matchingCategoryCondition = self.matchingCategoryCondition1;
controller.matchingCategoryLocation = self.matchingCategoryLocation1;
controller.itemPriority = self.itemPriority;
[self.tabBarController setSelectedIndex:1];
}
}
And here's where I try to make use of it in the destination, MatchViewController:
- (void)viewDidAppear:(BOOL)animated
{
if (_didAddNewItem == YES) {
NSLog(#"well then lets refresh the MC");
// Start loading indicator
UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
activityIndicator.center = CGPointMake(self.view.frame.size.width / 2.0, self.view.frame.size.height / 2.0);
[self.view addSubview: activityIndicator];
[activityIndicator startAnimating];
// Disable ability to scroll until table is MatchCenter table is done loading
self.matchCenter.scrollEnabled = NO;
_matchCenterDone = NO;
// Add new item to MatchCenter Array with the criteria from the matching userCategory instance, plus the search term
[PFCloud callFunctionInBackground:#"addToMatchCenter"
withParameters:#{
#"searchTerm": self.itemSearch,
#"categoryId": self.matchingCategoryId,
#"minPrice": self.matchingCategoryMinPrice,
#"maxPrice": self.matchingCategoryMaxPrice,
#"itemCondition": self.matchingCategoryCondition,
#"itemLocation": self.matchingCategoryLocation,
#"itemPriority": self.itemPriority,
}
block:^(NSString *result, NSError *error) {
if (!error) {
NSLog(#"'%#'", result);
self.matchCenterArray = [[NSArray alloc] init];
[PFCloud callFunctionInBackground:#"MatchCenter3"
withParameters:#{}
block:^(NSArray *result, NSError *error) {
if (!error) {
_matchCenterArray = result;
[_matchCenter reloadData];
[activityIndicator stopAnimating];
// Reenable scrolling/reset didAddNewItem bool
_matchCenterDone = YES;
self.matchCenter.scrollEnabled = YES;
//_didAddNewItem = NO;
NSLog(#"Result: '%#'", result);
}
}];
}
}];
}
}
I made sure it was properly setup as a property in the headers of both ViewControllers, so I'm not sure why it's not setting the value in the destination VC correctly. I know for a fact that addToMatchCenter function is running correctly without error, so it should be working.
#property (assign) BOOL didAddNewItem;
In your prepareForSegue, you are calling callFunctionInBackground asynchronously, meaning that it is quite likely that the segue will finish and the new view controller will be presented well before you set didAddNewItem in the block of callFunctionInBackground.
I'd be inclined to change that destination controller to initiate this asynchronous request itself, but have it show a UIActivityIndicatorView (or something) to suggest that the dependent request has not yet been finished, and then in the block you can remove the activity indicator view and update the UI accordingly.

how can I let UIPageViewController know when my async download is complete?

I currently have a UIPageViewController set up in my project almost exactly like the default page-based application template.
However, in the init method for my ModelController I am using NSURLConnection to async download data into an array (of images) that is supposed to be displayed on the PageViewController.
That means when my root view controller goes and inits a starting view controller the resources might not be downloaded yet and then the model controller is fetching things from an empty array which crashes the app.
How can I implement a safe way to show the images in a PageView? I was thinking of using an empty view controller with an activity indicator as the starting view controller but I don't know how I'd then let the model controller know when the download is completed so I can then update the views with the images.
my root view controller (this is the uipageviewcontroller delegate)
#interface CSAPromoViewController ()
#property (readonly, strong, nonatomic) CSAPromoModelController *modelController;
#end
#implementation CSAPromoViewController
#synthesize modelController = _modelController;
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.delegate = self;
CSAPageDataViewController *startingViewController = [self.modelController viewControllerAtIndex:0 storyboard:self.storyboard];
NSArray *viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers direction:UIPageViewControllerNavigationDirectionForward animated:NO completion:nil];
self.pageViewController.dataSource = self.modelController;
[self addChildViewController:self.pageViewController];
[self.view addSubview:self.pageViewController.view];
//set page view controller's bounds
CGRect pageViewRect = self.view.bounds;
self.pageViewController.view.frame = pageViewRect;
[self.pageViewController didMoveToParentViewController:self];
self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;
}
my model controller (this is the data source)
#interface CSAPromoModelController()
#property (readonly, strong, nonatomic) NSArray *promosArray;
#end
#implementation CSAPromoModelController
-(id)init
{
self = [super init];
if (self) {
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://blah.com"]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
[NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
_promosArray = [self parseJSON:data];
}];
}
return self;
}
- (CSAPageDataViewController *)viewControllerAtIndex:(NSUInteger)index storyboard:(UIStoryboard *)storyboard
{
// Return the data view controller for the given index.
if (([self.promosArray count] == 0) || (index >= [self.promosArray count] / 2)) {
return nil;
}
// Create a new view controller and pass suitable data.
CSAPageDataViewController *dataViewController = [storyboard instantiateViewControllerWithIdentifier:#"CSAPageDataViewController"];
dataViewController.promoOne = [self.promosArray objectAtIndex:index * 2];
dataViewController.promoTwo = [self.promosArray objectAtIndex:(index * 2) + 1];
return dataViewController;
}
the data view controller
#implementation CSAPageDataViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
self.promoLabelTop.text = [self.promoOne name];
self.promoImageTop.image = [self.promoOne image];
self.promoLabelBottom.text = [self.promoTwo name];
self.promoImageBottom.image = [self.promoTwo image];
}
Your problem you're trying to solve is an asynchronous one. Your approach however is for solving a synchronous problem.
For example, your class CSAPromoModelController is inherently asynchronous. This is because it's init method invokes an asynchronous method, and thus your class gets "infected" by asynchronism.
You might consider a re-design, where class CSAPromoModelController becomes a subclass of NSOperation with a complete handler, e.g. CSAPromoModelOperation. It's eventual result is the array of images. The imageArray becomes an ivar of your CSAPromoViewController. The CSAPromoViewController will have a method for creating a CSAPromoModelController object which will be initialized with an image. The completion handler of the operation passes the array of images. Within the completion handler you basically execute the same statements as in your original viewDidLoad method in order to setup the controllers.
You would use the operation as follows:
- (void)viewDidLoad
{
[super viewDidLoad];
self.pageViewController = [[UIPageViewController alloc] initWithTransitionStyle:UIPageViewControllerTransitionStyleScroll navigationOrientation:UIPageViewControllerNavigationOrientationHorizontal options:nil];
self.pageViewController.delegate = self;
NSURLRequest *request = ...
CSAPromoModelOperation* op =
[CSAPromoModelOperation alloc] initWithRequest:request
completion:^(NSArray* result, NSError*error)
{
// assuming we are executing on the main thread!
if (error == nil) {
self.imageArray = result;
CSAPageDataViewController* startingViewController =
[self viewControllerWithImage:self.imageArray[0]
storyboard:self.storyboard];
NSArray* viewControllers = #[startingViewController];
[self.pageViewController setViewControllers:viewControllers
direction:UIPageViewControllerNavigationDirectionForward
animated:NO
completion:nil];
...
}
else {
// handle error
}
}];
[op start];
}

DismissModalView Not Working

I've been pulling my hair out a bit over this. I'm creating a very simple app, it simply downloads an rss feed and displays it in a UITableview, which is inside a UINavigationController. Whilst it's downloading the feed I'm presenting a Modal View.
In my modal view I'm displaying a UIImageView and a UIActivityIndicatorView that is set to spin. I'm using ASIHTTRequest to asynchronously grab the feed and then using the either the completion block to get the response string and stop the spinner or the failure block to get the NSError and display a alert View. This all works perfectly.
I've then created a protocol to dismiss the modal view from the tableview which is called inside the completion block. But the modal view is never dismissed! I've tried pushing it into the navigation controller but exactly the same problem occurs. I even have tried setting the modal view delegate to nil but still no luck.
I've checked it without blocks using the ASIHTTPRequest delegate methods and it's the same, and if I don't present the modal view the table view is displayed normally.
Any Ideas? I've skipped out all the tableview delegate and datasource methods as well as the dealloc and any unused functions.
#interface MainTableViewController ()
-(void)loadModalView;
#end
#implementation MainTableViewController
#synthesize tableView;
#synthesize modalView;
// Implement loadView to create a view hierarchy programmatically, without using a nib.
- (void)loadView
{
[super loadView];
tableView = [[UITableView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height) style:UITableViewStylePlain];
tableView.delegate = self;
tableView.dataSource = self;
[self.view addSubview:tableView];
[self loadModalView];
}
-(void)loadModalView
{
modalView = [[ModalViewController alloc]init];
modalView.delegate = self;
[self presentModalViewController:modalView animated:NO];
}
//Modal View Delegate
-(void)downloadComplete
{
modalView.delegate = nil;
[self dismissModalViewControllerAnimated:NO];
}
#end
#interface ModalViewController ()
- (void)loadView
{
[super loadView];
backgroundImage = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 320, 460)];
[self.view addSubview:backgroundImage];
spinner = [[UIActivityIndicatorView alloc]initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinner.frame = CGRectMake(160, 240, spinner.bounds.size.width, spinner.bounds.size.height);
spinner.hidesWhenStopped = YES;
[self.view addSubview:spinner];
[spinner startAnimating];
NSString* urlString = FEED_URL;
NSURL* url = [NSURL URLWithString:urlString];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
[spinner stopAnimating];
[delegate downloadComplete];
// Use when fetching binary data
}];
[request setFailedBlock:^{
NSError *error = [request error];
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.description delegate:self cancelButtonTitle:#"Continute" otherButtonTitles: nil];
[alert show];
[alert release];
}];
[request startAsynchronous];
}
Matt
In my understanding.. you solution is quite complicated..
wouldn't it be better if the class MainTableViewController is the
one who downloads the Feeds.. for the ModalView it will just act as an ActivityIndicator and dismiss after downloading..
so inside your MainTableViewController loadview:
- (void)loadView
{
NSString* urlString = FEED_URL;
NSURL* url = [NSURL URLWithString:urlString];
ASIHTTPRequest* request = [ASIHTTPRequest requestWithURL:url];
[request startAsynchronous];
//after starting the request show immediately the modalview
modalView = [[ModalViewController alloc]init];
[self presentModalViewController:modalView animated:NO];
[request setCompletionBlock:^{
// Use when fetching text data
NSString *responseString = [request responseString];
//then when it is complete dissmiss the modal
[modalView dismissModalViewControllerAnimated:NO];
// Use when fetching binary data
}];
[request setFailedBlock:^{
NSError *error = [request error];
UIAlertView* alert = [[UIAlertView alloc]initWithTitle:#"Error" message:error.description delegate:self cancelButtonTitle:#"Continute" otherButtonTitles: nil];
[alert show];
[alert release];
}];
}
i didnt use blocks in my projects, but i think it will work the same..
also I use a plain UIActivityIndicatorView (large) as subviews not modalViews.. sadly i cant test the code here now.. but i can check it later though
The only way I solved this error was to synchronously download the data and push and pop the download view onto the navigation stack. Not ideal but it works.

Resources