Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/115.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 未找到webLink时UIWebView未转到didFailLoadWithError?_Ios_Objective C_Uiwebview_Uiwebviewdelegate - Fatal编程技术网

Ios 未找到webLink时UIWebView未转到didFailLoadWithError?

Ios 未找到webLink时UIWebView未转到didFailLoadWithError?,ios,objective-c,uiwebview,uiwebviewdelegate,Ios,Objective C,Uiwebview,Uiwebviewdelegate,我使用UIWebView从webLink加载web,并使用UIWebViewDelegate控制错误状态: [webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webLink]]]; - (void)webViewDidStartLoad:(UIWebView *)webView{ NSLog(@"START LOAD"); } - (void)webViewDidFinishLoad:(U

我使用
UIWebView
webLink
加载web,并使用
UIWebViewDelegate
控制错误状态:

[webView loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:webLink]]];


- (void)webViewDidStartLoad:(UIWebView *)webView{
    NSLog(@"START LOAD");

}

- (void)webViewDidFinishLoad:(UIWebView *)webView{
    NSLog(@"FINISH LOAD");
}

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error{
    NSLog(@"ERROR : %@",error);
}
但是当未找到
webLink
时,它不会转到
didFailLoadWithError
,而是转到
startLoad
didfishLoad
。当
webLink
未找到时,如何处理这种情况? 请帮忙

不幸的是,
UIWebView
没有将404(或类似代码)视为错误,因为收到了HTML响应。更糟糕的是,
UIWebView
无法为我们捕获响应代码,因此您必须通过
NSURLConnection
手动执行此操作。这里有一种解决方法:

@interface ViewController () <UIWebViewDelegate, NSURLConnectionDataDelegate>

@property (nonatomic) BOOL validatedRequest;
@property (nonatomic, strong) NSURL *originalUrl;

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];

    // since `shouldStartLoadWithRequest` only validates when a user clicks on a link, we'll bypass that
    // here and go right to the `NSURLConnection`, which will validate the request, and if good, it will
    // load the web view for us.

    self.originalUrl = [NSURL URLWithString:@"http://www.stackoverflow.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:self.originalUrl];
    [NSURLConnection connectionWithRequest:request delegate:self];
}

#pragma mark - UIWebViewDelegate

// you will see this called for 404 errors

- (void)webViewDidFinishLoad:(UIWebView *)webView
{
    self.validatedRequest = NO; // reset this for the next link the user clicks on
}

// you will not see this called for 404 errors

- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error
{
    NSLog(@"%s error=%@", __FUNCTION__, error);
}

// this is where you could, intercept HTML requests and route them through
// NSURLConnection, to see if the server responds successfully.

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    // we're only validating links we click on; if we validated that successfully, though, let's just go open it
    // nb: we're only validating links we click on because some sites initiate additional html requests of
    // their own, and don't want to get involved in mediating each and every server request; we're only
    // going to concern ourselves with those links the user clicks on.

    if (self.validatedRequest || navigationType != UIWebViewNavigationTypeLinkClicked)
        return YES;

    // if user clicked on a link and we haven't validated it yet, let's do so

    self.originalUrl = request.URL;

    [NSURLConnection connectionWithRequest:request delegate:self];

    // and if we're validating, don't bother to have the web view load it yet ...
    // the `didReceiveResponse` will do that for us once the connection has been validated

    return NO;
}

#pragma mark - NSURLConnectionDataDelegate method

// This code inspired by http://www.ardalahmet.com/2011/08/18/how-to-detect-and-handle-http-status-codes-in-uiwebviews/
// Given that some ISPs do redirects that one might otherwise prefer to see handled as errors, I'm also checking
// to see if the original URL's host matches the response's URL. This logic may be too restrictive (some valid redirects
// will be rejected, such as www.adobephotoshop.com which redirects you to www.adobe.com), but does capture the ISP
// redirect problem I am concerned about.

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{     
    NSString *originalUrlHostName = self.originalUrl.host;
    NSString *responseUrlHostName = response.URL.host;

    NSRange originalInResponse = [responseUrlHostName rangeOfString:originalUrlHostName]; // handle where we went to "apple.com" and got redirected to "www.apple.com"
    NSRange responseInOriginal = [originalUrlHostName rangeOfString:responseUrlHostName]; // handle where we went to "www.stackoverflow.com" and got redirected to "stackoverflow.com"

    if (originalInResponse.location == NSNotFound && responseInOriginal.location == NSNotFound) {
        NSLog(@"%s you were redirected from %@ to %@", __FUNCTION__, self.originalUrl.absoluteString, response.URL.absoluteString);
    }

    if ([response isKindOfClass:[NSHTTPURLResponse class]]) {
        NSInteger statusCode = [(NSHTTPURLResponse *)response statusCode];

        if (statusCode < 200 || statusCode >= 300) {
            NSLog(@"%s request to %@ failed with statusCode=%d", __FUNCTION__, response.URL.absoluteString, statusCode);
        } else {
            self.validatedRequest = YES;

            [self.webView loadRequest:connection.originalRequest];
        }
    }

    [connection cancel];
}

