0

I have a class called WikiWebView which is a subclass of UIWebView which loads Wikipedia subjects and is designed to fetch all the links of the webpage, in order to create a sort of site map for the subject. My problem is that I can only create the links once the web page has loaded, but the loading isn't done right after [self loadRequest:requestObj] is called.

- (void)loadSubject:(NSString *)subject
{
    // load the actual webpage
    NSString *wiki = @"http://www.wikipedia.org/wiki/";
    NSString *fullURL = [wiki stringByAppendingString:subject];
    NSURL *url = [NSURL URLWithString:fullURL];
    NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
    [self loadRequest:requestObj];

    // [self createLinks]; // need this to be called after the view has loaded
}


- (void)createLinks
{
    NSString *javascript =
    @"var string = \"\";"
    "var arr = document.getElementsByClassName(\"mw-redirect\");"
    "for (var i = 0; i < arr.length; ++i)"
    "{"
    "var redirectLink = arr[i].href;"
    "string = string + redirectLink + \" \";"
    "}"
    "string;";
    NSString *links = [self stringByEvaluatingJavaScriptFromString:javascript];
    self.links = [links componentsSeparatedByString:@" "];
}

I tried the normal delegation technique, which lead to this code being added:

- (id)init
{
    if (self = [super init])
    {
        self.delegate = self;    // weird
    }

    return self;
}

#pragma mark - UIWebViewDelegate
- (void)webViewDidStartLoad:(UIWebView *)webView {
    ++_numProcesses;
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error {
    --_numProcesses;
}
- (void)webViewDidFinishLoad:(UIWebView *)webView {
    --_numProcesses;
    if (_numProcesses == 0) {
        [self createLinks];
    }
}

However, the delegate methods are never called..

I've seen similar questions where the answers are to use blocks, but how would I do that in this case?

Community
  • 1
  • 1
michaelsnowden
  • 6,031
  • 2
  • 38
  • 83
  • "it doesn't work" is a useless statement. Tell us what the result was of the code you posted. Did you get an error? Are any of the delegate methods called? Be specific. – rdelmar Jun 10 '14 at 01:47
  • 1
    @rdelmar "it doesn't work" is a link to another question where setting self.delegate = self causes an infinite regress. – danh Jun 10 '14 at 01:51
  • If a web view cannot be it's own delegate, than your subclass cannot either. How about creating a distinct class to be the delegate and doing your scan for links in there? – danh Jun 10 '14 at 01:53
  • @danh I'd rather have something that doesn't split my code into different places. – michaelsnowden Jun 10 '14 at 02:27
  • @doctordoder, the delegate can be defined in the same file. – danh Jun 10 '14 at 03:16

1 Answers1

0

With code in one module, you can circumvent the problem of a web view being it's own delegate...

@interface MyCustomDelegate : NSObject <UIWebViewDelegate>
@end

@implementation MyWebViewSublcass

    // ...
    self.delegate = [[MyCustomDelegate alloc] init];

@end

@implementation MyCustomDelegate

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    // do your scan for links here
}

@end
danh
  • 62,181
  • 10
  • 95
  • 136