Skip to content

Instantly share code, notes, and snippets.

@brendanw
Last active April 21, 2020 00:19
Show Gist options
  • Save brendanw/73067fdd7bec1e32ae936cd0c19bffa5 to your computer and use it in GitHub Desktop.
Save brendanw/73067fdd7bec1e32ae936cd0c19bffa5 to your computer and use it in GitHub Desktop.
A hacky means for making api calls with coroutines-native-mt while we wait for ktor bugs to get fixed.
class PlainClient : IPlainClient {
private val client = HttpClient {
install(JsonFeature) {
val kxs = KotlinxSerializer(Json.nonstrict)
serializer = kxs
}
}
private val okhttp = OkHttpClient()
override fun get(
baseUrl: String,
path: String,
token: String
): PlainResponse {
return runBlocking {
val response = client.get<HttpResponse> {
header("Authorization", "Bearer $token")
url {
takeFrom(baseUrl)
encodedPath = path
}
}
PlainResponse(response.status.value, response.readText())
}
}
override fun post(baseUrl: String, path: String, token: String) {
TODO("Not yet implemented")
}
override fun postFormData(
baseUrl: String,
path: String,
token: String,
formParams: Map<String, String>
): PlainResponse {
return runBlocking {
val formData = formData {
formParams.forEach {
append(it.key, it.value)
}
}
val response = client.submitFormWithBinaryData<HttpResponse>(formData) {
header("Authorization", "Bearer $token")
url {
takeFrom(baseUrl)
encodedPath = path
}
}
PlainResponse(response.status.value, response.readText())
}
}
}
import common
import Alamofire
class PlainClient : IPlainClient {
func get(baseUrl: String, path: String, token: String) -> PlainResponse {
print("bclient get: baseUrl=\(baseUrl) path=\(path) token=\(token)")
let semaphore = DispatchSemaphore(value: 0)
var stringResponse: String = ""
var code: Int32 = -1
let headers: HTTPHeaders = [
"Authorization" : "Bearer \(token)"
]
let url = "\(baseUrl)\(path)"
let queue = DispatchQueue(label: "plainclient", qos: .userInitiated, attributes: .concurrent)
AF.request(url, method: .get, headers: headers).responseJSON(queue: queue) { response in
//print("bclient response: \(response)")
code = Int32(response.response!.statusCode)
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
stringResponse = utf8Text
}
semaphore.signal()
}
_ = semaphore.wait(timeout: .distantFuture)
return PlainResponse(statusCode: code, payload: stringResponse)
}
func postFormData(baseUrl: String, path: String, token: String, params: Dictionary<String, String>) -> PlainResponse {
print("bclient post: baseUrl=\(baseUrl) path=\(path) token=\(token)")
let semaphore = DispatchSemaphore(value: 0)
var stringResponse: String = ""
var code: Int32 = -1
let headers: HTTPHeaders = [
"Authorization" : "Bearer \(token)"
]
let url = "\(baseUrl)\(path)"
let queue = DispatchQueue(label: "plainclient", qos: .userInitiated, attributes: .concurrent)
AF.request(
url,
method: .post,
parameters: params,
headers: headers
).responseJSON(queue: queue) { response in
print("bclient response: \(response)")
code = Int32(response.response!.statusCode)
if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
stringResponse = utf8Text
}
semaphore.signal()
}
_ = semaphore.wait(timeout: .distantFuture)
return PlainResponse(statusCode: code, payload: stringResponse)
}
func post(baseUrl: String, path: String, token: String) {
//todo
}
}
/**
* An http client to use until ktor works with multithreaded coroutines.
* This goes in a common module that ios and android clients depend on.
* We just return a string as shared components can use kotlinx serialization
* thereafter to handle response parsing.
*/
interface IPlainClient {
fun get(
baseUrl: String,
path: String,
token: String
): PlainResponse
fun post(
baseUrl: String,
path: String,
token: String
)
fun postFormData(
baseUrl: String,
path: String,
token: String,
params: Map<String, String>
): PlainResponse
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment