I am very familiar with writing VB based applications but am new to Xcode (and Objective C). I have gone through numerous tutorials on the web and understand the basics and how to interact with Interface Builder etc. However, I am really struggling with some basic concepts of the C language and would be grateful for any help you can offer. Heres my problem…
I have a simple iphone app which has a view controller (FirstViewController) and a subview (SecondViewController) with associated header and class files.
In the FirstViewController.m have a function defined
#implementation FirstViewController
- (void) writeToServer:(const uint8_t *) buf {
[oStream write:buf maxLength:strlen((char*)buf)];
}
It doesn't really matter what the function is.
I want to use this function in my SecondViewController, so in SecondViewController.m I import FirstViewController.h
#import "SecondViewController.h"
#import "FirstViewController.h"
#implementation SecondViewController
-(IBAction) SetButton: (id) sender {
NSString *s = [#"Fill:" stringByAppendingString: FillLevelValue.text];
NSString *strToSend = [s stringByAppendingString: #":"];
const uint8_t *str = (uint8_t *) [strToSend cStringUsingEncoding:NSASCIIStringEncoding];
FillLevelValue.text = strToSend;
[FirstViewController writeToServer:str];
}
This last line is where my problem is.
XCode tells me that FirstViewController may not respond to writeToServer.
And when I try to run the application it crashes when this function is called.
I guess I don't fully understand how to share functions and more importantly, the relationship between classes.
In an ideal world I would create a global class to place my functions in and call them as required.
Any advice gratefully received.
In the deklaration of your method:
- (void) writeToServer:(const uint8_t *) buf;
The - at the beginning of the declaration indicates, that it is an instant method. This means, you have to create an instance of your class to call it. If there were a +, the method would be a class method and you could call it the way you do in your code.
Example:
#interface MyClass
{ }
- (void) myInstanceMethod;
+ (void) myClassMethod;
#end
Then in some function:
[MyClass myClassMethod]; // This is ok
//[MyClass myInstanceMethod]; // this doenst't work, you need an instance:
MyClass *theInstance = [[MyClass alloc] init];
[theInstance myInstanceMethod];
In the line:
[FirstViewController writeToServer:str];
...you are sending the message writeToServer: to the FirstViewController class. Instead, you need to send it to a FirstViewController object. This means that you need to obtain a reference to a FirstViewController object and then send the object the writeToServer: message:
[firstViewControllerObject writeToServer:str];
However, because there is only one view active at a time on the iPhone, you should not be having FirstViewController and SecondViewController objects existing at the same time and communicating with each other. Instead, you should create independent classes to perform the required class and the active view controller should be interacting with these classes.
Note: "You are sending the message sayHello: to the object myObject" is just another way of saying "you are calling the writeToServer: method of the object myObject. (A "method" is like the object-oriented version of a function.)
I would recommend reading the Learning Objective-C and Learn Cocoa II tutorials on Cocoa Dev Central to learn more about Cocoa/Objective-C and object-oriented programming.
In your FirstViewController.h file, you must declare writeToServer as a method of FirstViewController object in the #interface section
#interface FirstViewController : UIViewController {
}
- (void) writeToServer:(NSString *) str;
#end
Secondly, the following message you send is invalid as FirstViewController writeToServer is not a class method and is only valid if called from an instantiation of the FirstViewController class.
FirstViewController *firstViewCnt = [[FirstViewController alloc] init];
[firstViewCnt writeToServer:str];
[firstViewCnt release];
Or something like that.
You need to write:
- (void) writeToServer:(const uint8_t *) buf;
in your FirstViewController.h file. This is a hint for the compiler that the function is available for that particular class. Your code would still work without this, because the actual function is implemented, but you get the warning because the compiler doesn't check the .m file for existing functions when you include the header from another source file.
if you want to call this method like this only declare writeToServer method as class method (static method in short...)
for that you have declare and define it like
+ (void) writeToServer:(const uint8_t *) buf;
+ (void) writeToServer:(const uint8_t *) buf {
[oStream write:buf maxLength:strlen((char*)buf)];
}
only difference is + sign instead of -
sign indicate that method is class method(static)
and - sign is for instance method (non static)
Second option is creat instance of FirstViewController and call the existing method
i.e
FirstViewController FirstViewControllerObj = [[FirstViewController alloc] init];
[FirstViewControllerObj writeToServer:str];
FirstViewController.h
#interface FirstViewController: UIViewController
- (void)GetItNow;
FirstViewController.m
- (void)GetItNow{
NSLog(#"I acheived"); }
- (IBAction)goToSecondView:(id)sender {
SecondViewController* Second= [[SecondViewControlleralloc] initWithNibName:#"SecondViewController" bundle:nil];
rqVC.addId = self.addId;
[self.view addSubview:Second.view];
}
SecondViewController.h
#property (nonatomic, assign) id delegate;
SecondViewController.m
- (IBAction)Action_LoadFunds:(id)sender {
[self.view removeFromSuperview];
[_delegate GetItNow];
}
Related
I am working on a splitView application for my iPad. I have implemented a UIButton called as Upload. On clicking on it, a UITableView appears inside a UIPoverController. On clicking on any of the contents, I want to display some respective site in my UIwebView in UIDetailView. For this I have implemented a delegate method protocol. I have used the following lines of code in UploadTableViewController.h file::
#protocol UploadTableViewDelegate <NSObject>
#required
- (void)selected:(NSString *)his;
#end
#interface UploadSpaceTableViewController : UITableViewController{
id<UploadSpaceTableViewDelegate> delegate;
}
#property (retain) id delegate;
#end
In the corresponding .m file I have used the following lines of code ::
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (delegate != nil) {
NSString *hisSelected = [keys objectAtIndex:indexPath.row];
NSLog(#"%# lolwa", hisSelected);
[delegate selected:hisSelected];
}
}
in the .m file of class where I have implemented the function Selected, the code is ::
- (void)selected:(NSString *)Key {
NSLog(#"hello");
[self.UploadSpaceTableViewPopover dismissPopoverAnimated:YES];
}
-(IBAction)uploadpressed:(id)sender{
Upload.delegate = self;
self.Upload = [[UploadSpaceTableViewController alloc]
initWithStyle:UITableViewStylePlain];
self.UploadTableViewPopover = [[UIPopoverController alloc]
initWithContentViewController:UploadSpace];
[self.UploadTableViewPopover presentPopoverFromBarButtonItem:sender
permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
However, I am unable to get hello (written in the function Selected) NSLogged in gdb. This is the first time that I am using this delegate method protocol. I am unable to sort this out. Can someone help me out ? Thanks and regards.
[delegate keySelected:hisKeySelected]; is your first problem. You don't declare a delegate method named -keySelected:, you declare a delegate method named -Selected:.
Your second problem is the fact that you are most definitely not the delegate of your table view. In order for a delegate method like -didSelectRowAtIndexPath: to be called, you must be the table's delegate.
PS, don't begin instances, or method names, with an uppercase letter. In ObjC, uppercase letters indicate a class.
EDIT: this is what your UploadSpaceTableViewController header should look like:
#protocol UploadTableViewDelegate <NSObject>
#required
- (void)selected:(NSString *)his;
#end
#interface UploadSpaceTableViewController : UITableViewController<UITableViewDataSource, UITableViewDelegate>
#property (nonatomic, assign) id <UploadSpaceTableViewDelegate>delegate; //delegates are weak!!!
#end
And the .m, I will skip a lot of the unnecessary stuff:
-(void)viewDidLoad {
[self.tableView setDelegate:self];
[self.tableView setDataSource:self];
}
//other code
Furthermore, your delegate is declared retain, which is an absolutel No-No in ObjC. Declare is weak if using ARC, or assign if not.
You are also producing a nil delegate in in your -uploadPressed: method by setting it before you explicitly own or initialize the object. Here's how it should look:
self.Upload = [[UploadSpaceTableViewController alloc]initWithStyle:UITableViewStylePlain];
Upload.delegate = self;
Delegation works like this
declare a protocol - you have done this
declare a delegate property - you have done this
In the class which you want to be the delegate say it conforms to the protocoll
#interface MyClass : MySuperClass <UploadTableViewDelegate>
set the delegate property so the delegate class can get the delegate messages
uploadSpaceTVC.delegate = self;
call the delegate methods in your non delegate class (UploadSpaceTableViewController)
[self.delegate selected:#"test"];
As a new iOS developer, I have finally stumbled across delegates. I'm trying to follow a tutorial: http://gabriel-tips.blogspot.com/2011/05/input-accessory-view-how-to-add-extra.html, But I'm having difficulty understanding where I am supposed to put the actual delegate methods.
Secondly, would anyone mind providing a dumbed down explanation of how a delegate method is invoked?
Thanks!
A delegate is simply a class that agrees to do work for another class. The delegate methods are invoked by the delegating class. The delegate must therefore, provide an implementation of the appropriate method. Let's make a simple view controller with a table view.
// MyViewController.h
#interface MyViewController : UIViewController <UITableViewDelegate>
#property (nonatomic, retain) UITableView *myTableView;
#end
Here in the MyViewController.h file I have declared my view controller to be a delegate of type UITableViewDelegate (it really means it implements the UITableViewDelegate protocol. More on this later). I have thus agreed to respond to requests to my view controller. The requests will come from the table view called myTableView. However, simply stating that I adhere to UITableViewDelegate does not make my view controller a delegate of anything. I must specify that directly:
// MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
#end
Here I specifically set MyViewController to be the delegate of myTableView. Now whenever the table view wants to ask its delegate to do something, it will send that message to my view controller. Thus, MyViewController MUST provide implementations of the appropriate delegate methods:
// MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected section:%i row:%i", indexPath.section, indexPath.row);
}
#end
Here I have provided an implementation for the delegate method tableView:didSelectRowAtIndexPath: which will be called by myTableView when it is appropriate (the user selects a row).
Here you can find all the delegate methods defined in UITableViewDelegate. Some are required and others are optional:
http://developer.apple.com/library/ios/#documentation/UIKit/Reference/UITableViewDelegate_Protocol/Reference/Reference.html
In order to be a delegate of a class you should know which methods you are required to provide implementations for.
If you wanted to create your own delegate definitions, you would create a new protocol. You do not retain your delegates (see the property declaration), as this creates a retain cycle:
// MyViewController.h
#class MyViewController;
#protocol MyViewControllerDelegate
- (void)viewController:(MyViewController *)viewController didChangeSelection:(NSIndexPath *)newIndexPath;
#end
#interface MyViewController : UIViewController <UITableViewDelegate>
#property (nonatomic, retain) UITableView *myTableView;
#property (nonatomic, assign) id<MyViewControllerDelegate> delegate;
#end
Here we have created a new protocol. Any class that wants to be respond to the viewController:didChangeSelection: message could now do so. Just like with the table view above it would set the delegate to itself and then implement the method. Now that you have a delegate, you can invoke the method at an appropriate time.
// MyViewController.m
#import "MyViewController.h"
#implementation MyViewController
- (void)loadView
{
myTableView = [[UITableView alloc] initWithFrame:CGRectMake(0, 0, 320, 460)];
myTableView.delegate = self;
self.view = myTableView;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(#"Selected section:%i row:%i", indexPath.section, indexPath.row);
indexPath = [NSIndexPath indexPathForRow:1 inSection:0];
[self.delegate viewController:self didChangeSelection:indexPath];
}
#end
Now the delegate can receive the message and do what it wants knowing that my view controller changed the selection.
A delegate pattern is a convenient way to allow for the communication between independent controller that allows for loose coupling. So let's say you have a pattern like this:
A
/ \
B C
Where A instantiates B and C. Communicating between A to B and A to C are easy but how would you communicate between B and C? B to A? C to A? There are a couple different ways you could do so such as Key-Value Observing or Block Callbacks. Delegation, though, are still most frequently used although Blocks are coming on strong.
In this example, object A instantiates object B to create an object and fill it with info. How would object B pass the new object back to A as you want to keep things loose? Well, with these 9 easy steps, you can do it too! It may not make sense but we'll start with ClassB…
// ClassB.h
#protocol ClassBDelegate; //(1)
#interface ClassB : NSObject
#property (nonatomic, weak) id<ClassBDelegate>bDelegate; //(2)
-(void)makeNewObjectAndSendBack;
#end
#protocol ClassBDelegate : NSObject //(3)
-(void) classB:(Class B *)theClassB finishedWithObject:(id)finishedObject; //(4)
#end
ClassB.m
#implementation
#synthesize bDelegate = _bDelegate; //(5)
-(void)makeNewObjectAndSendBack {
//something something something
[self.bDelegate classB:self finishedWithObject:newObject]; //(6)
}
#end
define the protocol that will be established later
set an instance of an object that will conform to that protocol
set up the protocol
set up the method call that you'll use to send the finishedObject back to A.
synthesize the delegate
after you do what you need to do, you send it back using the method
you defined in 4
// ClassA.h
#interface ClassA : NSObject <ClassBDelegate> //(7)
#property (nonatomic, strong) ClassB theClassB;
-(void)yourMethodToDoSomething;
#end
ClassA.m
#implementation
#synthesize theClassB = _theClassB;
-(void)randomMethod {
self.theClassB = [ClassB new];
self.theClassB.bDelegate = self; //(8)
[self.theClassB makeNewObjectAndSendBack];
}
-(void) classB:(Class B *)theClassB finishedWithObject:(id)finishedObject { //(9)
[self doSomethingWithFinishedObject:finishedObject]; //ta-da!
}
#end
7.Conform to the ClassBDelegate protocol. This basically says that you
will implement the methods defined in the protocol definition.
8.Set the classB object's delegate object as self! This is crucial and
often skipped.
9.Implement the delegate method for when you get the new object back.
So the process, in short is: A instanciate B. A sets B's delegate as self. A tells B to do something. B does something and sends object back via delegate method. A gets it back.
For more information, including what you can do with protocols, check out:
Big Nerd Ranch talk about Protocols
Part 1
Part 2
Part 3
Good luck!
It seems you might be a little confused as to what delegates are and how they are used. Here are two links to Apple documentation you might find useful: A conceptual overview and a more in depth explaination.
I have been working on this problem for close to 4 days now.
I am at the point where I think its not so much a problem with my code, but the structure of my application that is causing the issue.
I am trying to implement protocols and delegates to get an array from one NSObject(class) to a ViewController.
my code is pretty much line by line copied from this tutorial the only differences are in the face I have ARC turned on so have had to replace (nonatomic, retain) to (strong) and have not used dealloc :)
so with that being said its still not passing the data back to the viewcontroller. (highly annoying) I have tried dozens of different combinations of solutions that I have had help with and nothing has worked. This has lead me to believe that maybe there is an error in the structure of my application or the way things have been initialized etc, which I will attempt to explain now.
When my viewcontroller with tableview loads the viewdidload method called the delegate of my parser class, then once the first cell of the tableview has loaded it called my connection class and tells it to download some data from the server.
Inside my connection class I use NSURLConnection delegates from the apple library, in the delegate method connectionDidFinishLoading the data that has been downloaded is passed over to my parser class (however this is where i think its going wrong because i declare the object again.. which i think is where things are going amiss)
this is how I call my parser class from my connection class.
parserClass *myparser = [[EngineResponses alloc] init];
[myparser ReciveResponse:receivedData];
then once the data is in my parser class it gets parsed and then I try to pass the data across to my viewcontroller.. but its never accessing that delegate method that I set up.
Hopefully this is where the problem is because I just dont know where else I am going wrong.
what do you think?
UPDATE: heres my code -
ViewController.h
#import "EngineResponses.h" //delegates & protocols
interface SearchViewController : UITableViewController <PassParsedData> {
//delegates to parser class
EngineResponses *engineResponses;
//..
ViewController.m
#import "EngineResponses.h"
//this is where I set up the delegate/protocol for the parser class
- (void)viewDidLoad
{
[super viewDidLoad];
//..
engineResponses = [[EngineResponses alloc] init];
[engineResponses setMydelegate:self];
//..
}
//this is where i set up and call the connection class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//..
if(indexPath.section == 0){
//..
if (indexPath.row == 0){
EngineRequests *engineRequests = [[EngineRequests alloc] init];
[engineRequests initalizePacketVariables:0 startCode:#"myReg" activationCode:#"myAct" methodName:#"GetStuff"];
//..
}
#pragma - Reciver methods
- (void)sendArray:(NSArray *)array
{
ICMfgFilterArray = array;
[self.tableView reloadData];
}
EngineRequests.m
//connection delegates etc..
//then I pass the data from the connection delegates over to the parser class
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
EngineResponses *engineResponses = [[EngineResponses alloc] init];
[engineResponses ReciveResponse:receivedData];
}
EngineResponses.h
#protocol PassParsedData
- (void)sendArray:(NSArray *)array;
#end
//..
id <PassParsedData> mydelegate;
//..
#property (strong) id <PassParsedData> mydelegate;
EngineResponses.m
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
[[self mydelegate]sendArray:filteredArray];
}
1
Allright. I will re-do it based on your updated code. To make it easy I copy your code and do the amendments.
ViewController.h
#import "EngineResponses.h" //delegates & protocols
interface SearchViewController : UITableViewController <PassParsedData> {
//delegates to parser class
EngineResponses *engineResponses;
EngineRequests *engineRequests;
//..
Explanation:
You are using ARC. If you define the pointer locally, as you did before, and to not
retain it - which you can't because of ARC - then it will be released directly after its
creation. You will have to keep at least one reference to the object.
Bare in mind that ARC means Automatic Reference Counting. As soon as there is no
reference to an object it will be released.
This proposal with the engineRequests object defined here only works while you
submit only one request at a time. If you have several requests, i.e. for more than one cell or
whatver, then you may go for a mutable array or mutable dictionary where you keep the requests while you use them.
ViewController.m
#import "EngineResponses.h"
//this is where I set up the delegate/protocol for the parser class
- (void)viewDidLoad
{
[super viewDidLoad];
//..
engineResponses = [[EngineResponses alloc] init];
[engineResponses setMydelegate:self];
engineRequests = [[EngineRequests alloc] init]; // Use instance variable instead of local variable
[engineRequests setEnineResponses:engineResponses];
//..
}
//this is where i set up and call the connection class
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//..
if(indexPath.section == 0){
//..
if (indexPath.row == 0){
[engineRequests initalizePacketVariables:0 startCode:#"myReg" activationCode:#"myAct" methodName:#"GetStuff"];
//..
}
#pragma - Reciver methods
- (void)sendArray:(NSArray *)array
{
ICMfgFilterArray = array;
[self.tableView reloadData];
}
Explanation: The engineRequets is now an instance varaible and should not be re-defined locally.
You could define a variable of the same name locally which would hide the instance variable. I think
in that case you get a compiler warning but that will work and will most probably confuse you.
Again, if you use more than one request at a time then this solution will not work!
EngineRequests.h
EngineResponses *engineResponses;
EngineRequests.m
#synthesize engineResponses;
//connection delegates etc..
//then I pass the data from the connection delegates over to the parser class
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//EngineResponses *engineResponses = [[EngineResponses alloc] init]; //This Object has already been created!
[engineResponses ReciveResponse:receivedData];
}
Explanation: Here, too, the reference to EngineResponses is now an instance variable, not a locally defined one. The object will not be newly created but it references to that very object that was created in the view controller. That is the one EngineResponses that 'knows' its view controller object and can therefore pass back the parsed data.
EngineResponses.h
#protocol PassParsedData
- (void)sendArray:(NSArray *)array;
#end
//..
id <PassParsedData> mydelegate;
//..
#property (strong) id <PassParsedData> mydelegate;
EngineResponses.m
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//..
[[self mydelegate]sendArray:filteredArray];
}
... give it a try :)
Always check for nil objects. Sending a message to a nil object will do nothing and your app will continue. I bet this is the problem since you are locally allocing all over the place. Why dont you make the receivedata method a static method instead since it looks like you dont need these classes for more than a few moments for some calculations and parsing. Then nil objects wont be a factor.
I am trying to call a method thats in my ViewController from a NSObject Class thats doing some parsing.
I initally call a connection class I have made wich downloads some data from my server, I then pass this data over to a parser class I have made, now what I am trying to do is pass this data back to the viewcontroller and reload the tableview thats in this view (thats on a navigation stack)
anyway this is causing some errors and I think it might be the way I am trying to call this method thats doing it. here is how I call it.
MyViewController *myViewController = [[MyViewController alloc] init];
[myViewController initFilterArray:filteredArray];
Now I think this is causing an issue because I am allocating a new viewcontroller object? is that right.. not to sure of the terminoligy.. but yea..
the result of which is that reloaddata is only calling
numberOfSectionsInTableView
tableView:numberOfRowsInSection
then thats it.
any help would be appreciated.
UPDATE:
so I am trying to set up a protocol/delegate to see if that fixes my problem.
so in my class.h this is what I am doing
#protocol PassParsedData <NSObject>
#required
- (void) sendMyArray:(NSArray *)modelArray;
#end
//..
id <PassParsedData> delegate;
//..
#property (strong) id delegate;
then in class.m
//..method
[[self delegate]sendMyArray:filteredArray];
//..
so thats my class, then over in my view controller where I want to call this sendMyArray I do this
viewcontroller.h
#import "class.h" //delegates & protocols
//..
interface VehicleSearchViewController : UITableViewController <PassParsedData> {
//..
then i call it like this
viewcontroller.m
//..
- (void)sendArray:(NSArray *)array
{
ICMfgFilterArray = array;
[self.tableView reloadData];
}
One way of doing this would be the recommended approach of delegates and protocols.
Your NSObject declares a protocol. The ViewController actually implements the protocol and sets itself as the delegate. Then the NSObject calls the method (not knowing who implements it). It is a loosely-coupled way to communicate between objects.
I actually recently wrote a blog post on a basic introduction to protocols and delegates if you're interested...
UPDATE
Based on your update above in question.
Don't forget to set your ViewController to be the delegate.
- (void)viewDidLoad {
// State that you will take care of messages from graphView (provided you have the protocol implementation!)
self.yourClass.delegate = self;
}
And the method in your ViewController should match the protocol signature. So in ViewController.m
- (void) sendMyArray:(NSArray *)modelArray {
ICMfgFilterArray = array;
[self.tableView reloadData];
}
I'm trying to pass a string through two views on an iPhone app. On my second view that I want to recover the string in the .h i have:
#import <UIKit/UIKit.h>
#import "MBProgressHUD.h"
#import "RootViewController.h"
#interface PromotionViewController : UITableViewController {
NSString *currentCat;
}
#property (nonatomic, retain) NSString *currentCat;
#end
And in the .m i have:
#synthesize currentCat;
However, in the first view controller when I try and set that variable I get a not found error:
PromotionViewController *loadXML = [[PromotionViewController alloc] initWithNibName:#"PromotionViewController" bundle:nil];
[self.navigationController pushViewController:loadXML animated:YES];
[PromotionViewController currentCat: #"Test"];
That third line gives me a: Class method +currentCat not found
What am i doing wrong?
Tom,
The issue in your code appears that you are trying to set the string using a static method call to the class. This would work if you implemented a static method named currentCat:
I don't think this is what your want.
See below on how to correct your issue.
[PromotionViewController currentCat:#"Test"];
//This will not work as it is calling the class itself not an instance of it.
[loadXml setCurrentCat:#"Test"];
//This will work. Keep in mind if you are going to call the objective-c
//synthesize setting directly you will need to capitalize the first letter
//of your instance variable name and add "set" to the front as I've done.
//Alternatively in objective-c 2.0 you can also use
//the setter method with the . notation
loadXml.currentCat = #"Test";
//This will work too
You need to get the string like this, as it's a property and not a method:
NSString* myString = controller.currentCat; // where controller is an instance of PromotionViewController
You need to do:
loadXML.currentCat = #"Test";
PromotionViewController *loadXML = [[PromotionViewController alloc] initWithNibName:#"PromotionViewController" bundle:nil];
[loadXML setCurrentCat: #"Test"];
[self.navigationController pushViewController:loadXML animated:YES];
That should do it.