2

I'm looking to pass a user chosen value from one view to the next so it can be submitted to Twitter, Facebook, etc.

Would a global variable be best to implement? I don't want the value to be stored or saved anywhere.. just to make it through the end of the navigation controller (submission to Facebook, Twitter, etc.)

Any suggestions? Thanks in advance.

Header File

#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#import "ShareViewController.h"
#include "TwitterRushViewController.h"

@interface KindViewController : UIViewController <UIPickerViewDelegate, UIScrollViewDelegate, CLLocationManagerDelegate> {
            IBOutlet UIScrollView *scrollView;
            IBOutlet UIPageControl *pageControl;
            BOOL pageControlIsChangingPage;

            CLLocationManager *locationManager;
            NSString *finalCoordinates;
            NSString *finalChoice;
            }

@property (nonatomic, retain) UIView *scrollView;
@property (nonatomic, retain) UIPageControl *pageControl;

@property (nonatomic, retain) CLLocationManager *locationManager; 
@property (retain) NSString *finalCoordinates;
@property (nonatomic, copy) NSString *finalChoice;


-(IBAction)changePage:(id)sender;
-(IBAction)submitChoice:(id)sender;
-(void)setupPage;

@end

Implementation File

#import "KindViewController.h"
#import "JSON/JSON.h"

@implementation KindViewController
@synthesize scrollView;
@synthesize pageControl;
@synthesize locationManager;
@synthesize finalCoordinates;
@synthesize finalChoice;

#pragma mark -
#pragma mark UIView boilerplate
- (void)viewDidLoad {   
    [self setupPage];   
    [super viewDidLoad];

    // Alert the User on Location Access
    self.locationManager = [[[CLLocationManager alloc] init] autorelease];
    self.locationManager.delegate = self;
    [locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
    }

-(void)viewWillAppear:(BOOL)animated {
    [locationManager startUpdatingLocation];    
    }

- (void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation {
    CLLocation *location = newLocation;
    NSLog(@"Our current Latitude is %f", location.coordinate.latitude);
    NSLog(@"Our current Longitude is %f", location.coordinate.longitude);
    NSString *Coordinates = [[NSString alloc] initWithFormat: @"Longitude=%f&Latitude=%f", location.coordinate.longitude, location.coordinate.latitude ];
    NSLog(@"Test: %@", Coordinates);
    finalCoordinates = Coordinates;
    [locationManager stopUpdatingLocation]; 
    }

#pragma mark -
#pragma mark The Guts
- (void)setupPage {
    scrollView.delegate = self;
    [scrollView setCanCancelContentTouches:NO];
    scrollView.indicatorStyle = UIScrollViewIndicatorStyleWhite;
    scrollView.clipsToBounds = YES;
    scrollView.scrollEnabled = YES;
    scrollView.pagingEnabled = YES;

    NSUInteger nimages = 0;
    CGFloat cx = 0;
    for (; ; nimages++) {
        NSString *imageName = [NSString stringWithFormat:@"choice%d.png", (nimages + 1)];
        UIImage *image = [UIImage imageNamed:imageName];
        if (image == nil) {
            break;
        }
        UIImageView *imageView = [[UIImageView alloc] initWithImage:image];

        CGRect rect = imageView.frame;
        rect.size.height = image.size.height;
        rect.size.width = image.size.width;
        rect.origin.x = ((scrollView.frame.size.width - image.size.width) / 2) + cx;
        rect.origin.y = ((scrollView.frame.size.height - image.size.height) / 2);

        imageView.frame = rect;

        [scrollView addSubview:imageView];
        [imageView release];

        cx += scrollView.frame.size.width;
    }
    self.pageControl.numberOfPages = nimages;
    [scrollView setContentSize:CGSizeMake(cx, [scrollView bounds].size.height)];
    }


#pragma mark -
#pragma mark UIScrollViewDelegate stuff
- (void)scrollViewDidScroll:(UIScrollView *)_scrollView {
    if (pageControlIsChangingPage) {
        return;
    }
    CGFloat pageWidth = _scrollView.frame.size.width;
    int page = floor((_scrollView.contentOffset.x - pageWidth / 2) / pageWidth) + 1;
    pageControl.currentPage = page;
    }

- (void)scrollViewDidEndDecelerating:(UIScrollView *)_scrollView {
    pageControlIsChangingPage = NO;
    }


#pragma mark -
#pragma mark PageControl stuff
- (IBAction)changePage:(id)sender {
    CGRect frame = scrollView.frame;
    frame.origin.x = frame.size.width * pageControl.currentPage;
    frame.origin.y = 0;
    [scrollView scrollRectToVisible:frame animated:YES];
    pageControlIsChangingPage = YES;
    }


-(IBAction)submitChoice:(id)sender; {

    // Spinner
    UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc]initWithFrame:CGRectMake(135,140,50,50)];
    [spinner startAnimating];
    [self.view addSubview:spinner];

    // Find the Date
    NSDateFormatter *format = [[NSDateFormatter alloc] init];
    [format setDateFormat:@"MMM dd, yyyy HH:mm"];

    NSDate *now = [[NSDate alloc] init];
    NSString *dateString = [format stringFromDate:now];

    // Echo Everything
    NSLog(@"Type is %f.", scrollView.contentOffset.x);
    NSLog(@"Date is %@", dateString);
    NSLog(@"Coordinates are %@", finalCoordinates);

    NSString *completeURL = [[NSString alloc] initWithFormat: @"http://www.example.com/insert.php?Type=%f&Time=%@&%@", scrollView.contentOffset.x, dateString, finalCoordinates];
    NSString *escapedUrl = [completeURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];

    NSLog(@"URL is %@.", escapedUrl);

    // Post to Web Server
    NSURL *urlToSend = [[NSURL alloc] initWithString:escapedUrl];
    NSLog(@"NSURL is %@.", urlToSend);

    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:urlToSend cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];

    NSData *urlData;
    NSURLResponse *response;
    NSError *error;
    urlData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];

    // Do the Button Action
    ShareViewController *shareViewController = [[ShareViewController alloc] initWithNibName:@"ShareViewController" bundle:nil];
    shareViewController.finalChoice = @"Facebook Property";
    [self.navigationController pushViewController:shareViewController animated:YES];
    [shareViewController release];

    [urlToSend release];
    [completeURL release];
    [spinner release];
    }

- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error {
    NSLog(@"There is an error updating the location");
    }

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

- (void)viewDidUnload {
    [super viewDidUnload];
    [pageControl release];
    }

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

@end

ShareViewController.h

#import <UIKit/UIKit.h>
#import "MapViewController.h"
#import "SA_OAuthTwitterController.h" 
#import "FBConnect/FBConnect.h"
#import "TwitterRushViewController.h"
#import "oAuth2TestViewController.h"

@class SA_OAuthTwitterEngine;

@interface ShareViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate> {
    }

@property (nonatomic, retain) IBOutlet UIButton *shareFacebookBTN;
@property (nonatomic, retain) IBOutlet UIButton *shareTwitterBTN;
@property (nonatomic, retain) KindViewController finalChoice;


/* Submissions */
- (IBAction)shareNoThanks:(id)sender;
- (IBAction)shareFacebook:(id)sender;
- (IBAction)shareTwitter:(id)sender;

@end
Adam Storr
  • 1,438
  • 2
  • 21
  • 46

3 Answers3

2

Just setting a property on the next UIViewController when you push it would probably be the easiest thing to do.

SomeViewController *someViewController = [[SomeViewController alloc] init];
someViewController.facebookProperty = @"Facebook Property";
someViewController.twitterProperty = @"Twitter Property";
[self.navigationController pushViewController:someViewController animated:YES];
[someViewController release];

Ok there are a few things wrong with ShareViewController.h. First if you have a property you also need to have an instance variable for that property. Next you are assigning a string to finalChoice but you have declared its type as KindViewController it should be NSString.

In ShareViewController.h

@interface ShareViewController : UIViewController <UITextFieldDelegate, SA_OAuthTwitterControllerDelegate> {
    NSString *finalChoice;
}

@property (nonatomic, retain) IBOutlet UIButton *shareFacebookBTN;
@property (nonatomic, retain) IBOutlet UIButton *shareTwitterBTN;
@property (nonatomic, copy) NSString *finalChoice;

And make sure you @synthesize finalChoice in your implementation file.

Aaron Vernon
  • 268
  • 2
  • 10
  • Thanks Aaron! How do I call this in the next view? Do I use a @synthesize? – Adam Storr Jan 09 '11 at 23:00
  • Yeah they should be defined as properties in SomeViewController e.g. have an instance variable called NSString *facebookProperty and a property @property (nonatomic, copy) NSString *facebookProperty. You should then synthesize it in the implementation file. – Aaron Vernon Jan 09 '11 at 23:03
  • Hi Aaron... thanks! That's exactly what I have in my file.. but I'm getting the following error "Request for member "facebookProperty" in something not a structure or union." I edited my answer to include my code. – Adam Storr Jan 09 '11 at 23:28
  • Hmm I am not sure, something strange is going on there. I would suggest simplifying what you have and seeing if you can get it to work. If you still have no luck then maybe post more code. – Aaron Vernon Jan 10 '11 at 00:38
  • I'm still trying to figure it out... but I've updated my answer to include my entire implementation file. – Adam Storr Jan 10 '11 at 02:32
  • Would you be able to post the header file for ShareViewController? – Aaron Vernon Jan 10 '11 at 02:56
  • Sorry I wanted to see the header file for ShareViewController just to see how the property is getting defined etc – Aaron Vernon Jan 10 '11 at 03:27
  • I think that's my problem. I attached the Header file above. – Adam Storr Jan 10 '11 at 04:34
0

Without knowing any of the specifics, I would avoid a global variable or tightly coupling the two views together.

Depending on your needs and implementation, delegation or notifications may a better choice to pass a variable between views.

Matt Bierner
  • 58,117
  • 21
  • 175
  • 206
0

There's a good discussion on the more general problem of how best to communicate between view controllers over here. The top-voted answer is pretty good.

The tl;dr version is basically:

  1. Global variables and singleton classes are rarely the right answer.
  2. Read up on the "dependency injection" design pattern.

Hope that helps.

Community
  • 1
  • 1
Cody Brimhall
  • 1,185
  • 1
  • 9
  • 18