2015-10-13 21 views
10

Tôi đang chuyển một ứng dụng angularJS lớn sang iOS 9 và muốn hưởng lợi từ WKWebView (di chuyển từ UIWebView). Ứng dụng này tự chứa cục bộ, do đó tất cả các tệp được phân phối cho gói chính của ứng dụng bằng cách sử dụng giao thức file: //.AngularJS trên WKWebView: bất kỳ giải pháp nào để xử lý tệp: // trên iOS 9?

Thật không may, có vẻ như WKWebView ban đầu phá vỡ tệp: // giao thức trên iOS 8.x, nhưng một số ánh sáng được truyền khi tôi nhìn thấy API iOS 9 loadFileURL mới (basePath :, allowReadAccessToURL :).

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

Than ôi, khi tôi đặt allowingReadAccessToURL vào thư mục gốc trong bó của tôi (app /), tôi chỉ có những "chỉ số tập tin", không có tập tin không đồng bộ được nạp.

Bất kỳ ai có một số kinh nghiệm về vấn đề đó?

[CẬP NHẬT] Tôi thấy mô tả vấn đề ban đầu của tôi không đủ chính xác. Tôi có HTML của tôi đang chạy. Nhưng các cuộc gọi angularJS không đồng bộ của tôi thực sự bị chặn bởi cơ quan giám sát an ninh trong khung công tác WebKit.

enter image description here enter image description here

+1

Bạn biết bạn có thể kết nối Trình kiểm tra web Safari với WKWebView của bạn để xem lỗi trong bảng điều khiển không? Điều đó có thể cung cấp nhiều gợi ý hơn. –

+0

@stefan arentz Chắc chắn rồi. Tôi đã cải thiện mô tả sự cố của mình bằng ảnh chụp màn hình. –

+0

@stefan arentz Tính năng tuyệt vời! – AppsolutEinfach

Trả lời

6

Mặc dù tôi không có câu trả lời nhanh (có nghĩa là sửa chữa nhanh) Tôi có giải pháp.

Điều này bao gồm việc từ bỏ giao thức tệp: // và chuyển sang http: // qua localhost.

NGẮN ĐÁP

Sau đây là các bước sau:

1) - Cài đặt một máy chủ Web địa phương trong ứng dụng của riêng bạn;

2) - Thiết lập máy chủ Web cục bộ để phân phối từ máy chủ cục bộ tại một cổng đã chọn mà bạn chọn;

3) - Thiết lập đại biểu thực sự phân phát tệp từ tài nguyên ứng dụng của bạn cho loại mime phù hợp;

4) - Ủy quyền bỏ qua iOS9 ATS để xử lý http (và không chỉ https).

Và thì đấy!

CỤ THỂ ĐÁP

1) Cài đặt một máy chủ Web địa phương trong ứng dụng của riêng bạn;

Cài đặt GCDWebServer fro repo Github của nó: https://github.com/swisspol/GCDWebServer

2) Thiết lập các máy chủ Web địa phương để phục vụ từ localhost tại một cổng nhất định bạn

Với thực tế angularjs của bạn hoặc các tập tin ứng dụng HTML được đặt vào thư mục "ứng dụng" trong thư mục tài nguyên của bạn.

Trong vc viewDidLoad của bạn:

@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]; 
} 

3) Thiết lập các đại biểu mà thực sự phục vụ các tập tin từ nguồn tài ứng dụng của bạn cho các loại mime đúng;

-(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); 
} 

4) Ủy quyền cho để bỏ qua iOS9 ATS để xử lý http (và không https chỉ)

Trong file info.plist của bạn trong Xcode, bạn phải thêm một cuốn từ điển có tên là "Cài đặt ứng dụng Giao thông vận tải An ninh "với bên trong một giá trị quan trọng như sau:

NSAllowsArbitraryLoads = true

Hy vọng nó giúp. Bất cứ ai vấp ngã khi một cái gì đó đơn giản được chào đón để trả lời!

2

Như tôi có thể nói, bạn đang làm cho ứng dụng di động và biên dịch nó sau ... Tôi đã có vấn đề khá tương tự. Nhưng đối với tôi xây dựng cuối cùng đã được thực hiện bởi adobe build.phonegap dịch vụ. Và có điều duy nhất tôi phải làm là để thêm cordova-whitelist-plugin trong config.xml như thế này

< gap:plugin name="cordova-plugin-whitelist" source="npm" version="1.0.0" /> 

và hơn thêm sự cho phép để truy cập vào liên kết như vậy

<allow-intent href="file:///*/*" /> 

cũng vào config.xml

Xin lỗi, nếu tôi hiểu bạn sai.

+0

Than ôi, tôi không sử dụng bất kỳ công nghệ của bên thứ ba nào. –

1

Sử dụng GCDWebServer là những gì tôi muốn giới thiệu, bạn có thể chạy máy chủ web cục bộ là http://localhost.

Swift 3,0

  1. Thêm GCDWebServer pod pod "GCDWebServer", "~> 3.0"

  2. Nhấp và kéo AngularJS của bạn thư mục web vào Xcode và khi được nhắc chọn 'Sao chép mục nếu cần thiết' và 'Tạo thư mục tài liệu tham khảo'

  3. Sử dụng mã này trong bộ điều khiển của bạn để chạy máy chủ web cục bộ

    class MainViewController: UIViewController, WKNavigationDelegate, WKScriptMessageHandler, WKUIDelegate, GIDSignInUIDelegate { 
    
    var webView : WKWebView! 
    
    var webServer:GCDWebServer? 
    
    override func viewDidLoad() { 
        super.viewDidLoad() 
        self.webView.load(URLRequest(url: loadDefaultIndexFile()!)) 
    } 
    
    private func loadDefaultIndexFile() -> URL? { 
        self.webServer = GCDWebServer() 
        let mainBundle = Bundle.main 
        // The path to my index.html is www/index.html. If using a default public folder then it could be public/index.html 
        let folderPath = mainBundle.path(forResource: "www", ofType: nil) 
        self.webServer?.addGETHandler(forBasePath: "/", directoryPath: folderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true) 
    
        do { 
         try self.webServer?.start(options: [ 
          "Port": 3000, 
          "BindToLocalhost": true 
          ]); 
        }catch{ 
         print(error) 
        } 
    
    // Path should be http://localhost:3000/index.html 
    return self.webServer?.serverURL 
    } 
    
    } 
    
Các vấn đề liên quan