NSURLProtocol - 在canInitWithRequest之后未调用startLoading为页面资源返回YES

Sto*_*nz2 8 objective-c uiwebview nsurlprotocol ios

我遇到的问题是我的视频资源UIWebView没有加载.这只是实际设备上的一个问题 - 一切都在模拟器上完美运行.

注意:我已经检查了这个,问题与多次加载相同的内容有关. 在对canInitWithRequest的YES响应之后,不要求NSURLProtocol加载

实际页面在我的自定义中加载正常NSURLProtocol,它YEScanInitWithRequest(几次)返回,然后startLoading在大约第4或第5次之后调用.然后它以类似的方式加载我的css文件.然后我看到我的视频对象的请求YES从中返回canInitWithRequest,但没有任何反应.startLoading从来没有为我的视频资源请求调用.这是我加载页面时设备的简化日志:

canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
START LOADING: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://cssResource
START LOADING: https://cssResource
canInitWithRequest: https://MyVideoResource
Run Code Online (Sandbox Code Playgroud)

当我从完全相同的设备类型运行相同iOS版本的模拟器加载完全相同的页面时,日志显示资源实际上由于某种原因开始加载:

canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://WebpageURL
START LOADING: https://WebpageURL
canInitWithRequest: https://WebpageURL
canInitWithRequest: https://cssResource
START LOADING: https://cssResource
canInitWithRequest: https://MyVideoResource
canInitWithRequest: https://MyVideoResource
START LOADING: https://MyVideoResource  -- WHY NOT ON DEVICE?
Run Code Online (Sandbox Code Playgroud)

该页面留下了一个永远不会播放的视频 - 它应该是一个白色的盒子,而它上面的"播放视频"按钮.页面看起来像是不断加载某些东西(状态栏中的活动指示器正在旋转)但没有发生任何事情,并且Xcode的Debug导航器中的网络活动是扁平化的.

tl; dr
有谁知道为什么我的iPhone上从未尝试过加载这个资源?显然,模拟器知道它需要加载.


编辑:这是我的NSURLProtocol稍微编辑过的相关代码

@implementation CHHTTPURLProtocol
{
    NSURLConnection *connection;
    NSHTTPURLResponse *httpResponse;
    NSData *responseData;
}

+ (BOOL)canInitWithRequest:(NSURLRequest *)request
{
    if (/* key exists on request */)
        return NO;
    else if (/* not http or https */)
        return NO;

    NSLog(@"canInitWithRequest: %@", request.URL.absoluteString);

    return YES;
}

+ (NSURLRequest *)canonicalRequestForRequest:(NSURLRequest *)request
{
    return request;
}

- (void)startLoading
{
    NSMutableURLRequest *request = [self.request mutableCopy];
    NSLog(@"START LOADING: %@", request.URL.absoluteString);
    if (authenticate) authenticate(request);
    /* add key to request */
    connection = [NSURLConnection connectionWithRequest:request delegate:self];
}

- (void)stopLoading
{
    [connection cancel];
    connection = nil;
}

/* Other methods like connection:didReceiveData: and connectionDidFinishLoding: */

+ (void)authenticateWithBlock:(AuthenticationBlock)block
{
    authenticate = block;
}

static AuthenticationBlock authenticate;
Run Code Online (Sandbox Code Playgroud)

Roy*_*alk 0

我没有明确的答案,但我确实有一些建议可以解决这个问题:您考虑过缓存吗?如果 UIWebView 认为它已经拥有视频的副本,则不会调用.

当 iOS 8 收到带有 Keep-Alive 标头的 HTTP 响应时,它会保留此连接以供以后重新使用(这是应该的),但它保留该连接的时间超过了 Keep-Alive 标头的超时参数。视频是最后加载的,如果 Mac 比真实设备更快,那么它可能就是最后加载的。查看您的代码,如果在 canInitWithRequest 之后但在 startLoading 之前 NSURLRequest 为 nil,您仍然会在 NSLog 中看到一些内容。

  1. 模拟器可能正在使用 OSX AVFoundation 来播放视频。这意味着iOS 上的框架不同并且支持的编解码器较少。
  2. ios 设备在文件名方面区分大小写,而模拟器则不区分大小写。
  3. 假设模拟器和真实设备之间的iOS 特定注意事项不同,如果这是 UIWebView 中的第二个视频,它绝对不应该在 iOS 上播放,但可以在模拟器上播放。