2015-10-13 7 views
10

Sto effettuando il porting di un'enorme app angularJS su iOS 9 e volevo beneficiare di WKWebView (migrazione da UIWebView). L'app è autonoma a livello locale, quindi tutti i file vengono serviti per il pacchetto principale dell'app utilizzando il protocollo file: //.AngularJS su WKWebView: qualsiasi soluzione per la gestione del file: // su iOS 9?

Sfortunatamente, sembra che WKWebView interrompa originariamente il file: // protocollo su iOS 8.x, ma alcune luci sono state lanciate quando ho visto la nuovissima API 9 loadFileURL (basePath :, allowReadAccessToURL :) API.

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

Ahimè, mentre ho impostato allowingReadAccessToURL nella cartella principale all'interno del mio pacco (APP /), ho avuto solo il "file di indice", nessun file asincrono vengono caricati.

Chi ha qualche esperienza con questo problema?

[AGGIORNAMENTO] Vedo che la mia descrizione del problema iniziale non era sufficientemente accurata. Ho il mio codice HTML in esecuzione. Ma le mie chiamate angularJS asincrone sono effettivamente bloccate dal watchdog di sicurezza nel framework WebKit.

enter image description here enter image description here

+1

Sai che puoi connettere Safari Web Inspector a WKWebView per vedere gli errori nella console? Questo potrebbe fornire ulteriori suggerimenti. –

+0

@stefan arentz certo. Ho migliorato la descrizione del mio problema con schermate. –

+0

@stefan arentz Grande funzionalità! – AppsolutEinfach

risposta

6

Anche se non ho una risposta rapida (intendo una soluzione rapida) ho una soluzione.

Si tratta di rinunciare al file: // protocollo e passare a http: // su localhost.

BREVE RISPOSTA

Ecco i passaggi:

1) - Installare un server Web locale nel proprio app;

2) - Impostare il server Web locale per servire da localhost su una determinata porta di propria scelta;

3) - Impostare il delegato che effettivamente serve il file dalle risorse dell'app dato il giusto tipo di mime;

4) - Autorizza a bypassare iOS9 ATS per gestire http (e non solo https).

E voilà!

DETTAGLIATA RISPOSTA

1) Installare un server Web locale nel proprio app;

Installare il GCDWebServer fro suo repo GitHub: https://github.com/swisspol/GCDWebServer

2) Configurazione del server Web locale per servire da localhost ad una data porta del

Dato tuoi angularjs o file app HTML si trovano nella cartella "app" nella cartella delle risorse.

Nel vostro 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]; 
} 

3) Impostare il delegato che in realtà servono il file dalla tua applicazione ressources dato il tipo MIME destra;

-(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) Autorizzazione per bypassare iOS9 ATS per gestire http (https e non solo)

Nel file info.plist in Xcode, è necessario aggiungere un dizionario di nome "Impostazioni App Transport Security "con al suo interno un valore-chiave come segue:

NSAllowsArbitraryLoads = true

Speranza che aiuta. Chiunque imbattersi in qualcosa di più semplice è il benvenuto a rispondere!

2

Come posso dire, si stanno facendo applicazione mobile e compilarlo dopo ... ho avuto problema abbastanza simile. Ma per me la build finale è stata fatta dal servizio di adobe build.phonegap. E c'è l'unica cosa che ho dovuto fare è aggiungere Cordova-whitelist-plugin in config.xml come questo

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

e di aggiungere l'autorizzazione per l'accesso a tali collegamenti

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

anche in config.xml

Scusa, se ho capito che hai torto.

+0

Ahimè, non sto usando alcuna tecnologia di terze parti. –

1

L'utilizzo di GCDWebServer è quello che consigliamo, è possibile eseguire un server Web locale come http://localhost.

Swift 3,0

  1. Aggiungere GCDWebServer pod pod "GCDWebServer", "~> 3.0"

  2. Fare clic e trascinare i AngularJS cartella web in Xcode e, quando richiesto selezionare 'Copia elementi, se necessario' e 'Crea cartella riferimenti'

  3. Utilizzare questo codice nel controller per eseguire un server Web localhost

    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 
    } 
    
    }