load local file in webview ios using http protocol. (Create Webview server in iOS)

Is there any way to create the server in iOS to run a web-view? I want to run a local HTML file in a web-view with a local-host URL.

I have already searched for this on google and found this two links 1) https://github.com/swisspol/GCDWebServer and 2) https://izeeshan.wordpress.com/2014/08/25/local-http-server-for-ios/ but could not find any solution.


Can anyone help me with the local server implementation in uiwebview?


Thanks in advance.

Replies

You can do that, but you shouldn't. You also shouldn't use UIWebView. Use WKWebView and load your HTML as a string. If you have supporting resources, pass a file URL to the directory in your app's resources where those web view resources are located.

john daniel

Please find below steps which indicates my actual issue.


1) Download ".zip" file from server and save it on application library directory for offline use.


2) ".zip" file contents html and javascript files. It works when the HTML page is simple. But if the HTML references something else, i.e. a JavaScript file also in the library directory (with an absolute path like <script src="file:////var/mobile/Containers/Data/Application/762035C9-2BF2-4CDD-B5B1-574A0E2B0728/Documents/xxxxx.js">), it will fail to load.


3) I want to setup local server in my device, On application launch local server starts and upload the application library directory on local server and then load the content using local host. See below example


- Using Library directory path


file:////Users/prince/Library/Developer/CoreSimulator/Devices/75EF3DD7-DFD1-4EDB-9A6B-9FBA60F4D98C/data/Containers/Data/Application/32F774B2-E811-4281-A37A-DC8A5183B7C8/Library/Application%20Support/adededfe6c1c7bd8b5d5adb19861b9e0/Responses/36b8f6a8d6f58d58f117856dc80b0d37/abc.html



- Using localhost path


http://localhost:8080/Application%20Support/adededfe6c1c7bd8b5d5adb19861b9e0/Responses/36b8f6a8d6f58d58f117856dc80b0d37/abc.html


Does anyone know why this happens, and how to resolve the issue?

Most local file access problems with

WKWebView
come down to the fact that folks aren’t initiating the load correctly. Specifically, you must use
loadFileURL(_:allowingReadAccessTo:)
, using the second parameter to define the scope of files that can be loaded by the web content.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

1. That's fine


2. You have to be careful with your paths. You need to make sure the entire local HTML site you want to serve is in the same directory. You won't be able to use absolute URLs. Refer to the method posted by eskimo. You start with a file URL to the main HTML file. Then you supply a file URL to the directory that contains all of the resources. Instead of that absolute URL, you would just use a relative URL - just "xxxxx.js".


3. Technically you can do that, but it is not a solution to this problem. Once you get the files in the same directory and you can load them with the "loadFileURL" method, you're done. You don't need an embedded server for this.

Hereby i'm sharing the whole demo code that i'm trying to achive the result :


CocoaPod Used :

platform :ios, '11.0'

inhibit_all_warnings!

use_frameworks!


target 'LocalWKWebView' do

pod 'Alamofire'

source 'https://github.com/CocoaPods/Specs.git'

pod 'Zip', '~> 1.1'

pod 'Swifter', '~> 1.4.7'

end



Source Code :


import UIKit

import WebKit

import Alamofire

import Zip

import Swifter

import Dispatch


//class ViewController: UIViewController, WKNavigationDelegate {

class ViewController: UIViewController,UIWebViewDelegate {


@IBOutlet weak var webView : UIWebView!


/*

Used to download and unzip the zip file with the custom CSS, JS

*/

func downloadFile(completionHandler: @escaping (URL?, Error?) -> ()) {

let destination: DownloadRequest.DownloadFileDestination = { _, _ in

let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]

let fileURL = documentsURL.appendingPathComponent("314431eb61594e1f9ad759e579760ef8.zip")

return (fileURL, [.removePreviousFile, .createIntermediateDirectories])

}

let downloadURL = "https://abc.s3.amazonaws.com/314431eb61594e1f9ad759e579760ef8.zip"

let downloadParameters : Parameters = ["":""]


Alamofire.download(downloadURL, method: .get, parameters: downloadParameters, encoding: JSONEncoding.default, to: destination)

.downloadProgress { progress in

print("Download Progress: \(progress.fractionCompleted)")

}

.response(completionHandler: { (DefaultDownloadResponse) in

if DefaultDownloadResponse.response?.statusCode == 200 {


let fm = FileManager.default

let documentsURL = try! fm.url(for:.documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)

let fileURL = documentsURL.appendingPathComponent("314431eb61594e1f9ad759e579760ef8.zip")


if(fm.fileExists(atPath: fileURL.path)) {

print("Download complete at: \(fileURL.absoluteString)")

do {

try Zip.unzipFile(fileURL, destination: documentsURL, overwrite: true, password: "", progress: { (progress) -> () in

print("Unzip Progress: \(progress)")

})

completionHandler(fileURL, nil)

}

catch {

print("Couldn't unzip")

completionHandler(nil, error)

}

}

}

})

}


override func viewDidLoad() {

super.viewDidLoad()



let path = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String

let url = NSURL(fileURLWithPath: path)

if let pathComponent = url.appendingPathComponent("314431eb61594e1f9ad759e579760ef8") {


let filePath = pathComponent.path

let fileManager = FileManager.default

if fileManager.fileExists(atPath: filePath) {

print("FILE AVAILABLE")

let folderURL = url

let htmlPath = folderURL.appendingPathComponent("ator.html")?.path

let folderPath = folderURL.path

print(folderPath)

let baseUrl = URL(fileURLWithPath: folderPath!, isDirectory: true)

print(baseUrl)

let htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)

// webView.loadFileURL(htmlURL, allowingReadAccessTo: folderURL!)

//Thitrd party swiftwer used to create localhost server


let httpServer = demoServer(folderPath ?? "")

// httpServer["/:prince"] = shareFilesFromDirectory(Bundle.main.path(forResource: "Web", ofType: nil)!)

httpServer["/:path"] = shareFilesFromDirectory(folderPath ?? "")

do {

try httpServer.start(8080)

let myRequest = NSURLRequest(url: NSURL(string: "http://localhost:8080/story_html5.html")! as URL)

print("myRequest>>",myRequest)

self.webView.loadRequest(myRequest as URLRequest)

}catch{

print("erororor")

}

} else {

print("FILE NOT AVAILABLE")

self.downlaodfileandunzip()

}

} else {

print("FILE PATH NOT AVAILABLE")

self.downlaodfileandunzip()

}

}


func downlaodfileandunzip(){

let loadCustomFiles = true

if(loadCustomFiles) {

// download & load custom files from remote URL

downloadFile(completionHandler: { url, error in

if(url != nil) {

let folderURL = url?.deletingPathExtension()

let htmlPath = folderURL?.appendingPathComponent("ator.html").path


let folderPath = folderURL?.path

print(folderPath)

let baseUrl = URL(fileURLWithPath: folderPath!, isDirectory: true)

print(baseUrl)

let htmlURL = URL(fileURLWithPath: htmlPath!, isDirectory: false)

// webView.loadFileURL(htmlURL, allowingReadAccessTo: folderURL!)

let httpServer = demoServer(folderPath ?? "")

// httpServer["/:prince"] = shareFilesFromDirectory(Bundle.main.path(forResource: "Web", ofType: nil)!)

httpServer["/:path"] = shareFilesFromDirectory(folderPath ?? "")

do {

try httpServer.start(8080)

let myRequest = NSURLRequest(url: NSURL(string: "http://localhost:8080/ator.html.html")! as URL)


print("myRequest>>",myRequest)

self.webView.loadRequest(myRequest as URLRequest)

}catch{

print("erororor")

}

} else {

print(error)

}

})

} else {

// load normal files from /web

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)

// / webView.navigationDelegate = self

self.view = webView

} catch {

// error handling

}

}

}





override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

}

}


issue : I'm trying to load the file using localhost as well as using webView.loadFileURL(htmlURL, allowingReadAccessTo: folderURL!) but it wont work.


Reference link Stack Overflow : https://stackoverflow.com/questions/58946593/load-local-file-in-webview-ios-using-http-protocol-create-webview-server-in-an


DropBox : https://www.dropbox.com/sh/70fgj7bwcmwz0k9/AACR5sLB-zrE7rkEmta_GoVqa?dl=0


Can anyone help me with the localhost server setup?

Sorry, I'm not going to learn and then install CocoaPods, Alamofire, Zip, Swifter?, etc. If you had a stand-alone project, I might have downloaded that.


I can give you some speculations.

1) Your example project seems to be trying at least 3 different things, including the one, super-difficult thing I told you not to try (and embedded server), and commenting out the one, super-easy thing that eskimo and I told you to do (loadFileURL).

2) When you start down a path of maximum complexity, you are going to have to deal with those complexities and figure them out before you can ever get to that really simple thing you are trying to accomplish. You seem to have a really complex chicken-and-egg problem there. I don't know if it is worth dealing with.

See if this helps: My findings in quest to preview and test website dev simple html basic stuff on iOS locally since a few years back Apple deciding to ruin the ability to launch Apache built in on MacOS plus made it apparently impossible to test on IOS iPad local pages or run a whole standard mini site offline.

I'm using WorldWideWeb by icon factory to preview and test website dev simple html basic stuff on iOS locally https://blog.iconfactory.com/2022/06/worldwideweb-part-2/

see also - I'm not fully sure if Vapor is the swift server or the framework to build one smh https://vapor.codes

https://www.raywenderlich.com/31498014-running-a-web-server-on-ios-with-vapor