Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Accessing property in the prepareForSegue of a UIViewController

I am relatively new to Objective-C and I am coming from a Java background, thus I find the notion of pointers and not-that-well explained compilation errors quite daunting.

I have a class that implements a delegate with the jsonControllerDidLinkedInAuth method. Whenever the delegator send a message to this class, passing itself and a (NSURL *)url, I am trying to assign the url to a property authUrl, when this operations finishes call the performSegueWithIdentifier, which in turn executes the prepareForSegue (as far as my understanding of this is concerned).

This doesn't seem to work, as I am receiving a:

App[3278:13517] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[UINavigationController setUrlAddress:]: unrecognized selector sent to instance 0x6acab00'

error message that terminates the application with SIGABRT.

Both of the methods reside in the same class, which is a UINavigationController and points to another UINavigationController. The compiler points me at the [vc setUrlAddress:self.authUrl]; of the second method.

- (void)jsonControllerDidLinkedInAuth:(JsonController *)controller :(NSURL *)url {
    authUrl = url;
    if (authUrl != nil) {
        [self performSegueWithIdentifier:@"LinkedInAuth" sender:self];
    } else {
        NSLog(@"Auth URL is null");
    }
}


- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    if ([[segue identifier] isEqualToString:@"LinkedInAuth"]) {
        // Get destination view
        LinkedInViewController *vc = [segue destinationViewController];
        NSLog(@"The auth url from prepareForSegue in SignupViewControlle: %@", self.authUrl);
        [vc setUrlAddress:self.authUrl];
    }
}

What seems to be the problem is that for some reason I cannot access the authUrl property of the class I currently am. I tried with authUrl, [self authUrl] and self.authUrl but none of this seem to do the job. Properties are synthesized, but I have also noticed a little hint: "UINavigationController setUrlAddress", shouldn't this be a LinkedInViewController like defined in the method above? I tried casting (LinkedInViewController)[segue destinationViewController], but then I get a message notifying me that you cannot cast onto a pointer.

Any help would be highly appreciated. Thanks for reading.

Edit 1: The NSLog just above the setUrlAddress does return the self.authUrl. I am assuming it must be some sort of a visibility problem, but I am not sure how to solve this.

like image 231
Daniel Z. Avatar asked Jun 29 '12 19:06

Daniel Z.


1 Answers

If your view controller is embedded in a UINavigationController, segue.destinationViewController refers to that navigation controller. This is what you could use:

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

        if ([[segue identifier] isEqualToString:@"LinkedInAuth"]) {
            UINavigationController *navigationController = (UINavigationController *)segue.destinationViewController;
            LinkedInViewController *linkedInViewController = [[navigationController viewControllers] lastObject];
            linkedInViewController setUrlAddress:self.authUrl];
        }
}

And if you have more than 1 segue that transitions to a view controller embedded in a UINavigationController, I usually add this to the beginning of prepareForSegue:sender:

if ([segue.destinationViewController isKindOfClass:[UINavigationController subclass]])
        id vc = [[(UINavigationController *)segue.destinationViewController viewControllers] lastObject]

Now vc contains the view controller you're actually interested in, so you don't have to copy and paste the casting for every segue.

like image 180
Scott Berrevoets Avatar answered Nov 20 '22 20:11

Scott Berrevoets