Resolved Need help: UIPIckerView and JSON

Discussion in 'iOS Programming' started by lasash, Sep 26, 2012.

  1. lasash, Sep 26, 2012
    Last edited: Sep 30, 2012

    lasash Suspended

    Joined:
    Sep 15, 2012
    #1
    Hello to all,

    After I posted my first thread here I got a lot of encouragement from people around here, and I appreciate that a lot.

    I continued studying through the book: iOS programming the big nerd ranch guide 3rd edition by Joe Conway & Aaron Hillegass, and i am now at chapter 22 (only 8 remain).

    I should by now know how to use the Objective C syntax and do stuff. But, I still find it difficult to get the little pieces of the puzzle together.

    I want to create an app that gets a json data, puts it in an array and then fetches the array into a UIPickerView.

    I succeeded to do that after lots of googling and youtube tutorials, but, the problem is I want to create three arrays with depend on each other, i.e:

    Phase 1: fetching json from url into array 1: id, title

    Phase 2:
    user chooses value from picker view ->
    value is saved in text field 1

    Phase 3:
    user presses text field 2 ->
    fetching json from url with the value of text field 1 as the parameter into array 2: id, title ->
    user chooses value from picker view ->
    value is saved in text field 2

    Phase 3:
    user presses text field 3 ->
    fetching json from url with the value of text field 2 as the parameter into array 3: url, title ->
    user chooses value from picker view with array 3 populated ->
    opening a webview with the url selected as the array 3 value

    and that's about it.

    I want to create the UIPickerView with a method (I'm used to say function from PHP Programming), that creates the PickerView automatically, because copying-pasting the code for each array is quite idiotic in my opinion.

    However, I'm stuck with all the UIPickerView additional methods.
    How can I make the UIPickerView dynamic and populate it dynamically as well, when the data of the next UiPickerView depends on the selection of the current PickerView's row's value?

    Thank you so much for helping.
    Liroy
     
  2. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #2
    - reloadAllComponents: will reload your picker's data.

    You have to keep a reference of the current stage the user is in and in the data source methods of your picker you have to return the data for the current stage.

    When the user selects something from the picker, update the stage the user is in and reload the picker.
     
  3. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #3
    Hey CodeBreaker, thanks for your reply.

    Are you saying that I should keep a NSString of the current stage the user is in (i.e. stage=1, stage=2, stage=3) and according to that, load him the right data source accordingly, instead of creating 3 different picker views?

    Thanks again for your help,
     
  4. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #4
    Yup, there is no need to create three pickers (it is against OOP, unless you are displaying all three at the same time).
     
  5. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #5
    I tried what you proposed and I kind of worked, but I am stuck again.
    Sorry for my novice mistakes, I am very new at this.

    This is my MainViewController.h:
    Code:
    #import <UIKit/UIKit.h>
    
    @interface MainViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
    {
        NSMutableArray *stepOneNames, *stepOneValues, *stepTwoNames, *stepTwoValues, *stepThreeNames, *stepThreeValues;
        __weak IBOutlet UIButton *searchBtn;
        IBOutlet UIPickerView *pickerView;
        IBOutlet UILabel *stepOneField;
        IBOutlet UILabel *stepTwoField;
        IBOutlet UILabel *stepThreeField;
    }
    
    @property (nonatomic, retain) NSString *currentStep, *categoryID;
    @property (nonatomic, retain) NSMutableArray *currentNames, *currentValues;
    @property (nonatomic, retain) UILabel *stepOneField, *stepTwoField, *stepThreeField, *currentField;
    
    @end
    
    And this is my MainViewController.m:
    Code:
    #import "MainViewController.h"
    
    @interface MainViewController ()
    @end
    
    @implementation MainViewController
    @synthesize stepOneField, stepTwoField, stepThreeField, currentStep, currentNames, currentValues, currentField, categoryID;
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            self.title = NSLocalizedString(@"ראשי", @"ראשי");
            self.tabBarItem.image = [UIImage imageNamed:@"first"];
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
        
        NSString *jsonURL=nil;
        
        if (currentStep==NULL)
        { currentStep=@"1"; }
        
        if ([currentStep isEqualToString:@"1"])
        {
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_fields.php"];
            currentNames=stepOneNames;
            currentValues=stepOneValues;
            currentField=stepOneField;
        }
        
        if ([currentStep isEqualToString:@"2"])
        {
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_categories.php?category_id=%@", categoryID];
            NSLog(@"%@", jsonURL);
            currentNames=stepTwoNames;
            currentValues=stepTwoValues;
            currentField=stepTwoField;
        }
        
        if ([currentStep isEqualToString:@"3"])
        {
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_links.php?category_id=%@", categoryID];
            currentNames=stepThreeNames;
            currentValues=stepThreeValues;
            currentField=stepThreeField;
        }
        
        currentNames=[[NSMutableArray alloc] init];
        currentValues=[[NSMutableArray alloc] init];
        
        NSURL *url = [NSURL URLWithString:jsonURL];
        NSData *data = [NSData dataWithContentsOfURL:url];
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        
        for (NSDictionary *s in [json objectForKey:@"options"])
        {
            NSString *fieldID=[s objectForKey:@"id"];
            NSString *fieldName=[s objectForKey:@"field_name"];
            [currentNames addObject:fieldName];
            [currentValues addObject:fieldID];
        }
        
        [pickerView selectRow:0 inComponent:0 animated:NO];
        currentField.text=[currentNames objectAtIndex:[pickerView selectedRowInComponent:0]];
    }
    
    - (void)viewDidUnload
    {
        searchBtn = nil;
        stepOneField = nil;
        stepTwoField = nil;
        stepTwoField = nil;
        stepThreeField = nil;
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
    {
        return 1;
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        currentField.text=[currentNames objectAtIndex:row];
        categoryID=[currentValues objectAtIndex:row];
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
    {
        return [currentValues count];
    }
    
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
    {
        if ([currentStep isEqualToString:@"1"]) { currentStep=@"2"; }
        if ([currentStep isEqualToString:@"2"]) { currentStep=@"3"; }
        NSLog(@"%@", currentStep);
        return [currentNames objectAtIndex:row];
    }
    
    @end
    
    I want to create three buttons, where each button is responsible for one stage (there are 3 stages), and the next stage is depending on its predecessor's choice).

    What am I doing wrong?

    Thanks again for your help CodeBreaker.
    I know I suck at this as a beginner.
     
  6. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #6
    You might want to consider using UITableViews with drill-down.
     
  7. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #7
    Code:
    #import "MainViewController.h"
    
    @interface MainViewController ()
    @end
    
    @implementation MainViewController
    @synthesize stepOneField, stepTwoField, stepThreeField, currentStep, currentNames, currentValues, currentField, categoryID;
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            self.title = NSLocalizedString(@"ראשי", @"ראשי");
            self.tabBarItem.image = [UIImage imageNamed:@"first"];
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
        
        NSString *jsonURL=nil;
        
        if (currentStep==NULL)
        { currentStep=@"1"; }
    
        jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_fields.php"];
    //    currentNames=stepOneNames;
    //    currentValues=stepOneValues;
        currentField=stepOneField;
       
        
        currentNames=[[NSMutableArray alloc] init];
        currentValues=[[NSMutableArray alloc] init];
        
        NSURL *url = [NSURL URLWithString:jsonURL];
        NSData *data = [NSData dataWithContentsOfURL:url];
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        
        for (NSDictionary *s in [json objectForKey:@"options"])
        {
            NSString *fieldID=[s objectForKey:@"id"];
            NSString *fieldName=[s objectForKey:@"field_name"];
            [currentNames addObject:fieldName];
            [currentValues addObject:fieldID];
        }
    
        [pickerView reloadAllComponents];
    
        
        [pickerView selectRow:0 inComponent:0 animated:NO];
        currentField.text=[currentNames objectAtIndex:[pickerView selectedRowInComponent:0]];
    }
    
    - (void)viewDidUnload
    {
        searchBtn = nil;
        stepOneField = nil;
        stepTwoField = nil;
        stepTwoField = nil;
        stepThreeField = nil;
        [super viewDidUnload];
        // Release any retained subviews of the main view.
        // e.g. self.myOutlet = nil;
    }
    
    - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
    {
        return (interfaceOrientation == UIInterfaceOrientationPortrait);
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
    {
        return 1;
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        currentField.text=[currentNames objectAtIndex:row];
        categoryID=[currentValues objectAtIndex:row];
        if ([currentStep isEqualToString:@"1"])
        {
              currentStep = @"2";
              jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_categories.php?category_id=%@", categoryID];
                NSLog(@"%@", jsonURL);
    //            currentNames=stepTwoNames;
    //            currentValues=stepTwoValues;
                currentField=stepTwoField;
                NSURL *url = [NSURL URLWithString:jsonURL];
                NSData *data = [NSData dataWithContentsOfURL:url];
                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
                [currentNames removeAllObjects];
                [currentValues removeAllObjects];    
                    for (NSDictionary *s in [json objectForKey:@"options"])
                    {
                        NSString *fieldID=[s objectForKey:@"id"];
                        NSString *fieldName=[s objectForKey:@"field_name"];
                        [currentNames addObject:fieldName];
                        [currentValues addObject:fieldID];
                    }
    
                [pickerView reloadAllComponents];
                return;
        }
        
        if ([currentStep isEqualToString:@"2"])
        {
            currentStep = @"3";
           jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_links.php?category_id=%@", categoryID];
    //            currentNames=stepThreeNames;
    //            currentValues=stepThreeValues;
                currentField=stepThreeField;
                NSURL *url = [NSURL URLWithString:jsonURL];
                NSData *data = [NSData dataWithContentsOfURL:url];
                NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
                [currentNames removeAllObjects];
                [currentValues removeAllObjects];    
                    for (NSDictionary *s in [json objectForKey:@"options"])
                    {
                        NSString *fieldID=[s objectForKey:@"id"];
                        NSString *fieldName=[s objectForKey:@"field_name"];
                        [currentNames addObject:fieldName];
                        [currentValues addObject:fieldID];
                    }
                [pickerView reloadAllComponents];            
                return;
        }
        
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
    {
        return [currentValues count];
    }
    
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
    {
    //    if ([currentStep isEqualToString:@"1"]) { currentStep=@"2"; }
    //    if ([currentStep isEqualToString:@"2"]) { currentStep=@"3"; }
    //    NSLog(@"%@", currentStep);
        return [currentNames objectAtIndex:row];
    }
    
    @end
    
    This should work.
     
  8. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #8
    CodeBreaker, that's awesome! It worked perfectly.

    I improved the code, but I have two problems now:

    1. I feel like I'm overdoing it, I should probably write blocks instead of copy-pasting the code from one button to another, right? I think I am using way too many variables here...

    2. I try to populate an array called currentLinks with a JSON field of category_link, and it keeps getting null when I add it to the didSelectRow method. Any ideas why? I tried for like 40 min to figure it out...

    BTW, if you need remarks inside the code for every step of the way, just let me know and I will add them ASAP.

    Thanks again!

    H controller:
    Code:
    @interface MainViewController : UIViewController <UIPickerViewDelegate, UIPickerViewDataSource>
    {
        IBOutlet UILabel *studyField;
        IBOutlet UILabel *studyCategory;
        IBOutlet UILabel *studyType;
        NSInteger studyFieldRow, studyCategoryRow, studyTypeRow;
        id studyFieldID, studyCategoryID, studyTypeID;
    }
    
    @property (strong, nonatomic) NSMutableArray *currentNames, *currentValues, *currentLinks;
    @property (strong, nonatomic) NSString *currentStep, *jsonURL, *currentLink;
    @property (strong, nonatomic) IBOutlet UIPickerView *pickerView;
    @property (strong, nonatomic) UILabel *currentField;
    
    - (IBAction)chooseField:(id)sender;
    - (IBAction)chooseCategory:(id)sender;
    - (IBAction)chooseType:(id)sender;
    - (IBAction)showResults:(id)sender;
    
    M Controller:
    Code:
    #import "MainViewController.h"
    #import "WebViewController.h"
    
    @interface MainViewController ()
    @end
    
    @implementation MainViewController
    @synthesize currentStep, currentNames, currentValues, currentLinks, pickerView, currentField, jsonURL, currentLink;
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            self.title = NSLocalizedString(@"ראשי", @"ראשי");
            self.tabBarItem.image = [UIImage imageNamed:@"first"];
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        
        if (currentStep==NULL)
        { currentStep=@"1"; }
        
        jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_fields.php"];
        currentField=studyField;
        
        currentNames=[[NSMutableArray alloc] init];
        currentValues=[[NSMutableArray alloc] init];
        
        NSURL *url = [NSURL URLWithString:jsonURL];
        NSData *data = [NSData dataWithContentsOfURL:url];
        NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
        
        for (NSDictionary *s in [json objectForKey:@"options"])
        {
            NSString *fieldID=[s objectForKey:@"id"];
            NSString *fieldName=[s objectForKey:@"field_name"];
            [currentNames addObject:fieldName];
            [currentValues addObject:fieldID];
        }
        
        [pickerView reloadAllComponents];
        
        [pickerView selectRow:0 inComponent:0 animated:YES];
        currentField.text=[currentNames objectAtIndex:[pickerView selectedRowInComponent:0]];
    }
    
    - (void)viewDidUnload
    {
        [self setPickerView:nil];
        studyField = nil;
        studyCategory = nil;
        studyType = nil;
        [super viewDidUnload];
    }
    
    - (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView;
    {
        return 1;
    }
    
    - (void)pickerView:(UIPickerView *)pickerView didSelectRow:(NSInteger)row inComponent:(NSInteger)component
    {
        if ([currentStep isEqualToString:@"1"])
        {
            studyFieldRow=row;
            studyFieldID=[currentValues objectAtIndex:row];
        }
        else if ([currentStep isEqualToString:@"2"])
        {
            studyCategoryRow=row;
            studyCategoryID=[currentValues objectAtIndex:row];
        }
        else
        {
            studyTypeRow=row;
            studyTypeID=[currentValues objectAtIndex:row];
        }
        currentField.text=[currentNames objectAtIndex:row];
        currentLink=[currentLinks objectAtIndex:row];
        NSLog(@"%@", currentLink);
    }
    
    - (NSInteger)pickerView:(UIPickerView *)pickerView numberOfRowsInComponent:(NSInteger)component;
    {
        return [currentValues count];
    }
    
    - (NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component;
    {
        return [currentNames objectAtIndex:row];
    }
    
    - (IBAction)chooseField:(id)sender {
            currentStep = @"1";
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_fields.php"];
            NSLog(@"%@", jsonURL);
            currentField=studyField;
            NSURL *url = [NSURL URLWithString:jsonURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            [currentNames removeAllObjects];
            [currentValues removeAllObjects];
            for (NSDictionary *s in [json objectForKey:@"options"])
            {
                NSString *fieldID=[s objectForKey:@"id"];
                NSString *fieldName=[s objectForKey:@"field_name"];
                [currentNames addObject:fieldName];
                [currentValues addObject:fieldID];
            }
        
            [pickerView reloadAllComponents];
            [pickerView selectRow:studyFieldRow inComponent:0 animated:YES];
            return;
    }
    
    - (IBAction)chooseCategory:(id)sender {
            currentStep = @"2";
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_categories.php?category_id=%@", studyFieldID];
            NSLog(@"%@", jsonURL);
            currentField=studyCategory;
            NSURL *url = [NSURL URLWithString:jsonURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            [currentNames removeAllObjects];
            [currentValues removeAllObjects];
            [currentLinks removeAllObjects];
            for (NSDictionary *s in [json objectForKey:@"options"])
            {
                NSString *fieldID=[s objectForKey:@"id"];
                NSString *categoryName=[s objectForKey:@"category_name"];
                NSString *categoryLink=[s objectForKey:@"category_link"];
                if ([categoryLink isEqualToString:@""]) { categoryLink=@"x"; }
                [currentValues addObject:fieldID];
                [currentNames addObject:categoryName];
                [currentLinks addObject:categoryLink];
                NSLog(@"%@", categoryLink);
            }
            
            [pickerView reloadAllComponents];
            [pickerView selectRow:studyCategoryRow inComponent:0 animated:YES];
            return;
    }
    
    - (IBAction)chooseType:(id)sender {
            currentStep = @"3";
            jsonURL=[NSString stringWithFormat:@"http://www.psychometry.co.il/mobile/engine_links.php?category_id=%@", studyCategoryID];
            currentField=studyType;
            NSURL *url = [NSURL URLWithString:jsonURL];
            NSData *data = [NSData dataWithContentsOfURL:url];
            NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
            [currentNames removeAllObjects];
            [currentValues removeAllObjects];
            [currentLinks removeAllObjects];
            for (NSDictionary *s in [json objectForKey:@"options"])
            {
                NSString *fieldID=[s objectForKey:@"link_url"];
                NSString *fieldName=[s objectForKey:@"link_name"];
                [currentNames addObject:fieldName];
                [currentValues addObject:fieldID];
            }
            [pickerView reloadAllComponents];
            [pickerView selectRow:studyTypeRow inComponent:0 animated:YES];
            return;
    }
    
    - (IBAction)showResults:(id)sender
    {
        WebViewController *wv=[[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
    //    wv.currentURL=[currentNames];
        [self presentModalViewController:wv animated:YES];
    }
    
    @end
    
     
  9. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #9
    1. You might be using extra variables, but I would suggest you let it be the way it is, until you achieve your full functionality. That's how I do it: write no-brainer, brute-force code and then improve upon it and remove everything that is not necessary.

    2. Are you sure something is added to currentLinks? Can you check it by printing the entire array? Also, I see that you are populating it only in `chooseCategory:`.
     
  10. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #10
    1. Ok, I'll keep that in mind, although my code feels really messy and dirty...
    2. Silly me, forgot to alloc & init the array, that's why it gave me nulls all the time.

    I have now another problem. Sorry for all the bugs, this is my first app.

    I am trying to open a WebViewController in modal window with the push of a button in ContactViewController, and passing it a parameter of the currentURL to open.

    It works on the simulator, but crashes on my iPhone. Any ideas?

    WebViewController.h:
    Code:
    #import <UIKit/UIKit.h>
    
    @interface WebViewController : UIViewController
    
    @property (weak, nonatomic) IBOutlet UIWebView *myWebView;
    @property (weak, nonatomic) NSString *currentURL;
    - (IBAction)dismissView:(id)sender;
    
    @end
    
    WebViewController.m:
    Code:
    #import "WebViewController.h"
    
    @implementation WebViewController
    @synthesize myWebView, currentURL;
    
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
        }
        return self;
    }
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
        // Do any additional setup after loading the view from its nib.
        NSURL *url=[NSURL URLWithString:currentURL];
        NSURLRequest*request=[NSURLRequest requestWithURL:url];
        [myWebView loadRequest:request];
    }
    
    - (void)didReceiveMemoryWarning
    {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
    }
    
    - (void)viewDidUnload {
        [self setMyWebView:nil];
        [super viewDidUnload];
    }
    - (IBAction)dismissView:(id)sender {
        [self dismissModalViewControllerAnimated:YES];
    }
    
    @end
    
    ContactViewController.m relevant methods (these are two buttons):
    Code:
    - (IBAction)showWebsite:(id)sender {
        WebViewController *wv=[[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
        wv.currentURL=@"http://www.psychometry.co.il";
        [self presentModalViewController:wv animated:YES];
    }
    
    - (IBAction)showFacebook:(id)sender {
        WebViewController *wv=[[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil];
        wv.currentURL=@"http://www.facebook.com/nivrevahpsychometry";
        [self presentModalViewController:wv animated:YES];
    }
    
    Thank you so much for helping, CodeBreaker...
     
  11. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #11
    Hmm, three possible bugs:

    1. currentURL is NULL.

    2. currentURL is released before you form a request with it. Your app will crash with EXC_BAD_ACCESS. Try declaring currentURL as a strong property. Generally, properties which are not retained by your view must be declared strong. An exception to this is when there is some other object (such as your application's delegate) which is in the memory and is holding on to the property.

    3. You may be setting currentURL after your view controller's view loads. This may explain why it crashes on the device and not on the simulator. Anyways, it is not a good idea to use a property of your view controller in viewDidLoad that is being set externally. A solution to this is initialising your WebViewController with currentURL like this:

    WebViewController.h (add this method)
    Code:
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil urlString:(NSString *)urlString;
    
    
    WebViewController.m
    Code:
    - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil urlString:(NSString *)urlString
    {
        self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
        if (self) {
            // Custom initialization
            [self setCurrentURL:urlString];
        }
        return self;
    }
    
    ContactViewController.m
    Code:
    - (IBAction)showWebsite:(id)sender {
        WebViewController *wv=[[WebViewController alloc] initWithNibName:@"WebViewController" bundle:nil urlString:@"http://www.psychometry.co.il"];
        [self presentModalViewController:wv animated:YES];
    }
    
     
  12. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #12
    Hello CodeBreaker,

    Again, it was my own silly newb mistake.
    Some of my XIB files where 4 inch retina, and some where 3.5 inch.
    And because my iPhone is 4S, it gave an uncaught error, something about NSLayoutConstraint.

    It is very confusing to learn Xcode while the iPhone is changing its screen size, upgrading its Xcode software and the SDK...

    I really want to thank you for your time and effort in solving all the errors in my code. You are a great person & developer, and I am grateful for that.
     
  13. CodeBreaker macrumors 6502

    Joined:
    Nov 5, 2010
    Location:
    Sea of Tranquility
    #13
    Glad it all worked out :)

    If xibs are annoying you, you can drop them completely and create all your views in code. It may be a bit daunting at start, but I find it to be faster and easier that way. It is also easier to support multiple screen sizes and debug view related bugs. And it also reduces your app's size.

    Whenever I start working on a partly developed project, the first thing I do is get rid of all the nibs ;)
     
  14. lasash thread starter Suspended

    Joined:
    Sep 15, 2012
    #14
    I actually find them quite helpful, especially when I'm just a starter on this. However, what you mentioned about the support for multiple screen sizes (i.e. ipad and iphone) is very important. I will remember that!

    Thank you again!
     

Share This Page