Using OpenAPI Generator for Model Generation in iOS Apps


Intro

Most iOS projects start the same way:

You create a few Codable structs manually, add a networking layer, and move on.

Then the backend grows.

Endpoints multiply.

Models become inconsistent.

The backend changes field names.

Someone forgets to update a DTO.

Suddenly your app contains hundreds of manually maintained models.

This is where OpenAPI Generator becomes valuable.

Instead of manually writing and maintaining API models, you generate them directly from the backend OpenAPI schema.

In this article, I’ll explain:

What is OpenAPI Generator?

OpenAPI Generator is a tool that generates API clients and models from an OpenAPI specification.

The backend exposes a schema file (openapi.json or swagger.yaml), and the generator creates:

For iOS projects, this means you can generate Swift Codable models automatically instead of writing them by hand.

Official website:

OpenAPI Generator


Why This Matters in Real Projects

The biggest benefit is not speed.

It’s consistency.

When your backend evolves:

If your models are generated:

This becomes especially important in:

Installation

The easiest way is via Homebrew:

brew install openapi-generator

Verify installation:

openapi-generator version

Generating Swift Models

Assume your backend provides:

openapi.yaml

You can generate Swift code like this:

openapi-generator generate \
  -i openapi.yaml \
  -g swift5 \
  -o GeneratedAPI

This generates:

Recommended Architecture

This is where many teams make mistakes.

Do NOT directly use generated models across your entire app.

Generated code is infrastructure code.

Treat it as external.

A cleaner architecture looks like this:

Presentation Layer
        ↓
Domain Models
        ↓
Mapper Layer
        ↓
Generated API Models
        ↓
Networking

Why?

Because generated code changes frequently.

If your UI depends directly on generated DTOs:

Generated models should remain isolated behind mapping layers.

This is one of the most important architectural decisions in long-term iOS projects.


Example

Generated model:

public struct UserResponse: Codable {
    public let id: Int?
    public let firstName: String?
    public let lastName: String?
}

Domain model:

struct User {
    let id: Int
    let fullName: String
}

Mapper:

extension User {
    init(dto: UserResponse) {
        self.id = dto.id ?? 0
        self.fullName = "\(dto.firstName ?? "") \(dto.lastName ?? "")"
    }
}

This keeps your app stable even if the API evolves.


Common Problems

1. Nullable Hell

Many OpenAPI schemas overuse nullable fields.

You end up with:

String?
Int?
Bool?

everywhere.

This is not a Swift problem.

It’s usually a backend schema quality problem.

Generated code exposes backend contract quality brutally fast.


2. Regeneration Conflicts

If developers manually edit generated files, regeneration becomes dangerous.

Rule:

Never modify generated code manually.

Instead:

3. Massive Generated Codebases

Large APIs can generate thousands of files.

Do not dump everything into the main target.

Use:

Treat generated code as dependency code.


CI/CD Integration

One underrated advantage:

You can automate generation during CI.

This allows:

Some teams even fail pull requests if the generated code changes unexpectedly.

That’s powerful.


Should You Generate the Entire API Client?

Usually: no.

For many iOS apps, generating only models is the sweet spot.

Why?

Because networking layers are often highly customized:

Many generated networking clients feel rigid.

A common approach is:

That gives you flexibility without manual DTO maintenance.


Final Thoughts

OpenAPI Generator is not just a code-generation tool.

It’s a contract-enforcement tool.

Used correctly, it:

Used incorrectly, it creates:

The key is separation:

That separation is what makes the approach scalable.