【问题标题】:NSTimer with UIWebView - feasibilityNSTimer 与 UIWebView - 可行性
【发布时间】:2012-06-27 06:22:44
【问题描述】:

目前我仍在阅读NSTimer 的一些文档和教程。根据我目前的理解,我们调用计时器并给它一个方法,以便它会重复自己。然后我想到了一个想法。(我正在开发其他应用程序)

我打算做什么

  • 实现UIWebView
  • UIWebView 中实现NSTimer(可能是0.5sec),方法是检查UIWebView 当前的url(绝对字符串),如果不是我指定的,它将重定向url。

我有我想要实现的代码,目的是纠正我对UIWebViewNSTimer 的了解,并在我开始研究之前看看它是否合理。(我还在阅读文档。所以想了解更多并在开始工作之前尝试更多)

现在让我感到困惑的是,我的方法与NSTimer 兼容吗?在UIWebView viewDidLoad 方法中使用NSTimer 是否合理?由于应用程序每 0.5 秒不断运行该方法,是否会出现内存过载/崩溃?

例如NSTimer(如果我错了,请纠正我。但由于我希望它永远运行,只要用户在UIWebView 中,我将只需要此代码集而不包括@987654336 @)

NSTimer *t = [NSTimer scheduledTimerWithTimeInterval: 2.0
                      target: self
                      selector:@selector(onTick:)
                      userInfo: nil repeats:NO];

-(void)onTick:(NSTimer *)timer {
   //do smth
}

EDIT2- @Robert Ryan,这是我正在使用的代码。(当我第一次更改此代码时,它现在才起作用)**(如果我屏蔽了 range2 部分,那么错误域 error-999 停止了。但是视图仍然没有加载)

     - (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *currentURL = [[request URL] absoluteString];
    NSRange range1= [currentURL rangeOfString:@"news"];
    NSRange range2= [currentURL rangeOfString:@"pdf"];
    if (range1.location == NSNotFound)
    {
        NSURL *url = [NSURL URLWithString:@"http://www.imc.jhmi.edu/news.html"];
        [webView loadRequest:[NSURLRequest requestWithURL:url]];

        return NO; //no to this if its not found.
    }
    if(range2.location==NSNotFound)
    {
        NSURL * url = [NSURL URLWithString:@"http://www.imc.jhmi.edu/news.html"];
        [webView loadRequest:[NSURLRequest requestWithURL:url]];
        return NO; //no to this if its not found
    }

    return YES; //everything else ok

}

EDIT3 - 如果我将 NSRange range1 和 range2 组合成 1 个语句,那么它会再次工作(希望它在一个小时后仍然可以工作。xD)

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *currentURL = [[request URL] absoluteString];
    NSRange range1= [currentURL rangeOfString:@"news"];
    NSRange range2= [currentURL rangeOfString:@"pdf"];
    if (range1.location == NSNotFound & range2.location==NSNotFound)
    {
        NSURL *url = [NSURL URLWithString:@"http://www.imc.jhmi.edu/news.html"];
        [webView loadRequest:[NSURLRequest requestWithURL:url]];

        return NO;
    }
return YES;
}

【问题讨论】:

  • 可能不是不兼容,但似乎效率低下。你为什么想做这个?你想解决什么问题?您是否担心用户会点击您页面上的链接,从而使他们远离相关网址?还是您害怕网页本身可能会进行重定向?无论如何,与其做一个 NSTimer (或任何其他方式在未来触发一个方法),你会不会更好地使用 UIWebViewDelegate 方法webViewDidFinishLoad:webView:shouldStartLoadWithRequest:navigationType:
  • @RobertRyan - 我试过webView:shouldStartLoadWithRequest:navigationType: 但从其他人告诉我的情况来看,这只是为了开始(我假设它在加载页面后不起作用)。我要解决的是当人们在视图中停留一段时间(比如说 5 分钟),并且他们决定进入其他网址时,我想限制他们进入我指定的网址之外的其他网址。
  • 不,这不仅适用于初始加载,还适用于通过该 UIWebView 进行的所有交互。它专为您所描述的内容而设计。比使用 NSTimer 或其他一些延迟方法调用进行轮询要好得多。试试webView:shouldStartLoadWithRequest:navigationType。我想你会很高兴的。只需确保您设置了 webview 的委托(否则您可能不会收到消息)。
  • 我已设置委托。我目前正在使用这种方法,但它对我不起作用。我已经发布了我当前使用该方法的代码。如果我启用/禁用 [webView reload] 它只是反冲,要么加载要么加载。

标签: objective-c ios uiwebview nstimer


【解决方案1】:

