CodyFire
๐ธ Powerful Codable API requests builder and manager for iOS.
Install / Use
/learn @CodyFlame/CodyFireREADME
This lib is about network requests with blackjack, roulette and craps!
Using it you will be able to convert your massive API layer code into an awesome convenient controllers with easy and maintainable network requests!
Use Codable models for everything related to API requests:
- json payload
- url-encoded payload
- multipart payload
- plain and json response
- url query
- headers
Wondered? That's only little part of what you will get from this lib! ๐ป
Quick examples
How to send GET request
APIRequest<ResponseModel>("endpoint").onSuccess { model in
//here's your decoded model!
//no need to check http.statusCode, I already did it for you! By default it's 200 OK
//of course you can choose which statusCode is equal to success (look at the `POST` and `DELETE` examples below)
}
How to send POST request
APIRequest<ResponseModel>("endpoint", payload: payloadModel)
.method(.post)
.desiredStatusCode(.created) //201 CREATED
.onSuccess { model in
//here's your decoded model!
//success was determined by comparing desiredStatusCode with http.statusCode
}
How to send DELETE request
APIRequest<Nothing>("endpoint")
.method(.delete)
.desiredStatusCode(.noContent) //204 NO CONTENT
.onSuccess { _ in
//here's empty successful response!
//success was determined by comparing desiredStatusCode with http.statusCode
}
How to send several requests?
You're able to run up to 10 requests one-by-one!
API.employee.all()
.and(API.office.all())
.and(API.car.all())
.and(API.event.all())
.and(API.post.all())
.onError { error in
print(error.description)
}.onSuccess { employees, offices, cars, events, posts in
// do what you want with received results!!! ๐ป
}
Or you can run unlimited amount of requests one-by-one or at the same time, if you need just a completion handler.
[API.employee.all(), API.office.all(), API.car.all()].flatten().onError {
print(error.description)
}.onSuccess {
print("flatten finished!")
}
to run them concurrently just add .concurrent(by: 3) to run by 3 at the same time
Of course you'll be able to send PUT and PATCH requests, send multipart codable structs with upload progress callback, catch errors, even redefine error descriptions for every endpoint. Wondered? ๐ Let's read the whole readme below! ๐ป
How to install
CodyFire is available through CocoaPods and SPM.
To install it, simply add the following line in your Podfile:
pod 'CodyFire', '~> 1.15.4'
Or you're looking for reactive code support? I have it! ๐บ
- for RxSwift https://github.com/MihaelIsaev/RxCodyFire
pod 'RxCodyFire', '~> 1.1.0'
# no need to install `CodyFire` cause it's in dependencies
using this pod you should always import just RxCodyFire and every APIRequest will have .observable
- for ReactiveCocoa https://github.com/MihaelIsaev/ReactiveCodyFire
pod 'ReactiveCodyFire', '~> 1.1.0'
# no need to install `CodyFire` cause it's in dependencies
using this pod you should always import just ReactiveCodyFire and every APIRequest will have .signalProducer
How to setup
CodyFire automatically detects which environment you're on, so I suggest you to definitely use this awesome feature ๐
import CodyFire
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
let dev = CodyFireEnvironment(baseURL: "http://localhost:8080")
let testFlight = CodyFireEnvironment(baseURL: "https://stage.myapi.com")
let appStore = CodyFireEnvironment(baseURL: "https://api.myapi.com")
CodyFire.shared.configureEnvironments(dev: dev, testFlight: testFlight, appStore: appStore)
//Also if you want to be able to switch environments manually just uncomment the line below (read more about that)
//CodyFire.shared.setupEnvByProjectScheme()
return true
}
}
Isn't it cool? ๐
Or you can set different Server URL for every APIRequest
let server1 = ServerURL(base: "https://server1.com", path: "v1")
let server2 = ServerURL(base: "https://server2.com", path: "v1")
let server3 = ServerURL(base: "https://server3.com")
And then initialize your APIRequests like this ๐ฅ
APIRequest(server1, "endpoint", payload: payloadObject)
APIRequest(server2, "endpoint", payload: payloadObject)
APIRequest(server3, "endpoint", payload: payloadObject)
Or in some cases you even can do it like this ๐
APIRequest("endpoint", payload: payloadObject).serverURL(server1)
Create your API controllers
I promise that this is API code architecture from your dreams which are come true!
Create an API folder and API.swift file inside it
class API {
typealias auth = AuthController
typealias task = TaskController
}
Create a folder named Controllers inside API folder, and create a folder for each controller
API/Controllers/Auth/Auth.swift
class AuthController {}
API/Controllers/Task/Task.swift
class TaskController {}
Create an extension file for each controller's endpoint
Auth login as simple POST request
API/Controllers/Auth/Auth+Login.swift
import CodyFire
extension AuthController {
struct LoginRequest: JSONPayload {
let email, password: String
init (email: String, password: String) {
self.email = email
self.password = password
}
}
struct LoginResponse: Codable {
var token: String
}
static func login(_ request: LoginRequest) -> APIRequest<LoginResponse> {
return APIRequest("login", payload: request).method(.post).addCustomError(.notFound, "User not found")
}
}
Auth login for Basic auth
API/Controllers/Auth/Auth+Login.swift
import CodyFire
extension AuthController {
struct LoginResponse: Codable {
var token: String
}
static func login(email: String, password: String) -> APIRequest<LoginResponse> {
return APIRequest("login").method(.post).basicAuth(email: email, password: password)
.addCustomError(.notFound, "User not found")
}
}
Task REST endpoints
Get task by id or a list of tasks by offset and limit
API/Controllers/Task/Task+Get.swift
import CodyFire
extension TaskController {
struct Task: Codable {
var id: UUID
var name: String
}
struct ListQuery: Codable {
var offset, limit: Int
init (offset: Int, limit: Int) {
self.offset = offset
self.limit = limit
}
}
static func get(_ query: ListQuery? = nil) -> APIRequest<[Task]> {
return APIRequest("task").query(query)
}
static func get(id: UUID) -> APIRequest<Task> {
return APIRequest("task/" + id.uuidString)
}
}
Create a task
API/Controllers/Task/Task+Create.swift
import CodyFire
extension TaskController {
struct CreateRequest: JSONPayload {
var name: String
init (name: String) {
self.name = name
}
}
static func create(_ request: CreateRequest) -> APIRequest<Task> {
return APIRequest("post", payload: request).method(.post).desiredStatusCode(.created)
}
}
Edit a task
API/Controllers/Task/Task+Edit.swift
import CodyFire
extension TaskController {
struct EditRequest: JSONPayload {
var name: String
init (name: String) {
self.name = name
}
}
static func create(id: UUID, request: EditRequest) -> APIRequest<Task> {
return APIRequest("post/" + id.uuidString, payload: request).method(.patch)
}
}
Delete a task
API/Controllers/Task/Task+Delete.swift
import CodyFire
extension TaskController {
static func delete(id: UUID) -> APIRequest<Nothing> {
return APIRequest("post/" + id.uuidString).method(.delete).desiredStatusCode(.noContent)
}
}
Easily use your API endpoints!
Send login request
API.auth.login(email: "test@mail.com", password: "qwerty").onError { error in
switch error.code {
case .notFound: print("User not found")
default: print(error.description)
}
}.onSuccess { token in
print("Received auth token: "+ token)
}
Get a list of tasks
API.task.get().onError { error in
print(error.description)
}.onSuccess { tasks in
print("received \(tasks.count) tasks")
}
Create a task
API.task.create(TaskController.CreateRequest(name: "Install CodyFire")).onError { error in
print(error.description)
}.onSuccess { task in
print("just created new task: \(task)")
}
Delete a task
let taskId = UUID()
API.task.delete(id: taskId).onError { error in
print(error.description)
}.onSuccess { _ in
print("just removed task with id: \(taskId)")
}
Multipart example
//declare a PostController
class PostController()
extension PostController {
struct CreateRequest: MultipartPayload {
var text: String
var tags: [String]
var images: [Att
Related Skills
node-connect
346.8kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
107.6kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
346.8kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
346.8kQQBot ๅฏๅชไฝๆถๅ่ฝๅใไฝฟ็จ <qqmedia> ๆ ็ญพ๏ผ็ณป็ปๆ นๆฎๆไปถๆฉๅฑๅ่ชๅจ่ฏๅซ็ฑปๅ๏ผๅพ็/่ฏญ้ณ/่ง้ข/ๆไปถ๏ผใ

