Writing HTML with HTMLKit in Swift

Continuing my exploration of HTMLKit, I find its potential quite promising. In this post, I delve deeper into leveraging its capabilities to seamlessly integrate HTML into Swift. Along the way, I've written a small web application that fetches stock information, presenting it through both a chart and a data table. I will be sharing specific examples of the Swift code I've authored to achieve these functionalities.

Search form

The search form includes labels, input fields, date pickers, and a submit button, making it easy for you to enter your search details and submit them smoothly.

struct SearchForm: View {
	private let ticker = "ticker"
	private let from = "from"
	private let to = "to"

	private let today = Date().convertToOnlyDate
	private let sevenDaysAgo = Calendar.current.date(
		byAdding: .day, 
		value: -7, 
		to: Date()
	)!.convertToOnlyDate

	var body: Content {
		Form {
			Label {
				"Ticker:"
			}
			Input()
				.type(.text)
				.name(ticker)
				.id(ticker)

			Label {
				"From date:"
			}
			Input()
				.type(.date)
				.name(from)
				.id(from)
				.value(sevenDaysAgo)

			Label {
				"To date:"
			}
			Input()
				.type(.date)
				.name(to)
				.id(to)
				.value(today)

			Button {
				"Search"
			}
			.type(.submit)
		}
		.method(.post)
		.action("/search")
	}
}

Handling the query

This code works behind the scenes, managing the search request on the server, retrieving stock information, and displaying it in the SearchView for you.

func getSearch(_ request: Request) async throws -> Vapor.View {
	let data = try request.content.decode(SearchPayload.self)

	let getStockData = Task {
		return try await Stock.get(search: data)
	}
	let stockData = try await getStockData.value
	return try await request.htmlkit.render(SearchView(stock: stockData))
}

Search results

After searching, you'll land on a page where you can search for another stock. Plus, you'll see the results in a chart and a table for easy understanding.

struct SearchView: View {
	let stock: Stock
	let reversedResults: [Stock.Result]
	let highestClosingPrice: Double

	var body: Content {
		BaseView {
			Main {
				SearchForm()

				Div {
					H1 { stock.ticker }
					StockChart(stock: stock, highestClosingPrice: highestClosingPrice)
					StockTable(reversedResults: reversedResults)
				}
				.id("results")
			}
		}
	}

	init(stock: Stock) {
		self.stock = stock
		reversedResults = stock.results.reversed()
		highestClosingPrice = stock.results.map { $0.closingPrice }.max() ?? 0
	}
}

Thoughts

I find HTMLKit quite capable, especially with its convenient approach to writing HTML in Swift. In my next exploration, I plan to dive into the SwiftUI-like components that HTMLKit provides, discovering more about their functionality.


Category:

Tag:

Year: