Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

HTTP Request in Swift without NSURLRequest

We want to make HTTP(S) requests (GET) to call an API. The Problem is, NSURLRequest is (at the moment) not implemented in the Foundation for Linux (https://github.com/apple/swift-corelibs-foundation/blob/master/Foundation/NSURLRequest.swift).

Are there any other possibilities to create an HTTP request?

like image 907
boxi Avatar asked Jan 25 '16 16:01

boxi


4 Answers

There is a nice project called HTTPMiddleware that can be useful, it's just a middleware framework but it works well.

Here's a code example:

import HTTP
import HTTPMiddleware

struct Middleware: HTTPRequestMiddlewareType {
    func respond(request: HTTPRequest) -> HTTPRequestMiddlewareResult {
        // You can change the request and pass it forward
        return .Next(request)

        // Or you can respond early and bypass the chain
        return .Respond(HTTPResponse(statusCode: 404, reasonPhrase: "Not Found"))
    }
}

struct Responder: HTTPResponderType {
    func respond(request: HTTPRequest) -> HTTPResponse {
        // May or may not be called depending on the middleware
        return HTTPResponse(statusCode: 200, reasonPhrase: "OK")
    }
}

let request = HTTPRequest(method: .GET, uri: URI(path: "/"))
let chain = Middleware() >>> Responder()
let response = chain.respond(request)

Here is the official page, you can also find a JSON parser in the sources that can be useful for common requests. The installation requires only the uri_parser.

like image 179
Alessandro Ornano Avatar answered Oct 24 '22 00:10

Alessandro Ornano


Consider following solution based on ccurl library:

https://dl.dropboxusercontent.com/u/2504173/CurlSampleApp.tar.gz

I did it on Ubuntu 14.04

Swift 3.0 - latest development version: https://swift.org/builds/development/ubuntu1404/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a/swift-DEVELOPMENT-SNAPSHOT-2016-06-06-a-ubuntu14.04.tar.gz

Following package and instructions worked fine in general:

https://swiftpkgs.ng.bluemix.net/package/SwiftOnTheServer/CCurl

But in order to fix compilation errors I had to modify sots_curl.h in CCurl package. Following line was added:

#include <stdint.h>

For the app building you need to perform following in the app folder:

swift build

For app running you need to perform following command in the app folder:

.build/debug/app

Hope it helps. Ask questions if any :)

like image 29
Igor B. Avatar answered Oct 23 '22 23:10

Igor B.


Considering that Swift on Linux is fast-evolving work in progress, the best approach, I think, is to hold off doing any serious development until the situation is more stable. Even if you overcome the obstacle of making HTTP requests, there will likely be other unpleasant surprises due to the technology being immature on Linux.

However, if this is just a matter of curiosity and learning, here are some ideas, even though I haven't tried them myself:

  • Maybe calling CoreFoundation C APIs directly will work.
  • Write a C wrapper, that provides the interface you need, using good old C network APIs. This approach would probably require more effort than the others, as you will be re-inventing a lot of wheels.
  • Write a C wrapper, but wrap a higher-level C library that works with URLs; libcurl comes to mind.

Regardless of which of these approaches you take, you will need to interface with C code. One way to do this is to use system modules, see Importing a Swift module using a C library as a possible starting point.

like image 2
Anatoli P Avatar answered Oct 24 '22 00:10

Anatoli P


Since mid-2017 there is IBM's SwiftyRequest library, which works on both Linux and iOS. I've tried it on Linux and seems to work fine.

Making a request looks like this (adapted an example from docs):

import SwiftyRequest

let request = RestRequest(method: .get, url: "http://myApiCall/hello")
request.responseString() { response in
    switch response.result {
    case .success(let result):
        print("Success")
    case .failure(let error):
        print("Failure")
    }
}

If you're using JSON for the responses, it can even construct you an object based on a "schema" you provide (have a look at .responseObject and JSONDecodable in the tests for examples).

like image 2
naktinis Avatar answered Oct 23 '22 22:10

naktinis