Passing data between ObjectClass and ViewController - iphone

I am trying to pass some data back to my view controller from an object class.
This is a basic over view of what classes and views are doing, and then I will show you my code.
So ViewController, loads its tableviewcells. Then inside this delegate method it calles a connection class I have created, inside that conection class is NSURLConnection methods connecting and downloading data from the database, in the connectionDidFinishLoading method of this connection class I set up a parsing class and pass all of the downloaded data over to that.
Then I parse that data, and at the end of that parser inside parserDidEndDocument, I am trying to send the data that is now in an array variable back to my view controller to display. However.. for some reason my protocols and delegates are not working.
I have set up protocols inside m parser class and set the delegates in my view controller but it never makes it to my protocol method.
I will show you my code below.
parserclass.h
#protocol PassParsedData <NSObject>
#required
- (void)sendManufactureArray:(NSArray *)array;
#end
//..
id <PassParsedData> delegate;
//..
#property (strong) id delegate;
//
parserclass.m
#import "VehicleSearchViewController.h"
//..
#synthesize delegate;
//..
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
//.. array stuff is set up and i can log it so i know its working.. i just want to show you the protocol and delegate stuff to be clear
[[self delegate]sendManufactureArray:filteredArray];
}
Then moving onto my view controller where I am hoping to call the protocol and get the filteredArray data back.
ViewController.h
#import "EngineResponses.h" //delegates & protocols
//..
#interface SearchViewController : UITableViewController <PassParsedData> {
//..
Viewcontroller.h
#import "EngineResponses.h"
//..
- (void)viewDidLoad
{
[super viewDidLoad];
//..
parserClass *pc = [[parserClass alloc] init];
[pc setDelegate:self];
//..
}
- (void)sendManufactureArray:(NSArray *)array //Breakpoint here is never accessed
{
FilterArray = array;
[self.tableView reloadData];
}
As you can see in that last method which is the protocol I am calling, its never accessed by the thread. I have checked, This call
[[self delegate]sendManufactureArray:filteredArray];
gets accessed fine.. but it just never makes it back to the View Controller.. any ideas... am I missing anything? .. im at a complete loss, been working on this all day.
any help would be HUGELY appreciated! :)
UPDATE:
I have added this to my ViewController.h
//..
ParserClass *parserclass;
//..
#property (strong, nonatomic) ParserClass *parserclass;
//..
viewcontroller.m
#synthesize parserclass;
//..
//then I call this in viewdidload
[engineResponses setDelegate:self];

As others have said in the comments, your pc variable is being deallocated at the end of the viewDidLoad block, since the only reference it has goes out of scope there. If you want it to live on, you must enlarge its scope (i.e. make it an instance variable).

Related

calling functions and passing information between views

Thanks in advance for your help!
In the main ViewController.m of my project I am adding a customized tableView like so:
messageController = [[MyMessagesController alloc] initWithStyle:UITableViewStylePlain];
[self addChildViewController:messageController];
[self.view addSubview:messageController.view];
Then, in the MyMessagesController.m section tableView didSelectRowAtIndexPath: I'd like to write code that would take effect in the ViewController.m where it was created and added as a childViewController.
How can I access the functions of the ViewController.m from MyMessagesController.m?
Can I make it a delegate somehow so I could call [delegate functionName];?
Could I pass information back to the ViewController.m? About which of the rows in table was selected by sending through an NSString or NSArray or anything?
Yes, use a delegate, if you are unsure how best to accomplish this, here is a good reference from Apple about delegate programming
Got it figured out, here's how you turn one viewController into a delegate for another:
In the .h of the parent controller -
#interface ViewController : UIViewController <NameOfDelegate> {
In the .m of the parent controller, once you create the new view -
newViewController.delegate = self;
and also:
- (void)functionToCall:(id)sender {
NSLog(#"Function Called!!!");
}
In the .h of the newViewController you're adding -
#protocol NameOfDelegate;
#interface newViewController : UIViewController/OR/TableViewController {
id <NameOfDelegate> delegate;
}
#property (nonatomic, strong) id <NameOfDelegate> delegate;
#end
#protocol NameOfDelegate
- (void)functionToCall:(id)sender;
#end
in the .m of the newViewController -
#implementation newViewController
#synthesize delegate;
and when you're ready to call the function in your delegate -
[delegate functionToCall:self];

EXD_BAD_ACCESS passing data back to delegate

