Swagger/OpenAPI Generierung für Swift (iOS/macOS)
\n\nDie Entwicklung mobiler Anwendungen für iOS und macOS erfordert oft die Integration mit REST-APIs. Das manuelle Schreiben der Netzwerkschicht ist ein zeitaufwändiger und fehleranfälliger Prozess. Codegenerierungswerkzeuge auf Basis von OpenAPI (Swagger)-Spezifikationen ermöglichen die automatische Erstellung typisierter Swift-Modelle, Netzwerkanfragen und sogar vollständiger API-Clients. Dies beschleunigt die Entwicklung, reduziert die Anzahl von Fehlern und erleichtert die Wartung des Codes bei API-Änderungen.
\n\nIn diesem Artikel betrachten wir die wichtigsten Werkzeuge zur Generierung von Swift-Code aus OpenAPI-Spezifikationen, zeigen Beispiele für deren Verwendung und geben Empfehlungen zur Integration in iOS/macOS-Projekte.
\n\nWichtige Generierungswerkzeuge
\n\nHeutzutage gibt es mehrere beliebte Lösungen, die Swift als Zielsprache unterstützen:
\n\n- \n
- OpenAPI Generator — das beliebteste Open-Source-Werkzeug. Unterstützt viele Sprachen, einschließlich Swift 5 und Combine. \n
- Swagger Codegen — der Vorgänger des OpenAPI Generators, wird noch unterstützt, ist aber weniger flexibel. \n
- Create API — ein Generator von Apple, integriert in Xcode 15+, zur Erstellung von Clients aus OpenAPI-Spezifikationen. \n
Betrachten wir jedes dieser Werkzeuge genauer.
\n\nOpenAPI Generator für Swift
\n\nOpenAPI Generator ist ein universelles Werkzeug, das als CLI, Docker-Image oder Plugin für Gradle/Maven verwendet werden kann. Für Swift stehen mehrere Generatoren zur Verfügung:
\n\n- \n
swift5— Generierung in Swift 5 mit Unterstützung für Codable, URLSession und Combine. \n swift5-deprecated— eine veraltete Version für Abwärtskompatibilität. \n
Installation und Verwendung
\n\nAm einfachsten ist die Verwendung von Docker:
\n\ndocker run --rm -v "${PWD}:/local" \\\n openapitools/openapi-generator-cli generate \\\n -i /local/spec.yaml \\\n -g swift5 \\\n -o /local/SwiftClient\n\nNach der Ausführung erscheint im Ordner SwiftClient ein generiertes Xcode-Projekt mit Modellen, API-Anfragen und Tests.
Beispiel für generierten Code
\n\nAngenommen, wir haben eine Spezifikation mit einem Endpunkt zum Abrufen eines Benutzers:
\n\nopenapi: 3.0.0\ninfo:\n title: User API\n version: 1.0.0\npaths:\n /users/{id}:\n get:\n operationId: getUserById\n parameters:\n - name: id\n in: path\n required: true\n schema:\n type: integer\n responses:\n '200':\n description: OK\n content:\n application/json:\n schema:\n $ref: '#/components/schemas/User'\ncomponents:\n schemas:\n User:\n type: object\n properties:\n id:\n type: integer\n name:\n type: string\n email:\n type: string\n required:\n - id\n - name\n - email\n\nDer OpenAPI Generator erstellt das folgende Swift-Modell:
\n\nimport Foundation\n\npublic struct User: Codable {\n public let id: Int\n public let name: String\n public let email: String\n\n enum CodingKeys: String, CodingKey {\n case id\n case name\n case email\n }\n}\n\nUnd die entsprechende API-Methode:
\n\nimport Foundation\nimport Combine\n\npublic class UserAPI {\n public static func getUserById(id: Int) -> AnyPublisher<User, Error> {\n var request = URLRequest(url: URL(string: "https://api.example.com/users/\\(id)")!)\n request.httpMethod = "GET"\n return URLSession.shared.dataTaskPublisher(for: request)\n .map(\\.data)\n .decode(type: User.self, decoder: JSONDecoder())\n .eraseToAnyPublisher()\n }\n}\n\nCreate API von Apple (Xcode 15+)
\n\nAb Xcode 15