如果您想要确保用户不会导航到其他网址,您可以添加以下内容

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ([[request.URL absoluteString] isEqualToString:@"http://YourAllowableURL1.com"]) {
        return YES;
    }

    if ([[request.URL absoluteString] isEqualToString:@"http://YourAllowableURL2.com"]) {
        return YES;
    }

    return NO;// user will not be able to go to any other urls
}

您还可以指定允许的 URL 列表,并确保仅对这些 URL 返回 YES

【讨论】:

  • 我目前正在使用该方法,但它对我不起作用。我已经发布了我当前使用该方法的代码。如果我启用/禁用 [webView reload] 它只是反冲,要么加载要么加载。
【解决方案2】:

使用 NSTimer 来确定是否尝试访问“未经批准”的网站并不是您想要的。如果 URL 不可接受,shouldStartLoadWithRequest 将允许您取消当前请求。但是,它不允许您更改 URL 以实现重定向。如果你真的想重定向,你可以发起一个全新的请求,也许在一点延迟之后,例如,

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *currentURL = [[request URL] absoluteString];
    NSRange range = [currentURL rangeOfString:@"imc.jhmi.edu"];

    if (range.location == NSNotFound)
    {
        double delayInSeconds = 0.1;
        dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
        dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
            NSURL *url = [NSURL URLWithString:@"http://www.imc.jhmi.edu/news.html"];
            [webView loadRequest:[NSURLRequest requestWithURL:url]];
        });

        return NO;
    }

    return YES;
}

实际上看起来你不必等待,你实际上可以立即发起新请求,但在之前的shouldStartLoadWithRequest 完成之前这样做似乎不正确。但如果你想这样做,那显然是:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSString *currentURL = [[request URL] absoluteString];
    NSRange range = [currentURL rangeOfString:@"imc.jhmi.edu"];

    if (range.location == NSNotFound)
    {
        NSURL *url = [NSURL URLWithString:@"http://www.imc.jhmi.edu/news.html"];
        [webView loadRequest:[NSURLRequest requestWithURL:url]];

        return NO;
    }

    return YES;
}

就我个人而言,我根本不会重定向用户,但最多会弹出一个 UIAlertView 告诉他们必须留在这个网站上,但这取决于你:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    NSLog(@"%s %@", __FUNCTION__, request);

    NSString *currentURL = [[request URL] absoluteString];
    NSRange range = [currentURL rangeOfString:@"imc.jhmi.edu"];

    if (range.location == NSNotFound)
    {
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"This app only follows links within the www.imc.jhmi.edu site." 
                                                        message:nil 
                                                       delegate:nil 
                                              cancelButtonTitle:@"Ok" 
                                              otherButtonTitles:nil];
        [alert show];
        // [alert release]; // use in non-ARC
        return NO;
    }

    return YES;
}

【讨论】:

  • 天哪,loadRequest!为什么我没有想到使用不同的方式来加载它。可能是因为我没有在我的代码中用新的 currentURL 替换当前的绝对字符串,这就是它仍然刷新到同一页面的原因。(我觉得很愚蠢,没有想到这种可能性)。哇,现在还有一个新的东西让我阅读,dispatch_time 部分并使用 ^(void) (我假设在方法中调用一个新方法)非常感谢!现在效果很好。
  • 好的,又出现了一个问题。我不知道会发生什么(我从不接触代码或它工作后的任何东西),但现在当我启动 UIWebView 时,屏幕只是保持空白。
  • @YangJieDomodomo 如果你真的什么都没改变,那很好奇。我会尝试注释掉你的 shouldStartLoadWithRequest 并查看它是否有效(以确保 (a) 算法中没有错误;以及 (b) 你的初始负载满足 shouldStartLoadWithRequest 中的规则。如果它在评论后有效完成此例程后,您就知道问题出在哪里了。但是,如果它仍然不起作用,那么您的问题在于viewDidLoad 或您的观点。祝您狩猎愉快!
  • @YangJieDomodomo 我不想强调这一点,但您在更新的问题中列出的shouldStartLoadWithRequest 的初始版本看起来非常可疑;逻辑看起来不正确。如果您使用最新版本更新您的问题,我很乐意查看它,但您问题中列出的版本似乎无法正常工作。
  • @YangJieDomodomo 我认为您的返回值颠倒了。如果您正在重新加载数据,那么shouldStartLoadWithRequest 应该返回 NO(即,您不应该让原始请求通过,因为您正在重新加载它),否则它应该返回 YES(即,因为一切正常,原始请求请求应该被允许继续)。
猜你喜欢
  • 1970-01-01
  • 2012-06-18
  • 2012-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-19
  • 2023-04-02
  • 2012-12-02
相关资源
最近更新 更多