0

I'm trying to follow the suggestion in the accepted answer at How to intercept click on link in UITextView? , but I've managed to get myself very confused, partially because I don't understand delegation very well, and by now I've added and deleted so many things I have no idea what's going on.

Here's GHFeedback.h:

#import <UIKit/UIKit.h>
#import "GHApplicationSubclassed.h"

@interface GHFeedback : UIViewController <UIApplicationDelegate>

@property (nonatomic, strong) UITextView *feedbackInstructions;
@property (nonatomic, strong) GHApplicationSubclassed *ghAppSub;

@end

Here's GHFeedback.m:

#import "GHFeedback.h"
#import <MessageUI/MessageUI.h>
#import "GHApplicationSubclassed.h"

@interface GHFeedback () <UIApplicationDelegate, MFMailComposeViewControllerDelegate>

@end

@implementation GHFeedback

@synthesize feedbackInstructions, ghAppSub;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
        self.ghAppSub.delegate=self;
}
return self;
}

-(void)openURL:(NSURL *)url //This is the method I'm trying to add--the text set for self.feedbackInstructions in IB contains an email address, and I want a subject line to appear automatically if the user sends an email.
{
    MFMailComposeViewController *mailer = [[MFMailComposeViewController alloc] init];
    mailer.mailComposeDelegate = self;
    [mailer setSubject:@"feedback on Haiku"];
    [self presentViewController:mailer animated:YES completion:NULL];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view from its nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

Here's GHApplicationSubclassed.h:

#import <UIKit/UIKit.h>

@interface GHApplicationSubclassed : UIApplication <UIApplicationDelegate>

@property (nonatomic, strong) GHApplicationSubclassed *appli;

@end

Here's GHApplicationSubclassed.m:

#import "GHApplicationSubclassed.h"

@implementation GHApplicationSubclassed

@synthesize appli;

-(BOOL)openURL:(NSURL *)url
{
    if  ([self.delegate openURL:url]) //This line gets an error, "no known instance method for selector 'openURL'
        return YES;
    else
        return [super openURL:url];
}

@end

I'd love explicit instructions on how to fix this. (By "explicit" I mean that, rather than saying something like, "then implement the delegate method," you could say something like, "then add this method to GHFeedback.m: -(void)openURL {[actual methods, etc., etc.]}.

Thanks so much for your help.

EDIT: What I want to happen is this.

There's a UITextView displayed in the view controller for GHFeedback that says, "if you have any questions/problems with the app, please email me," and then gives my email address. Right now, when the user presses that email address, the iOS Mail program opens an empty draft email. I would like to give the draft email that opens an automatic subject line of "feedback on Haiku."

Community
  • 1
  • 1
Joel Derfner
  • 2,207
  • 6
  • 33
  • 45
  • Can you explain what you want to happen? That might make it easier to follow – mkral Dec 13 '12 at 15:22
  • Done. Sorry for not being clear in the first place. – Joel Derfner Dec 13 '12 at 15:36
  • Also, delegation is often simpler than most people think. Say we have a class `Timer` in our view controller. We could init a `Timer` and start the timer. Imagine that the time finishes after 2minutes. In the `Timer` class we could set up a delegate method to callback to our view controller so it knows the timer finished but we have to set the `delegate` of the `Timer` instance we created so it knows what class (our view controller in this case) to send the "timerDidFinish" method to. the in the header just helps xcode know what delegate methods that class has set up. – mkral Dec 13 '12 at 15:43
  • Okay, so here I would need to set the delegate of `GHApplicationSubclassed` to be the view controller `GHFeedback`, so that `GHApplication` knows where to send the (overridden) `openURL` method. Do I do this in `GHApplicationSubclassed` (`self.delegate = self.instanceOfGHFeedback`) or in `GHFeedback` (self.instanceOfGHApplicationSubclassed.delegate = self)? I'm suspecting the former.... – Joel Derfner Dec 13 '12 at 15:50
  • It's actually the latter example. If `GHFeedback` is the Controller you want to know when `GHApplication` calls `openURL` in the controller. – mkral Dec 13 '12 at 16:33
  • Compared to my timer example `GHApplication` is the `Timer` – mkral Dec 13 '12 at 16:34

1 Answers1

0
if  ([self.delegate openURL:url]) 

The return type of openURL: is void, so there is actually nothing to check in this if-statement.

maybe you want to use

if ([(GHFeedback *)self.delegate respondsToSelector:@selector(openURL:)]{
    [(GHFeedback *)self.delegate openURL:url]; 
    return YES;
}

if the correct openURL: still wont get fired, the self.delegate must be nil.

vikingosegundo
  • 52,040
  • 14
  • 137
  • 178
  • If what? If what? I'm dying to know! :) – Joel Derfner Dec 13 '12 at 15:45
  • @JoelDerfner he means the `if` statement isn't being fired. Not sure if youre joking or not though – mkral Dec 13 '12 at 15:46
  • I added my comment to an unfinished version of this answer that ended with the word "if." So I wasn't joking then, but retroactively I am now. :) – Joel Derfner Dec 13 '12 at 16:02
  • Hmm. Using the code you suggest, `[self.delegate openURL:url` still gets the error `no known instance method for selector(openURL).` :( Sorry for not understanding.... – Joel Derfner Dec 13 '12 at 16:21
  • you can cast, i changed my code fro that. or you create a protocol that extends the UIApplicationDelegate Protocol with `openURL:` and overwrite the delegate to conform to it. – vikingosegundo Dec 13 '12 at 16:27