ios - type - WKWebView carga recursos desde la carpeta de documentos local
wkwebview before ios 11.0(nscoding support was broken in previous versions) (5)
Método Swift 4
Este método le permite a WKWebView leer correctamente su jerarquía de directorios y subdirectorios para archivos CSS / JS vinculados. NO necesita cambiar su código HTML, CSS o JS.
Actualizado para Xcode 9.3
Paso 1
Importe la carpeta de archivos web locales en cualquier lugar de su proyecto. Asegúrese de que usted:
☑️ Copiar elementos si es necesario
Create️ Crear referencias de carpeta (no "Crear grupos")
☑️ Añadir a objetivos
Paso 2
Vaya a View Controller con WKWebView y agregue el siguiente código al método viewDidLoad
:
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
-
index
: el nombre del archivo a cargar (sin la extensión.html
) -
website
: el nombre de su carpeta web (index.html
debe estar en la raíz de este directorio)
Conclusión
El código general debe verse algo como esto:
import UIKit
import WebKit
class ViewController: UIViewController, WKUIDelegate, WKNavigationDelegate {
@IBOutlet weak var webView: WKWebView!
override func viewDidLoad() {
super.viewDidLoad()
webView.uiDelegate = self
webView.navigationDelegate = self
let url = Bundle.main.url(forResource: "index", withExtension: "html", subdirectory: "Website")!
webView.loadFileURL(url, allowingReadAccessTo: url)
let request = URLRequest(url: url)
webView.load(request)
}
}
Si alguno de ustedes tiene más preguntas sobre este método o el código, haré todo lo posible para responder. :)
En mi aplicación Swift para iOS, quiero descargar algunas páginas HTML dinámicas desde un servidor remoto, guardarlas en el directorio de documentos y mostrar esas páginas desde el directorio de documentos.
Estaba usando esto para cargar la página:
var appWebView:WKWebView?
...
appWebView!.loadRequest(NSURLRequest(URL: NSURL(fileURLWithPath: htmlPath)))
Todo funciona en el simulador, pero cuando me cambié a teléfonos reales, solo mostraba una página en blanco. Luego me conecté a la aplicación usando Safari, y encontré que se quejaba con "No se pudo cargar el recurso".
Luego intenté leer primero el contenido de la página en htmlPath
, luego usar
appWebView!.loadHTMLString()
para cargar la página. Funciona cuando la página HTML es simple. Pero si el HTML hace referencia a otra cosa, es decir, un archivo JavaScript también en el directorio del documento (con una ruta absoluta como <script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">
), no se cargará.
¿Alguien sabe por qué sucede esto y cómo resolver el problema?
Más información:
- Versión XCode: 7.3.1
- Destino de implementación: 8.1 (también intenté usar 9.3, pero eso no ayudó).
Compruebe ese ticket: iOS: ¿Cómo cargar archivos locales (no en el paquete) en un WKWebView?
var nsurl = URL(fileURLWithPath: URL(fileURLWithPath: URL(fileURLWithPath: documentsDirectory()).appendingPathComponent(user_appli).absoluteString).appendingPathComponent("index.html").absoluteString) //locally
var readAccessToURL: URL? = nsurl.deletingLastPathComponent?.deletingLastPathComponent
if let anURL = readAccessToURL {
webView?.loadFileURL(nsurl, allowingReadAccessTo: anURL)
}
Esta es una versión simplificada de lo que he usado para cargar archivos locales en un proyecto mío (iOS 10, Swift 3). Acabo de actualizar mi código (7.5.2017) después de probarlo nuevamente en iOS 10.3.1 y iPhone 7+ según lo solicitado por Raghuram y Fox5150 en los comentarios.
Acabo de crear un proyecto completamente nuevo y esta es la estructura de carpetas:
Actualización 19.04.2018: Se agregó una nueva función para descargar un archivo .zip con HTML, CSS, JS, descomprimirlo en / Documents / (Alamofire + Zip) y luego cargar esos archivos en el webView. Puedes encontrarlo en el proyecto de ejemplo GitHub también. Una vez más, siéntase libre de tenedor y estrella! :)
Actualización 08.02.2018: finalmente se agregó un proyecto de ejemplo de GitHub , que también incluye un archivo JavaScript local. Siéntete libre de tenedor y estrella! :)
Versión 1 con webView.loadFileURL ()
ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let htmlUrl = URL(fileURLWithPath: htmlPath!, isDirectory: false)
webView.loadFileURL(htmlUrl, allowingReadAccessTo: htmlUrl)
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Versión 2 con webView.loadHTMLString ()
ViewController.swift
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let webView = WKWebView()
let htmlPath = Bundle.main.path(forResource: "index", ofType: "html")
let folderPath = Bundle.main.bundlePath
let baseUrl = URL(fileURLWithPath: folderPath, isDirectory: true)
do {
let htmlString = try NSString(contentsOfFile: htmlPath!, encoding: String.Encoding.utf8.rawValue)
webView.loadHTMLString(htmlString as String, baseURL: baseUrl)
} catch {
// catch error
}
webView.navigationDelegate = self
view = webView
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Gotchas a tener en cuenta:
- Asegúrese de que sus archivos html / js / css locales estén en Proyecto -> Destino -> Fases de compilación -> Copiar recursos del paquete
- Asegúrese de que sus archivos html no hagan referencia a las rutas relativas, por ejemplo,
css/styles.css
porque iOScss/styles.css
su estructura de archivos y styles.css estará en el mismo nivel que index.html, por lo tanto escriba<link rel="stylesheet" type="text/css" href="styles.css">
lugar
Dadas las 2 versiones y las trampas aquí están mis archivos html / css del proyecto:
web / index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Offline WebKit</title>
<link rel="stylesheet" type="text/css" href="styles.css">
</head>
<body>
<h1 id="webkit-h1">Offline WebKit!</h1>
</body>
</html>
web / css / styles.css
#webkit-h1 {
font-size: 80px;
color: lightblue;
}
Si alguien quiere un proyecto de muestra de GitHub, dímelo en la sección de comentarios y lo subiré.
Esta solución me ayudó a:
[configuration.preferences setValue:@YES forKey:@"allowFileAccessFromFileURLs"];
Esto funciona bien (Swift 3, Xcode 8):
import UIKit
import WebKit
class ViewController: UIViewController, WKNavigationDelegate {
var webView: WKWebView!
override func loadView() {
webView = WKWebView()
webView.navigationDelegate = self
view = webView
}
override func viewDidLoad() {
super.viewDidLoad()
if let url = Bundle.main.url(forResource: "file", withExtension: "txt")
{
do
{
let contents = try String(contentsOfFile: url.path)
webView.loadHTMLString(contents, baseURL: url.deletingLastPathComponent())
}
catch
{
print("Could not load the HTML string.")
}
}
}
}