1

I need to initialize a GCDWebServer with two paths for different local resources (HTML5 games).

Now I can create a path only for one resource with addGETHandler. This handler can be used once if you will use it again, the old handler will be removed, and the new one will take its place.

This is my code:

let firstGameFolderPath = Bundle.main.path(forResource: "game1", ofType: nil)
ServerService.gcdWebServer.addGETHandler(forBasePath: "/", directoryPath: firstGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
ServerService.gcdWebServer.start(withPort: 8080, bonjourName: "GCD Web Server")

If someone has any ideas how to solve this task it will be nice.

P.S. I had the idea to create 2 servers with different ports, but it's too expensive.

Controller where all happens (method didSelectRowAt):

import UIKit

class MenuViewController: UITableViewController, UINavigationControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.tableFooterView = UIView()
        self.navigationController?.delegate = self
    }

    // MARK: - Table view data source

    override func numberOfSections(in tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 3
    }

    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let menuCell = tableView.dequeueReusableCell(withIdentifier: "MenuCell") as? MenuTableViewCell
        switch indexPath.row {
        case 0:
            menuCell?.updateCell(title: "Главная")
        case 1:
            menuCell?.updateCell(title: "Первая игра")
        case 2:
            menuCell?.updateCell(title: "Вторая игра")
        default:
            break
        }
        return menuCell!
    }

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let menuCell = tableView.cellForRow(at: indexPath) as! MenuTableViewCell

        switch indexPath.row {
        case 0:
            self.view.window!.rootViewController?.dismiss(animated: true, completion: nil)
        case 1:
            menuCell.activityIndicator.startAnimating()
            let firstGameFolderPath = Bundle.main.path(forResource: "game1", ofType: nil)
            ServerService.gcdWebServer.addGETHandler(forBasePath: "/", directoryPath: firstGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
            ServerService.gcdWebServer.start(withPort: 8080, bonjourName: "GCD Web Server")
            self.perform(#selector(showGameVC), with: nil, afterDelay: 1) //Delay for launching WebServer
        case 2:
            menuCell.activityIndicator.startAnimating()
            let secondGameFolderPath = Bundle.main.path(forResource: "game2", ofType: nil)
            ServerService.gcdWebServer.addGETHandler(forBasePath: "/", directoryPath: secondGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
            ServerService.gcdWebServer.start(withPort: 8080, bonjourName: "GCD Web Server")
            self.perform(#selector(showGameVC), with: nil, afterDelay: 1) //Delay for launching WebServer
        default:
            break
        }

        tableView.deselectRow(at: indexPath, animated: true)
    }

    @objc func showGameVC() {
        let gameViewController = self.storyboard?.instantiateViewController(withIdentifier: "GameVC") as! GameViewController
        self.navigationController?.pushViewController(gameViewController, animated: true)
    }
} 

Link to repo

MrTishman
  • 77
  • 7

2 Answers2

1

You can add as many handlers as you want to a GCDWebServer, so simply add another one with a different directory path AND a different base path:

ServerService.gcdWebServer.addGETHandler(forBasePath: "/assets1/", directoryPath: firstGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
ServerService.gcdWebServer.addGETHandler(forBasePath: "/assets2/", directoryPath: secondGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)

This handler can be used once if you will use it again, the old handler will be removed, and the new one will take its place.

That's not true, handlers are never removed unless you call -removeAllHandlers - see https://github.com/swisspol/GCDWebServer/blob/master/GCDWebServer/Core/GCDWebServer.m.

Pol
  • 3,848
  • 1
  • 38
  • 55
0

You can try giving different base paths to them.

let firstGameFolderPath = Bundle.main.path(forResource: "game1", ofType: nil)
ServerService.gcdWebServer.addGETHandler(forBasePath: "/game1", directoryPath: firstGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
ServerService.gcdWebServer.start(withPort: 8080, bonjourName: "GCD Web Server")

let secondGameFolderPath = Bundle.main.path(forResource: "game2", ofType: nil)
ServerService.gcdWebServer.addGETHandler(forBasePath: "/game2", directoryPath: secondGameFolderPath!, indexFilename: "index.html", cacheAge: 0, allowRangeRequests: true)
ServerService.gcdWebServer.start(withPort: 8080, bonjourName: "GCD Web Server")

and then when you need to load the game you can add the same game1 or game2 to your post request url.

like this

let game1Request = URLRequest(url: URL(string:"{YourGCDWebServerURL}/game1")!)
let game2Request = URLRequest(url: URL(string:"{YourGCDWebServerURL}/game2")!)
nishith Singh
  • 2,968
  • 1
  • 15
  • 25
  • Yea, I did it, but here's a BIG problem) The serverURL is available 2-3 seconds after starting the server. This is not very convenient when you switch between resources, and you have to set a delay. I will add my swift file to topic for better understanding. – MrTishman Jan 26 '19 at 11:27
  • I mean: better run server with 2 resources (for example) in viewDidAppear, and when UIView loads, we will have running server with serverURL. – MrTishman Jan 26 '19 at 11:34
  • Your code file would help. If your application use case allows you can also try loading the GCDWebServer when your application loads. Say in applicationDidFinishLaunching. That way you will have it ready when your view appears – nishith Singh Jan 26 '19 at 14:12