Доступ к локальным файлам в WKWebView с помощью JavaScript

У меня есть приложение для iOS, часть логики которого написана на JavaScript. Я создал WKWebView, в который я загружаю свой исходный файл .js, но при выполнении ему нужно читать из других файлов из моих локальных ресурсов. Проблема в том, что я не понимаю, как этого добиться.

Я пробовал загружать каждый отдельный файл один за другим из Swift в webView, но это слишком много файлов, чтобы загружать их вручную.
Хотя, возможно, для Swift есть http-сервер, который будет иметь доступ к файлам проекта. И я нашел такие решения, как это или это.
Подход выглядит великолепно, но даже если я это сделаю, я все равно не смогу получить доступ к файлам и папкам из моей структуры проекта Xcode. Я создал базовый http-сервер, а также DAV-сервер, добавил обработчики GET и т. д.

Возможно, я что-то не так настроил, но в конце, когда я создаю объект http server, Я все еще могу получить к нему доступ с моего webView в http://192.168.0.11:8080, так что наверняка он правильно инициализирован и работает.


person mcgtrt    schedule 16.12.2020    source источник
comment
Наличие веб-сервера, работающего в вашем приложении только для обслуживания файлов, выглядит излишним (подумайте о бедных пользователях вашего приложения). И нет, вы не можете получить доступ к файлам проекта напрямую из WebView. Но вы можете внедрить то, что вам нужно, на страницу, используя метод evaluateJavaScript. С одной стороны у вас есть собственный компонент (какой-то класс), который имеет доступ к локальным файлам. В середине у вас есть WKWebView.evaluateJavaScript, который может отправлять данные на страницу внутри WKWebView (используя обмен сообщениями или внедрение JavaScript). Затем внутри веб-страницы вы сможете либо прослушивать сообщения, либо читать введенные вами переменные.   -  person Kiril S.    schedule 17.12.2020


Ответы (1)


Отвечая на мой вопрос, это поможет кому-то в будущем. В конце я использовал эту библиотеку. И похоже, что отсутствовала какая-то конфигурация, поэтому сервер динамически обслуживает все страницы и файлы. Мой код:

guard let websitePath = Bundle.main.path(forResource: "myFolderNameInProjectStructure", ofType: nil) else { return }
let httpServer = GCDWebServer()
httpServer.addGETHandler(forBasePath: "/", directoryPath: websitePath, indexFilename: nil, cacheAge: 3600, allowRangeRequests: true)
httpServer.addHandler(forMethod: "GET", pathRegex: "/.*\\.html", request: GCDWebServerRequest.self) { (request) in
    return GCDWebServerDataResponse(htmlTemplate: websitePath + request.path, variables: ["variable": "value"])
}
httpServer.start(withPort: 8080, bonjourName: "MC Local Server")

Когда эта конфигурация выполнена и сервер работает на порту по вашему выбору (у меня 8080), вы просто открываете встроенный браузер внутри приложения (например, WKWebView) и загружаете

let url = URL(string: "http://localhost:8080/index.html")!
webView.load(URLRequest(url: url))

Если вы просто хотите всегда запускать index.html при подключении к / http-сервера, вы можете добавить эту конфигурацию перед методом httpServer.start():

httpServer.addHandler(forMethod: "GET", path: "/", request: GCDWebServerRequest.self) { (request) in
    return GCDWebServerResponse(redirect: URL(string: "index.html")!, permanent: true)
}

А теперь в webView просто подключитесь к http://localhost:8080 и файл, который вы указали как GCDWebServerResponse, загрузится.

person mcgtrt    schedule 18.12.2020