Acceso a la propiedad en prepareForSegue de un 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 delegador send a message to this class, passing itself and a (NSURL *)url, I am trying to assign the url a una propiedad 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.

preguntado el 29 de junio de 12 a las 20:06

2 Respuestas

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]

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

Respondido el 29 de junio de 12 a las 20:06

Thank you, this works like a charm! Also, your message saved me a lot of debugging as there are few other ViewControllers that would behave in a similar fashion. - daniel z

You're welcome. See my updated answer for an easy way to access the view controller you're interested in without having to cast every time. - Scott Berrevoets

It doesn't look like you're assigning the delegate, which you need to do in order for the delegate pattern to work. Try adding vc.delegate = self to your prepareForSegue.

Respondido el 29 de junio de 12 a las 20:06

The delegate was assigned in another method that initiated the authentication, then the delegator (not shown in my code snippets) called the jsonControllerDidLinkedInAuth:, but thank you anyway :) My problem was related to having my ViewController embedded in a NavigationController, as pointed out by Scott. - daniel z

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.