Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
protected String[] responseAs = new String[0];
protected String sourceFolder = "Classes" + File.separator + "OpenAPIs";
protected HashSet objcReservedWords;
protected String apiDocPath = "docs/";
protected String modelDocPath = "docs/";

/**
* Constructor for the swift4 language codegen module.
Expand All @@ -79,6 +81,8 @@ public Swift4Codegen() {
embeddedTemplateDir = templateDir = "swift4";
apiPackage = File.separator + "APIs";
modelPackage = File.separator + "Models";
modelDocTemplateFiles.put("model_doc.mustache", ".md");
apiDocTemplateFiles.put("api_doc.mustache", ".md");

languageSpecificPrimitives = new HashSet<>(
Arrays.asList(
Expand All @@ -90,7 +94,12 @@ public Swift4Codegen() {
"Bool",
"Void",
"String",
"URL",
"Data",
"Date",
"Character",
"UUID",
"URL",
"AnyObject",
"Any")
);
Expand Down Expand Up @@ -365,6 +374,10 @@ public void processOpts() {

setLenientTypeCast(convertPropertyToBooleanAndWriteBack(LENIENT_TYPE_CAST));

// make api and model doc path available in mustache template
additionalProperties.put("apiDocPath", apiDocPath);
additionalProperties.put("modelDocPath", modelDocPath);

supportingFiles.add(new SupportingFile("Podspec.mustache",
"",
projectName + ".podspec"));
Expand Down Expand Up @@ -404,6 +417,9 @@ public void processOpts() {
supportingFiles.add(new SupportingFile("gitignore.mustache",
"",
".gitignore"));
supportingFiles.add(new SupportingFile("README.mustache",
"",
"README.md"));

}

Expand Down Expand Up @@ -565,6 +581,26 @@ public String toApiName(String name) {
return camelize(name) + "API";
}

@Override
public String apiDocFileFolder() {
return (outputFolder + "/" + apiDocPath).replace("/", File.separator);
}

@Override
public String modelDocFileFolder() {
return (outputFolder + "/" + modelDocPath).replace("/", File.separator);
}

@Override
public String toModelDocFilename(String name) {
return toModelName(name);
}

@Override
public String toApiDocFilename(String name) {
return toApiName(name);
}

@Override
public String toOperationId(String operationId) {
operationId = camelize(sanitizeName(operationId), true);
Expand Down Expand Up @@ -880,4 +916,116 @@ public void postProcessFile(File file, String fileType) {
}
}
}

@Override
public Map<String, Object> postProcessOperationsWithModels(Map<String, Object> objs, List<Object> allModels) {
Map<String, Object> objectMap = (Map<String, Object>) objs.get("operations");

HashMap<String, CodegenModel> modelMaps = new HashMap<String, CodegenModel>();
for (Object o : allModels) {
HashMap<String, Object> h = (HashMap<String, Object>) o;
CodegenModel m = (CodegenModel) h.get("model");
modelMaps.put(m.classname, m);
}

List<CodegenOperation> operations = (List<CodegenOperation>) objectMap.get("operation");
for (CodegenOperation operation : operations) {
for (CodegenParameter cp : operation.allParams) {
cp.vendorExtensions.put("x-swift-example", constructExampleCode(cp, modelMaps));
}
}
return objs;
}

public String constructExampleCode(CodegenParameter codegenParameter, HashMap<String, CodegenModel> modelMaps) {
if (codegenParameter.isListContainer) { // array
return "[" + constructExampleCode(codegenParameter.items, modelMaps) + "]";
} else if (codegenParameter.isMapContainer) { // TODO: map, file type
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenParameter.dataType)) { // primitive type
if ("String".equals(codegenParameter.dataType) || "Character".equals(codegenParameter.dataType)) {
if (StringUtils.isEmpty(codegenParameter.example)) {
return "\"" + codegenParameter.example + "\"";
} else {
return "\"" + codegenParameter.paramName + "_example\"";
}
} else if ("Bool".equals(codegenParameter.dataType)) { // boolean
if (Boolean.TRUE.equals(codegenParameter.example)) {
return "true";
} else {
return "false";
}
} else if ("URL".equals(codegenParameter.dataType)) { // URL
return "URL(string: \"https://example.com\")!";
} else if ("Date".equals(codegenParameter.dataType)) { // date
return "Date()";
} else { // numeric
if (StringUtils.isEmpty(codegenParameter.example)) {
return codegenParameter.example;
} else {
return "987";
}
}
} else { // model
// look up the model
if (modelMaps.containsKey(codegenParameter.dataType)) {
return constructExampleCode(modelMaps.get(codegenParameter.dataType), modelMaps);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenParameter.dataType);
return "TODO";
}
}
}

public String constructExampleCode(CodegenProperty codegenProperty, HashMap<String, CodegenModel> modelMaps) {
if (codegenProperty.isListContainer) { // array
return "[" + constructExampleCode(codegenProperty.items, modelMaps) + "]";
} else if (codegenProperty.isMapContainer) { // TODO: map, file type
return "\"TODO\"";
} else if (languageSpecificPrimitives.contains(codegenProperty.dataType)) { // primitive type
if ("String".equals(codegenProperty.dataType) || "Character".equals(codegenProperty.dataType)) {
if (StringUtils.isEmpty(codegenProperty.example)) {
return "\"" + codegenProperty.example + "\"";
} else {
return "\"" + codegenProperty.name + "_example\"";
}
} else if ("Bool".equals(codegenProperty.dataType)) { // boolean
if (Boolean.TRUE.equals(codegenProperty.example)) {
return "true";
} else {
return "false";
}
} else if ("URL".equals(codegenProperty.dataType)) { // URL
return "URL(string: \"https://example.com\")!";
} else if ("Date".equals(codegenProperty.dataType)) { // date
return "Date()";
} else { // numeric
if (StringUtils.isEmpty(codegenProperty.example)) {
return codegenProperty.example;
} else {
return "123";
}
}
} else {
// look up the model
if (modelMaps.containsKey(codegenProperty.dataType)) {
return constructExampleCode(modelMaps.get(codegenProperty.dataType), modelMaps);
} else {
//LOGGER.error("Error in constructing examples. Failed to look up the model " + codegenProperty.dataType);
return "\"TODO\"";
}
}
}

public String constructExampleCode(CodegenModel codegenModel, HashMap<String, CodegenModel> modelMaps) {
String example;
example = codegenModel.name + "(";
List<String> propertyExamples = new ArrayList<>();
for (CodegenProperty codegenProperty : codegenModel.vars) {
propertyExamples.add(codegenProperty.name + ": " + constructExampleCode(codegenProperty, modelMaps));
}
example += StringUtils.join(propertyExamples, ", ");
example += ")";
return example;
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Swift4 API client for {{packageName}}
# Swift4 API client for {{{projectName}}}

{{#appDescription}}
{{{appDescription}}}
Expand All @@ -18,10 +18,14 @@ For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
{{/infoUrl}}

## Installation
Put the package under your project folder and add the following in import:
```
"./{{packageName}}"
```

### Carthage

Run `carthage update`

### CocoaPods

Run `pod install`

## Documentation for API Endpoints

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
# {{classname}}{{#description}}
{{description}}{{/description}}

All URIs are relative to *{{{basePath}}}*

Method | HTTP request | Description
------------- | ------------- | -------------
{{#operations}}{{#operation}}[**{{operationId}}**]({{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
{{/operation}}{{/operations}}

{{#operations}}
{{#operation}}
# **{{{operationId}}}**
```swift
{{^usePromiseKit}}
{{^useRxSwift}}
open class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#hasParams}}, {{/hasParams}}completion: @escaping (_ data: {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}?, _ error: Error?) -> Void)
{{/useRxSwift}}
{{/usePromiseKit}}
{{#usePromiseKit}}
open class func {{operationId}}({{#allParams}} {{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
{{/usePromiseKit}}
{{#useRxSwift}}
open class func {{operationId}}({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
{{/useRxSwift}}
```

{{{summary}}}{{#notes}}

{{{notes}}}{{/notes}}

### Example
```swift
// The following code samples are still beta. For any issue, please report via https://github.com/OpenAPITools/openapi-generator/issues/new
import {{{projectName}}}

{{#allParams}}let {{paramName}} = {{{vendorExtensions.x-swift-example}}} // {{{dataType}}} | {{{description}}}{{^required}} (optional){{/required}}{{#defaultValue}} (default to {{{.}}}){{/defaultValue}}
{{/allParams}}

{{^usePromiseKit}}
{{^useRxSwift}}
{{#summary}}
// {{{.}}}
{{/summary}}
{{classname}}.{{{operationId}}}({{#allParams}}{{paramName}}: {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { (response, error) in
guard error == nil else {
print(error)
return
}

if (response) {
dump(response)
}
}
{{/useRxSwift}}
{{/usePromiseKit}}
{{#usePromiseKit}}
{{#summary}}
// {{{.}}}
{{/summary}}
{{classname}}.{{{operationId}}}({{#allParams}}{{paramName}}: {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}).then {
// when the promise is fulfilled
}.always {
// regardless of whether the promise is fulfilled, or rejected
}.catch { errorType in
// when the promise is rejected
}
{{/usePromiseKit}}
{{#useRxSwift}}
// TODO RxSwift sample code not yet implemented. To contribute, please open a ticket via https://github.com/OpenAPITools/openapi-generator/issues/new
{{/useRxSwift}}
```

### Parameters
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
Name | Type | Description | Notes
------------- | ------------- | ------------- | -------------{{/-last}}{{/allParams}}
{{#allParams}} **{{paramName}}** | {{#isPrimitiveType}}**{{dataType}}**{{/isPrimitiveType}}{{^isPrimitiveType}}[**{{dataType}}**]({{baseType}}.md){{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#defaultValue}}[default to {{defaultValue}}]{{/defaultValue}}
{{/allParams}}

### Return type

{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{{returnType}}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}Void (empty response body){{/returnType}}

### Authorization

{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}](../README.md#{{{name}}}){{^-last}}, {{/-last}}{{/authMethods}}

### HTTP request headers

- **Content-Type**: {{#consumes}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
- **Accept**: {{#produces}}{{{mediaType}}}{{#hasMore}}, {{/hasMore}}{{/produces}}{{^produces}}Not defined{{/produces}}

[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)

{{/operation}}
{{/operations}}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{{#models}}{{#model}}# {{classname}}

## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
{{#vars}}**{{name}}** | {{#isPrimitiveType}}**{{{dataType}}}**{{/isPrimitiveType}}{{^isPrimitiveType}}{{^isContainer}}[**{{dataType}}**]({{complexType}}.md){{/isContainer}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{/isPrimitiveType}} | {{description}} | {{^required}}[optional] {{/required}}{{#readOnly}}[readonly] {{/readOnly}}{{#defaultValue}}[default to {{{.}}}]{{/defaultValue}}
{{/vars}}

[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)

{{/model}}{{/models}}
Loading