I'm a relatively new iPhone developer and am making great progress building my 2nd iPhone app. In the app I'm building now I'm doing some code separation with some protocols and delegates so that I car re-use some of my code in a variety of places throughout my code.
Here's what I want to happen:
CITRootViewController creates an instance of a CITReportCreator class, passing itself as a property so that the reportCreator can open additional view controllers and such.
CITReportCreator class is declared as implementing the CITImageCaptureDelegate protocol, which is declared in the CITImageCaptureViewController file.
CITImageCaptureViewController defines the delegate protocol and has a method that passes back data and references to the child view controller so that CITReportCreator can interact with it's data, close the related XIB, etc.
I believe I'm getting the delegate and protocol established correctly, and verified that my 'delegate' object still contains data when it is called, but I'm getting a EXC_BAD_ACCESS method when my view controller tries to pass data back to the delegate in this line of code:
[self.delegate childViewControllerDidFinish:self];
Here's a good portion of the rest of my code. I had this working by using CITRootViewController as my delegate instead of the CITReportCreator class, but now that I'm separating the code, something has broke.
CITReootViewController.m (the view controller that calls the Report Creator)
//create a nrew report
-(IBAction)createReport:(id)sender {
CITReportCreator *report = [CITReportCreator alloc];
[report createNewReport:self];
}
CITReportCreator.h
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import "CITImageCaptureViewController.h"
#interface CITReportCreator : NSObject <CITImageCaptureDelegate>
#property (strong, nonatomic) NSArray *imageList;
#property (nonatomic) NSInteger imageIndex;
-(int) createNewReport:(UIViewController *)parent ;
//Delegate Methods
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
And CITReportCreator.m
#import "CITReportCreator.h"
#implementation CITReportCreator
{
UIViewController *parentController;
}
#synthesize imageList;
#synthesize imageIndex;
-(int) createNewReport:(UIViewController *)parent
{
//store a reference to the parent view controller
parentController = parent;
// init code....
//head to the first image capture view
[self startImageCapture];
return 0;
}
-(int)startImageCapture
{
//pull the image name from the array of images
NSString *imageName = [imageList objectAtIndex:imageIndex];
//prep the image capture controller
CITImageCaptureViewController *capture = [[CITImageCaptureViewController alloc] initWithNibName:#"CITImageCaptureViewController" bundle:nil];
//Assign the capture controller's delegate
capture.imageName = imageName;
capture.delegate = self;
//Display the capture controller
[parentController presentModalViewController:capture animated:YES];
return 0;
}
//a break point set here never gets hit.
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
{
[viewController dismissModalViewControllerAnimated:YES];
}
#end
And finally, the CITImageCaptureViewControllers
CITImageCaptureViewController.h
#import <UIKit/UIKit.h>
#protocol CITImageCaptureDelegate <NSObject>
-(void) childViewControllerDidFinish:(UIViewController*)viewController;
#end
#interface CITImageCaptureViewController : UIViewController
{
id<CITImageCaptureDelegate> delegate;
}
#property (nonatomic,assign) id<CITImageCaptureDelegate> delegate;
#property (nonatomic, assign) NSString *imageName;
//continue button pressed method
-(IBAction)continueButtonPressed:(id)sender;
#end
And the .m file
#import "CITImageCaptureViewController.h"
#interface CITImageCaptureViewController ()
#end
#implementation CITImageCaptureViewController
#synthesize navItem;
#synthesize imageName;
#synthesize delegate = _delegate; //i think this may be part of the problem
//cutting out initWithNibName, viewDidLoad, etc...
- (IBAction)continueButtonPressed:(id)sender
{
[self.delegate childViewControllerDidFinish:self];
}
#end
I find nothing with delegates and protocols all that simple, but I'm guessing I'm missing a small change somewhere. Can you help me head in the right direction?

Delegate Method Protocol Not Working - Objective C

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"];

Call a ViewController method from NSObject Class

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];
}

protocol method is not being called by the delegate object

Another case of protocol method not being called - NO idea what am I doing wrong here...
Here is the code, omitting unnecessary info...
first header file: AccessNumber.h
#protocol AddItemDelegate <NSObject>
#required
- (void) processSuccessful: (BOOL)success;
#end
#interface AccessNumber : UIViewController <UITableViewDelegate, UITableViewDataSource, ABPeoplePickerNavigationControllerDelegate, UIAlertViewDelegate> {
id <AddItemDelegate> delegate;
}
#property (retain) id <AddItemDelegate> delegate;
#end
first .m file: AccessNumber.m - I am calling the protocol method from viewdidload just for testing purposes, it should basically get called from another method, but same thing for the sake of this convo (tried both of course)
#import "AccessNumber.h"
#import "History.h"
#synthesize delegate;
- (void)viewDidLoad
{
[super viewDidLoad];
....
[[self delegate] processSuccessful:YES];
}
second file header: History.h
#interface History : UIViewController <UITableViewDelegate, UITableViewDataSource, AddItemDelegate> {
....
}
method implementation in history.m
- (void) processSuccessful: (BOOL)success {
NSLog(#"SUCCESS");
}
Appreciate any help. Thanks!
In the code i don't see something like:
theAccessNumber.delegate = self;
You must set the History instance as the delegate property of the AccessNumber instance.
Regards.
The code seems a little bit funny but you are not telling your "AccessNumber" class who is his delegate, even though you are making the "History" class implement the protocol established by yourself (otherwise you would get a warning).
You have to set the delegate for the "AccessNumber" class like this when setting it up from within "AccessNumber.m":
self.delegate = historyInstance;
or like this when setting it up from within "History.m":
accessNumberInstance.delegate = self;
There are very vew situations where you should retain a delegate, normally your delagate will outlive the object. So change your property from retain to assign. And be sure you are setting the delegate. Where are you doing it? If your object really depends on it you should be passing it in the constructor (iniWithDelagate). Try doing a NSLog before calling the delagate method just to see if it isn't nil.