can't able to handle UIActions from subclasses - iphone

I am creating a class for soap webservice to get some information from .net webserver.
for that i am using NSMutableURLRequest and parse the result using NSXmlParser.
Now i am calling that web services class from myviewcontroller.m class like this.
mywebserviceClass *obj=[[mywebserviceClass alloc] init];
[obj mymethod];
i am adding result to an array to use that array details in myviewcontroller.m class.
but i did n't get details into array while i am using that array immediately after this method.
i am trying like this by calling another method after 2 sec to use that array like this.
[self performSelector:#selector(myanotherMethod) withObject:nil afterDelay:2];
i know the reason why it is, it takes time to parse.
I am trying another way like i am creating object for viewcontroller and call this method like this.
myviewcontroller *obj=[[myviewcontroller alloc] init];
[obj myanothermethod];
NOw i can able to get details but i can't able to handle UIActivities like raising alerts.
While as told in the above performSelector method i can able to handle all UIActivities.
But i need to call that method after completion of parsing of result.
Can any one please help me.
Thank you.

Call your web service in viewDidLoad/ViewWillAppear methods of UIViewController. Collect your data and then call Parse method like- [self performSelectorOnMainThread:#selector(methodName) waitUntilDone:YES]; Below that use your array to display view or if you are displaying in table view then just call [mytblviewobj reloadData];

Related

Moving NSURLConnection methods to reusable class

I am using NSURLConnection to download some JSON from a webservice, and then display in a UITableView. I have all the code working well in the view class, but I wondered if I could have the NSURLConnection methods available to other classes?
For example, something like the following:
NSURLConnectionClass *connection = [[NSURLConnectionClass alloc] init];
NSArray *myDataArray = [connection withURL: [NSURL URLWithString: #"http://www.example.com"]];
// Reload table with new data
I realise this wont work as NSURLConnection is asynchronous, but wondered if there was something else I could try. I'm basically trying to avoid repeating code in every view that downloads data.
You can create a delegate protocol for your custom connection class. This way it can download async and still and call back when done. Even better would be to use blocks for callbacks. This pattern is used in the popular ASIHttpRequest class.
You can even make this class the delegate and data source for the table view. This way you only have to call [tableview reloadData] when done loading. Downside is that this mixes up the MVC pattern a bit.

iphone - How to send a message from one object to another?

I'm kind of a newbie to objective programming, so sorry for the dumb question.
I'm doing some kind of a messenger for some social network, and i'm stuck at the very simple thing - how to send a message from the object of one class to the object of the another class?
I have a class, called SignInViewController, which creates an instance of SignUpViewController after a SignUpButton is pressed and it's done just like that:
SignUpViewController *signUpViewController = [[SignUpViewController alloc]init];
signUpViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:signUpViewController animated:YES];
Then, after some management done with the AFNetwork (i use a specific class for this, called ServerManager), i want to send the message to draw a new textfield in my SignUpViewController instance, and i think it could be done like that:
in the SignUpViewController.h:
- (void)showTheCodeTextField;
in the ServerManager.m:
[[SignUpViewController self] showTheCodeTextField];
and then in SignUpViewController.m:
-(void)showTheCodeTextField
{
NSLog(#"Time to draw codeTextField");
}
I am getting a familiar SIGABRT at the latter line of code. I know I am doing something wrong, but I just can't figure out what exactly.
Could you help me out please?
You can use NSNotificationCenter to make that work.
After presenting your SignUpController you add it as an observer of notifications that ServerManager sends.And when that notification comes, you call your message to draw the view.
So, after
SignUpViewController *signUpViewController = [[SignUpViewController alloc]init];
signUpViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentModalViewController:signUpViewController animated:YES];
Make an observer
[[NSNotificationCenter defaultCenter]signUpViewController selector:#selector(showTheCodeTextField:) name:#"SignUpSucceded" object:[ServerManager sharedInstance]];
Than, in your Server Manager, you send a notification, containig that textField, and the method in your SignUp gets called.That's it.You've got the textField text in your notification.userinfo
[[NSNotificationCenter defaultCenter]postNotificationName:#"SignUpSucceded" object:self userInfo:[NSDictionary dictionaryWithObject:textField.text forKey:#"login"]];
}
Getting tour Text here in signUpView
-(void)showTheCodeTextField:(NSNotification*)notification
{
NSLog(#"Time to draw codeTextField %#",[notification userInfo]);
}
it is better if you use delegate on button event declare your delegate where you create your button and just use that delegate in any class where ever you want just use that delegate it is very helpful learn delegate for objective c its easy and efficient
Your ServerManager class needs to have a reference to the SignUpViewController instance. Right now you are getting the self of the class not of the class instance. You should probably have a property on your ServerManager class which references the instance of your SignUpViewController.
Looks like you're trying to send a message to a class (SignUpViewController) instead to it's instance/the object (signUpViewController):
Change
[[SignUpViewController self] showTheCodeTextField];
to
[[signUpViewController self] showTheCodeTextField];
and you should be o.k.
If you have an instance of SignUpViewController in your ServerManager instance, you'd use this convention (assuming your instance is named 'signUpController'):
[[self signUpController] showTheCodeTextField];
Another possibility would be to send your ServerManager a notification containing a reference to your SignUpViewController, and passing the showTheCodeTextField message to that. This assumes you have knowledge of how to send a notification.
Good luck to you in your endeavors. You look like you're just getting started in Cocoa and Objective-C. Hang in there!

Update Issue with my viewController?

I just give u example of my problem:-
I have implemented this method:
-(void)viewWillAppear:(BOOL)animated {
NSLog(#"update");}
inside my viewController, but it's called anytime, how I can call it manually?
Thanks in advance...
[self viewWillAppear:YES]; if you are in the object already.
It wouldn't be right to call that method directly as you are bound to do [super viewWillAppear:animated]; within it. This method is to do all the necessary set up just before the view will appear. You don't know what kind of setup the superclass does. So it is better to package the part of code that you want to reuse into a different method and call it from both the viewWillAppear: method and the other method that you want to call it from.

Adding object to NSMutableArray in another xib

Im trying to add an object to a NSMutableArray in another xib. But seems isnt working. What im doing wrong?
Thanks!
-(void) buy {
CartViewController *carrinho = [[CartViewController alloc] initWithNibName:#"CartViewController" bundle:[NSBundle mainBundle]];
carrinho.produtoCodigo = [[NSMutableArray alloc]init];
[carrinho.produtoCodigo addObject:#"aa"];
[carrinho release];
NSLog(#"did");
}
Your code looks fine so far. Make sure the connections in InterfaceBuilder and the File's owner in the XIB is set correctly.
Ok, several things. First you don't need to pass in [NSBundle mainBundle]. nil works fine if you want the main bundle. Second issue is, produtoCodigo should be a property set to retain and as such you should pass in an autoreleased NSMutableArray i.e. [NSMutableArray array].
Thirdly, I would question why you would want to do this. It seems like a bad design. Ideally the mutable array should be an internal ivar in CartViewController. You should then have a method on CartViewController to handle the item. You should not care about how it is stored internally, only that you want to add an object to the controller.
If you want to pass in multiple objects you should have a method that takes an array of objects and pass that in.
Now finally, nibs don't really hold arrays, the class does. As such it shouldn't be an issue with your nib. The issue should therefore be with the class. Where are you checking whether the array is being updated and finding that it isn't?
you declare and create carrinho as a view controller, which should allocate and init the carrinho.produtoCodigo as well, if you have it synthesized. Then you alloc it again, which may be a memory leak. After adding the aa, you release it. Therefore, overall, you haven't accomplished anything. That mutable array comes into being, is modified, and then destroyed.
You mention "another xib" and from the name CartController and method name "buy" it sounds like you want to update a shopping cart that is being held by some other class. Therefore, the view or class with the cart (and mutable array) needs to be modified. It's like if you and a friend go shopping, and you delegate the job of managing the cart to him. He is the delegate, and only he can put stuff in the cart. Just because you want to buy something, you have to give it to him first so that he can put it in the cart. Right now, your code is like you grab something off the rack, but then put it back on the rack. It never makes it into the cart.
What you want to do is create a shopping protocol with a message addToCart which is what this code would instead do. It would send the message to the delegate to add the item to the cart. The other xib code has a method -(void)addToCart:(id)item; which is what is invoked when this code chunk does to call to the delegate. Look up protocols and delegates; they are simple to create, and the only way to get multiple controllers talking to one another.
Maybe you inserted this below code in the second XIB:
-(void) viewDidLoad {
produtoCodigo = [[NSMutableArray alloc] init];
}
because if you make allocate an array again, the previous objects in it will be removed.

Call back a function in the original class

I found some useful information on the web but I still can't manage to do it by myself ;)
Ok, let me put my problem in context for you :
I have a first class (myViewController) whose declaration is below :
// i just give you relevant information
RssParser *rssParser;
UIActivityIndicator *activityIndicator;
In my viewDidLoad method (myViewController) I have :
//once again, I summarize it for you
[activityIndicator startAnimating];
[rssParser parse];
Now, suppose you are in the parserDidEndDocument method (which is in RssParser class), how am I suppose to stop the animation of the activityIndicator ? How can I get access to my instance of activity Indicator from the RssParser class ?
Hope I made myself clear ;)
Thanks guys!
Gauthier
A common way to do this is to use a delegate. Check the RssParser class for the use of a delegate or implement one yourself. Set the delegate of rssParser to self in MyViewController. Now you can implement the method that is called after the document is parse with MyViewController. If you create an ivar for activityIndicator then you can easily access activityIndicator again.