0
votes

So, I'm following this answer in trying to pass data between two classes in an iOS project without storyboards. I'm trying to abstract all my server calls in a different class, so the ViewControllers don't get too cramped. I have an OfferRequest class, which handles the server requests and declares the protocol:

@protocol OfferRequestDelegate <NSObject>

-(void)addOfferRequest: (OfferRequest *)request dataFromRequest: (NSMutableArray *)data;

@end

@interface OfferRequest : NSObject <LocationManagerDelegate, NSURLConnectionDataDelegate>

@property (nonatomic, weak) id <OfferRequestDelegate> delegate;
@end

The idea is to call addOfferRequest: dataFromRequest in connectionDidFinishLoading, set the data as the result from the request and pass it on to the ViewController.

In OfferRequest.m:

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

    NSMutableArray *result = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:nil];
    [self.delegate addOfferRequest:self dataFromRequest:result];

}

I declare my ViewController as a delegate for the OfferRequest:

@interface CategorySuggestionViewController : UIViewController <OfferRequestDelegate>

Initialize the OfferRequest object and set it's delegate:

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.

    offer = [OfferRequest new];
    offer.delegate = self;
}

And then implement the delegate method:

-(void)addOfferRequest:(OfferRequest *)request dataFromRequest:(NSMutableArray *)data {
    NSLog(@"received data = %@", data);
}

But it never gets called. What am I missing ?

3
Does your connectionDidFinishLoading method get called? - Rukshan
Could you paste the code with the the creation of connection and the request for that connection? -Off topic- Maybe you should consider using blocks. - Adi Pop
Did you check inside connectionDidFinishLoading if delegate is not nil ? - Adi Pop
@smeshko Are you allocating offer in any other place apart from viewDidLoad? - thavasidurai
initiliaze your offer =[[OfferRequest alloc]init]; instead of offer = [OfferRequest new] - karthikeyan

3 Answers

0
votes

try this...

your OfferRequest class like below i have given name it as connectionClass

connectionClass.h

@protocol connectionDelegate <NSObject>
-(void)connectionSucceed:(NSData *)data;
-(void)connectionFailed:(NSError *)error;
@end

#import <Foundation/Foundation.h>

@interface connectionClass : NSObject
{
    id<connectionDelegate> delegate;
    NSMutableData *receivedData;
    NSString *encodedString;
    NSMutableURLRequest *theRequest;
    NSURL *url;
    NSString *length;
    NSURLConnection *Connect;

}
@property(nonatomic, retain) id<connectionDelegate> delegate;
@property(nonatomic, retain) NSMutableData *receivedData;
- (void)connectionWithURL:(NSString *)URL;
@end

connectionClass.m

#import "connectionClass.h"

@implementation connectionClass
@synthesize delegate, receivedData;
- (void)connectionWithURL:(NSString *)URL
{
    url=[[NSURL alloc] initWithString:[self urlencode:URL]];
    theRequest= [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:60];
    [theRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    length = [NSString stringWithFormat:@"%lu", (unsigned long)[URL length]];
    [theRequest setValue:length forHTTPHeaderField:@"Content-Length"];
    [theRequest setHTTPMethod:@"POST"];

    [theRequest setHTTPBody:[URL dataUsingEncoding:NSUTF8StringEncoding]];

    Connect = [NSURLConnection connectionWithRequest:theRequest delegate:self];

    if (Connect)
    {
        self.receivedData = [NSMutableData data];
    }
    else
    {
        NSError *error;
        [self.delegate connectionFailed:error];
    }
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    [self.receivedData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [self.receivedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [self.delegate connectionSucceed:self.receivedData];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    [self.delegate connectionFailed:error];
}
-(NSString *) urlencode: (NSString *) string
{
    encodedString = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL, (CFStringRef)string, NULL, (CFStringRef)@"", kCFStringEncodingUTF16));
    return encodedString;
}


@end

don't forget to import your connectionclass and delegate

@interface yourclass : UIViewController<connectionDelegate>

Initialize the OfferRequest object and set it's delegate:

-(void)viewWillAppear:(BOOL)animated
{
    connection = [[connectionClass alloc]init];
    connection.delegate = self;
     [connection connectionWithURL:[NSString stringWithFormat:@"pass your url here"]];
}

The delegate method will have your values

-(void)connectionSucceed:(NSData *)data
{
    NSError *error;
    self.dictionary = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:&error];
    //nslog your data
}

//Connection failure
-(void)connectionFailed:(NSError *)error
{
  //handle error message
}
0
votes

Ok, I don't know where the problem exactly was, but what I did to fix it, was to create a new init method, where I pass the delegate:

-(instancetype)initWithDelegate: (id<OfferRequestDelegate>) delegate {
    self = [super init];

    if (self) {
        self.delegate = delegate;
    }

    return self;
}

So I initialize the OfferRequest object in the VC and pass self and now it works.

-2
votes

I guess delegate should be a pointer object and not the object.

It may be help you

@property (nonatomic, weak) NSObject <OfferRequestDelegate> *delegate;

and make should your delegate is been set, i.e. make sure your code below is getting called.

 [self.delegate addOfferRequest:self dataFromRequest:result];