I'm working with a UIWebView and am already using webViewDidFinishLoad: method with an optional block that gets executed after loading complete:
-(void)webViewDidFinishLoad:(UIWebView *)webView
{
[super webViewDidFinishLoad:webView];
//... bunch of other code
if(self.webViewFinishLoadBlock != nil)
{
self.webViewFinishLoadBlock();
}
}
Now I'm working with an even more complicated sequence of loading pages and redirects that makes the logic above not sufficient. I don't want to register myself as a delegate of dummyWebView and have to juggle multiple completion blocks stored in my view controller's properties:
dummyWebView = [[UIWebView alloc] initWithFrame:CGRectZero];
[dummyWebView loadRequest:[NSURLRequest requestWithURL:logoutURL]];
//Ideally here I would know when dummyWebView finishes loading, because there's some code I want to execute once it is done
My question is:
Is there some kind of third party framework that would allow me to use loadRequest:withCompletion:
to simplify writing callback code?
You can just:
Subclass UIWebView
with a property to hold the webViewDidFinish
completion block;
Make sure it specifies its delegate;
Implement the webViewDidFinish
much like you wrote it (though I'd suggest the block return both the web view as well as the NSError
object, if any); and
Implement the webView:didFailLoadWithError:
, too.
Thus:
// MyWebView.h
#import <UIKit/UIKit.h>
typedef void(^WebViewFinishLoadBlock)(UIWebView *, NSError *);
@interface MyWebView : UIWebView
@property(nonatomic, copy) WebViewFinishLoadBlock webViewFinishLoadBlock;
- (void)loadRequest:(NSURLRequest *)request withCompletionHandler:(WebViewFinishLoadBlock)completionHandler;
@end
And
// MyWebView.m
#import "MyWebView.h"
@interface MyWebView () <UIWebViewDelegate>
@end
@implementation MyWebView
- (void)loadRequest:(NSURLRequest *)request withCompletionHandler:(WebViewFinishLoadBlock)completionHandler
{
self.delegate = self;
self.webViewFinishLoadBlock = completionHandler;
[self loadRequest:request];
}
#pragma mark - UIWebViewDelegate
- (void)webViewDidFinishLoad:(UIWebView *)webView
{
if (self.webViewFinishLoadBlock) {
self.webViewFinishLoadBlock(webView, nil);
self.webViewFinishLoadBlock = nil;
}
}
- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
if (self.webViewFinishLoadBlock) {
self.webViewFinishLoadBlock(webView, error);
self.webViewFinishLoadBlock = nil;
}
}
@end
And then:
MyWebView *webView = [[MyWebView alloc] init];
webView.frame = self.view.bounds;
[self.view addSubview:webView];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[webView loadRequest:request withCompletionHandler:^(UIWebView *webView, NSError *error) {
if (error) {
NSLog(@"failed: %@", error);
} else {
NSLog(@"succeeded");
}
}];