【问题标题】:iOS how can I add a completion block to UIWebView loadRequest:?iOS 如何向 UIWebView loadRequest: 添加完成块?
【发布时间】:2014-10-23 15:12:25
【问题描述】:

我正在使用 UIWebView,并且已经在使用带有可选块的 webViewDidFinishLoad: 方法,该块在加载完成后执行:

    -(void)webViewDidFinishLoad:(UIWebView *)webView
    {
        [super webViewDidFinishLoad:webView];

//... bunch of other code        

        if(self.webViewFinishLoadBlock != nil)
        {
            self.webViewFinishLoadBlock();
        }
    }

现在我正在处理一个更复杂的加载页面和重定向序列,这使得上面的逻辑不够用。我不想将自己注册为 dummyWebView 的代表,并且必须处理存储在我的视图控制器属性中的多个完成块:

    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

我的问题是:

是否有某种第三方框架可以让我使用loadRequest:withCompletion: 来简化编写回调代码?

【问题讨论】:

    标签: ios objective-c asynchronous uiwebview objective-c-blocks


    【解决方案1】:

    你可以:

    • 子类 UIWebView 具有一个属性来保存 webViewDidFinish 完成块;

    • 确保它指定了它的委托;

    • 像你写的那样实现webViewDidFinish(虽然我建议块返回web视图以及NSError对象,如果有的话);和

    • 也实现webView:didFailLoadWithError:

    因此:

    //  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
    

    //  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
    

    然后:

    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");
        }
    }];
    

    【讨论】:

      【解决方案2】:
      - (void)webViewDidFinishLoad:(UIWebView *)webView
      

      是一个委托方法。按照约定,委托方法要求对象将自身传递回委托:

      (UIWebView*)webView
      

      通过一个参数。

      如果我们想使用属性request: 获取最后一个请求参数,这意味着webView.request.URL

      父对象可以是多个对象的委托,它可以通过该参数识别从哪个对象获取响应。要么开启对你的响应,要么构建一些基础设施来更优雅地处理它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-01-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多