0

I'm using a prepare for segue to send a string through to the next controller. It is set as a string right up to being sent (according to NSLog), but as soon as I log it on the next controller it is an NSObject and not a string and therefore the value has become null.

Here is the first view controller the bodyText field is what I am trying to send across to the next view controller:

#import "GFAddPostTextViewController.h"
#import "GFSelectGroupViewController.h"

@interface GFAddPostTextViewController ()
@property (weak, nonatomic) IBOutlet UITextField *bodyTextField;
@end

@implementation GFAddPostTextViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    if([segue.identifier isEqualToString:@"selectGroup"]) {

        GFSelectGroupViewController *destViewController = segue.destinationViewController;

        destViewController.bodyText = self.bodyTextField.text;

        NSLog(@"%@", destViewController.bodyText);

    }

}


@end 

Here is the header file of the receiving View Controller:

#import <UIKit/UIKit.h>

@interface GFSelectGroupViewController : UITableViewController
@property (weak, nonatomic) IBOutlet NSString *bodyText;
@end

And finally the implementation file of the Receiving View Controller (The save method is where I call self.bodyText and where it is going wrong as it thinks bodytext is null):

#import "GFSelectGroupViewController.h"
#import <AFNetworking.h>
#import "GFCredentialStore.h"
#import "GFGroupResponseSerializer.h"

#define kBaseURL "http://someserver.com/"
#define kGroupURL "groups.json"
#define kPostURL "posts.json"

@interface GFSelectGroupViewController ()
@property (nonatomic, strong) NSArray *groups;
@property (strong, nonatomic) IBOutlet UITableView *tableView;
@property (weak, nonatomic) IBOutlet UIBarButtonItem *saveButton;
@end

@implementation GFSelectGroupViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    GFCredentialStore *credentialStore = [[GFCredentialStore alloc] init];

    NSString *authToken = [credentialStore authToken];
    NSLog(@"%@", authToken);

    __weak typeof(self)weakSelf = self;

    [self.saveButton setTarget:self];
    [self.saveButton setAction:@selector(save:)];

    NSString *urlString = [NSString stringWithFormat:@"%s%s", kBaseURL, kGroupURL];

    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    manager.responseSerializer = [GFGroupResponseSerializer serializer];
    [manager.requestSerializer setValue:authToken forHTTPHeaderField:@"auth_token"];
    NSLog(@"%@", manager.requestSerializer.HTTPRequestHeaders);
    [manager GET:urlString parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
        __strong typeof(weakSelf)strongSelf = weakSelf;
        strongSelf.groups = (NSArray *)responseObject;
        [strongSelf.tableView reloadData];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];
}

-(void)save:(id)sender {

    NSString * postURL = [NSString stringWithFormat:@"%s%s", kBaseURL, kPostURL];

    NSString *body = self.bodyText;
    NSLog(@"%@", body);

    NSDictionary *params = @{ @"post[body]" : body};


    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    [manager POST:postURL parameters:params success:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSLog(@"JSON: %@", responseObject);
        [self dismissViewControllerAnimated:NO completion:nil];
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

}

New to iOS so any help highly appreciated. Thanks.

jckly
  • 831
  • 1
  • 11
  • 22
  • Something seems a bit odd about you having a NSString as an IBOutlet, is that supposed to be a UILabel or something? – Kevin DiTraglia Mar 30 '14 at 19:47
  • 1
    Remove `IBOutlet` from your string, make it `copy` (instead of `weak`) and give it a go... – Alladinian Mar 30 '14 at 19:47
  • You have a `weak` `NSString` property - which means that if you assign an object to that property, and there is no other `strong` reference pointing to it, it will be deallocated - have a look at http://stackoverflow.com/questions/11013587/differences-between-strong-and-weak-in-objective-c – Rich Tolley Mar 30 '14 at 19:50

1 Answers1

1

The problem is in the property declaration. You declared the string as weak (and IBOutlet, it shouldn't be that too).

Under ARC rules, this object will be removed from memory as soon as all strong pointers are not pointing to it anymore. Because you set it in the prepareForSegue method, it is nulled before you access it. So change your property declaration to:

@interface GFSelectGroupViewController : UITableViewController
@property (strong, nonatomic) NSString *bodyText;
@end

And in prepareForSegue method, set it like this:

...
GFSelectGroupViewController *destViewController = segue.destinationViewController;

destViewController.bodyText = [self.bodyTextField.text copy];
...

Also help yourself with debugging, print out the variable in the viewDidLoad method of GFSelectGroupViewController, to see it is copied correctly.

Legoless
  • 10,942
  • 7
  • 48
  • 68
  • Not only does this work perfectly, I understand why now. Thanks a lot I've accepted and upvoted. – jckly Mar 30 '14 at 20:09