A minimal, fast and unopinionated web framework for Swift

Related tags

Networking blackfire
Overview

![Fire Image] (http://i.imgur.com/1qR6Nl4.png)

Blackfire

An extremely fast Swift web framework

Swift Version SwiftPM compatible License Apache Plaforms

πŸ”₯ Getting Started

If you're familiar with express.js then Blackfire will be known to you. The most simple example of how to use can be seen below:

main.swift

import Blackfire

// Create a nice new πŸ”₯ app for us to play with.
let app = Flame()

// Let's add a route to begin with.
app.get("/") { (req, res) in
  res.send(text: "Hello World")
}

app.start(port: 3000) { result in
  switch result {
    case .success:
      print("Server started on port 3000")
    case .failure(let error):
      print("Server failed with error: \(error)")
  }
}
$ curl localhost:3000 
Hello World%

🎁 Features

Blackfire has all the standard features of a typical minimal Web Framework, let's take a look at some of these.

πŸ”± Routing

Routing, as seen in the above example, takes place by assigning a handler to a method in your App

app.get("/") { (req, res) in
  res.send(text: "I'm a GET request")
}
app.post("/users") { (req, res) in
  res.send(text: "I'm a POST request to /users")
}
app.delete("/all/files") { (req, res) in
  res.send(text: "I'm a DELETE request to /all/files ...wait")
}
app.put("/em/up") { (req, res) in
  res.send(text: "I'm a PUT request to /em/up Am I being robbed?")
}

This can become tedious if you have a lot of /users/<something> routes however, so we created the........

πŸ’ Router

Don't be scared that it's a monkey handling it, he had a pretty decent job interview on the whiteboard and seems to be doing ok.

The router object allows you to group routes together. For example

let users = Router()
users.get("/") { req, res in
  res.send(text: "Get me all the users")
}
users.post("/") { req, res in
  res.send(text: "Creating a new user")
}
users.get("/favourites") { req, res in
  res.send(json: ["food": "🍌"])
}

// Let's use the router to match for /users
app.use("/users", users)
$ curl localhost:3000/users
Get me all the users%
$ curl localhost:3000/users/favourites
{"food":"🍌"}%

Powerful stuff.

πŸ“« Request

The request or req object contains a bunch of helpful information that your handler may want to use:

These include:

  • request.params A key value pair of Strings that are matched in the route
  • request.body The raw body of the recieved request, in the form of a String
  • request.headers A key value pair of Strings of the headers that appeared in the route
  • request.method The method of this request, formed from the HTTPMethod enum.
  • request.path The path of this request
  • request.httpProtocol The protocol for this request.

πŸ“£ Response

The response or res object contains everything you need to return data back to the consumer

  • res.send(text: String) Send back a basic text response in the form of Content-Type: text/plain
  • res.send(json: Any) Send back some JSON, takes in a JSON parseable object. This method can fail if the object is not parseable
  • res.send(status: Int) Send back a HTTP status with no body
  • res.send(html: String) Send back some html with the header of Content-Type: text/html
  • res.send(error: String) Sends back an error, setting the status to 500.
  • res.headers Set some headers to send back to the client

🐈 Threading

Threading is a contentious issue when it comes to web frameworks, the age old question of Single vs Multithreaded is enough to start a flame war.

So let's fight the fire with fire and solve it once and for all.

πŸ‘Έ Queue Types

A Flame app can take a type of either .serial or .concurrent. These do exactly as they say on the tin and allow for either all requests to be handled via DispatchQueue.main or DispatchQueue.global().

Why did we do this?

We think that giving you the power to choose which type you want for your app is a good thing. We're not sorry.

Just as an FYI, we chose to go with .serial as the default setting. It was a 50/50 chance we got it right. Good thing it can be changed.

Example

// An app which handles only on the main thread.
let app = Flame(type: .serial)

// An app which handles on multiple concurrent threads.
let app = Flame(type: .concurrent)
Comments
  • Database connector

    Database connector

    Hi, I really like your work because I'm a fan of Express.js and I think swift would be very interesting switch.

    I think it would be very interesting to add some DB connectors (eg. MySQL/MariaDB and MongoDB) as default one in order to provide more appeal to blackfish project. What do you think?

    enhancement 
    opened by matteocrippa 21
  • 500 Internal Server Error (InvalidPath) on seemingly trivial routes

    500 Internal Server Error (InvalidPath) on seemingly trivial routes

    My app is set up as follows:

    let app = Blackfish()
    let model = Model()
    
    app.use(renderer: StencilRenderer(), ext: ".stencil")
    
    app.get("/") { request, response in
      response.render("index.stencil")
    }
    app.get("/students.html") { request, response in
      response.render("students.stencil", data: ["students": model.students])
    }
    
    app.use(path: "/api/students", controller: StudentController(model: model))
    app.use(path: "/api/courses", controller: CourseController(model: model))
    
    app.listen(port: 3000) { error in
      print(error ?? "BlackFishTest listening on port 3000")
    }
    

    The error is related to the paths / and /students.html. The paths starting with api still work as before. Files index.stencil and students.stencil are in the Resources folder. What's wrong here?

    I'm using the February 8 build on Ubuntu.

    opened by svanimpe 14
  • JSON input

    JSON input

    It is unclear to me whether Blackfish supports JSON input or not. I've tried sending a POST request with JSON in the body, but cannot find any properties on request to read it. There is a body property, but that's internal and simply a byte array.

    opened by svanimpe 13
  • Is blackfish using non-blocking IO

    Is blackfish using non-blocking IO

    Hey cool project! I took a quick look at the source code and I see that you are using recv to read data from the socket. As far as I know that function blocks if there is no data to be read. Did I get this right? Are you planning to add non-blocking IO in the near feature?

    opened by guidomb 8
  • no targets found for file layout

    no targets found for file layout

    Hi,

    Stupid question and not especially relative to blackfish but this is with your library I'm testing packages ... Inside my project folder I created a Package.swift :

    import PackageDescription
    
    let package = Package (
        name: "Blackfish",
        dependencies: [
            .Package(url: "https://github.com/elliottminns/blackfish", majorVersion: 0),
        ]
    )
    

    When I run swift build I have this output error : error: no targets found for this file layout I'm sure I'm doing something very wrong but can't find what ...

    Any help please ? πŸ˜…

    opened by abiaad 7
  • JSON parsing bug

    JSON parsing bug

    Swift: Apple Swift version 3.0.2 (swift-3.0.2-RELEASE) Target: x86_64-apple-macosx10.9

    Xcode: Xcode 8.2.1 (8C1002)

    OS: macOS 10.12.2

    Function: public func send(json: Any) { self.headers["Content-Type"] = "application/json" do { let data = try JSONSerialization.data(withJSONObject: json, options: []) self.body = Buffer(data: data) } catch { self.status = 500 } send() }

    P.s: JSONSerialization.isValidJSONObject(json) => false

    Result: Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** +[NSJSONSerialization dataWithJSONObject:options:error:]: Invalid top-level type in JSON write' *** First throw call stack: ( 0 CoreFoundation 0x00007fffc73c1e7b exceptionPreprocess + 171 1 libobjc.A.dylib 0x00007fffdbfaccad objc_exception_throw + 48 2 CoreFoundation 0x00007fffc744099d +[NSException raise:format:] + 205 3 Foundation 0x00007fffc8d5dd5c +[NSJSONSerialization dataWithJSONObject:options:error:] + 249 4 Blackfire 0x000000010068ebbe TFC9Blackfire12HTTPResponse4sendfT4jsonP__T + 702 5 OwnServer 0x00000001000024c0 TF9OwnServerU2_FTC9Blackfire7RequestCS0_12HTTPResponse_T + 224 6 Blackfire 0x00000001006934d3 TTRXFo_oC9Blackfire7RequestoCS_12HTTPResponse__XFo_iTS0_S1___iT + 35 7 Blackfire 0x0000000100693571 TPA__TTRXFo_oC9Blackfire7RequestoCS_12HTTPResponse__XFo_iTS0_S1___iT + 81 8 Blackfire 0x0000000100697507 TTRXFo_iTC9Blackfire7RequestCS_12HTTPResponse__iT__XFo_oS0_oS1__ + 39 9 Blackfire 0x000000010069726a TFFV9Blackfire14RequestHandler6handleFT7requestCS_11HTTPRequest8responseCS_12HTTPResponse_T_U_FFTCS_7RequestS2__T_T + 90 10 Blackfire 0x00000001006973be TTRXFo_oXFo_oC9Blackfire7RequestoCS_12HTTPResponse___zoPs5Error__XFo_iXFo_iTS0_S1___iT___zoPS2__ + 126 11 libswiftCore.dylib 0x0000000100775dd5 TFEsPs8Sequence7forEachfzFzWx8Iterator7Element_T_T + 389 12 Blackfire 0x0000000100697084 TFV9Blackfire14RequestHandler6handlefT7requestCS_11HTTPRequest8responseCS_12HTTPResponse_T + 1076 13 Blackfire 0x00000001006839e1 TFC9Blackfire5Flame6serverfTCS_10HTTPServer10didReceiveCS_11HTTPRequest8responseCS_12HTTPResponse_T + 161 14 Blackfire 0x0000000100683a53 TTWC9Blackfire5FlameS_18HTTPServerDelegateS_FS1_6serverfTCS_10HTTPServer10didReceiveCS_11HTTPRequest8responseCS_12HTTPResponse_T + 67 15 Blackfire 0x0000000100690f80 TFFC9Blackfire10HTTPServer6serverFTCS_6Server19didCreateConnectionPS_10Connection__T_U_FTCS_6BufferSi_T + 800 16 Blackfire 0x00000001006856d5 TFFC9Blackfire16SocketConnection4readFT8callbackFTCS_6BufferSi_T__T_U_FT_T + 453 17 Blackfire 0x00000001006857f7 TTRXFo___XFdCb__ + 39 18 libdispatch.dylib 0x00000001006e5f5c _dispatch_client_callout + 8 19 libdispatch.dylib 0x00000001006fcb15 _dispatch_continuation_pop + 1025 20 libdispatch.dylib 0x00000001006f2658 _dispatch_source_latch_and_call + 195 21 libdispatch.dylib 0x00000001006e8da5 _dispatch_source_invoke + 1106 22 libdispatch.dylib 0x00000001006feca7 _dispatch_root_queue_drain_deferred_item + 704 23 libdispatch.dylib 0x00000001007038f0 _dispatch_kevent_worker_thread + 983 24 libsystem_pthread.dylib 0x000000010075d773 _pthread_wqthread + 1004 25 libsystem_pthread.dylib 0x000000010075d375 start_wqthread + 13 ) libc++abi.dylib: terminating with uncaught exception of type NSException

    bug 
    opened by iDevPro 6
  • Blackfish example project not working in Heroku

    Blackfish example project not working in Heroku

    When i have clicked on "Deploy to Heroku", it end up with this error message.

    -----> Fetching set buildpack https://github.com/kylef/heroku-buildpack-swift... done
    -----> Swift app detected
    Cloning into 'swiftenv'...
    -----> Installing DEVELOPMENT-SNAPSHOT-2016-02-08-a
    Downloading https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-02-08-a/swift-DEVELOPMENT-SNAPSHOT-2016-02-08-a-ubuntu14.04.tar.gz
    DEVELOPMENT-SNAPSHOT-2016-02-08-a has been installed.
    -----> Installing clang-3.7.0
    -----> Building Package
    Cloning https://github.com/elliottminns/blackfish.git
    Using version 0.4.2 of package blackfish
    Cloning https://github.com/elliottminns/echo.git
    Using version 0.5.1 of package echo
    Cloning https://github.com/elliottminns/uv-module.git
    Using version 0.1.0 of package uv-module
    Cloning https://github.com/elliottminns/blackfish-stencil.git
    Using version 0.1.1 of package blackfish-stencil
    Cloning https://github.com/kylef/Stencil.git
    Using version 0.5.3 of package Stencil
    Cloning https://github.com/kylef/PathKit.git
    Using version 0.6.1 of package PathKit
    Compiling Swift Module 'Echo' (9 sources)
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/DispatchQueue.swift:36:53: error: 'inout' must appear before the parameter name
        func runBlock(block: () -> (), onThread thread: inout pthread_t) {
                                                        ^~~~~~
                                       inout            
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/uv-module-0.1.0/module.modulemap:3:12: error: header '/usr/local/include/uv.h' not found
        header "/usr/local/include/uv.h"
               ^
    /tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/Packages/echo-0.5.1/Sources/Connection.swift:1:8: error: could not build Objective-C module 'CUV'
    import CUV
           ^
    <unknown>:0: error: build had 1 command failures
    swift-build: error: exit(1): ["/app/tmp/cache/swiftenv/versions/DEVELOPMENT-SNAPSHOT-2016-02-08-a/usr/bin/swift-build-tool", "-f", "/tmp/build_96fdfa39c92eee5ea4bac852362a2078/elliottminns-blackfish-example-79d541e/.build/release/Echo.o/llbuild.yaml"]
     !     Push rejected, failed to compile Swift app
    
    
    opened by speaktoalvin 6
  • Request Library - Proposal

    Request Library - Proposal

    Most modern API's required the ability to send out HTTP requests to other services.

    Currently there aren't any other HTTP servers providing this, and for Blackfish to be a number one Web Server, it should have this functionality.

    My proposal is that seeming though Echo is what is powering the Event Loop behind Blackfish, and given it's asynchronous nature, the Request library should also be powered by Echo and it's own repository. This means that it'll be reusable across other packages and will also be non-blocking.

    My thought process is to use libcurl as the main driver and implement a wrapper in swift to open up this process. The best JSON parsing library I have currently found is Swift-PureJsonSerializer and I think would add a nice addition to the Requesting Library.

    enhancement 
    opened by elliottminns 6
  • Hangs at 16k+ requests

    Hangs at 16k+ requests

    running ab -r -n 10000 -c 100 http://localhost:8080/ once is fine, but only 4.2k average RPS, but if you run it a second time, it hangs at 6k requests and never crashes or dies. I suspect that it's not letting go of clients fast enough.

    opened by wess 6
  • Fix typo and missing initializer

    Fix typo and missing initializer

    Had to fix this before I was able to deploy it on my service.

    Also I've written a little sample app to deploy it right away, will need a new blackfish release though before it's working: https://github.com/kimar/blackfish-example/tree/master

    opened by kimar 4
  • Middleware

    Middleware

    Be able to add middleware that can intercept any handlers before passing it on to its next handler

    See http://expressjs.com/en/guide/writing-middleware.html for example

    enhancement 
    opened by elliottminns 4
  • About create module

    About create module

    Hello,

    How about create module for project ? There is no examples, and another information... not about swift build, and not about Xcode project create for adding this module to own project... Please expand documentation :)

    opened by iDevPro 2
Owner
Elliott Minns
Elliott Minns
Minimal web framework and middleware for Swift

Kunugi Kunugi(怚) is minimal web framework and middleware systems for Swift. This is inpired by Node.js' Koa. Kunugi doesn't provide http server its se

Yusuke Ito 35 Apr 18, 2022
RestKit is a framework for consuming and modeling RESTful web resources on iOS and OS X

RestKit RestKit is a modern Objective-C framework for implementing RESTful web services clients on iOS and Mac OS X. It provides a powerful object map

The RestKit Project 10.2k Dec 29, 2022
A Swift web framework and HTTP server.

A Swift Web Framework and HTTP Server Summary Kitura is a web framework and web server that is created for web services written in Swift. For more inf

Kitura 7.6k Jan 6, 2023
A Ruby on Rails inspired Web Framework for Swift that runs on Linux and OS X

IMPORTANT! We don't see any way how to make web development as great as Ruby on Rails or Django with a very static nature of current Swift. We hope th

Saulius Grigaitis 2k Dec 5, 2022
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework

Serverside non-blocking IO in Swift Ask questions in our Slack channel! Lightning (formerly Edge) Node Lightning is an HTTP Server and TCP Client/Serv

SkyLab 316 Oct 6, 2022
πŸ’§ A server-side Swift web framework.

Vapor is a web framework for Swift. It provides a beautifully expressive and easy to use foundation for your next website, API, or cloud project. Take

Vapor 22.4k Jan 2, 2023
Super lightweight web framework in Swift based on SWSGI

Ambassador Super lightweight web framework in Swift based on SWSGI Features Super lightweight Easy to use, designed for UI automatic testing API mocki

Envoy 170 Nov 15, 2022
libuv base Swift web HTTP server framework

Notice Trevi now open a Trevi Community. Yoseob/Trevi project split up into respective Trevi, lime, middlewares and sys packages at our community. If

leeyoseob 46 Jan 29, 2022
Fast Websockets in Swift for iOS and OSX

SwiftWebSocket Conforming WebSocket (RFC 6455) client library for iOS and Mac OSX. SwiftWebSocket passes all 521 of the Autobahn's fuzzing tests, incl

Josh 1.5k Dec 28, 2022
A super fast & convenient object mapper tailored for your needs

A super fast & convenient object mapper tailored for your needs. Mapping objects to arrays or dictionaries can be a really cumbersome task, but those

Christoffer Winterkvist 246 Sep 9, 2022
Lightweight library for web server applications in Swift on macOS and Linux powered by coroutines.

Why Zewo? β€’ Support β€’ Community β€’ Contributing Zewo Zewo is a lightweight library for web applications in Swift. What sets Zewo apart? Zewo is not a w

Zewo 1.9k Dec 22, 2022
This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and AppleTV app.

This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and Apple TV app. With this Framework you can create iPh

Prioregroup.com 479 Nov 22, 2022
Robust Swift networking for web APIs

Conduit Conduit is a session-based Swift HTTP networking and auth library. Within each session, requests are sent through a serial pipeline before bei

Mindbody 52 Oct 26, 2022
A lightweight library for writing HTTP web servers with Swift

Taylor Disclaimer: Not actively working on it anymore. You can check out some alternatives Swift 2.0 required. Working with Xcode 7.1. Disclaimer: It

Jorge Izquierdo 925 Nov 17, 2022
Frank is a DSL for quickly writing web applications in Swift

Frank Frank is a DSL for quickly writing web applications in Swift with type-safe path routing. Sources/main.swift import Frank // Handle GET request

Kyle Fuller Archive 377 Jun 29, 2022
High Performance (nearly)100% Swift Web server supporting dynamic content.

Dynamo - Dynamic Swift Web Server Starting this project the intention was to code the simplest possible Web Server entirely in Swift. Unfortunately I

John Holdsworth 68 Jul 25, 2022
A web API client in Swift built using Async/Await

Get A modern web API client in Swift built using Async/Await and Actors. let cli

Alexander Grebenyuk 745 Jan 3, 2023
WKZombie is an iOS/OSX web-browser without a graphical user interface.

WKZombie is a Swift framework for iOS/OSX to navigate within websites and collect data without the need of User Interface or API, also known as Headless browser. It can be used to run automated tests / snapshots and manipulate websites using Javascript.

Mathias KΓΆhnke 1.1k Dec 16, 2022
MVVM project to show AQI of cities via web socket

Air Quality Monitoring Application Swift project with JSON parsing using codable About the application The app consists of live realtime data from the

Pran Kishore 0 Nov 27, 2021