WKWebView上的AngularJS:在iOS 9上处理file://的任何解决方案?

Sté*_*uca 11 uiwebview ios angularjs wkwebview

我正在向iOS 9移植一个巨大的angularJS应用程序,并希望从WKWebView(从UIWebView迁移)中受益.该应用程序是本地自包含的,因此使用file:// protocol为app主程序包提供所有文件.

不幸的是,听起来WKWebView最初破坏了iOS 8.x上的file://协议,但是当我看到全新的iOS 9 loadFileURL(basePath:,allowReadAccessToURL :) API时,会有一些亮点.

let readAccessPath = NSURL(string:"app", relativeToURL:bundleURL)?.absoluteURL
webView.loadFileURL(basePath!, allowingReadAccessToURL:readAccessPath!)
Run Code Online (Sandbox Code Playgroud)

唉,当我将allowsReadAccessToURL设置为我的bundle(app /)中的根文件夹时,我只获得了"索引文件",没有加载异步文件.

有没有这方面经验的人?

[更新]我看到我的初始问题描述不够准确.我确实在运行HTML.但我的异步angularJS调用实际上被WebKit框架中的安全监视程序阻止.

在此输入图像描述 在此输入图像描述

Sté*_*uca 6

虽然我没有快速回答(我的意思是快速修复)但我确实有一个解决方案.

这涉及放弃file://协议并通过localhost切换到http://.

简短的回答

以下是步骤:

1) - 在您自己的应用程序中安装本地Web服务器;

2) - 设置本地Web服务器以从您选择的给定端口的localhost提供服务;

3) - 在给定正确的mime类型的情况下,设置实际为您的应用资源提供文件的代理;

4) - 授权绕过iOS9 ATS处理http(而不仅仅是https).

瞧!

详细答案

1)在您自己的应用程序中安装本地Web服务器;

从Github repo安装GCDWebServer:https://github.com/swisspol/GCDWebServer

2)将本地Web服务器设置为从您的给定端口的localhost提供服务

鉴于您的angularjs或HTML应用程序文件位于资源文件夹中的"app"文件夹中.

在您的vc ViewDidLoad中:

@implementation ViewController

GCDWebServer* _webServer;

- (void)viewDidLoad
{
    [super viewDidLoad];
    self.webView = [[WKWebView alloc] initWithFrame:self.view.frame];
    [self.view addSubview:self.webView];

    self.webView.navigationDelegate = self;

    NSURL *bundleURL = [NSBundle mainBundle].bundleURL;
    NSURL *basePath = nil;

    // Init WebServer

    [self initWebServer:[[NSURL URLWithString:@"app" relativeToURL:bundleURL] absoluteURL]];

    basePath = [NSURL URLWithString:@"http://localhost:8080/page.html#/home" relativeToURL:nil];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:basePath];
    [self.webView loadRequest:request];
}
Run Code Online (Sandbox Code Playgroud)

3)在给定正确的mime类型的情况下,设置实际为您的应用程序资源提供文件的委托;

-(void)initWebServer:(NSURL *)basePath {
    // Create server
    _webServer = [[GCDWebServer alloc] init];

    #define GCDWebServer_DEBUG 0
    #define GCDWebServer_VERBOSE 1
    #define GCDWebServer_INFO 2
    #define GCDWebServer_WARNING 3
    #define GCDWebServer_ERROR 4
    #define GCDWebServer_EXCEPTION 5

    [GCDWebServer setLogLevel:GCDWebServer_ERROR];
    // Add a handler to respond to GET requests on any URL
    [_webServer addDefaultHandlerForMethod:@"GET"
                              requestClass:[GCDWebServerRequest class]
                              processBlock:^GCDWebServerResponse *(GCDWebServerRequest* request) {



                                  //NSLog([NSString stringWithFormat:@"WS: loading %@", request]);
                                  NSString * page = request.URL.lastPathComponent;
                                  NSString * path = request.URL.path;
                                  NSString * file = path;

                                  //NSLog(@"WS: loading %@", file);

                                  NSString * fullPath = [NSString stringWithFormat:@"%@%@", basePath, path];
                                  NSString * sFullPath = [fullPath substringFromIndex:7];

                                  BOOL isText = NO;

                                  if([page.lastPathComponent hasSuffix:@"html"]) {
                                      isText = YES;
                                  }



                                  if (isText) {
                                      NSError * error = nil;
                                      NSString * html = [NSString stringWithContentsOfFile:sFullPath encoding:NSUTF8StringEncoding error: &error];
                                      return [GCDWebServerDataResponse responseWithHTML:html];
                                  }
                                  else {
                                      NSData * data = [NSData dataWithContentsOfFile:sFullPath];
                                      if (data !=nil) {

                                          NSString * type = @"image/jpeg";

                                          if      ([page.lastPathComponent hasSuffix:@"jpg"]) type = @"image/jpeg";
                                          else if ([page.lastPathComponent hasSuffix:@"png"]) type = @"image/png";
                                          else if ([page.lastPathComponent hasSuffix:@"css"]) type = @"text/css";
                                          else if ([page.lastPathComponent hasSuffix:@"js" ]) type = @"text/javascript";


                                          return [GCDWebServerDataResponse responseWithData:data contentType:type];
                                      }
                                      else {

                                          return [GCDWebServerDataResponse responseWithHTML:[NSString stringWithFormat:@"<html><body><p>404 : unknown file %@ World</p></body></html>", sFullPath]];
                                      //return [GCDWebServerDataResponse responseWithHTML:@"<html><body><p>Hello World</p></body></html>"];
                                      }
                                  }
                              }];

    // Start server on port 8080
    [_webServer startWithPort:8080 bonjourName:nil];
    NSLog(@"Visiting %@", _webServer.serverURL);
}
Run Code Online (Sandbox Code Playgroud)

4)授权绕过iOS9 ATS处理http(而不仅仅是https)

在Xcode的info.plist文件中,您必须在键值内添加名为"App Transport Security Settings"的字典,如下所示:

NSAllowsArbitraryLoads = true

希望能帮助到你.任何偶然发现更简单的人都欢迎回答!