@end
@界面视图控制器()
@属性(非原子)BOOL validatedRequest;
@性质(非原子,强)NSURL*原始ALURL;
@结束
@实现视图控制器
-(无效)viewDidLoad
{
[超级视图下载];
//由于'shoulldstartdoadwithrequest'仅在用户单击链接时进行验证,因此我们将绕过该选项
//在这里,直接转到“NSURLConnection”,它将验证请求,如果正确,它将验证请求
//为我们加载web视图。
self.originalUrl=[NSURL URLWithString:@”http://www.stackoverflow.com"];
NSURLRequest*request=[nsurlRequestRequestWithURL:self.originalUrl];
[NSURLConnection connectionWithRequest:request委托:self];
}
#pragma标记-UIWebViewDelegate
//您将看到这被称为404错误
-(无效)webViewDidFinishLoad:(UIWebView*)webView
{
self.validateRequest=NO;//为用户单击的下一个链接重置此项
}
//您将不会看到此调用404错误
-(void)webView:(UIWebView*)webView失败加载错误:(NSError*)错误
{
NSLog(@“%s error=%@”,函数错误);
}
//在这里,您可以截获HTML请求并将其路由通过
//NSURLConnection,查看服务器是否成功响应。
-(BOOL)webView:(UIWebView*)webView应加载WithRequest:(NSURLRequest*)请求导航类型:(UIWebViewNavigationType)导航类型
{
//我们只是验证我们点击的链接;但是,如果我们成功验证了,我们就打开它
//注意:我们只是验证我们点击的链接,因为一些网站会启动额外的html请求
//他们自己的,不想参与调解每一个服务器请求;我们只是
//我们将关注用户点击的链接。
if(self.validatedRequest | | navigationType!=UIWebViewNavigationTypeLinkClicked)
返回YES;
//若用户点击了一个链接,而我们还并没有对它进行验证,那个么我们就这样做吧
self.originalUrl=request.URL;
[NSURLConnection connectionWithRequest:request委托:self];
//如果我们正在验证,还不用麻烦让web视图加载它。。。
//一旦连接被验证,“DidReceiverResponse”将为我们这样做
返回否;
}
#pragma标记-NSURLConnectionDataDelegate方法
//这段代码的灵感来自http://www.ardalahmet.com/2011/08/18/how-to-detect-and-handle-http-status-codes-in-uiwebviews/
//考虑到一些ISP确实会重定向,人们可能更愿意将其视为错误处理,我也在检查
//查看原始URL的主机是否与响应的URL匹配。此逻辑可能过于严格(某些有效重定向)
//将被拒绝,例如www.adobephotoshop.com,它会将您重定向到www.adobe.com),但会捕获ISP
//重定向我关心的问题。
-(void)连接:(NSURLConnection*)连接DidReceiverResponse:(NSURResponse*)响应
{     
NSString*originalUrlHostName=self.originalUrl.host;
NSString*responseUrlHostName=response.URL.host;
NSRange originalinsresponse=[responseUrlHostName rangeOfString:originalUrlHostName];//处理我们转到“apple.com”并被重定向到“www.apple.com”的位置
NSRange responseInOriginal=[originalUrlHostName rangeOfString:responseUrlHostName];//处理我们转到“www.stackoverflow.com”并被重定向到“stackoverflow.com”的位置
if(originalInResponse.location==NSNotFound&&responseInOriginal.location==NSNotFound){
NSLog(@“%s”您已从%@重定向到%@),_函数,self.originalUrl.absoluteString,response.URL.absoluteString);
}
if([response iskindof类:[NSHTTPURLResponse类]]){
NSInteger状态代码=[(NSHTTPURLRRESPONSE*)响应状态代码];
如果(状态代码<200 | |状态代码>=300){
NSLog(@“%s”对%@的请求失败,状态代码=%d“,_函数,response.URL.absoluteString,状态代码);
}否则{
self.validatedRequest=是;
[self.webView加载请求:connection.originalRequest];
}
}
[连接取消];
}
@结束
注意,在我的实现中,我不仅检查状态代码,而且还检查重定向(您可能不想这样做)。我这样做是因为一些ISP拦截HTTP请求,如果找不到目标站点,就将您重定向到他们自己的搜索网页(知道我的ISP正在检查我搜索的每个网站,我觉得这有点令人毛骨悚然)。如果你正在处理通过wifi连接的iPhone,你必须处理这些变幻莫测的问题

因此,例如,我上面的代码正在搜索“”(其中我故意省略了“.com”这一段,这将导致DNS查找失败),但我的ISP Verizon截获了该请求,并通过HTTP连接将其重定向到自己的搜索页面,因此,我的应用程序正在报告:

2013-01-21 23:14:21.896网络测试[24198:c07]-[ViewController连接:didReceiveResponse:]您已从重定向到

你可能想知道什么样的重定向是可以接受的(例如,如果你转到“www.adobephotoshop.com”,它会将你重定向到“www.adobe.com”),什么样的重定向是不可以接受的(例如,如果我转到“www.applecom”,它会将我重定向到“search.dnsassist.verizon.net”。