forked from loafle/openapi-generator-original
Add a swift4 client generator (#6010)
* Add a swift4 client generator * Updates per review comments: - Changed Alamofire dependency from 4.0 to 4.5 - Added "Codable", "Encodable", and "Decodable" to list of reserved words in generator - Ran "pod update" in default, promisekit, and rxswift samples test projects
This commit is contained in:
40
bin/swift4-petstore-all.sh
Executable file
40
bin/swift4-petstore-all.sh
Executable file
@@ -0,0 +1,40 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=`ls -ld "$SCRIPT"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=`dirname "$SCRIPT"`/..
|
||||||
|
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore.json -o samples/client/petstore/swift4/default"
|
||||||
|
|
||||||
|
echo "#### Petstore Swift API client (default) ####"
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
|
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore-promisekit.json -o samples/client/petstore/swift4/promisekit"
|
||||||
|
echo "#### Petstore Swift API client (promisekit) ####"
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
|
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore-rxswift.json -o samples/client/petstore/swift4/rxswift"
|
||||||
|
echo "#### Petstore Swift API client (rxswift) ####"
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
7
bin/swift4-petstore-promisekit.json
Normal file
7
bin/swift4-petstore-promisekit.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"podSummary": "PetstoreClient",
|
||||||
|
"podHomepage": "https://github.com/swagger-api/swagger-codegen",
|
||||||
|
"podAuthors": "",
|
||||||
|
"projectName": "PetstoreClient",
|
||||||
|
"responseAs": "PromiseKit"
|
||||||
|
}
|
||||||
31
bin/swift4-petstore-promisekit.sh
Executable file
31
bin/swift4-petstore-promisekit.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=`ls -ld "$SCRIPT"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=`dirname "$SCRIPT"`/..
|
||||||
|
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore-promisekit.json -o samples/client/petstore/swift4/promisekit"
|
||||||
|
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
7
bin/swift4-petstore-rxswift.json
Normal file
7
bin/swift4-petstore-rxswift.json
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"podSummary": "PetstoreClient",
|
||||||
|
"podHomepage": "https://github.com/swagger-api/swagger-codegen",
|
||||||
|
"podAuthors": "",
|
||||||
|
"projectName": "PetstoreClient",
|
||||||
|
"responseAs": "RxSwift"
|
||||||
|
}
|
||||||
31
bin/swift4-petstore-rxswift.sh
Executable file
31
bin/swift4-petstore-rxswift.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=`ls -ld "$SCRIPT"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=`dirname "$SCRIPT"`/..
|
||||||
|
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore-rxswift.json -o samples/client/petstore/swift4/rxswift"
|
||||||
|
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
6
bin/swift4-petstore.json
Normal file
6
bin/swift4-petstore.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"podSummary": "PetstoreClient",
|
||||||
|
"podHomepage": "https://github.com/swagger-api/swagger-codegen",
|
||||||
|
"podAuthors": "",
|
||||||
|
"projectName": "PetstoreClient"
|
||||||
|
}
|
||||||
31
bin/swift4-petstore.sh
Executable file
31
bin/swift4-petstore.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
SCRIPT="$0"
|
||||||
|
|
||||||
|
while [ -h "$SCRIPT" ] ; do
|
||||||
|
ls=`ls -ld "$SCRIPT"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
SCRIPT="$link"
|
||||||
|
else
|
||||||
|
SCRIPT=`dirname "$SCRIPT"`/"$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
if [ ! -d "${APP_DIR}" ]; then
|
||||||
|
APP_DIR=`dirname "$SCRIPT"`/..
|
||||||
|
APP_DIR=`cd "${APP_DIR}"; pwd`
|
||||||
|
fi
|
||||||
|
|
||||||
|
executable="./modules/swagger-codegen-cli/target/swagger-codegen-cli.jar"
|
||||||
|
|
||||||
|
if [ ! -f "$executable" ]
|
||||||
|
then
|
||||||
|
mvn clean package
|
||||||
|
fi
|
||||||
|
|
||||||
|
# if you've executed sbt assembly previously it will use that instead.
|
||||||
|
export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties"
|
||||||
|
ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift4 -i modules/swagger-codegen/src/test/resources/2_0/petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c ./bin/swift4-petstore.json -o samples/client/petstore/swift4/default"
|
||||||
|
|
||||||
|
java $JAVA_OPTS -jar $executable $ags
|
||||||
3
bin/windows/swift4-petstore-all.bat
Executable file
3
bin/windows/swift4-petstore-all.bat
Executable file
@@ -0,0 +1,3 @@
|
|||||||
|
call .\bin\windows\swift4-petstore.bat
|
||||||
|
call .\bin\windows\swift4-petstore-promisekit.bat
|
||||||
|
call .\bin\windows\swift4-petstore-rxswift.bat
|
||||||
10
bin/windows/swift4-petstore-promisekit.bat
Executable file
10
bin/windows/swift4-petstore-promisekit.bat
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
|
||||||
|
|
||||||
|
If Not Exist %executable% (
|
||||||
|
mvn clean package
|
||||||
|
)
|
||||||
|
|
||||||
|
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
|
||||||
|
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c bin\swift4-petstore-promisekit.json -o samples\client\petstore\swift4\promisekit
|
||||||
|
|
||||||
|
java %JAVA_OPTS% -jar %executable% %ags%
|
||||||
10
bin/windows/swift4-petstore-rxswift.bat
Executable file
10
bin/windows/swift4-petstore-rxswift.bat
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
|
||||||
|
|
||||||
|
If Not Exist %executable% (
|
||||||
|
mvn clean package
|
||||||
|
)
|
||||||
|
|
||||||
|
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
|
||||||
|
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -c bin\swift4-petstore-rxswift.json -o samples\client\petstore\swift4\rxswift
|
||||||
|
|
||||||
|
java %JAVA_OPTS% -jar %executable% %ags%
|
||||||
10
bin/windows/swift4-petstore.bat
Executable file
10
bin/windows/swift4-petstore.bat
Executable file
@@ -0,0 +1,10 @@
|
|||||||
|
set executable=.\modules\swagger-codegen-cli\target\swagger-codegen-cli.jar
|
||||||
|
|
||||||
|
If Not Exist %executable% (
|
||||||
|
mvn clean package
|
||||||
|
)
|
||||||
|
|
||||||
|
REM set JAVA_OPTS=%JAVA_OPTS% -Xmx1024M
|
||||||
|
set ags=generate -i modules\swagger-codegen\src\test\resources\2_0\petstore-with-fake-endpoints-models-for-testing.yaml -l swift4 -o samples\client\petstore\swift4\default
|
||||||
|
|
||||||
|
java %JAVA_OPTS% -jar %executable% %ags%
|
||||||
@@ -0,0 +1,640 @@
|
|||||||
|
package io.swagger.codegen.languages;
|
||||||
|
|
||||||
|
import com.google.common.base.Predicate;
|
||||||
|
import com.google.common.collect.Iterators;
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import io.swagger.codegen.*;
|
||||||
|
import io.swagger.models.Model;
|
||||||
|
import io.swagger.models.ModelImpl;
|
||||||
|
import io.swagger.models.Operation;
|
||||||
|
import io.swagger.models.Swagger;
|
||||||
|
import io.swagger.models.parameters.HeaderParameter;
|
||||||
|
import io.swagger.models.parameters.Parameter;
|
||||||
|
import io.swagger.models.properties.ArrayProperty;
|
||||||
|
import io.swagger.models.properties.MapProperty;
|
||||||
|
import io.swagger.models.properties.Property;
|
||||||
|
import org.apache.commons.lang3.ArrayUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.text.WordUtils;
|
||||||
|
|
||||||
|
import javax.annotation.Nullable;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class Swift4Codegen extends DefaultCodegen implements CodegenConfig {
|
||||||
|
public static final String PROJECT_NAME = "projectName";
|
||||||
|
public static final String RESPONSE_AS = "responseAs";
|
||||||
|
public static final String UNWRAP_REQUIRED = "unwrapRequired";
|
||||||
|
public static final String POD_SOURCE = "podSource";
|
||||||
|
public static final String POD_AUTHORS = "podAuthors";
|
||||||
|
public static final String POD_SOCIAL_MEDIA_URL = "podSocialMediaURL";
|
||||||
|
public static final String POD_DOCSET_URL = "podDocsetURL";
|
||||||
|
public static final String POD_LICENSE = "podLicense";
|
||||||
|
public static final String POD_HOMEPAGE = "podHomepage";
|
||||||
|
public static final String POD_SUMMARY = "podSummary";
|
||||||
|
public static final String POD_DESCRIPTION = "podDescription";
|
||||||
|
public static final String POD_SCREENSHOTS = "podScreenshots";
|
||||||
|
public static final String POD_DOCUMENTATION_URL = "podDocumentationURL";
|
||||||
|
public static final String SWIFT_USE_API_NAMESPACE = "swiftUseApiNamespace";
|
||||||
|
public static final String DEFAULT_POD_AUTHORS = "Swagger Codegen";
|
||||||
|
public static final String LENIENT_TYPE_CAST = "lenientTypeCast";
|
||||||
|
protected static final String LIBRARY_PROMISE_KIT = "PromiseKit";
|
||||||
|
protected static final String LIBRARY_RX_SWIFT = "RxSwift";
|
||||||
|
protected static final String[] RESPONSE_LIBRARIES = {LIBRARY_PROMISE_KIT, LIBRARY_RX_SWIFT};
|
||||||
|
protected String projectName = "SwaggerClient";
|
||||||
|
protected boolean unwrapRequired;
|
||||||
|
protected boolean lenientTypeCast = false;
|
||||||
|
protected boolean swiftUseApiNamespace;
|
||||||
|
protected String[] responseAs = new String[0];
|
||||||
|
protected String sourceFolder = "Classes" + File.separator + "Swaggers";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenType getTag() {
|
||||||
|
return CodegenType.CLIENT;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return "swift4";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getHelp() {
|
||||||
|
return "Generates a swift client library.";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void addAdditionPropertiesToCodeGenModel(CodegenModel codegenModel, ModelImpl swaggerModel) {
|
||||||
|
|
||||||
|
final Property additionalProperties = swaggerModel.getAdditionalProperties();
|
||||||
|
|
||||||
|
if(additionalProperties != null) {
|
||||||
|
codegenModel.additionalPropertiesType = getSwaggerType(additionalProperties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Swift4Codegen() {
|
||||||
|
super();
|
||||||
|
outputFolder = "generated-code" + File.separator + "swift";
|
||||||
|
modelTemplateFiles.put("model.mustache", ".swift");
|
||||||
|
apiTemplateFiles.put("api.mustache", ".swift");
|
||||||
|
embeddedTemplateDir = templateDir = "swift4";
|
||||||
|
apiPackage = File.separator + "APIs";
|
||||||
|
modelPackage = File.separator + "Models";
|
||||||
|
|
||||||
|
languageSpecificPrimitives = new HashSet<>(
|
||||||
|
Arrays.asList(
|
||||||
|
"Int",
|
||||||
|
"Int32",
|
||||||
|
"Int64",
|
||||||
|
"Float",
|
||||||
|
"Double",
|
||||||
|
"Bool",
|
||||||
|
"Void",
|
||||||
|
"String",
|
||||||
|
"Character",
|
||||||
|
"AnyObject",
|
||||||
|
"Any")
|
||||||
|
);
|
||||||
|
defaultIncludes = new HashSet<>(
|
||||||
|
Arrays.asList(
|
||||||
|
"Data",
|
||||||
|
"Date",
|
||||||
|
"URL", // for file
|
||||||
|
"UUID",
|
||||||
|
"Array",
|
||||||
|
"Dictionary",
|
||||||
|
"Set",
|
||||||
|
"Any",
|
||||||
|
"Empty",
|
||||||
|
"AnyObject",
|
||||||
|
"Any")
|
||||||
|
);
|
||||||
|
reservedWords = new HashSet<>(
|
||||||
|
Arrays.asList(
|
||||||
|
// name used by swift client
|
||||||
|
"ErrorResponse", "Response",
|
||||||
|
|
||||||
|
// swift keywords
|
||||||
|
"Int", "Int32", "Int64", "Int64", "Float", "Double", "Bool", "Void", "String", "Character", "AnyObject", "Any", "Error", "URL",
|
||||||
|
"class", "Class", "break", "as", "associativity", "deinit", "case", "dynamicType", "convenience", "enum", "continue",
|
||||||
|
"false", "dynamic", "extension", "default", "is", "didSet", "func", "do", "nil", "final", "import", "else",
|
||||||
|
"self", "get", "init", "fallthrough", "Self", "infix", "internal", "for", "super", "inout", "let", "if",
|
||||||
|
"true", "lazy", "operator", "in", "COLUMN", "left", "private", "return", "FILE", "mutating", "protocol",
|
||||||
|
"switch", "FUNCTION", "none", "public", "where", "LINE", "nonmutating", "static", "while", "optional",
|
||||||
|
"struct", "override", "subscript", "postfix", "typealias", "precedence", "var", "prefix", "Protocol",
|
||||||
|
"required", "right", "set", "Type", "unowned", "weak", "Codable", "Encodable", "Decodable")
|
||||||
|
);
|
||||||
|
|
||||||
|
typeMapping = new HashMap<>();
|
||||||
|
typeMapping.put("array", "Array");
|
||||||
|
typeMapping.put("List", "Array");
|
||||||
|
typeMapping.put("map", "Dictionary");
|
||||||
|
typeMapping.put("date", "Date");
|
||||||
|
typeMapping.put("Date", "Date");
|
||||||
|
typeMapping.put("DateTime", "Date");
|
||||||
|
typeMapping.put("boolean", "Bool");
|
||||||
|
typeMapping.put("string", "String");
|
||||||
|
typeMapping.put("char", "Character");
|
||||||
|
typeMapping.put("short", "Int");
|
||||||
|
typeMapping.put("int", "Int32");
|
||||||
|
typeMapping.put("long", "Int64");
|
||||||
|
typeMapping.put("integer", "Int32");
|
||||||
|
typeMapping.put("Integer", "Int32");
|
||||||
|
typeMapping.put("float", "Float");
|
||||||
|
typeMapping.put("number", "Double");
|
||||||
|
typeMapping.put("double", "Double");
|
||||||
|
typeMapping.put("object", "Any");
|
||||||
|
typeMapping.put("file", "URL");
|
||||||
|
typeMapping.put("binary", "Data");
|
||||||
|
typeMapping.put("ByteArray", "Data");
|
||||||
|
typeMapping.put("UUID", "UUID");
|
||||||
|
|
||||||
|
importMapping = new HashMap<>();
|
||||||
|
|
||||||
|
cliOptions.add(new CliOption(PROJECT_NAME, "Project name in Xcode"));
|
||||||
|
cliOptions.add(new CliOption(RESPONSE_AS, "Optionally use libraries to manage response. Currently " +
|
||||||
|
StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available."));
|
||||||
|
cliOptions.add(new CliOption(UNWRAP_REQUIRED, "Treat 'required' properties in response as non-optional " +
|
||||||
|
"(which would crash the app if api returns null as opposed to required option specified in json schema"));
|
||||||
|
cliOptions.add(new CliOption(POD_SOURCE, "Source information used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.POD_VERSION, "Version used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_AUTHORS, "Authors used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_SOCIAL_MEDIA_URL, "Social Media URL used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_DOCSET_URL, "Docset URL used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_LICENSE, "License used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_HOMEPAGE, "Homepage used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_SUMMARY, "Summary used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_DESCRIPTION, "Description used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_SCREENSHOTS, "Screenshots used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(POD_DOCUMENTATION_URL, "Documentation URL used for Podspec"));
|
||||||
|
cliOptions.add(new CliOption(SWIFT_USE_API_NAMESPACE, "Flag to make all the API classes inner-class of {{projectName}}API"));
|
||||||
|
cliOptions.add(new CliOption(CodegenConstants.HIDE_GENERATION_TIMESTAMP, "hides the timestamp when files were generated")
|
||||||
|
.defaultValue(Boolean.TRUE.toString()));
|
||||||
|
cliOptions.add(new CliOption(LENIENT_TYPE_CAST, "Accept and cast values for simple types (string->bool, string->int, int->string)")
|
||||||
|
.defaultValue(Boolean.FALSE.toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void processOpts() {
|
||||||
|
super.processOpts();
|
||||||
|
|
||||||
|
// default HIDE_GENERATION_TIMESTAMP to true
|
||||||
|
if (!additionalProperties.containsKey(CodegenConstants.HIDE_GENERATION_TIMESTAMP)) {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP, Boolean.TRUE.toString());
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(CodegenConstants.HIDE_GENERATION_TIMESTAMP,
|
||||||
|
Boolean.valueOf(additionalProperties().get(CodegenConstants.HIDE_GENERATION_TIMESTAMP).toString()));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup project name
|
||||||
|
if (additionalProperties.containsKey(PROJECT_NAME)) {
|
||||||
|
setProjectName((String) additionalProperties.get(PROJECT_NAME));
|
||||||
|
} else {
|
||||||
|
additionalProperties.put(PROJECT_NAME, projectName);
|
||||||
|
}
|
||||||
|
sourceFolder = projectName + File.separator + sourceFolder;
|
||||||
|
|
||||||
|
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
|
||||||
|
if (additionalProperties.containsKey(UNWRAP_REQUIRED)) {
|
||||||
|
setUnwrapRequired(convertPropertyToBooleanAndWriteBack(UNWRAP_REQUIRED));
|
||||||
|
}
|
||||||
|
additionalProperties.put(UNWRAP_REQUIRED, unwrapRequired);
|
||||||
|
|
||||||
|
// Setup unwrapRequired option, which makes all the properties with "required" non-optional
|
||||||
|
if (additionalProperties.containsKey(RESPONSE_AS)) {
|
||||||
|
Object responseAsObject = additionalProperties.get(RESPONSE_AS);
|
||||||
|
if (responseAsObject instanceof String) {
|
||||||
|
setResponseAs(((String) responseAsObject).split(","));
|
||||||
|
} else {
|
||||||
|
setResponseAs((String[]) responseAsObject);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
additionalProperties.put(RESPONSE_AS, responseAs);
|
||||||
|
if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) {
|
||||||
|
additionalProperties.put("usePromiseKit", true);
|
||||||
|
}
|
||||||
|
if (ArrayUtils.contains(responseAs, LIBRARY_RX_SWIFT)) {
|
||||||
|
additionalProperties.put("useRxSwift", true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup swiftUseApiNamespace option, which makes all the API classes inner-class of {{projectName}}API
|
||||||
|
if (additionalProperties.containsKey(SWIFT_USE_API_NAMESPACE)) {
|
||||||
|
setSwiftUseApiNamespace(convertPropertyToBooleanAndWriteBack(SWIFT_USE_API_NAMESPACE));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!additionalProperties.containsKey(POD_AUTHORS)) {
|
||||||
|
additionalProperties.put(POD_AUTHORS, DEFAULT_POD_AUTHORS);
|
||||||
|
}
|
||||||
|
|
||||||
|
setLenientTypeCast(convertPropertyToBooleanAndWriteBack(LENIENT_TYPE_CAST));
|
||||||
|
|
||||||
|
supportingFiles.add(new SupportingFile("Podspec.mustache", "", projectName + ".podspec"));
|
||||||
|
supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile"));
|
||||||
|
supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("AlamofireImplementations.mustache", sourceFolder,
|
||||||
|
"AlamofireImplementations.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("Configuration.mustache", sourceFolder, "Configuration.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("Extensions.mustache", sourceFolder, "Extensions.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("CodableHelper.mustache", sourceFolder, "CodableHelper.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("JSONEncodableEncoding.mustache", sourceFolder, "JSONEncodableEncoding.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("JSONEncodingHelper.mustache", sourceFolder, "JSONEncodingHelper.swift"));
|
||||||
|
supportingFiles.add(new SupportingFile("git_push.sh.mustache", "", "git_push.sh"));
|
||||||
|
supportingFiles.add(new SupportingFile("gitignore.mustache", "", ".gitignore"));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected boolean isReservedWord(String word) {
|
||||||
|
return word != null && reservedWords.contains(word); //don't lowercase as super does
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeReservedWord(String name) {
|
||||||
|
if(this.reservedWordsMappings().containsKey(name)) {
|
||||||
|
return this.reservedWordsMappings().get(name);
|
||||||
|
}
|
||||||
|
return "_" + name; // add an underscore to the name
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String modelFileFolder() {
|
||||||
|
return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String apiFileFolder() {
|
||||||
|
return outputFolder + File.separator + sourceFolder + apiPackage().replace('.', File.separatorChar);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getTypeDeclaration(Property p) {
|
||||||
|
if (p instanceof ArrayProperty) {
|
||||||
|
ArrayProperty ap = (ArrayProperty) p;
|
||||||
|
Property inner = ap.getItems();
|
||||||
|
return "[" + getTypeDeclaration(inner) + "]";
|
||||||
|
} else if (p instanceof MapProperty) {
|
||||||
|
MapProperty mp = (MapProperty) p;
|
||||||
|
Property inner = mp.getAdditionalProperties();
|
||||||
|
return "[String:" + getTypeDeclaration(inner) + "]";
|
||||||
|
}
|
||||||
|
return super.getTypeDeclaration(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getSwaggerType(Property p) {
|
||||||
|
String swaggerType = super.getSwaggerType(p);
|
||||||
|
String type;
|
||||||
|
if (typeMapping.containsKey(swaggerType)) {
|
||||||
|
type = typeMapping.get(swaggerType);
|
||||||
|
if (languageSpecificPrimitives.contains(type) || defaultIncludes.contains(type))
|
||||||
|
return type;
|
||||||
|
} else
|
||||||
|
type = swaggerType;
|
||||||
|
return toModelName(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDataTypeFile(String dataType) {
|
||||||
|
return dataType != null && dataType.equals("URL");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDataTypeBinary(final String dataType) {
|
||||||
|
return dataType != null && dataType.equals("Data");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Output the proper model name (capitalized)
|
||||||
|
*
|
||||||
|
* @param name the name of the model
|
||||||
|
* @return capitalized model name
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toModelName(String name) {
|
||||||
|
name = sanitizeName(name); // FIXME parameter should not be assigned. Also declare it as "final"
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNameSuffix)) { // set model suffix
|
||||||
|
name = name + "_" + modelNameSuffix;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!StringUtils.isEmpty(modelNamePrefix)) { // set model prefix
|
||||||
|
name = modelNamePrefix + "_" + name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the model name
|
||||||
|
// phone_number => PhoneNumber
|
||||||
|
name = camelize(name);
|
||||||
|
|
||||||
|
// model name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(name)) {
|
||||||
|
String modelName = "Model" + name;
|
||||||
|
LOGGER.warn(name + " (reserved word) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// model name starts with number
|
||||||
|
if (name.matches("^\\d.*")) {
|
||||||
|
String modelName = "Model" + name; // e.g. 200Response => Model200Response (after camelize)
|
||||||
|
LOGGER.warn(name + " (model name starts with number) cannot be used as model name. Renamed to " + modelName);
|
||||||
|
return modelName;
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the capitalized file name of the model
|
||||||
|
*
|
||||||
|
* @param name the model name
|
||||||
|
* @return the file name of the model
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String toModelFilename(String name) {
|
||||||
|
// should be the same as the model name
|
||||||
|
return toModelName(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toDefaultValue(Property p) {
|
||||||
|
// nil
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toInstantiationType(Property p) {
|
||||||
|
if (p instanceof MapProperty) {
|
||||||
|
MapProperty ap = (MapProperty) p;
|
||||||
|
String inner = getSwaggerType(ap.getAdditionalProperties());
|
||||||
|
return inner;
|
||||||
|
} else if (p instanceof ArrayProperty) {
|
||||||
|
ArrayProperty ap = (ArrayProperty) p;
|
||||||
|
String inner = getSwaggerType(ap.getItems());
|
||||||
|
return "[" + inner + "]";
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toApiName(String name) {
|
||||||
|
if (name.length() == 0)
|
||||||
|
return "DefaultAPI";
|
||||||
|
return initialCaps(name) + "API";
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toOperationId(String operationId) {
|
||||||
|
operationId = camelize(sanitizeName(operationId), true);
|
||||||
|
|
||||||
|
// throw exception if method name is empty. This should not happen but keep the check just in case
|
||||||
|
if (StringUtils.isEmpty(operationId)) {
|
||||||
|
throw new RuntimeException("Empty method name (operationId) not allowed");
|
||||||
|
}
|
||||||
|
|
||||||
|
// method name cannot use reserved keyword, e.g. return
|
||||||
|
if (isReservedWord(operationId)) {
|
||||||
|
String newOperationId = camelize(("call_" + operationId), true);
|
||||||
|
LOGGER.warn(operationId + " (reserved word) cannot be used as method name. Renamed to " + newOperationId);
|
||||||
|
return newOperationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
return operationId;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toVarName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name);
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize the variable name
|
||||||
|
// pet_id => petId
|
||||||
|
name = camelize(name, true);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toParamName(String name) {
|
||||||
|
// sanitize name
|
||||||
|
name = sanitizeName(name);
|
||||||
|
|
||||||
|
// replace - with _ e.g. created-at => created_at
|
||||||
|
name = name.replaceAll("-", "_");
|
||||||
|
|
||||||
|
// if it's all uppper case, do nothing
|
||||||
|
if (name.matches("^[A-Z_]*$")) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
// camelize(lower) the variable name
|
||||||
|
// pet_id => petId
|
||||||
|
name = camelize(name, true);
|
||||||
|
|
||||||
|
// for reserved word or word starting with number, append _
|
||||||
|
if (isReservedWord(name) || name.matches("^\\d.*")) {
|
||||||
|
name = escapeReservedWord(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CodegenModel fromModel(String name, Model model, Map<String, Model> allDefinitions) {
|
||||||
|
CodegenModel codegenModel = super.fromModel(name, model, allDefinitions);
|
||||||
|
if(codegenModel.description != null) {
|
||||||
|
codegenModel.imports.add("ApiModel");
|
||||||
|
}
|
||||||
|
if (allDefinitions != null) {
|
||||||
|
String parentSchema = codegenModel.parentSchema;
|
||||||
|
|
||||||
|
// multilevel inheritance: reconcile properties of all the parents
|
||||||
|
while (parentSchema != null) {
|
||||||
|
final Model parentModel = allDefinitions.get(parentSchema);
|
||||||
|
final CodegenModel parentCodegenModel = super.fromModel(codegenModel.parent, parentModel, allDefinitions);
|
||||||
|
codegenModel = Swift4Codegen.reconcileProperties(codegenModel, parentCodegenModel);
|
||||||
|
|
||||||
|
// get the next parent
|
||||||
|
parentSchema = parentCodegenModel.parentSchema;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return codegenModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setProjectName(String projectName) {
|
||||||
|
this.projectName = projectName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setUnwrapRequired(boolean unwrapRequired) {
|
||||||
|
this.unwrapRequired = unwrapRequired;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLenientTypeCast(boolean lenientTypeCast) {
|
||||||
|
this.lenientTypeCast = lenientTypeCast;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResponseAs(String[] responseAs) {
|
||||||
|
this.responseAs = responseAs;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSwiftUseApiNamespace(boolean swiftUseApiNamespace) {
|
||||||
|
this.swiftUseApiNamespace = swiftUseApiNamespace;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumValue(String value, String datatype) {
|
||||||
|
return String.valueOf(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumDefaultValue(String value, String datatype) {
|
||||||
|
return datatype + "_" + value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumVarName(String name, String datatype) {
|
||||||
|
if (name.length() == 0) {
|
||||||
|
return "empty";
|
||||||
|
}
|
||||||
|
|
||||||
|
Pattern startWithNumberPattern = Pattern.compile("^\\d+");
|
||||||
|
Matcher startWithNumberMatcher = startWithNumberPattern.matcher(name);
|
||||||
|
if (startWithNumberMatcher.find()) {
|
||||||
|
String startingNumbers = startWithNumberMatcher.group(0);
|
||||||
|
String nameWithoutStartingNumbers = name.substring(startingNumbers.length());
|
||||||
|
|
||||||
|
return "_" + startingNumbers + camelize(nameWithoutStartingNumbers, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// for symbol, e.g. $, #
|
||||||
|
if (getSymbolName(name) != null) {
|
||||||
|
return camelize(WordUtils.capitalizeFully(getSymbolName(name).toUpperCase()), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Camelize only when we have a structure defined below
|
||||||
|
Boolean camelized = false;
|
||||||
|
if (name.matches("[A-Z][a-z0-9]+[a-zA-Z0-9]*")) {
|
||||||
|
name = camelize(name, true);
|
||||||
|
camelized = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reserved Name
|
||||||
|
String nameLowercase = StringUtils.lowerCase(name);
|
||||||
|
if (isReservedWord(nameLowercase)) {
|
||||||
|
return escapeReservedWord(nameLowercase);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for numerical conversions
|
||||||
|
if ("Int".equals(datatype) || "Int32".equals(datatype) || "Int64".equals(datatype) ||
|
||||||
|
"Float".equals(datatype) || "Double".equals(datatype)) {
|
||||||
|
String varName = "number" + camelize(name);
|
||||||
|
varName = varName.replaceAll("-", "minus");
|
||||||
|
varName = varName.replaceAll("\\+", "plus");
|
||||||
|
varName = varName.replaceAll("\\.", "dot");
|
||||||
|
return varName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we have already camelized the word, don't progress
|
||||||
|
// any further
|
||||||
|
if (camelized) {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
char[] separators = {'-', '_', ' ', ':', '(', ')'};
|
||||||
|
return camelize(WordUtils.capitalizeFully(StringUtils.lowerCase(name), separators).replaceAll("[-_ :\\(\\)]", ""), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toEnumName(CodegenProperty property) {
|
||||||
|
String enumName = toModelName(property.name);
|
||||||
|
|
||||||
|
// Ensure that the enum type doesn't match a reserved word or
|
||||||
|
// the variable name doesn't match the generated enum type or the
|
||||||
|
// Swift compiler will generate an error
|
||||||
|
if (isReservedWord(property.datatypeWithEnum) || toVarName(property.name).equals(property.datatypeWithEnum)) {
|
||||||
|
enumName = property.datatypeWithEnum + "Enum";
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: toModelName already does something for names starting with number, so this code is probably never called
|
||||||
|
if (enumName.matches("\\d.*")) { // starts with number
|
||||||
|
return "_" + enumName;
|
||||||
|
} else {
|
||||||
|
return enumName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<String, Object> postProcessModels(Map<String, Object> objs) {
|
||||||
|
// process enum in models
|
||||||
|
return postProcessModelsEnum(objs);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeQuotationMark(String input) {
|
||||||
|
// remove " to avoid code injection
|
||||||
|
return input.replace("\"", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String escapeUnsafeCharacters(String input) {
|
||||||
|
return input.replace("*/", "*_/").replace("/*", "/_*");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static CodegenModel reconcileProperties(CodegenModel codegenModel, CodegenModel parentCodegenModel) {
|
||||||
|
// To support inheritance in this generator, we will analyze
|
||||||
|
// the parent and child models, look for properties that match, and remove
|
||||||
|
// them from the child models and leave them in the parent.
|
||||||
|
// Because the child models extend the parents, the properties will be available via the parent.
|
||||||
|
|
||||||
|
// Get the properties for the parent and child models
|
||||||
|
final List<CodegenProperty> parentModelCodegenProperties = parentCodegenModel.vars;
|
||||||
|
List<CodegenProperty> codegenProperties = codegenModel.vars;
|
||||||
|
codegenModel.allVars = new ArrayList<CodegenProperty>(codegenProperties);
|
||||||
|
codegenModel.parentVars = parentCodegenModel.allVars;
|
||||||
|
|
||||||
|
// Iterate over all of the parent model properties
|
||||||
|
boolean removedChildProperty = false;
|
||||||
|
|
||||||
|
for (CodegenProperty parentModelCodegenProperty : parentModelCodegenProperties) {
|
||||||
|
// Now that we have found a prop in the parent class,
|
||||||
|
// and search the child class for the same prop.
|
||||||
|
Iterator<CodegenProperty> iterator = codegenProperties.iterator();
|
||||||
|
while (iterator.hasNext()) {
|
||||||
|
CodegenProperty codegenProperty = iterator.next();
|
||||||
|
if (codegenProperty.baseName == parentModelCodegenProperty.baseName) {
|
||||||
|
// We found a property in the child class that is
|
||||||
|
// a duplicate of the one in the parent, so remove it.
|
||||||
|
iterator.remove();
|
||||||
|
removedChildProperty = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(removedChildProperty) {
|
||||||
|
// If we removed an entry from this model's vars, we need to ensure hasMore is updated
|
||||||
|
int count = 0, numVars = codegenProperties.size();
|
||||||
|
for(CodegenProperty codegenProperty : codegenProperties) {
|
||||||
|
count += 1;
|
||||||
|
codegenProperty.hasMore = (count < numVars) ? true : false;
|
||||||
|
}
|
||||||
|
codegenModel.vars = codegenProperties;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return codegenModel;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -62,6 +62,7 @@ io.swagger.codegen.languages.StaticHtml2Generator
|
|||||||
io.swagger.codegen.languages.StaticHtmlGenerator
|
io.swagger.codegen.languages.StaticHtmlGenerator
|
||||||
io.swagger.codegen.languages.SwaggerGenerator
|
io.swagger.codegen.languages.SwaggerGenerator
|
||||||
io.swagger.codegen.languages.SwaggerYamlGenerator
|
io.swagger.codegen.languages.SwaggerYamlGenerator
|
||||||
|
io.swagger.codegen.languages.Swift4Codegen
|
||||||
io.swagger.codegen.languages.Swift3Codegen
|
io.swagger.codegen.languages.Swift3Codegen
|
||||||
io.swagger.codegen.languages.SwiftCodegen
|
io.swagger.codegen.languages.SwiftCodegen
|
||||||
io.swagger.codegen.languages.TizenClientCodegen
|
io.swagger.codegen.languages.TizenClientCodegen
|
||||||
|
|||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// APIHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class APIHelper {
|
||||||
|
static func rejectNil(_ source: [String:Any?]) -> [String:Any]? {
|
||||||
|
var destination = [String:Any]()
|
||||||
|
for (key, nillableValue) in source {
|
||||||
|
if let value: Any = nillableValue {
|
||||||
|
destination[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if destination.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
static func rejectNilHeaders(_ source: [String:Any?]) -> [String:String] {
|
||||||
|
var destination = [String:String]()
|
||||||
|
for (key, nillableValue) in source {
|
||||||
|
if let value: Any = nillableValue {
|
||||||
|
destination[key] = "\(value)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
static func convertBoolToString(_ source: [String: Any]?) -> [String:Any]? {
|
||||||
|
guard let source = source else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var destination = [String:Any]()
|
||||||
|
let theTrue = NSNumber(value: true as Bool)
|
||||||
|
let theFalse = NSNumber(value: false as Bool)
|
||||||
|
for (key, value) in source {
|
||||||
|
switch value {
|
||||||
|
case let x where x as? NSNumber === theTrue || x as? NSNumber === theFalse:
|
||||||
|
destination[key] = "\(value as! Bool)" as Any?
|
||||||
|
default:
|
||||||
|
destination[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func mapValuesToQueryItems(values: [String:Any?]) -> [URLQueryItem]? {
|
||||||
|
let returnValues = values
|
||||||
|
.filter { $0.1 != nil }
|
||||||
|
.map { (item: (_key: String, _value: Any?)) -> URLQueryItem in
|
||||||
|
URLQueryItem(name: item._key, value:"\(item._value!)")
|
||||||
|
}
|
||||||
|
if returnValues.count == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return returnValues
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// APIs.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class {{projectName}}API {
|
||||||
|
open static var basePath = "{{{basePath}}}"
|
||||||
|
open static var credential: URLCredential?
|
||||||
|
open static var customHeaders: [String:String] = [:]
|
||||||
|
open static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class RequestBuilder<T> {
|
||||||
|
var credential: URLCredential?
|
||||||
|
var headers: [String:String]
|
||||||
|
let parameters: [String:Any]?
|
||||||
|
let isBody: Bool
|
||||||
|
let method: String
|
||||||
|
let URLString: String
|
||||||
|
|
||||||
|
/// Optional block to obtain a reference to the request's progress instance when available.
|
||||||
|
public var onProgressReady: ((Progress) -> ())?
|
||||||
|
|
||||||
|
required public init(method: String, URLString: String, parameters: [String:Any]?, isBody: Bool, headers: [String:String] = [:]) {
|
||||||
|
self.method = method
|
||||||
|
self.URLString = URLString
|
||||||
|
self.parameters = parameters
|
||||||
|
self.isBody = isBody
|
||||||
|
self.headers = headers
|
||||||
|
|
||||||
|
addHeaders({{projectName}}API.customHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func addHeaders(_ aHeaders:[String:String]) {
|
||||||
|
for (header, value) in aHeaders {
|
||||||
|
headers[header] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(_ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) { }
|
||||||
|
|
||||||
|
public func addHeader(name: String, value: String) -> Self {
|
||||||
|
if !value.isEmpty {
|
||||||
|
headers[name] = value
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
open func addCredential() -> Self {
|
||||||
|
self.credential = {{projectName}}API.credential
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol RequestBuilderFactory {
|
||||||
|
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type
|
||||||
|
func getBuilder<T:Decodable>() -> RequestBuilder<T>.Type
|
||||||
|
}
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
// AlamofireImplementations.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
class AlamofireRequestBuilderFactory: RequestBuilderFactory {
|
||||||
|
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type {
|
||||||
|
return AlamofireRequestBuilder<T>.self
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBuilder<T:Decodable>() -> RequestBuilder<T>.Type {
|
||||||
|
return AlamofireDecodableRequestBuilder<T>.self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store manager to retain its reference
|
||||||
|
private var managerStore: [String: Alamofire.SessionManager] = [:]
|
||||||
|
|
||||||
|
open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||||
|
required public init(method: String, URLString: String, parameters: [String : Any]?, isBody: Bool, headers: [String : String] = [:]) {
|
||||||
|
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the session
|
||||||
|
configuration.
|
||||||
|
*/
|
||||||
|
open func createSessionManager() -> Alamofire.SessionManager {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
configuration.httpAdditionalHeaders = buildHeaders()
|
||||||
|
return Alamofire.SessionManager(configuration: configuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the Content-Type
|
||||||
|
that is given to an uploaded form part.
|
||||||
|
|
||||||
|
Return nil to use the default behavior (inferring the Content-Type from
|
||||||
|
the file extension). Return the desired Content-Type otherwise.
|
||||||
|
*/
|
||||||
|
open func contentTypeForFormPart(fileURL: URL) -> String? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the request
|
||||||
|
configuration (e.g. to override the cache policy).
|
||||||
|
*/
|
||||||
|
open func makeRequest(manager: SessionManager, method: HTTPMethod, encoding: ParameterEncoding, headers: [String:String]) -> DataRequest {
|
||||||
|
return manager.request(URLString, method: method, parameters: parameters, encoding: encoding, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func execute(_ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
let managerId:String = UUID().uuidString
|
||||||
|
// Create a new manager for each request to customize its request header
|
||||||
|
let manager = createSessionManager()
|
||||||
|
managerStore[managerId] = manager
|
||||||
|
|
||||||
|
let encoding:ParameterEncoding = isBody ? JSONDataEncoding() : URLEncoding()
|
||||||
|
|
||||||
|
let xMethod = Alamofire.HTTPMethod(rawValue: method)
|
||||||
|
let fileKeys = parameters == nil ? [] : parameters!.filter { $1 is NSURL }
|
||||||
|
.map { $0.0 }
|
||||||
|
|
||||||
|
if fileKeys.count > 0 {
|
||||||
|
manager.upload(multipartFormData: { mpForm in
|
||||||
|
for (k, v) in self.parameters! {
|
||||||
|
switch v {
|
||||||
|
case let fileURL as URL:
|
||||||
|
if let mimeType = self.contentTypeForFormPart(fileURL: fileURL) {
|
||||||
|
mpForm.append(fileURL, withName: k, fileName: fileURL.lastPathComponent, mimeType: mimeType)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mpForm.append(fileURL, withName: k)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case let string as String:
|
||||||
|
mpForm.append(string.data(using: String.Encoding.utf8)!, withName: k)
|
||||||
|
break
|
||||||
|
case let number as NSNumber:
|
||||||
|
mpForm.append(number.stringValue.data(using: String.Encoding.utf8)!, withName: k)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
fatalError("Unprocessable value \(v) with key \(k)")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, to: URLString, method: xMethod!, headers: nil, encodingCompletion: { encodingResult in
|
||||||
|
switch encodingResult {
|
||||||
|
case .success(let upload, _, _):
|
||||||
|
if let onProgressReady = self.onProgressReady {
|
||||||
|
onProgressReady(upload.uploadProgress)
|
||||||
|
}
|
||||||
|
self.processRequest(request: upload, managerId, completion)
|
||||||
|
case .failure(let encodingError):
|
||||||
|
completion(nil, ErrorResponse.Error(415, nil, encodingError))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let request = makeRequest(manager: manager, method: xMethod!, encoding: encoding, headers: headers)
|
||||||
|
if let onProgressReady = self.onProgressReady {
|
||||||
|
onProgressReady(request.progress)
|
||||||
|
}
|
||||||
|
processRequest(request: request, managerId, completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func processRequest(request: DataRequest, _ managerId: String, _ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
if let credential = self.credential {
|
||||||
|
request.authenticate(usingCredential: credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanupRequest = {
|
||||||
|
_ = managerStore.removeValue(forKey: managerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
let validatedRequest = request.validate()
|
||||||
|
|
||||||
|
switch T.self {
|
||||||
|
case is String.Type:
|
||||||
|
validatedRequest.responseString(completionHandler: { (stringResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if stringResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: stringResponse.response!,
|
||||||
|
body: ((stringResponse.result.value ?? "") as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Void.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (voidResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if voidResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: voidResponse.response!,
|
||||||
|
body: nil),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if (dataResponse.result.isFailure) {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: dataResponse.response!,
|
||||||
|
body: (dataResponse.data as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func buildHeaders() -> [String: String] {
|
||||||
|
var httpHeaders = SessionManager.defaultHTTPHeaders
|
||||||
|
for (key, value) in self.headers {
|
||||||
|
httpHeaders[key] = value
|
||||||
|
}
|
||||||
|
return httpHeaders
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AlamofireDecodableRequestBuilderError: Error {
|
||||||
|
case emptyDataResponse
|
||||||
|
case nilHTTPResponse
|
||||||
|
case jsonDecoding(DecodingError)
|
||||||
|
case generalError(Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilder<T> {
|
||||||
|
|
||||||
|
override fileprivate func processRequest(request: DataRequest, _ managerId: String, _ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
if let credential = self.credential {
|
||||||
|
request.authenticate(usingCredential: credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanupRequest = {
|
||||||
|
_ = managerStore.removeValue(forKey: managerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
let validatedRequest = request.validate()
|
||||||
|
|
||||||
|
switch T.self {
|
||||||
|
case is String.Type:
|
||||||
|
validatedRequest.responseString(completionHandler: { (stringResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if stringResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: stringResponse.response!,
|
||||||
|
body: ((stringResponse.result.value ?? "") as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Void.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (voidResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if voidResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: voidResponse.response!,
|
||||||
|
body: nil),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Data.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if (dataResponse.result.isFailure) {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: dataResponse.response!,
|
||||||
|
body: (dataResponse.data as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse: DataResponse<Data>) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
guard dataResponse.result.isSuccess else {
|
||||||
|
completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let data = dataResponse.data, !data.isEmpty else {
|
||||||
|
completion(nil, ErrorResponse.Error(-1, nil, AlamofireDecodableRequestBuilderError.emptyDataResponse))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let httpResponse = dataResponse.response else {
|
||||||
|
completion(nil, ErrorResponse.Error(-2, nil, AlamofireDecodableRequestBuilderError.nilHTTPResponse))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseObj: Response<T>? = nil
|
||||||
|
|
||||||
|
let decodeResult: (decodableObj: T?, error: Error?) = CodableHelper.decode(T.self, from: data)
|
||||||
|
if decodeResult.error == nil {
|
||||||
|
responseObj = Response(response: httpResponse, body: decodeResult.decodableObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(responseObj, decodeResult.error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
github "Alamofire/Alamofire" >= 3.1.0{{#usePromiseKit}}
|
||||||
|
github "mxcl/PromiseKit" >=1.5.3{{/usePromiseKit}}{{#useRxSwift}}
|
||||||
|
github "ReactiveX/RxSwift" ~> 2.0{{/useRxSwift}}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// CodableHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public typealias EncodeResult = (data: Data?, error: Error?)
|
||||||
|
|
||||||
|
open class CodableHelper {
|
||||||
|
|
||||||
|
open class func decode<T>(_ type: T.Type, from data: Data) -> (decodableObj: T?, error: Error?) where T : Decodable {
|
||||||
|
var returnedDecodable: T? = nil
|
||||||
|
var returnedError: Error? = nil
|
||||||
|
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.dataDecodingStrategy = .base64Decode
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
decoder.dateDecodingStrategy = .iso8601
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
returnedDecodable = try decoder.decode(type, from: data)
|
||||||
|
} catch {
|
||||||
|
returnedError = error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (returnedDecodable, returnedError)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class func encode<T>(_ value: T, prettyPrint: Bool = false) -> EncodeResult where T : Encodable {
|
||||||
|
var returnedData: Data?
|
||||||
|
var returnedError: Error? = nil
|
||||||
|
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.outputFormatting = (prettyPrint ? .prettyPrinted : .compact)
|
||||||
|
encoder.dataEncodingStrategy = .base64Encode
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
encoder.dateEncodingStrategy = .iso8601
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
returnedData = try encoder.encode(value)
|
||||||
|
} catch {
|
||||||
|
returnedError = error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (returnedData, returnedError)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Configuration.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class Configuration {
|
||||||
|
|
||||||
|
// This value is used to configure the date formatter that is used to serialize dates into JSON format.
|
||||||
|
// You must set it prior to encoding any dates, and it will only be read once.
|
||||||
|
open static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
// Extensions.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire{{#usePromiseKit}}
|
||||||
|
import PromiseKit{{/usePromiseKit}}
|
||||||
|
|
||||||
|
extension Bool: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Float: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int32: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return NSNumber(value: self as Int32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int64: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return NSNumber(value: self as Int64) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Double: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encodeIfPossible<T>(_ object: T) -> Any {
|
||||||
|
if let encodableObject = object as? JSONEncodable {
|
||||||
|
return encodableObject.encodeToJSON()
|
||||||
|
} else {
|
||||||
|
return object as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Array: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.map(encodeIfPossible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Dictionary: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
var dictionary = [AnyHashable: Any]()
|
||||||
|
for (key, value) in self {
|
||||||
|
dictionary[key as! NSObject] = encodeIfPossible(value)
|
||||||
|
}
|
||||||
|
return dictionary as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Data: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.base64EncodedString(options: Data.Base64EncodingOptions())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let dateFormatter: DateFormatter = {
|
||||||
|
let fmt = DateFormatter()
|
||||||
|
fmt.dateFormat = Configuration.dateFormat
|
||||||
|
fmt.locale = Locale(identifier: "en_US_POSIX")
|
||||||
|
return fmt
|
||||||
|
}()
|
||||||
|
|
||||||
|
extension Date: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return dateFormatter.string(from: self) as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UUID: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.uuidString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{#usePromiseKit}}extension RequestBuilder {
|
||||||
|
public func execute() -> Promise<Response<T>> {
|
||||||
|
let deferred = Promise<Response<T>>.pending()
|
||||||
|
self.execute { (response: Response<T>?, error: Error?) in
|
||||||
|
if let response = response {
|
||||||
|
deferred.fulfill(response)
|
||||||
|
} else {
|
||||||
|
deferred.reject(error!)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deferred.promise
|
||||||
|
}
|
||||||
|
}{{/usePromiseKit}}
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// JSONDataEncoding.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
public struct JSONDataEncoding: ParameterEncoding {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private static let jsonDataKey = "jsonData"
|
||||||
|
|
||||||
|
// MARK: Encoding
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply. This should have a single key/value
|
||||||
|
/// pair with "jsonData" as the key and a Data object as the value.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let jsonData = parameters?[JSONDataEncoding.jsonDataKey] as? Data, !jsonData.isEmpty else {
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = jsonData
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func encodingParameters(jsonData: Data?) -> Parameters? {
|
||||||
|
var returnedParams: Parameters? = nil
|
||||||
|
if let jsonData = jsonData, !jsonData.isEmpty {
|
||||||
|
var params = Parameters()
|
||||||
|
params[jsonDataKey] = jsonData
|
||||||
|
returnedParams = params
|
||||||
|
}
|
||||||
|
return returnedParams
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// JSONEncodingHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
open class JSONEncodingHelper {
|
||||||
|
|
||||||
|
open class func encodingParameters<T:Encodable>(forEncodableObject encodableObj: T?) -> Parameters? {
|
||||||
|
var params: Parameters? = nil
|
||||||
|
|
||||||
|
// Encode the Encodable object
|
||||||
|
if let encodableObj = encodableObj {
|
||||||
|
let encodeResult = CodableHelper.encode(encodableObj, prettyPrint: true)
|
||||||
|
if encodeResult.error == nil {
|
||||||
|
params = JSONDataEncoding.encodingParameters(jsonData: encodeResult.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Models.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ErrorResponse : Error {
|
||||||
|
case Error(Int, Data?, Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Response<T> {
|
||||||
|
open let statusCode: Int
|
||||||
|
open let header: [String: String]
|
||||||
|
open let body: T?
|
||||||
|
|
||||||
|
public init(statusCode: Int, header: [String: String], body: T?) {
|
||||||
|
self.statusCode = statusCode
|
||||||
|
self.header = header
|
||||||
|
self.body = body
|
||||||
|
}
|
||||||
|
|
||||||
|
public convenience init(response: HTTPURLResponse, body: T?) {
|
||||||
|
let rawHeader = response.allHeaderFields
|
||||||
|
var header = [String:String]()
|
||||||
|
for (key, value) in rawHeader {
|
||||||
|
header[key as! String] = value as? String
|
||||||
|
}
|
||||||
|
self.init(statusCode: response.statusCode, header: header, body: body)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = '{{projectName}}'{{#projectDescription}}
|
||||||
|
s.summary = '{{projectDescription}}'{{/projectDescription}}
|
||||||
|
s.ios.deployment_target = '9.0'
|
||||||
|
s.osx.deployment_target = '10.11'
|
||||||
|
s.version = '{{#podVersion}}{{podVersion}}{{/podVersion}}{{^podVersion}}0.0.1{{/podVersion}}'
|
||||||
|
s.source = {{#podSource}}{{& podSource}}{{/podSource}}{{^podSource}}{ :git => 'git@github.com:swagger-api/swagger-mustache.git', :tag => 'v1.0.0' }{{/podSource}}{{#podAuthors}}
|
||||||
|
s.authors = '{{podAuthors}}'{{/podAuthors}}{{#podSocialMediaURL}}
|
||||||
|
s.social_media_url = '{{podSocialMediaURL}}'{{/podSocialMediaURL}}{{#podDocsetURL}}
|
||||||
|
s.docset_url = '{{podDocsetURL}}'{{/podDocsetURL}}
|
||||||
|
s.license = {{#podLicense}}{{& podLicense}}{{/podLicense}}{{^podLicense}}'Proprietary'{{/podLicense}}{{#podHomepage}}
|
||||||
|
s.homepage = '{{podHomepage}}'{{/podHomepage}}{{#podSummary}}
|
||||||
|
s.summary = '{{podSummary}}'{{/podSummary}}{{#podDescription}}
|
||||||
|
s.description = '{{podDescription}}'{{/podDescription}}{{#podScreenshots}}
|
||||||
|
s.screenshots = {{& podScreenshots}}{{/podScreenshots}}{{#podDocumentationURL}}
|
||||||
|
s.documentation_url = '{{podDocumentationURL}}'{{/podDocumentationURL}}
|
||||||
|
s.source_files = '{{projectName}}/Classes/Swaggers/**/*.swift'{{#usePromiseKit}}
|
||||||
|
s.dependency 'PromiseKit', '~> 4.2.2'{{/usePromiseKit}}{{#useRxSwift}}
|
||||||
|
s.dependency 'RxSwift', '~> 3.4.1'{{/useRxSwift}}
|
||||||
|
s.dependency 'Alamofire', '~> 4.5'
|
||||||
|
end
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
# Swift4 API client for {{packageName}}
|
||||||
|
|
||||||
|
{{#appDescription}}
|
||||||
|
{{{appDescription}}}
|
||||||
|
{{/appDescription}}
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
This API client was generated by the [swagger-codegen](https://github.com/swagger-api/swagger-codegen) project. By using the [swagger-spec](https://github.com/swagger-api/swagger-spec) from a remote server, you can easily generate an API client.
|
||||||
|
|
||||||
|
- API version: {{appVersion}}
|
||||||
|
- Package version: {{packageVersion}}
|
||||||
|
{{^hideGenerationTimestamp}}
|
||||||
|
- Build date: {{generatedDate}}
|
||||||
|
{{/hideGenerationTimestamp}}
|
||||||
|
- Build package: {{generatorClass}}
|
||||||
|
{{#infoUrl}}
|
||||||
|
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
|
||||||
|
{{/infoUrl}}
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Put the package under your project folder and add the following in import:
|
||||||
|
```
|
||||||
|
"./{{packageName}}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Documentation for API Endpoints
|
||||||
|
|
||||||
|
All URIs are relative to *{{basePath}}*
|
||||||
|
|
||||||
|
Class | Method | HTTP request | Description
|
||||||
|
------------ | ------------- | ------------- | -------------
|
||||||
|
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{#summary}}{{summary}}{{/summary}}
|
||||||
|
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
|
||||||
|
|
||||||
|
## Documentation For Models
|
||||||
|
|
||||||
|
{{#models}}{{#model}} - [{{{classname}}}]({{modelDocPath}}{{{classname}}}.md)
|
||||||
|
{{/model}}{{/models}}
|
||||||
|
|
||||||
|
## Documentation For Authorization
|
||||||
|
|
||||||
|
{{^authMethods}} All endpoints do not require authorization.
|
||||||
|
{{/authMethods}}{{#authMethods}}{{#last}} Authentication schemes defined for the API:{{/last}}{{/authMethods}}
|
||||||
|
{{#authMethods}}## {{{name}}}
|
||||||
|
|
||||||
|
{{#isApiKey}}- **Type**: API key
|
||||||
|
- **API key parameter name**: {{{keyParamName}}}
|
||||||
|
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
|
||||||
|
{{/isApiKey}}
|
||||||
|
{{#isBasic}}- **Type**: HTTP basic authentication
|
||||||
|
{{/isBasic}}
|
||||||
|
{{#isOAuth}}- **Type**: OAuth
|
||||||
|
- **Flow**: {{{flow}}}
|
||||||
|
- **Authorization URL**: {{{authorizationUrl}}}
|
||||||
|
- **Scopes**: {{^scopes}}N/A{{/scopes}}
|
||||||
|
{{#scopes}} - **{{{scope}}}**: {{{description}}}
|
||||||
|
{{/scopes}}
|
||||||
|
{{/isOAuth}}
|
||||||
|
|
||||||
|
{{/authMethods}}
|
||||||
|
|
||||||
|
## Author
|
||||||
|
|
||||||
|
{{#apiInfo}}{{#apis}}{{^hasMore}}{{infoEmail}}
|
||||||
|
{{/hasMore}}{{/apis}}{{/apiInfo}}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
"{{baseName}}": {{paramName}}{{^isEnum}}{{#isInteger}}{{^required}}?{{/required}}.encodeToJSON(){{/isInteger}}{{#isLong}}{{^required}}?{{/required}}.encodeToJSON(){{/isLong}}{{/isEnum}}{{#isEnum}}{{^isContainer}}{{^required}}?{{/required}}.rawValue{{/isContainer}}{{/isEnum}}{{#isDate}}{{^required}}?{{/required}}.encodeToJSON(){{/isDate}}{{#isDateTime}}{{^required}}?{{/required}}.encodeToJSON(){{/isDateTime}}
|
||||||
153
modules/swagger-codegen/src/main/resources/swift4/api.mustache
Normal file
153
modules/swagger-codegen/src/main/resources/swift4/api.mustache
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
{{#operations}}//
|
||||||
|
// {{classname}}.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire{{#usePromiseKit}}
|
||||||
|
import PromiseKit{{/usePromiseKit}}{{#useRxSwift}}
|
||||||
|
import RxSwift{{/useRxSwift}}
|
||||||
|
|
||||||
|
{{#swiftUseApiNamespace}}
|
||||||
|
extension {{projectName}}API {
|
||||||
|
{{/swiftUseApiNamespace}}
|
||||||
|
|
||||||
|
{{#description}}
|
||||||
|
/** {{description}} */{{/description}}
|
||||||
|
open class {{classname}} {
|
||||||
|
{{#operation}}
|
||||||
|
{{#allParams}}
|
||||||
|
{{#isEnum}}
|
||||||
|
/**
|
||||||
|
* enum for parameter {{paramName}}
|
||||||
|
*/
|
||||||
|
public enum {{enumName}}_{{operationId}}: {{^isContainer}}{{{dataType}}}{{/isContainer}}{{#isContainer}}String{{/isContainer}} { {{#allowableValues}}{{#enumVars}}
|
||||||
|
case {{name}} = {{#isContainer}}"{{/isContainer}}{{#isString}}"{{/isString}}{{{value}}}{{#isString}}"{{/isString}}{{#isContainer}}"{{/isContainer}}{{/enumVars}}{{/allowableValues}}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/allParams}}
|
||||||
|
/**
|
||||||
|
{{#summary}}
|
||||||
|
{{{summary}}}
|
||||||
|
{{/summary}}{{#allParams}}
|
||||||
|
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
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 ((_ {{#returnType}}data: {{{returnType}}}?,_ {{/returnType}}error: Error?) -> Void)) {
|
||||||
|
{{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}).execute { (response, error) -> Void in
|
||||||
|
completion({{#returnType}}response?.body, {{/returnType}}error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{{#usePromiseKit}}
|
||||||
|
/**
|
||||||
|
{{#summary}}
|
||||||
|
{{{summary}}}
|
||||||
|
{{/summary}}{{#allParams}}
|
||||||
|
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
||||||
|
- returns: Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
|
||||||
|
*/
|
||||||
|
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}}> {
|
||||||
|
let deferred = Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>.pending()
|
||||||
|
{{operationId}}({{#allParams}}{{paramName}}: {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#returnType}}data, {{/returnType}}error in
|
||||||
|
if let error = error {
|
||||||
|
deferred.reject(error)
|
||||||
|
} else {
|
||||||
|
deferred.fulfill({{#returnType}}data!{{/returnType}})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return deferred.promise
|
||||||
|
}
|
||||||
|
{{/usePromiseKit}}
|
||||||
|
{{#useRxSwift}}
|
||||||
|
/**
|
||||||
|
{{#summary}}
|
||||||
|
{{{summary}}}
|
||||||
|
{{/summary}}{{#allParams}}
|
||||||
|
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
||||||
|
- returns: Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>
|
||||||
|
*/
|
||||||
|
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}}> {
|
||||||
|
return Observable.create { observer -> Disposable in
|
||||||
|
{{operationId}}({{#allParams}}{{paramName}}: {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) { {{#returnType}}data, {{/returnType}}error in
|
||||||
|
if let error = error {
|
||||||
|
observer.on(.error(error as Error))
|
||||||
|
} else {
|
||||||
|
observer.on(.next({{#returnType}}data!{{/returnType}}))
|
||||||
|
}
|
||||||
|
observer.on(.completed)
|
||||||
|
}
|
||||||
|
return Disposables.create()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/useRxSwift}}
|
||||||
|
|
||||||
|
/**
|
||||||
|
{{#summary}}
|
||||||
|
{{{summary}}}
|
||||||
|
{{/summary}}
|
||||||
|
- {{httpMethod}} {{{path}}}{{#notes}}
|
||||||
|
- {{{notes}}}{{/notes}}{{#subresourceOperation}}
|
||||||
|
- subresourceOperation: {{subresourceOperation}}{{/subresourceOperation}}{{#defaultResponse}}
|
||||||
|
- defaultResponse: {{defaultResponse}}{{/defaultResponse}}{{#authMethods}}
|
||||||
|
- {{#isBasic}}BASIC{{/isBasic}}{{#isOAuth}}OAuth{{/isOAuth}}{{#isApiKey}}API Key{{/isApiKey}}:
|
||||||
|
- type: {{type}}{{#keyParamName}} {{keyParamName}} {{#isKeyInQuery}}(QUERY){{/isKeyInQuery}}{{#isKeyInHeaer}}(HEADER){{/isKeyInHeaer}}{{/keyParamName}}
|
||||||
|
- name: {{name}}{{/authMethods}}{{#responseHeaders}}
|
||||||
|
- responseHeaders: {{responseHeaders}}{{/responseHeaders}}{{#examples}}
|
||||||
|
- examples: {{{examples}}}{{/examples}}{{#externalDocs}}
|
||||||
|
- externalDocs: {{externalDocs}}{{/externalDocs}}{{#hasParams}}
|
||||||
|
{{/hasParams}}{{#allParams}}
|
||||||
|
- parameter {{paramName}}: ({{#isFormParam}}form{{/isFormParam}}{{#isQueryParam}}query{{/isQueryParam}}{{#isPathParam}}path{{/isPathParam}}{{#isHeaderParam}}header{{/isHeaderParam}}{{#isBodyParam}}body{{/isBodyParam}}) {{description}} {{^required}}(optional{{#defaultValue}}, default to {{{.}}}{{/defaultValue}}){{/required}}{{/allParams}}
|
||||||
|
|
||||||
|
- returns: RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {{description}}
|
||||||
|
*/
|
||||||
|
open class func {{operationId}}WithRequestBuilder({{#allParams}}{{paramName}}: {{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}{{{datatypeWithEnum}}}_{{operationId}}{{/isContainer}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{^required}}? = nil{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> {
|
||||||
|
{{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{{path}}}"{{#pathParams}}
|
||||||
|
path = path.replacingOccurrences(of: "{{=<% %>=}}{<%baseName%>}<%={{ }}=%>", with: "\({{paramName}}{{#isEnum}}{{#isContainer}}{{{dataType}}}{{/isContainer}}{{^isContainer}}.rawValue{{/isContainer}}{{/isEnum}})", options: .literal, range: nil){{/pathParams}}
|
||||||
|
let URLString = {{projectName}}API.basePath + path
|
||||||
|
{{#bodyParam}}
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: {{paramName}})
|
||||||
|
{{/bodyParam}}
|
||||||
|
{{^bodyParam}}
|
||||||
|
{{#hasFormParams}}
|
||||||
|
let formParams: [String:Any?] = [
|
||||||
|
{{#formParams}}
|
||||||
|
{{> _param}}{{#hasMore}},{{/hasMore}}
|
||||||
|
{{/formParams}}
|
||||||
|
]
|
||||||
|
|
||||||
|
let nonNullParameters = APIHelper.rejectNil(formParams)
|
||||||
|
let parameters = APIHelper.convertBoolToString(nonNullParameters)
|
||||||
|
{{/hasFormParams}}
|
||||||
|
{{^hasFormParams}}
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
{{/hasFormParams}}
|
||||||
|
{{/bodyParam}}
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
{{#hasQueryParams}}
|
||||||
|
url?.queryItems = APIHelper.mapValuesToQueryItems(values:[
|
||||||
|
{{#queryParams}}
|
||||||
|
{{> _param}}{{#hasMore}}, {{/hasMore}}
|
||||||
|
{{/queryParams}}
|
||||||
|
])
|
||||||
|
{{/hasQueryParams}}{{#headerParams}}{{^secondaryParam}}
|
||||||
|
let nillableHeaders: [String: Any?] = [{{/secondaryParam}}
|
||||||
|
{{> _param}}{{#hasMore}},{{/hasMore}}{{^hasMore}}
|
||||||
|
]
|
||||||
|
let headerParameters = APIHelper.rejectNilHeaders(nillableHeaders){{/hasMore}}{{/headerParams}}
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}>.Type = {{projectName}}API.requestBuilderFactory.{{#returnType}}getBuilder(){{/returnType}}{{^returnType}}getNonDecodableBuilder(){{/returnType}}
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "{{httpMethod}}", URLString: (url?.string ?? URLString), parameters: parameters, isBody: {{hasBodyParam}}{{#headerParams}}{{^secondaryParam}}, headers: headerParameters{{/secondaryParam}}{{/headerParams}})
|
||||||
|
}
|
||||||
|
|
||||||
|
{{/operation}}
|
||||||
|
}
|
||||||
|
{{#swiftUseApiNamespace}}
|
||||||
|
}
|
||||||
|
{{/swiftUseApiNamespace}}
|
||||||
|
{{/operations}}
|
||||||
52
modules/swagger-codegen/src/main/resources/swift4/git_push.sh.mustache
Executable file
52
modules/swagger-codegen/src/main/resources/swift4/git_push.sh.mustache
Executable file
@@ -0,0 +1,52 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ref: https://help.github.com/articles/adding-an-existing-project-to-github-using-the-command-line/
|
||||||
|
#
|
||||||
|
# Usage example: /bin/sh ./git_push.sh wing328 swagger-petstore-perl "minor update"
|
||||||
|
|
||||||
|
git_user_id=$1
|
||||||
|
git_repo_id=$2
|
||||||
|
release_note=$3
|
||||||
|
|
||||||
|
if [ "$git_user_id" = "" ]; then
|
||||||
|
git_user_id="{{{gitUserId}}}"
|
||||||
|
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$git_repo_id" = "" ]; then
|
||||||
|
git_repo_id="{{{gitRepoId}}}"
|
||||||
|
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$release_note" = "" ]; then
|
||||||
|
release_note="{{{releaseNote}}}"
|
||||||
|
echo "[INFO] No command line input provided. Set \$release_note to $release_note"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Initialize the local directory as a Git repository
|
||||||
|
git init
|
||||||
|
|
||||||
|
# Adds the files in the local repository and stages them for commit.
|
||||||
|
git add .
|
||||||
|
|
||||||
|
# Commits the tracked changes and prepares them to be pushed to a remote repository.
|
||||||
|
git commit -m "$release_note"
|
||||||
|
|
||||||
|
# Sets the new remote
|
||||||
|
git_remote=`git remote`
|
||||||
|
if [ "$git_remote" = "" ]; then # git remote not defined
|
||||||
|
|
||||||
|
if [ "$GIT_TOKEN" = "" ]; then
|
||||||
|
echo "[INFO] \$GIT_TOKEN (environment variable) is not set. Using the git crediential in your environment."
|
||||||
|
git remote add origin https://github.com/${git_user_id}/${git_repo_id}.git
|
||||||
|
else
|
||||||
|
git remote add origin https://${git_user_id}:${GIT_TOKEN}@github.com/${git_user_id}/${git_repo_id}.git
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
git pull origin master
|
||||||
|
|
||||||
|
# Pushes (Forces) the changes in the local repository up to the remote repository
|
||||||
|
echo "Git pushing to https://github.com/${git_user_id}/${git_repo_id}.git"
|
||||||
|
git push origin master 2>&1 | grep -v 'To https'
|
||||||
|
|
||||||
@@ -0,0 +1,63 @@
|
|||||||
|
# Xcode
|
||||||
|
#
|
||||||
|
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||||
|
|
||||||
|
## Build generated
|
||||||
|
build/
|
||||||
|
DerivedData
|
||||||
|
|
||||||
|
## Various settings
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
xcuserdata
|
||||||
|
|
||||||
|
## Other
|
||||||
|
*.xccheckout
|
||||||
|
*.moved-aside
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcscmblueprint
|
||||||
|
|
||||||
|
## Obj-C/Swift specific
|
||||||
|
*.hmap
|
||||||
|
*.ipa
|
||||||
|
|
||||||
|
## Playgrounds
|
||||||
|
timeline.xctimeline
|
||||||
|
playground.xcworkspace
|
||||||
|
|
||||||
|
# Swift Package Manager
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||||
|
# Packages/
|
||||||
|
.build/
|
||||||
|
|
||||||
|
# CocoaPods
|
||||||
|
#
|
||||||
|
# We recommend against adding the Pods directory to your .gitignore. However
|
||||||
|
# you should judge for yourself, the pros and cons are mentioned at:
|
||||||
|
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||||
|
#
|
||||||
|
# Pods/
|
||||||
|
|
||||||
|
# Carthage
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||||
|
# Carthage/Checkouts
|
||||||
|
|
||||||
|
Carthage/Build
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
#
|
||||||
|
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||||
|
# screenshots whenever they are needed.
|
||||||
|
# For more information about the recommended setup visit:
|
||||||
|
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
|
||||||
|
|
||||||
|
fastlane/report.xml
|
||||||
|
fastlane/screenshots
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
{{#models}}{{#model}}//
|
||||||
|
// {{classname}}.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
{{#description}}
|
||||||
|
|
||||||
|
/** {{description}} */{{/description}}
|
||||||
|
{{#isArrayModel}}
|
||||||
|
public typealias {{classname}} = [{{arrayModelType}}]
|
||||||
|
{{/isArrayModel}}
|
||||||
|
{{^isArrayModel}}
|
||||||
|
{{#isEnum}}
|
||||||
|
public enum {{classname}}: {{dataType}}, Codable {
|
||||||
|
{{#allowableValues}}{{#enumVars}} case {{name}} = "{{{value}}}"
|
||||||
|
{{/enumVars}}{{/allowableValues}}
|
||||||
|
}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{^isEnum}}
|
||||||
|
{{#vars.isEmpty}}
|
||||||
|
public typealias {{classname}} = {{dataType}}
|
||||||
|
{{/vars.isEmpty}}
|
||||||
|
{{^vars.isEmpty}}
|
||||||
|
open class {{classname}}: {{#parent}}{{{parent}}}{{/parent}}{{^parent}}Codable{{/parent}} {
|
||||||
|
|
||||||
|
{{#vars}}
|
||||||
|
{{#isEnum}}
|
||||||
|
public enum {{enumName}}: {{^isContainer}}{{datatype}}{{/isContainer}}{{#isContainer}}String{{/isContainer}}, Codable { {{#allowableValues}}{{#enumVars}}
|
||||||
|
case {{name}} = {{#isContainer}}"{{/isContainer}}{{#isString}}"{{/isString}}{{{value}}}{{#isString}}"{{/isString}}{{#isContainer}}"{{/isContainer}}{{/enumVars}}{{/allowableValues}}
|
||||||
|
}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/vars}}
|
||||||
|
{{#vars}}
|
||||||
|
{{#isEnum}}
|
||||||
|
{{#description}}/** {{description}} */
|
||||||
|
{{/description}}public var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{^isEnum}}
|
||||||
|
{{#description}}/** {{description}} */
|
||||||
|
{{/description}}public var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/vars}}
|
||||||
|
|
||||||
|
{{#additionalPropertiesType}}
|
||||||
|
public var additionalProperties: [AnyHashable:{{{additionalPropertiesType}}}] = [:]
|
||||||
|
|
||||||
|
{{/additionalPropertiesType}}
|
||||||
|
{{^unwrapRequired}}
|
||||||
|
{{^parent}}public init() {}{{/parent}}{{/unwrapRequired}}
|
||||||
|
{{#unwrapRequired}}
|
||||||
|
public init({{#allVars}}{{^-first}}, {{/-first}}{{name}}: {{#isEnum}}{{datatypeWithEnum}}{{/isEnum}}{{^isEnum}}{{datatype}}{{/isEnum}}{{^required}}?=nil{{/required}}{{/allVars}}) {
|
||||||
|
{{#vars}}
|
||||||
|
self.{{name}} = {{name}}
|
||||||
|
{{/vars}}
|
||||||
|
}{{/unwrapRequired}}
|
||||||
|
{{#additionalPropertiesType}}
|
||||||
|
public subscript(key: AnyHashable) -> {{{additionalPropertiesType}}}? {
|
||||||
|
get {
|
||||||
|
if let value = additionalProperties[key] {
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
set {
|
||||||
|
additionalProperties[key] = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{/additionalPropertiesType}}
|
||||||
|
}
|
||||||
|
{{/vars.isEmpty}}
|
||||||
|
{{/isEnum}}
|
||||||
|
{{/isArrayModel}}
|
||||||
|
{{/model}}
|
||||||
|
{{/models}}
|
||||||
63
samples/client/petstore/swift4/.gitignore
vendored
Normal file
63
samples/client/petstore/swift4/.gitignore
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Xcode
|
||||||
|
#
|
||||||
|
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||||
|
|
||||||
|
## Build generated
|
||||||
|
build/
|
||||||
|
DerivedData
|
||||||
|
|
||||||
|
## Various settings
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
xcuserdata
|
||||||
|
|
||||||
|
## Other
|
||||||
|
*.xccheckout
|
||||||
|
*.moved-aside
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcscmblueprint
|
||||||
|
|
||||||
|
## Obj-C/Swift specific
|
||||||
|
*.hmap
|
||||||
|
*.ipa
|
||||||
|
|
||||||
|
## Playgrounds
|
||||||
|
timeline.xctimeline
|
||||||
|
playground.xcworkspace
|
||||||
|
|
||||||
|
# Swift Package Manager
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||||
|
# Packages/
|
||||||
|
.build/
|
||||||
|
|
||||||
|
# CocoaPods
|
||||||
|
#
|
||||||
|
# We recommend against adding the Pods directory to your .gitignore. However
|
||||||
|
# you should judge for yourself, the pros and cons are mentioned at:
|
||||||
|
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||||
|
#
|
||||||
|
# Pods/
|
||||||
|
|
||||||
|
# Carthage
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||||
|
# Carthage/Checkouts
|
||||||
|
|
||||||
|
Carthage/Build
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
#
|
||||||
|
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||||
|
# screenshots whenever they are needed.
|
||||||
|
# For more information about the recommended setup visit:
|
||||||
|
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
|
||||||
|
|
||||||
|
fastlane/report.xml
|
||||||
|
fastlane/screenshots
|
||||||
23
samples/client/petstore/swift4/.swagger-codegen-ignore
Normal file
23
samples/client/petstore/swift4/.swagger-codegen-ignore
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
# Swagger Codegen Ignore
|
||||||
|
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
||||||
63
samples/client/petstore/swift4/default/.gitignore
vendored
Normal file
63
samples/client/petstore/swift4/default/.gitignore
vendored
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
# Xcode
|
||||||
|
#
|
||||||
|
# gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
|
||||||
|
|
||||||
|
## Build generated
|
||||||
|
build/
|
||||||
|
DerivedData
|
||||||
|
|
||||||
|
## Various settings
|
||||||
|
*.pbxuser
|
||||||
|
!default.pbxuser
|
||||||
|
*.mode1v3
|
||||||
|
!default.mode1v3
|
||||||
|
*.mode2v3
|
||||||
|
!default.mode2v3
|
||||||
|
*.perspectivev3
|
||||||
|
!default.perspectivev3
|
||||||
|
xcuserdata
|
||||||
|
|
||||||
|
## Other
|
||||||
|
*.xccheckout
|
||||||
|
*.moved-aside
|
||||||
|
*.xcuserstate
|
||||||
|
*.xcscmblueprint
|
||||||
|
|
||||||
|
## Obj-C/Swift specific
|
||||||
|
*.hmap
|
||||||
|
*.ipa
|
||||||
|
|
||||||
|
## Playgrounds
|
||||||
|
timeline.xctimeline
|
||||||
|
playground.xcworkspace
|
||||||
|
|
||||||
|
# Swift Package Manager
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Swift Package Manager dependencies.
|
||||||
|
# Packages/
|
||||||
|
.build/
|
||||||
|
|
||||||
|
# CocoaPods
|
||||||
|
#
|
||||||
|
# We recommend against adding the Pods directory to your .gitignore. However
|
||||||
|
# you should judge for yourself, the pros and cons are mentioned at:
|
||||||
|
# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
|
||||||
|
#
|
||||||
|
# Pods/
|
||||||
|
|
||||||
|
# Carthage
|
||||||
|
#
|
||||||
|
# Add this line if you want to avoid checking in source code from Carthage dependencies.
|
||||||
|
# Carthage/Checkouts
|
||||||
|
|
||||||
|
Carthage/Build
|
||||||
|
|
||||||
|
# fastlane
|
||||||
|
#
|
||||||
|
# It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
|
||||||
|
# screenshots whenever they are needed.
|
||||||
|
# For more information about the recommended setup visit:
|
||||||
|
# https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
|
||||||
|
|
||||||
|
fastlane/report.xml
|
||||||
|
fastlane/screenshots
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
# Swagger Codegen Ignore
|
||||||
|
# Generated by swagger-codegen https://github.com/swagger-api/swagger-codegen
|
||||||
|
|
||||||
|
# Use this file to prevent files from being overwritten by the generator.
|
||||||
|
# The patterns follow closely to .gitignore or .dockerignore.
|
||||||
|
|
||||||
|
# As an example, the C# client generator defines ApiClient.cs.
|
||||||
|
# You can make changes and tell Swagger Codgen to ignore just this file by uncommenting the following line:
|
||||||
|
#ApiClient.cs
|
||||||
|
|
||||||
|
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
|
||||||
|
#foo/*/qux
|
||||||
|
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
|
||||||
|
#foo/**/qux
|
||||||
|
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
|
||||||
|
|
||||||
|
# You can also negate patterns with an exclamation (!).
|
||||||
|
# For example, you can ignore all files in a docs folder with the file extension .md:
|
||||||
|
#docs/*.md
|
||||||
|
# Then explicitly reverse the ignore rule for a single file:
|
||||||
|
#!docs/README.md
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
2.2.3-SNAPSHOT
|
||||||
1
samples/client/petstore/swift4/default/Cartfile
Normal file
1
samples/client/petstore/swift4/default/Cartfile
Normal file
@@ -0,0 +1 @@
|
|||||||
|
github "Alamofire/Alamofire" >= 3.1.0
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
Pod::Spec.new do |s|
|
||||||
|
s.name = 'PetstoreClient'
|
||||||
|
s.ios.deployment_target = '9.0'
|
||||||
|
s.osx.deployment_target = '10.11'
|
||||||
|
s.version = '0.0.1'
|
||||||
|
s.source = { :git => 'git@github.com:swagger-api/swagger-mustache.git', :tag => 'v1.0.0' }
|
||||||
|
s.authors = ''
|
||||||
|
s.license = 'Proprietary'
|
||||||
|
s.homepage = 'https://github.com/swagger-api/swagger-codegen'
|
||||||
|
s.summary = 'PetstoreClient'
|
||||||
|
s.source_files = 'PetstoreClient/Classes/Swaggers/**/*.swift'
|
||||||
|
s.dependency 'Alamofire', '~> 4.5'
|
||||||
|
end
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
// APIHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class APIHelper {
|
||||||
|
static func rejectNil(_ source: [String:Any?]) -> [String:Any]? {
|
||||||
|
var destination = [String:Any]()
|
||||||
|
for (key, nillableValue) in source {
|
||||||
|
if let value: Any = nillableValue {
|
||||||
|
destination[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if destination.isEmpty {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
static func rejectNilHeaders(_ source: [String:Any?]) -> [String:String] {
|
||||||
|
var destination = [String:String]()
|
||||||
|
for (key, nillableValue) in source {
|
||||||
|
if let value: Any = nillableValue {
|
||||||
|
destination[key] = "\(value)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
static func convertBoolToString(_ source: [String: Any]?) -> [String:Any]? {
|
||||||
|
guard let source = source else {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
var destination = [String:Any]()
|
||||||
|
let theTrue = NSNumber(value: true as Bool)
|
||||||
|
let theFalse = NSNumber(value: false as Bool)
|
||||||
|
for (key, value) in source {
|
||||||
|
switch value {
|
||||||
|
case let x where x as? NSNumber === theTrue || x as? NSNumber === theFalse:
|
||||||
|
destination[key] = "\(value as! Bool)" as Any?
|
||||||
|
default:
|
||||||
|
destination[key] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func mapValuesToQueryItems(values: [String:Any?]) -> [URLQueryItem]? {
|
||||||
|
let returnValues = values
|
||||||
|
.filter { $0.1 != nil }
|
||||||
|
.map { (item: (_key: String, _value: Any?)) -> URLQueryItem in
|
||||||
|
URLQueryItem(name: item._key, value:"\(item._value!)")
|
||||||
|
}
|
||||||
|
if returnValues.count == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
return returnValues
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
// APIs.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class PetstoreClientAPI {
|
||||||
|
open static var basePath = "http://petstore.swagger.io:80/v2"
|
||||||
|
open static var credential: URLCredential?
|
||||||
|
open static var customHeaders: [String:String] = [:]
|
||||||
|
open static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory()
|
||||||
|
}
|
||||||
|
|
||||||
|
open class RequestBuilder<T> {
|
||||||
|
var credential: URLCredential?
|
||||||
|
var headers: [String:String]
|
||||||
|
let parameters: [String:Any]?
|
||||||
|
let isBody: Bool
|
||||||
|
let method: String
|
||||||
|
let URLString: String
|
||||||
|
|
||||||
|
/// Optional block to obtain a reference to the request's progress instance when available.
|
||||||
|
public var onProgressReady: ((Progress) -> ())?
|
||||||
|
|
||||||
|
required public init(method: String, URLString: String, parameters: [String:Any]?, isBody: Bool, headers: [String:String] = [:]) {
|
||||||
|
self.method = method
|
||||||
|
self.URLString = URLString
|
||||||
|
self.parameters = parameters
|
||||||
|
self.isBody = isBody
|
||||||
|
self.headers = headers
|
||||||
|
|
||||||
|
addHeaders(PetstoreClientAPI.customHeaders)
|
||||||
|
}
|
||||||
|
|
||||||
|
open func addHeaders(_ aHeaders:[String:String]) {
|
||||||
|
for (header, value) in aHeaders {
|
||||||
|
headers[header] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func execute(_ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) { }
|
||||||
|
|
||||||
|
public func addHeader(name: String, value: String) -> Self {
|
||||||
|
if !value.isEmpty {
|
||||||
|
headers[name] = value
|
||||||
|
}
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
open func addCredential() -> Self {
|
||||||
|
self.credential = PetstoreClientAPI.credential
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public protocol RequestBuilderFactory {
|
||||||
|
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type
|
||||||
|
func getBuilder<T:Decodable>() -> RequestBuilder<T>.Type
|
||||||
|
}
|
||||||
@@ -0,0 +1,407 @@
|
|||||||
|
//
|
||||||
|
// FakeAPI.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class FakeAPI {
|
||||||
|
/**
|
||||||
|
|
||||||
|
- parameter body: (body) Input boolean as post body (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func fakeOuterBooleanSerialize(body: OuterBoolean? = nil, completion: @escaping ((_ data: OuterBoolean?,_ error: Error?) -> Void)) {
|
||||||
|
fakeOuterBooleanSerializeWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
- POST /fake/outer/boolean
|
||||||
|
- Test serialization of outer boolean types
|
||||||
|
- examples: [{contentType=application/json, example={ }}]
|
||||||
|
|
||||||
|
- parameter body: (body) Input boolean as post body (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<OuterBoolean>
|
||||||
|
*/
|
||||||
|
open class func fakeOuterBooleanSerializeWithRequestBuilder(body: OuterBoolean? = nil) -> RequestBuilder<OuterBoolean> {
|
||||||
|
let path = "/fake/outer/boolean"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<OuterBoolean>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
- parameter body: (body) Input composite as post body (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func fakeOuterCompositeSerialize(body: OuterComposite? = nil, completion: @escaping ((_ data: OuterComposite?,_ error: Error?) -> Void)) {
|
||||||
|
fakeOuterCompositeSerializeWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
- POST /fake/outer/composite
|
||||||
|
- Test serialization of object with outer number type
|
||||||
|
- examples: [{contentType=application/json, example={
|
||||||
|
"my_string" : { },
|
||||||
|
"my_number" : { },
|
||||||
|
"my_boolean" : { }
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter body: (body) Input composite as post body (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<OuterComposite>
|
||||||
|
*/
|
||||||
|
open class func fakeOuterCompositeSerializeWithRequestBuilder(body: OuterComposite? = nil) -> RequestBuilder<OuterComposite> {
|
||||||
|
let path = "/fake/outer/composite"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<OuterComposite>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
- parameter body: (body) Input number as post body (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func fakeOuterNumberSerialize(body: OuterNumber? = nil, completion: @escaping ((_ data: OuterNumber?,_ error: Error?) -> Void)) {
|
||||||
|
fakeOuterNumberSerializeWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
- POST /fake/outer/number
|
||||||
|
- Test serialization of outer number types
|
||||||
|
- examples: [{contentType=application/json, example={ }}]
|
||||||
|
|
||||||
|
- parameter body: (body) Input number as post body (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<OuterNumber>
|
||||||
|
*/
|
||||||
|
open class func fakeOuterNumberSerializeWithRequestBuilder(body: OuterNumber? = nil) -> RequestBuilder<OuterNumber> {
|
||||||
|
let path = "/fake/outer/number"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<OuterNumber>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
|
||||||
|
- parameter body: (body) Input string as post body (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func fakeOuterStringSerialize(body: OuterString? = nil, completion: @escaping ((_ data: OuterString?,_ error: Error?) -> Void)) {
|
||||||
|
fakeOuterStringSerializeWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
- POST /fake/outer/string
|
||||||
|
- Test serialization of outer string types
|
||||||
|
- examples: [{contentType=application/json, example={ }}]
|
||||||
|
|
||||||
|
- parameter body: (body) Input string as post body (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<OuterString>
|
||||||
|
*/
|
||||||
|
open class func fakeOuterStringSerializeWithRequestBuilder(body: OuterString? = nil) -> RequestBuilder<OuterString> {
|
||||||
|
let path = "/fake/outer/string"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<OuterString>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
To test \"client\" model
|
||||||
|
|
||||||
|
- parameter body: (body) client model
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func testClientModel(body: Client, completion: @escaping ((_ data: Client?,_ error: Error?) -> Void)) {
|
||||||
|
testClientModelWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
To test \"client\" model
|
||||||
|
- PATCH /fake
|
||||||
|
- To test \"client\" model
|
||||||
|
- examples: [{contentType=application/json, example={
|
||||||
|
"client" : "aeiou"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter body: (body) client model
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Client>
|
||||||
|
*/
|
||||||
|
open class func testClientModelWithRequestBuilder(body: Client) -> RequestBuilder<Client> {
|
||||||
|
let path = "/fake"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Client>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "PATCH", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
|
||||||
|
|
||||||
|
- parameter number: (form) None
|
||||||
|
- parameter double: (form) None
|
||||||
|
- parameter patternWithoutDelimiter: (form) None
|
||||||
|
- parameter byte: (form) None
|
||||||
|
- parameter integer: (form) None (optional)
|
||||||
|
- parameter int32: (form) None (optional)
|
||||||
|
- parameter int64: (form) None (optional)
|
||||||
|
- parameter float: (form) None (optional)
|
||||||
|
- parameter string: (form) None (optional)
|
||||||
|
- parameter binary: (form) None (optional)
|
||||||
|
- parameter date: (form) None (optional)
|
||||||
|
- parameter dateTime: (form) None (optional)
|
||||||
|
- parameter password: (form) None (optional)
|
||||||
|
- parameter callback: (form) None (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func testEndpointParameters(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int32? = nil, int32: Int32? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: Data? = nil, date: Date? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
testEndpointParametersWithRequestBuilder(number: number, double: double, patternWithoutDelimiter: patternWithoutDelimiter, byte: byte, integer: integer, int32: int32, int64: int64, float: float, string: string, binary: binary, date: date, dateTime: dateTime, password: password, callback: callback).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
|
||||||
|
- POST /fake
|
||||||
|
- Fake endpoint for testing various parameters 假端點 偽のエンドポイント 가짜 엔드 포인트
|
||||||
|
- BASIC:
|
||||||
|
- type: basic
|
||||||
|
- name: http_basic_test
|
||||||
|
|
||||||
|
- parameter number: (form) None
|
||||||
|
- parameter double: (form) None
|
||||||
|
- parameter patternWithoutDelimiter: (form) None
|
||||||
|
- parameter byte: (form) None
|
||||||
|
- parameter integer: (form) None (optional)
|
||||||
|
- parameter int32: (form) None (optional)
|
||||||
|
- parameter int64: (form) None (optional)
|
||||||
|
- parameter float: (form) None (optional)
|
||||||
|
- parameter string: (form) None (optional)
|
||||||
|
- parameter binary: (form) None (optional)
|
||||||
|
- parameter date: (form) None (optional)
|
||||||
|
- parameter dateTime: (form) None (optional)
|
||||||
|
- parameter password: (form) None (optional)
|
||||||
|
- parameter callback: (form) None (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func testEndpointParametersWithRequestBuilder(number: Double, double: Double, patternWithoutDelimiter: String, byte: Data, integer: Int32? = nil, int32: Int32? = nil, int64: Int64? = nil, float: Float? = nil, string: String? = nil, binary: Data? = nil, date: Date? = nil, dateTime: Date? = nil, password: String? = nil, callback: String? = nil) -> RequestBuilder<Void> {
|
||||||
|
let path = "/fake"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let formParams: [String:Any?] = [
|
||||||
|
"integer": integer?.encodeToJSON(),
|
||||||
|
"int32": int32?.encodeToJSON(),
|
||||||
|
"int64": int64?.encodeToJSON(),
|
||||||
|
"number": number,
|
||||||
|
"float": float,
|
||||||
|
"double": double,
|
||||||
|
"string": string,
|
||||||
|
"pattern_without_delimiter": patternWithoutDelimiter,
|
||||||
|
"byte": byte,
|
||||||
|
"binary": binary,
|
||||||
|
"date": date?.encodeToJSON(),
|
||||||
|
"dateTime": dateTime?.encodeToJSON(),
|
||||||
|
"password": password,
|
||||||
|
"callback": callback
|
||||||
|
]
|
||||||
|
|
||||||
|
let nonNullParameters = APIHelper.rejectNil(formParams)
|
||||||
|
let parameters = APIHelper.convertBoolToString(nonNullParameters)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumFormStringArray
|
||||||
|
*/
|
||||||
|
public enum EnumFormStringArray_testEnumParameters: String {
|
||||||
|
case greaterThan = ">"
|
||||||
|
case dollar = "$"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumFormString
|
||||||
|
*/
|
||||||
|
public enum EnumFormString_testEnumParameters: String {
|
||||||
|
case abc = "_abc"
|
||||||
|
case efg = "-efg"
|
||||||
|
case xyz = "(xyz)"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumHeaderStringArray
|
||||||
|
*/
|
||||||
|
public enum EnumHeaderStringArray_testEnumParameters: String {
|
||||||
|
case greaterThan = ">"
|
||||||
|
case dollar = "$"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumHeaderString
|
||||||
|
*/
|
||||||
|
public enum EnumHeaderString_testEnumParameters: String {
|
||||||
|
case abc = "_abc"
|
||||||
|
case efg = "-efg"
|
||||||
|
case xyz = "(xyz)"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumQueryStringArray
|
||||||
|
*/
|
||||||
|
public enum EnumQueryStringArray_testEnumParameters: String {
|
||||||
|
case greaterThan = ">"
|
||||||
|
case dollar = "$"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumQueryString
|
||||||
|
*/
|
||||||
|
public enum EnumQueryString_testEnumParameters: String {
|
||||||
|
case abc = "_abc"
|
||||||
|
case efg = "-efg"
|
||||||
|
case xyz = "(xyz)"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumQueryInteger
|
||||||
|
*/
|
||||||
|
public enum EnumQueryInteger_testEnumParameters: Int32 {
|
||||||
|
case _1 = 1
|
||||||
|
case numberminus2 = -2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter enumQueryDouble
|
||||||
|
*/
|
||||||
|
public enum EnumQueryDouble_testEnumParameters: Double {
|
||||||
|
case _11 = 1.1
|
||||||
|
case numberminus12 = -1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
To test enum parameters
|
||||||
|
|
||||||
|
- parameter enumFormStringArray: (form) Form parameter enum test (string array) (optional)
|
||||||
|
- parameter enumFormString: (form) Form parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumHeaderStringArray: (header) Header parameter enum test (string array) (optional)
|
||||||
|
- parameter enumHeaderString: (header) Header parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumQueryStringArray: (query) Query parameter enum test (string array) (optional)
|
||||||
|
- parameter enumQueryString: (query) Query parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumQueryInteger: (query) Query parameter enum test (double) (optional)
|
||||||
|
- parameter enumQueryDouble: (form) Query parameter enum test (double) (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func testEnumParameters(enumFormStringArray: [String]? = nil, enumFormString: EnumFormString_testEnumParameters? = nil, enumHeaderStringArray: [String]? = nil, enumHeaderString: EnumHeaderString_testEnumParameters? = nil, enumQueryStringArray: [String]? = nil, enumQueryString: EnumQueryString_testEnumParameters? = nil, enumQueryInteger: EnumQueryInteger_testEnumParameters? = nil, enumQueryDouble: EnumQueryDouble_testEnumParameters? = nil, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
testEnumParametersWithRequestBuilder(enumFormStringArray: enumFormStringArray, enumFormString: enumFormString, enumHeaderStringArray: enumHeaderStringArray, enumHeaderString: enumHeaderString, enumQueryStringArray: enumQueryStringArray, enumQueryString: enumQueryString, enumQueryInteger: enumQueryInteger, enumQueryDouble: enumQueryDouble).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
To test enum parameters
|
||||||
|
- GET /fake
|
||||||
|
- To test enum parameters
|
||||||
|
|
||||||
|
- parameter enumFormStringArray: (form) Form parameter enum test (string array) (optional)
|
||||||
|
- parameter enumFormString: (form) Form parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumHeaderStringArray: (header) Header parameter enum test (string array) (optional)
|
||||||
|
- parameter enumHeaderString: (header) Header parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumQueryStringArray: (query) Query parameter enum test (string array) (optional)
|
||||||
|
- parameter enumQueryString: (query) Query parameter enum test (string) (optional, default to -efg)
|
||||||
|
- parameter enumQueryInteger: (query) Query parameter enum test (double) (optional)
|
||||||
|
- parameter enumQueryDouble: (form) Query parameter enum test (double) (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func testEnumParametersWithRequestBuilder(enumFormStringArray: [String]? = nil, enumFormString: EnumFormString_testEnumParameters? = nil, enumHeaderStringArray: [String]? = nil, enumHeaderString: EnumHeaderString_testEnumParameters? = nil, enumQueryStringArray: [String]? = nil, enumQueryString: EnumQueryString_testEnumParameters? = nil, enumQueryInteger: EnumQueryInteger_testEnumParameters? = nil, enumQueryDouble: EnumQueryDouble_testEnumParameters? = nil) -> RequestBuilder<Void> {
|
||||||
|
let path = "/fake"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let formParams: [String:Any?] = [
|
||||||
|
"enum_form_string_array": enumFormStringArray,
|
||||||
|
"enum_form_string": enumFormString?.rawValue,
|
||||||
|
"enum_query_double": enumQueryDouble?.rawValue
|
||||||
|
]
|
||||||
|
|
||||||
|
let nonNullParameters = APIHelper.rejectNil(formParams)
|
||||||
|
let parameters = APIHelper.convertBoolToString(nonNullParameters)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
url?.queryItems = APIHelper.mapValuesToQueryItems(values:[
|
||||||
|
"enum_query_string_array": enumQueryStringArray,
|
||||||
|
"enum_query_string": enumQueryString?.rawValue,
|
||||||
|
"enum_query_integer": enumQueryInteger?.rawValue
|
||||||
|
])
|
||||||
|
|
||||||
|
let nillableHeaders: [String: Any?] = [
|
||||||
|
"enum_header_string_array": enumHeaderStringArray,
|
||||||
|
"enum_header_string": enumHeaderString?.rawValue
|
||||||
|
]
|
||||||
|
let headerParameters = APIHelper.rejectNilHeaders(nillableHeaders)
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false, headers: headerParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
//
|
||||||
|
// FakeclassnametagsAPI.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class FakeclassnametagsAPI {
|
||||||
|
/**
|
||||||
|
To test class name in snake case
|
||||||
|
|
||||||
|
- parameter body: (body) client model
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func testClassname(body: Client, completion: @escaping ((_ data: Client?,_ error: Error?) -> Void)) {
|
||||||
|
testClassnameWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
To test class name in snake case
|
||||||
|
- PATCH /fake_classname_test
|
||||||
|
- examples: [{contentType=application/json, example={
|
||||||
|
"client" : "aeiou"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter body: (body) client model
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Client>
|
||||||
|
*/
|
||||||
|
open class func testClassnameWithRequestBuilder(body: Client) -> RequestBuilder<Client> {
|
||||||
|
let path = "/fake_classname_test"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let convertedParameters = APIHelper.convertBoolToString(parameters)
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Client>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "PATCH", URLString: URLString, parameters: convertedParameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,506 @@
|
|||||||
|
//
|
||||||
|
// PetAPI.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class PetAPI {
|
||||||
|
/**
|
||||||
|
Add a new pet to the store
|
||||||
|
|
||||||
|
- parameter body: (body) Pet object that needs to be added to the store
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func addPet(body: Pet, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
addPetWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Add a new pet to the store
|
||||||
|
- POST /pet
|
||||||
|
-
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
|
||||||
|
- parameter body: (body) Pet object that needs to be added to the store
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func addPetWithRequestBuilder(body: Pet) -> RequestBuilder<Void> {
|
||||||
|
let path = "/pet"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Deletes a pet
|
||||||
|
|
||||||
|
- parameter petId: (path) Pet id to delete
|
||||||
|
- parameter apiKey: (header) (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func deletePet(petId: Int64, apiKey: String? = nil, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
deletePetWithRequestBuilder(petId: petId, apiKey: apiKey).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Deletes a pet
|
||||||
|
- DELETE /pet/{petId}
|
||||||
|
-
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
|
||||||
|
- parameter petId: (path) Pet id to delete
|
||||||
|
- parameter apiKey: (header) (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func deletePetWithRequestBuilder(petId: Int64, apiKey: String? = nil) -> RequestBuilder<Void> {
|
||||||
|
var path = "/pet/{petId}"
|
||||||
|
path = path.replacingOccurrences(of: "{petId}", with: "\(petId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
let nillableHeaders: [String: Any?] = [
|
||||||
|
"api_key": apiKey
|
||||||
|
]
|
||||||
|
let headerParameters = APIHelper.rejectNilHeaders(nillableHeaders)
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "DELETE", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false, headers: headerParameters)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* enum for parameter status
|
||||||
|
*/
|
||||||
|
public enum Status_findPetsByStatus: String {
|
||||||
|
case available = "available"
|
||||||
|
case pending = "pending"
|
||||||
|
case sold = "sold"
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds Pets by status
|
||||||
|
|
||||||
|
- parameter status: (query) Status values that need to be considered for filter
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func findPetsByStatus(status: [String], completion: @escaping ((_ data: [Pet]?,_ error: Error?) -> Void)) {
|
||||||
|
findPetsByStatusWithRequestBuilder(status: status).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds Pets by status
|
||||||
|
- GET /pet/findByStatus
|
||||||
|
- Multiple status values can be provided with comma separated strings
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example=[ {
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
} ]}]
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example=[ {
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
} ]}]
|
||||||
|
|
||||||
|
- parameter status: (query) Status values that need to be considered for filter
|
||||||
|
|
||||||
|
- returns: RequestBuilder<[Pet]>
|
||||||
|
*/
|
||||||
|
open class func findPetsByStatusWithRequestBuilder(status: [String]) -> RequestBuilder<[Pet]> {
|
||||||
|
let path = "/pet/findByStatus"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
url?.queryItems = APIHelper.mapValuesToQueryItems(values:[
|
||||||
|
"status": status
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds Pets by tags
|
||||||
|
|
||||||
|
- parameter tags: (query) Tags to filter by
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func findPetsByTags(tags: [String], completion: @escaping ((_ data: [Pet]?,_ error: Error?) -> Void)) {
|
||||||
|
findPetsByTagsWithRequestBuilder(tags: tags).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Finds Pets by tags
|
||||||
|
- GET /pet/findByTags
|
||||||
|
- Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing.
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example=[ {
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
} ]}]
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example=[ {
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
} ]}]
|
||||||
|
|
||||||
|
- parameter tags: (query) Tags to filter by
|
||||||
|
|
||||||
|
- returns: RequestBuilder<[Pet]>
|
||||||
|
*/
|
||||||
|
open class func findPetsByTagsWithRequestBuilder(tags: [String]) -> RequestBuilder<[Pet]> {
|
||||||
|
let path = "/pet/findByTags"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
url?.queryItems = APIHelper.mapValuesToQueryItems(values:[
|
||||||
|
"tags": tags
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find pet by ID
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet to return
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func getPetById(petId: Int64, completion: @escaping ((_ data: Pet?,_ error: Error?) -> Void)) {
|
||||||
|
getPetByIdWithRequestBuilder(petId: petId).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find pet by ID
|
||||||
|
- GET /pet/{petId}
|
||||||
|
- Returns a single pet
|
||||||
|
- API Key:
|
||||||
|
- type: apiKey api_key
|
||||||
|
- name: api_key
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example={
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
}}]
|
||||||
|
- examples: [{contentType=application/xml, example=<Pet>
|
||||||
|
<id>123456789</id>
|
||||||
|
<name>doggie</name>
|
||||||
|
<photoUrls>
|
||||||
|
<photoUrls>aeiou</photoUrls>
|
||||||
|
</photoUrls>
|
||||||
|
<tags>
|
||||||
|
</tags>
|
||||||
|
<status>aeiou</status>
|
||||||
|
</Pet>}, {contentType=application/json, example={
|
||||||
|
"photoUrls" : [ "aeiou" ],
|
||||||
|
"name" : "doggie",
|
||||||
|
"id" : 0,
|
||||||
|
"category" : {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 6
|
||||||
|
},
|
||||||
|
"tags" : [ {
|
||||||
|
"name" : "aeiou",
|
||||||
|
"id" : 1
|
||||||
|
} ],
|
||||||
|
"status" : "available"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet to return
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Pet>
|
||||||
|
*/
|
||||||
|
open class func getPetByIdWithRequestBuilder(petId: Int64) -> RequestBuilder<Pet> {
|
||||||
|
var path = "/pet/{petId}"
|
||||||
|
path = path.replacingOccurrences(of: "{petId}", with: "\(petId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Pet>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update an existing pet
|
||||||
|
|
||||||
|
- parameter body: (body) Pet object that needs to be added to the store
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func updatePet(body: Pet, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
updatePetWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Update an existing pet
|
||||||
|
- PUT /pet
|
||||||
|
-
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
|
||||||
|
- parameter body: (body) Pet object that needs to be added to the store
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func updatePetWithRequestBuilder(body: Pet) -> RequestBuilder<Void> {
|
||||||
|
let path = "/pet"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "PUT", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Updates a pet in the store with form data
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet that needs to be updated
|
||||||
|
- parameter name: (form) Updated name of the pet (optional)
|
||||||
|
- parameter status: (form) Updated status of the pet (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func updatePetWithForm(petId: Int64, name: String? = nil, status: String? = nil, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
updatePetWithFormWithRequestBuilder(petId: petId, name: name, status: status).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Updates a pet in the store with form data
|
||||||
|
- POST /pet/{petId}
|
||||||
|
-
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet that needs to be updated
|
||||||
|
- parameter name: (form) Updated name of the pet (optional)
|
||||||
|
- parameter status: (form) Updated status of the pet (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func updatePetWithFormWithRequestBuilder(petId: Int64, name: String? = nil, status: String? = nil) -> RequestBuilder<Void> {
|
||||||
|
var path = "/pet/{petId}"
|
||||||
|
path = path.replacingOccurrences(of: "{petId}", with: "\(petId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let formParams: [String:Any?] = [
|
||||||
|
"name": name,
|
||||||
|
"status": status
|
||||||
|
]
|
||||||
|
|
||||||
|
let nonNullParameters = APIHelper.rejectNil(formParams)
|
||||||
|
let parameters = APIHelper.convertBoolToString(nonNullParameters)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
uploads an image
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet to update
|
||||||
|
- parameter additionalMetadata: (form) Additional data to pass to server (optional)
|
||||||
|
- parameter file: (form) file to upload (optional)
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func uploadFile(petId: Int64, additionalMetadata: String? = nil, file: URL? = nil, completion: @escaping ((_ data: ApiResponse?,_ error: Error?) -> Void)) {
|
||||||
|
uploadFileWithRequestBuilder(petId: petId, additionalMetadata: additionalMetadata, file: file).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
uploads an image
|
||||||
|
- POST /pet/{petId}/uploadImage
|
||||||
|
-
|
||||||
|
- OAuth:
|
||||||
|
- type: oauth2
|
||||||
|
- name: petstore_auth
|
||||||
|
- examples: [{contentType=application/json, example={
|
||||||
|
"code" : 0,
|
||||||
|
"type" : "aeiou",
|
||||||
|
"message" : "aeiou"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter petId: (path) ID of pet to update
|
||||||
|
- parameter additionalMetadata: (form) Additional data to pass to server (optional)
|
||||||
|
- parameter file: (form) file to upload (optional)
|
||||||
|
|
||||||
|
- returns: RequestBuilder<ApiResponse>
|
||||||
|
*/
|
||||||
|
open class func uploadFileWithRequestBuilder(petId: Int64, additionalMetadata: String? = nil, file: URL? = nil) -> RequestBuilder<ApiResponse> {
|
||||||
|
var path = "/pet/{petId}/uploadImage"
|
||||||
|
path = path.replacingOccurrences(of: "{petId}", with: "\(petId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let formParams: [String:Any?] = [
|
||||||
|
"additionalMetadata": additionalMetadata,
|
||||||
|
"file": file
|
||||||
|
]
|
||||||
|
|
||||||
|
let nonNullParameters = APIHelper.rejectNil(formParams)
|
||||||
|
let parameters = APIHelper.convertBoolToString(nonNullParameters)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<ApiResponse>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,219 @@
|
|||||||
|
//
|
||||||
|
// StoreAPI.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class StoreAPI {
|
||||||
|
/**
|
||||||
|
Delete purchase order by ID
|
||||||
|
|
||||||
|
- parameter orderId: (path) ID of the order that needs to be deleted
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func deleteOrder(orderId: String, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
deleteOrderWithRequestBuilder(orderId: orderId).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Delete purchase order by ID
|
||||||
|
- DELETE /store/order/{order_id}
|
||||||
|
- For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors
|
||||||
|
|
||||||
|
- parameter orderId: (path) ID of the order that needs to be deleted
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func deleteOrderWithRequestBuilder(orderId: String) -> RequestBuilder<Void> {
|
||||||
|
var path = "/store/order/{order_id}"
|
||||||
|
path = path.replacingOccurrences(of: "{order_id}", with: "\(orderId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "DELETE", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns pet inventories by status
|
||||||
|
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func getInventory(completion: @escaping ((_ data: [String:Int32]?,_ error: Error?) -> Void)) {
|
||||||
|
getInventoryWithRequestBuilder().execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Returns pet inventories by status
|
||||||
|
- GET /store/inventory
|
||||||
|
- Returns a map of status codes to quantities
|
||||||
|
- API Key:
|
||||||
|
- type: apiKey api_key
|
||||||
|
- name: api_key
|
||||||
|
- examples: [{contentType=application/json, example={
|
||||||
|
"key" : 0
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- returns: RequestBuilder<[String:Int32]>
|
||||||
|
*/
|
||||||
|
open class func getInventoryWithRequestBuilder() -> RequestBuilder<[String:Int32]> {
|
||||||
|
let path = "/store/inventory"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<[String:Int32]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find purchase order by ID
|
||||||
|
|
||||||
|
- parameter orderId: (path) ID of pet that needs to be fetched
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func getOrderById(orderId: Int64, completion: @escaping ((_ data: Order?,_ error: Error?) -> Void)) {
|
||||||
|
getOrderByIdWithRequestBuilder(orderId: orderId).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Find purchase order by ID
|
||||||
|
- GET /store/order/{order_id}
|
||||||
|
- For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions
|
||||||
|
- examples: [{contentType=application/xml, example=<Order>
|
||||||
|
<id>123456789</id>
|
||||||
|
<petId>123456789</petId>
|
||||||
|
<quantity>123</quantity>
|
||||||
|
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
|
||||||
|
<status>aeiou</status>
|
||||||
|
<complete>true</complete>
|
||||||
|
</Order>}, {contentType=application/json, example={
|
||||||
|
"petId" : 6,
|
||||||
|
"quantity" : 1,
|
||||||
|
"id" : 0,
|
||||||
|
"shipDate" : "2000-01-23T04:56:07.000+00:00",
|
||||||
|
"complete" : false,
|
||||||
|
"status" : "placed"
|
||||||
|
}}]
|
||||||
|
- examples: [{contentType=application/xml, example=<Order>
|
||||||
|
<id>123456789</id>
|
||||||
|
<petId>123456789</petId>
|
||||||
|
<quantity>123</quantity>
|
||||||
|
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
|
||||||
|
<status>aeiou</status>
|
||||||
|
<complete>true</complete>
|
||||||
|
</Order>}, {contentType=application/json, example={
|
||||||
|
"petId" : 6,
|
||||||
|
"quantity" : 1,
|
||||||
|
"id" : 0,
|
||||||
|
"shipDate" : "2000-01-23T04:56:07.000+00:00",
|
||||||
|
"complete" : false,
|
||||||
|
"status" : "placed"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter orderId: (path) ID of pet that needs to be fetched
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Order>
|
||||||
|
*/
|
||||||
|
open class func getOrderByIdWithRequestBuilder(orderId: Int64) -> RequestBuilder<Order> {
|
||||||
|
var path = "/store/order/{order_id}"
|
||||||
|
path = path.replacingOccurrences(of: "{order_id}", with: "\(orderId)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Order>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Place an order for a pet
|
||||||
|
|
||||||
|
- parameter body: (body) order placed for purchasing the pet
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func placeOrder(body: Order, completion: @escaping ((_ data: Order?,_ error: Error?) -> Void)) {
|
||||||
|
placeOrderWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Place an order for a pet
|
||||||
|
- POST /store/order
|
||||||
|
-
|
||||||
|
- examples: [{contentType=application/xml, example=<Order>
|
||||||
|
<id>123456789</id>
|
||||||
|
<petId>123456789</petId>
|
||||||
|
<quantity>123</quantity>
|
||||||
|
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
|
||||||
|
<status>aeiou</status>
|
||||||
|
<complete>true</complete>
|
||||||
|
</Order>}, {contentType=application/json, example={
|
||||||
|
"petId" : 6,
|
||||||
|
"quantity" : 1,
|
||||||
|
"id" : 0,
|
||||||
|
"shipDate" : "2000-01-23T04:56:07.000+00:00",
|
||||||
|
"complete" : false,
|
||||||
|
"status" : "placed"
|
||||||
|
}}]
|
||||||
|
- examples: [{contentType=application/xml, example=<Order>
|
||||||
|
<id>123456789</id>
|
||||||
|
<petId>123456789</petId>
|
||||||
|
<quantity>123</quantity>
|
||||||
|
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
|
||||||
|
<status>aeiou</status>
|
||||||
|
<complete>true</complete>
|
||||||
|
</Order>}, {contentType=application/json, example={
|
||||||
|
"petId" : 6,
|
||||||
|
"quantity" : 1,
|
||||||
|
"id" : 0,
|
||||||
|
"shipDate" : "2000-01-23T04:56:07.000+00:00",
|
||||||
|
"complete" : false,
|
||||||
|
"status" : "placed"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter body: (body) order placed for purchasing the pet
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Order>
|
||||||
|
*/
|
||||||
|
open class func placeOrderWithRequestBuilder(body: Order) -> RequestBuilder<Order> {
|
||||||
|
let path = "/store/order"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Order>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,344 @@
|
|||||||
|
//
|
||||||
|
// UserAPI.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
open class UserAPI {
|
||||||
|
/**
|
||||||
|
Create user
|
||||||
|
|
||||||
|
- parameter body: (body) Created user object
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func createUser(body: User, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
createUserWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Create user
|
||||||
|
- POST /user
|
||||||
|
- This can only be done by the logged in user.
|
||||||
|
|
||||||
|
- parameter body: (body) Created user object
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func createUserWithRequestBuilder(body: User) -> RequestBuilder<Void> {
|
||||||
|
let path = "/user"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates list of users with given input array
|
||||||
|
|
||||||
|
- parameter body: (body) List of user object
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func createUsersWithArrayInput(body: [User], completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
createUsersWithArrayInputWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates list of users with given input array
|
||||||
|
- POST /user/createWithArray
|
||||||
|
-
|
||||||
|
|
||||||
|
- parameter body: (body) List of user object
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func createUsersWithArrayInputWithRequestBuilder(body: [User]) -> RequestBuilder<Void> {
|
||||||
|
let path = "/user/createWithArray"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates list of users with given input array
|
||||||
|
|
||||||
|
- parameter body: (body) List of user object
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func createUsersWithListInput(body: [User], completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
createUsersWithListInputWithRequestBuilder(body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Creates list of users with given input array
|
||||||
|
- POST /user/createWithList
|
||||||
|
-
|
||||||
|
|
||||||
|
- parameter body: (body) List of user object
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func createUsersWithListInputWithRequestBuilder(body: [User]) -> RequestBuilder<Void> {
|
||||||
|
let path = "/user/createWithList"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "POST", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Delete user
|
||||||
|
|
||||||
|
- parameter username: (path) The name that needs to be deleted
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func deleteUser(username: String, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
deleteUserWithRequestBuilder(username: username).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Delete user
|
||||||
|
- DELETE /user/{username}
|
||||||
|
- This can only be done by the logged in user.
|
||||||
|
|
||||||
|
- parameter username: (path) The name that needs to be deleted
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func deleteUserWithRequestBuilder(username: String) -> RequestBuilder<Void> {
|
||||||
|
var path = "/user/{username}"
|
||||||
|
path = path.replacingOccurrences(of: "{username}", with: "\(username)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "DELETE", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get user by user name
|
||||||
|
|
||||||
|
- parameter username: (path) The name that needs to be fetched. Use user1 for testing.
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func getUserByName(username: String, completion: @escaping ((_ data: User?,_ error: Error?) -> Void)) {
|
||||||
|
getUserByNameWithRequestBuilder(username: username).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Get user by user name
|
||||||
|
- GET /user/{username}
|
||||||
|
-
|
||||||
|
- examples: [{contentType=application/xml, example=<User>
|
||||||
|
<id>123456789</id>
|
||||||
|
<username>aeiou</username>
|
||||||
|
<firstName>aeiou</firstName>
|
||||||
|
<lastName>aeiou</lastName>
|
||||||
|
<email>aeiou</email>
|
||||||
|
<password>aeiou</password>
|
||||||
|
<phone>aeiou</phone>
|
||||||
|
<userStatus>123</userStatus>
|
||||||
|
</User>}, {contentType=application/json, example={
|
||||||
|
"firstName" : "aeiou",
|
||||||
|
"lastName" : "aeiou",
|
||||||
|
"password" : "aeiou",
|
||||||
|
"userStatus" : 6,
|
||||||
|
"phone" : "aeiou",
|
||||||
|
"id" : 0,
|
||||||
|
"email" : "aeiou",
|
||||||
|
"username" : "aeiou"
|
||||||
|
}}]
|
||||||
|
- examples: [{contentType=application/xml, example=<User>
|
||||||
|
<id>123456789</id>
|
||||||
|
<username>aeiou</username>
|
||||||
|
<firstName>aeiou</firstName>
|
||||||
|
<lastName>aeiou</lastName>
|
||||||
|
<email>aeiou</email>
|
||||||
|
<password>aeiou</password>
|
||||||
|
<phone>aeiou</phone>
|
||||||
|
<userStatus>123</userStatus>
|
||||||
|
</User>}, {contentType=application/json, example={
|
||||||
|
"firstName" : "aeiou",
|
||||||
|
"lastName" : "aeiou",
|
||||||
|
"password" : "aeiou",
|
||||||
|
"userStatus" : 6,
|
||||||
|
"phone" : "aeiou",
|
||||||
|
"id" : 0,
|
||||||
|
"email" : "aeiou",
|
||||||
|
"username" : "aeiou"
|
||||||
|
}}]
|
||||||
|
|
||||||
|
- parameter username: (path) The name that needs to be fetched. Use user1 for testing.
|
||||||
|
|
||||||
|
- returns: RequestBuilder<User>
|
||||||
|
*/
|
||||||
|
open class func getUserByNameWithRequestBuilder(username: String) -> RequestBuilder<User> {
|
||||||
|
var path = "/user/{username}"
|
||||||
|
path = path.replacingOccurrences(of: "{username}", with: "\(username)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<User>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logs user into the system
|
||||||
|
|
||||||
|
- parameter username: (query) The user name for login
|
||||||
|
- parameter password: (query) The password for login in clear text
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func loginUser(username: String, password: String, completion: @escaping ((_ data: String?,_ error: Error?) -> Void)) {
|
||||||
|
loginUserWithRequestBuilder(username: username, password: password).execute { (response, error) -> Void in
|
||||||
|
completion(response?.body, error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logs user into the system
|
||||||
|
- GET /user/login
|
||||||
|
-
|
||||||
|
- responseHeaders: [X-Rate-Limit(Int32), X-Expires-After(Date)]
|
||||||
|
- responseHeaders: [X-Rate-Limit(Int32), X-Expires-After(Date)]
|
||||||
|
- examples: [{contentType=application/xml, example=aeiou}, {contentType=application/json, example="aeiou"}]
|
||||||
|
- examples: [{contentType=application/xml, example=aeiou}, {contentType=application/json, example="aeiou"}]
|
||||||
|
|
||||||
|
- parameter username: (query) The user name for login
|
||||||
|
- parameter password: (query) The password for login in clear text
|
||||||
|
|
||||||
|
- returns: RequestBuilder<String>
|
||||||
|
*/
|
||||||
|
open class func loginUserWithRequestBuilder(username: String, password: String) -> RequestBuilder<String> {
|
||||||
|
let path = "/user/login"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
url?.queryItems = APIHelper.mapValuesToQueryItems(values:[
|
||||||
|
"username": username,
|
||||||
|
"password": password
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<String>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logs out current logged in user session
|
||||||
|
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func logoutUser(completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
logoutUserWithRequestBuilder().execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Logs out current logged in user session
|
||||||
|
- GET /user/logout
|
||||||
|
-
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func logoutUserWithRequestBuilder() -> RequestBuilder<Void> {
|
||||||
|
let path = "/user/logout"
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters: [String:Any]? = nil
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "GET", URLString: (url?.string ?? URLString), parameters: parameters, isBody: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
Updated user
|
||||||
|
|
||||||
|
- parameter username: (path) name that need to be deleted
|
||||||
|
- parameter body: (body) Updated user object
|
||||||
|
- parameter completion: completion handler to receive the data and the error objects
|
||||||
|
*/
|
||||||
|
open class func updateUser(username: String, body: User, completion: @escaping ((_ error: Error?) -> Void)) {
|
||||||
|
updateUserWithRequestBuilder(username: username, body: body).execute { (response, error) -> Void in
|
||||||
|
completion(error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
Updated user
|
||||||
|
- PUT /user/{username}
|
||||||
|
- This can only be done by the logged in user.
|
||||||
|
|
||||||
|
- parameter username: (path) name that need to be deleted
|
||||||
|
- parameter body: (body) Updated user object
|
||||||
|
|
||||||
|
- returns: RequestBuilder<Void>
|
||||||
|
*/
|
||||||
|
open class func updateUserWithRequestBuilder(username: String, body: User) -> RequestBuilder<Void> {
|
||||||
|
var path = "/user/{username}"
|
||||||
|
path = path.replacingOccurrences(of: "{username}", with: "\(username)", options: .literal, range: nil)
|
||||||
|
let URLString = PetstoreClientAPI.basePath + path
|
||||||
|
let parameters = JSONEncodingHelper.encodingParameters(forEncodableObject: body)
|
||||||
|
|
||||||
|
let url = NSURLComponents(string: URLString)
|
||||||
|
|
||||||
|
|
||||||
|
let requestBuilder: RequestBuilder<Void>.Type = PetstoreClientAPI.requestBuilderFactory.getNonDecodableBuilder()
|
||||||
|
|
||||||
|
return requestBuilder.init(method: "PUT", URLString: (url?.string ?? URLString), parameters: parameters, isBody: true)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,307 @@
|
|||||||
|
// AlamofireImplementations.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
class AlamofireRequestBuilderFactory: RequestBuilderFactory {
|
||||||
|
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type {
|
||||||
|
return AlamofireRequestBuilder<T>.self
|
||||||
|
}
|
||||||
|
|
||||||
|
func getBuilder<T:Decodable>() -> RequestBuilder<T>.Type {
|
||||||
|
return AlamofireDecodableRequestBuilder<T>.self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Store manager to retain its reference
|
||||||
|
private var managerStore: [String: Alamofire.SessionManager] = [:]
|
||||||
|
|
||||||
|
open class AlamofireRequestBuilder<T>: RequestBuilder<T> {
|
||||||
|
required public init(method: String, URLString: String, parameters: [String : Any]?, isBody: Bool, headers: [String : String] = [:]) {
|
||||||
|
super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the session
|
||||||
|
configuration.
|
||||||
|
*/
|
||||||
|
open func createSessionManager() -> Alamofire.SessionManager {
|
||||||
|
let configuration = URLSessionConfiguration.default
|
||||||
|
configuration.httpAdditionalHeaders = buildHeaders()
|
||||||
|
return Alamofire.SessionManager(configuration: configuration)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the Content-Type
|
||||||
|
that is given to an uploaded form part.
|
||||||
|
|
||||||
|
Return nil to use the default behavior (inferring the Content-Type from
|
||||||
|
the file extension). Return the desired Content-Type otherwise.
|
||||||
|
*/
|
||||||
|
open func contentTypeForFormPart(fileURL: URL) -> String? {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
May be overridden by a subclass if you want to control the request
|
||||||
|
configuration (e.g. to override the cache policy).
|
||||||
|
*/
|
||||||
|
open func makeRequest(manager: SessionManager, method: HTTPMethod, encoding: ParameterEncoding, headers: [String:String]) -> DataRequest {
|
||||||
|
return manager.request(URLString, method: method, parameters: parameters, encoding: encoding, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func execute(_ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
let managerId:String = UUID().uuidString
|
||||||
|
// Create a new manager for each request to customize its request header
|
||||||
|
let manager = createSessionManager()
|
||||||
|
managerStore[managerId] = manager
|
||||||
|
|
||||||
|
let encoding:ParameterEncoding = isBody ? JSONDataEncoding() : URLEncoding()
|
||||||
|
|
||||||
|
let xMethod = Alamofire.HTTPMethod(rawValue: method)
|
||||||
|
let fileKeys = parameters == nil ? [] : parameters!.filter { $1 is NSURL }
|
||||||
|
.map { $0.0 }
|
||||||
|
|
||||||
|
if fileKeys.count > 0 {
|
||||||
|
manager.upload(multipartFormData: { mpForm in
|
||||||
|
for (k, v) in self.parameters! {
|
||||||
|
switch v {
|
||||||
|
case let fileURL as URL:
|
||||||
|
if let mimeType = self.contentTypeForFormPart(fileURL: fileURL) {
|
||||||
|
mpForm.append(fileURL, withName: k, fileName: fileURL.lastPathComponent, mimeType: mimeType)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
mpForm.append(fileURL, withName: k)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
case let string as String:
|
||||||
|
mpForm.append(string.data(using: String.Encoding.utf8)!, withName: k)
|
||||||
|
break
|
||||||
|
case let number as NSNumber:
|
||||||
|
mpForm.append(number.stringValue.data(using: String.Encoding.utf8)!, withName: k)
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
fatalError("Unprocessable value \(v) with key \(k)")
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, to: URLString, method: xMethod!, headers: nil, encodingCompletion: { encodingResult in
|
||||||
|
switch encodingResult {
|
||||||
|
case .success(let upload, _, _):
|
||||||
|
if let onProgressReady = self.onProgressReady {
|
||||||
|
onProgressReady(upload.uploadProgress)
|
||||||
|
}
|
||||||
|
self.processRequest(request: upload, managerId, completion)
|
||||||
|
case .failure(let encodingError):
|
||||||
|
completion(nil, ErrorResponse.Error(415, nil, encodingError))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
let request = makeRequest(manager: manager, method: xMethod!, encoding: encoding, headers: headers)
|
||||||
|
if let onProgressReady = self.onProgressReady {
|
||||||
|
onProgressReady(request.progress)
|
||||||
|
}
|
||||||
|
processRequest(request: request, managerId, completion)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fileprivate func processRequest(request: DataRequest, _ managerId: String, _ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
if let credential = self.credential {
|
||||||
|
request.authenticate(usingCredential: credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanupRequest = {
|
||||||
|
_ = managerStore.removeValue(forKey: managerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
let validatedRequest = request.validate()
|
||||||
|
|
||||||
|
switch T.self {
|
||||||
|
case is String.Type:
|
||||||
|
validatedRequest.responseString(completionHandler: { (stringResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if stringResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: stringResponse.response!,
|
||||||
|
body: ((stringResponse.result.value ?? "") as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Void.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (voidResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if voidResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: voidResponse.response!,
|
||||||
|
body: nil),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if (dataResponse.result.isFailure) {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: dataResponse.response!,
|
||||||
|
body: (dataResponse.data as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
open func buildHeaders() -> [String: String] {
|
||||||
|
var httpHeaders = SessionManager.defaultHTTPHeaders
|
||||||
|
for (key, value) in self.headers {
|
||||||
|
httpHeaders[key] = value
|
||||||
|
}
|
||||||
|
return httpHeaders
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AlamofireDecodableRequestBuilderError: Error {
|
||||||
|
case emptyDataResponse
|
||||||
|
case nilHTTPResponse
|
||||||
|
case jsonDecoding(DecodingError)
|
||||||
|
case generalError(Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class AlamofireDecodableRequestBuilder<T:Decodable>: AlamofireRequestBuilder<T> {
|
||||||
|
|
||||||
|
override fileprivate func processRequest(request: DataRequest, _ managerId: String, _ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) {
|
||||||
|
if let credential = self.credential {
|
||||||
|
request.authenticate(usingCredential: credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
let cleanupRequest = {
|
||||||
|
_ = managerStore.removeValue(forKey: managerId)
|
||||||
|
}
|
||||||
|
|
||||||
|
let validatedRequest = request.validate()
|
||||||
|
|
||||||
|
switch T.self {
|
||||||
|
case is String.Type:
|
||||||
|
validatedRequest.responseString(completionHandler: { (stringResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if stringResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error as Error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: stringResponse.response!,
|
||||||
|
body: ((stringResponse.result.value ?? "") as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Void.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (voidResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if voidResponse.result.isFailure {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: voidResponse.response!,
|
||||||
|
body: nil),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
case is Data.Type:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
if (dataResponse.result.isFailure) {
|
||||||
|
completion(
|
||||||
|
nil,
|
||||||
|
ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(
|
||||||
|
Response(
|
||||||
|
response: dataResponse.response!,
|
||||||
|
body: (dataResponse.data as! T)
|
||||||
|
),
|
||||||
|
nil
|
||||||
|
)
|
||||||
|
})
|
||||||
|
default:
|
||||||
|
validatedRequest.responseData(completionHandler: { (dataResponse: DataResponse<Data>) in
|
||||||
|
cleanupRequest()
|
||||||
|
|
||||||
|
guard dataResponse.result.isSuccess else {
|
||||||
|
completion(nil, ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let data = dataResponse.data, !data.isEmpty else {
|
||||||
|
completion(nil, ErrorResponse.Error(-1, nil, AlamofireDecodableRequestBuilderError.emptyDataResponse))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let httpResponse = dataResponse.response else {
|
||||||
|
completion(nil, ErrorResponse.Error(-2, nil, AlamofireDecodableRequestBuilderError.nilHTTPResponse))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseObj: Response<T>? = nil
|
||||||
|
|
||||||
|
let decodeResult: (decodableObj: T?, error: Error?) = CodableHelper.decode(T.self, from: data)
|
||||||
|
if decodeResult.error == nil {
|
||||||
|
responseObj = Response(response: httpResponse, body: decodeResult.decodableObj)
|
||||||
|
}
|
||||||
|
|
||||||
|
completion(responseObj, decodeResult.error)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
//
|
||||||
|
// CodableHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
public typealias EncodeResult = (data: Data?, error: Error?)
|
||||||
|
|
||||||
|
open class CodableHelper {
|
||||||
|
|
||||||
|
open class func decode<T>(_ type: T.Type, from data: Data) -> (decodableObj: T?, error: Error?) where T : Decodable {
|
||||||
|
var returnedDecodable: T? = nil
|
||||||
|
var returnedError: Error? = nil
|
||||||
|
|
||||||
|
let decoder = JSONDecoder()
|
||||||
|
decoder.dataDecodingStrategy = .base64Decode
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
decoder.dateDecodingStrategy = .iso8601
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
returnedDecodable = try decoder.decode(type, from: data)
|
||||||
|
} catch {
|
||||||
|
returnedError = error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (returnedDecodable, returnedError)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class func encode<T>(_ value: T, prettyPrint: Bool = false) -> EncodeResult where T : Encodable {
|
||||||
|
var returnedData: Data?
|
||||||
|
var returnedError: Error? = nil
|
||||||
|
|
||||||
|
let encoder = JSONEncoder()
|
||||||
|
encoder.outputFormatting = (prettyPrint ? .prettyPrinted : .compact)
|
||||||
|
encoder.dataEncodingStrategy = .base64Encode
|
||||||
|
if #available(iOS 10.0, *) {
|
||||||
|
encoder.dateEncodingStrategy = .iso8601
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
returnedData = try encoder.encode(value)
|
||||||
|
} catch {
|
||||||
|
returnedError = error
|
||||||
|
}
|
||||||
|
|
||||||
|
return (returnedData, returnedError)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,15 @@
|
|||||||
|
// Configuration.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
open class Configuration {
|
||||||
|
|
||||||
|
// This value is used to configure the date formatter that is used to serialize dates into JSON format.
|
||||||
|
// You must set it prior to encoding any dates, and it will only be read once.
|
||||||
|
open static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,87 @@
|
|||||||
|
// Extensions.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
extension Bool: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Float: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int32: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return NSNumber(value: self as Int32) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Int64: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return NSNumber(value: self as Int64) }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Double: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any { return self as Any }
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encodeIfPossible<T>(_ object: T) -> Any {
|
||||||
|
if let encodableObject = object as? JSONEncodable {
|
||||||
|
return encodableObject.encodeToJSON()
|
||||||
|
} else {
|
||||||
|
return object as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Array: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.map(encodeIfPossible)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Dictionary: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
var dictionary = [AnyHashable: Any]()
|
||||||
|
for (key, value) in self {
|
||||||
|
dictionary[key as! NSObject] = encodeIfPossible(value)
|
||||||
|
}
|
||||||
|
return dictionary as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Data: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.base64EncodedString(options: Data.Base64EncodingOptions())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private let dateFormatter: DateFormatter = {
|
||||||
|
let fmt = DateFormatter()
|
||||||
|
fmt.dateFormat = Configuration.dateFormat
|
||||||
|
fmt.locale = Locale(identifier: "en_US_POSIX")
|
||||||
|
return fmt
|
||||||
|
}()
|
||||||
|
|
||||||
|
extension Date: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return dateFormatter.string(from: self) as Any
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UUID: JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any {
|
||||||
|
return self.uuidString
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -0,0 +1,54 @@
|
|||||||
|
//
|
||||||
|
// JSONDataEncoding.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
public struct JSONDataEncoding: ParameterEncoding {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
private static let jsonDataKey = "jsonData"
|
||||||
|
|
||||||
|
// MARK: Encoding
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply. This should have a single key/value
|
||||||
|
/// pair with "jsonData" as the key and a Data object as the value.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let jsonData = parameters?[JSONDataEncoding.jsonDataKey] as? Data, !jsonData.isEmpty else {
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = jsonData
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
public static func encodingParameters(jsonData: Data?) -> Parameters? {
|
||||||
|
var returnedParams: Parameters? = nil
|
||||||
|
if let jsonData = jsonData, !jsonData.isEmpty {
|
||||||
|
var params = Parameters()
|
||||||
|
params[jsonDataKey] = jsonData
|
||||||
|
returnedParams = params
|
||||||
|
}
|
||||||
|
return returnedParams
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
//
|
||||||
|
// JSONEncodingHelper.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import Alamofire
|
||||||
|
|
||||||
|
open class JSONEncodingHelper {
|
||||||
|
|
||||||
|
open class func encodingParameters<T:Encodable>(forEncodableObject encodableObj: T?) -> Parameters? {
|
||||||
|
var params: Parameters? = nil
|
||||||
|
|
||||||
|
// Encode the Encodable object
|
||||||
|
if let encodableObj = encodableObj {
|
||||||
|
let encodeResult = CodableHelper.encode(encodableObj, prettyPrint: true)
|
||||||
|
if encodeResult.error == nil {
|
||||||
|
params = JSONDataEncoding.encodingParameters(jsonData: encodeResult.data)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return params
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Models.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
protocol JSONEncodable {
|
||||||
|
func encodeToJSON() -> Any
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ErrorResponse : Error {
|
||||||
|
case Error(Int, Data?, Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
open class Response<T> {
|
||||||
|
open let statusCode: Int
|
||||||
|
open let header: [String: String]
|
||||||
|
open let body: T?
|
||||||
|
|
||||||
|
public init(statusCode: Int, header: [String: String], body: T?) {
|
||||||
|
self.statusCode = statusCode
|
||||||
|
self.header = header
|
||||||
|
self.body = body
|
||||||
|
}
|
||||||
|
|
||||||
|
public convenience init(response: HTTPURLResponse, body: T?) {
|
||||||
|
let rawHeader = response.allHeaderFields
|
||||||
|
var header = [String:String]()
|
||||||
|
for (key, value) in rawHeader {
|
||||||
|
header[key as! String] = value as? String
|
||||||
|
}
|
||||||
|
self.init(statusCode: response.statusCode, header: header, body: body)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// AdditionalPropertiesClass.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class AdditionalPropertiesClass: Codable {
|
||||||
|
|
||||||
|
public var mapProperty: [String:String]?
|
||||||
|
public var mapOfMapProperty: [String:[String:String]]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Animal.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Animal: Codable {
|
||||||
|
|
||||||
|
public var className: String?
|
||||||
|
public var color: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// AnimalFarm.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public typealias AnimalFarm = [Animal]
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ApiResponse.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class ApiResponse: Codable {
|
||||||
|
|
||||||
|
public var code: Int32?
|
||||||
|
public var type: String?
|
||||||
|
public var message: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// ArrayOfArrayOfNumberOnly.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class ArrayOfArrayOfNumberOnly: Codable {
|
||||||
|
|
||||||
|
public var arrayArrayNumber: [[Double]]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// ArrayOfNumberOnly.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class ArrayOfNumberOnly: Codable {
|
||||||
|
|
||||||
|
public var arrayNumber: [Double]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// ArrayTest.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class ArrayTest: Codable {
|
||||||
|
|
||||||
|
public var arrayOfString: [String]?
|
||||||
|
public var arrayArrayOfInteger: [[Int64]]?
|
||||||
|
public var arrayArrayOfModel: [[ReadOnlyFirst]]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
//
|
||||||
|
// Capitalization.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Capitalization: Codable {
|
||||||
|
|
||||||
|
public var smallCamel: String?
|
||||||
|
public var capitalCamel: String?
|
||||||
|
public var smallSnake: String?
|
||||||
|
public var capitalSnake: String?
|
||||||
|
public var sCAETHFlowPoints: String?
|
||||||
|
/** Name of the pet */
|
||||||
|
public var ATT_NAME: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Cat.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Cat: Animal {
|
||||||
|
|
||||||
|
public var declawed: Bool?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Category.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Category: Codable {
|
||||||
|
|
||||||
|
public var id: Int64?
|
||||||
|
public var name: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// ClassModel.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
/** Model for testing model with \"_class\" property */
|
||||||
|
open class ClassModel: Codable {
|
||||||
|
|
||||||
|
public var _class: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Client.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Client: Codable {
|
||||||
|
|
||||||
|
public var client: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// Dog.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Dog: Animal {
|
||||||
|
|
||||||
|
public var breed: String?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// EnumArrays.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class EnumArrays: Codable {
|
||||||
|
|
||||||
|
public enum JustSymbol: String, Codable {
|
||||||
|
case greaterThanOrEqualTo = ">="
|
||||||
|
case dollar = "$"
|
||||||
|
}
|
||||||
|
public enum ArrayEnum: String, Codable {
|
||||||
|
case fish = "fish"
|
||||||
|
case crab = "crab"
|
||||||
|
}
|
||||||
|
public var justSymbol: JustSymbol?
|
||||||
|
public var arrayEnum: [ArrayEnum]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// EnumClass.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public enum EnumClass: String, Codable {
|
||||||
|
case abc = "_abc"
|
||||||
|
case efg = "-efg"
|
||||||
|
case xyz = "(xyz)"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// EnumTest.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class EnumTest: Codable {
|
||||||
|
|
||||||
|
public enum EnumString: String, Codable {
|
||||||
|
case upper = "UPPER"
|
||||||
|
case lower = "lower"
|
||||||
|
case empty = ""
|
||||||
|
}
|
||||||
|
public enum EnumInteger: Int32, Codable {
|
||||||
|
case _1 = 1
|
||||||
|
case numberminus1 = -1
|
||||||
|
}
|
||||||
|
public enum EnumNumber: Double, Codable {
|
||||||
|
case _11 = 1.1
|
||||||
|
case numberminus12 = -1.2
|
||||||
|
}
|
||||||
|
public var enumString: EnumString?
|
||||||
|
public var enumInteger: EnumInteger?
|
||||||
|
public var enumNumber: EnumNumber?
|
||||||
|
public var outerEnum: OuterEnum?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// FormatTest.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class FormatTest: Codable {
|
||||||
|
|
||||||
|
public var integer: Int32?
|
||||||
|
public var int32: Int32?
|
||||||
|
public var int64: Int64?
|
||||||
|
public var number: Double?
|
||||||
|
public var float: Float?
|
||||||
|
public var double: Double?
|
||||||
|
public var string: String?
|
||||||
|
public var byte: Data?
|
||||||
|
public var binary: Data?
|
||||||
|
public var date: Date?
|
||||||
|
public var dateTime: Date?
|
||||||
|
public var uuid: UUID?
|
||||||
|
public var password: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// HasOnlyReadOnly.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class HasOnlyReadOnly: Codable {
|
||||||
|
|
||||||
|
public var bar: String?
|
||||||
|
public var foo: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// List.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class List: Codable {
|
||||||
|
|
||||||
|
public var _123List: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
//
|
||||||
|
// MapTest.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class MapTest: Codable {
|
||||||
|
|
||||||
|
public enum MapOfEnumString: String, Codable {
|
||||||
|
case upper = "UPPER"
|
||||||
|
case lower = "lower"
|
||||||
|
}
|
||||||
|
public var mapMapOfString: [String:[String:String]]?
|
||||||
|
public var mapOfEnumString: [String:String]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// MixedPropertiesAndAdditionalPropertiesClass.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class MixedPropertiesAndAdditionalPropertiesClass: Codable {
|
||||||
|
|
||||||
|
public var uuid: UUID?
|
||||||
|
public var dateTime: Date?
|
||||||
|
public var map: [String:Animal]?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// Model200Response.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
/** Model for testing model name starting with number */
|
||||||
|
open class Model200Response: Codable {
|
||||||
|
|
||||||
|
public var name: Int32?
|
||||||
|
public var _class: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
//
|
||||||
|
// Name.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
/** Model for testing model name same as property name */
|
||||||
|
open class Name: Codable {
|
||||||
|
|
||||||
|
public var name: Int32?
|
||||||
|
public var snakeCase: Int32?
|
||||||
|
public var property: String?
|
||||||
|
public var _123Number: Int32?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// NumberOnly.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class NumberOnly: Codable {
|
||||||
|
|
||||||
|
public var justNumber: Double?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Order.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Order: Codable {
|
||||||
|
|
||||||
|
public enum Status: String, Codable {
|
||||||
|
case placed = "placed"
|
||||||
|
case approved = "approved"
|
||||||
|
case delivered = "delivered"
|
||||||
|
}
|
||||||
|
public var id: Int64?
|
||||||
|
public var petId: Int64?
|
||||||
|
public var quantity: Int32?
|
||||||
|
public var shipDate: Date?
|
||||||
|
/** Order Status */
|
||||||
|
public var status: Status?
|
||||||
|
public var complete: Bool?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// OuterBoolean.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public typealias OuterBoolean = Bool
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// OuterComposite.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class OuterComposite: Codable {
|
||||||
|
|
||||||
|
public var myNumber: OuterNumber?
|
||||||
|
public var myString: OuterString?
|
||||||
|
public var myBoolean: OuterBoolean?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// OuterEnum.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public enum OuterEnum: String, Codable {
|
||||||
|
case placed = "placed"
|
||||||
|
case approved = "approved"
|
||||||
|
case delivered = "delivered"
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// OuterNumber.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public typealias OuterNumber = Double
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
//
|
||||||
|
// OuterString.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
public typealias OuterString = String
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
//
|
||||||
|
// Pet.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Pet: Codable {
|
||||||
|
|
||||||
|
public enum Status: String, Codable {
|
||||||
|
case available = "available"
|
||||||
|
case pending = "pending"
|
||||||
|
case sold = "sold"
|
||||||
|
}
|
||||||
|
public var id: Int64?
|
||||||
|
public var category: Category?
|
||||||
|
public var name: String?
|
||||||
|
public var photoUrls: [String]?
|
||||||
|
public var tags: [Tag]?
|
||||||
|
/** pet status in the store */
|
||||||
|
public var status: Status?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// ReadOnlyFirst.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class ReadOnlyFirst: Codable {
|
||||||
|
|
||||||
|
public var bar: String?
|
||||||
|
public var baz: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Return.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
/** Model for testing reserved words */
|
||||||
|
open class Return: Codable {
|
||||||
|
|
||||||
|
public var _return: Int32?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// SpecialModelName.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class SpecialModelName: Codable {
|
||||||
|
|
||||||
|
public var specialPropertyName: Int64?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
//
|
||||||
|
// Tag.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class Tag: Codable {
|
||||||
|
|
||||||
|
public var id: Int64?
|
||||||
|
public var name: String?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
//
|
||||||
|
// User.swift
|
||||||
|
//
|
||||||
|
// Generated by swagger-codegen
|
||||||
|
// https://github.com/swagger-api/swagger-codegen
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
|
||||||
|
open class User: Codable {
|
||||||
|
|
||||||
|
public var id: Int64?
|
||||||
|
public var username: String?
|
||||||
|
public var firstName: String?
|
||||||
|
public var lastName: String?
|
||||||
|
public var email: String?
|
||||||
|
public var password: String?
|
||||||
|
public var phone: String?
|
||||||
|
/** User Status */
|
||||||
|
public var userStatus: Int32?
|
||||||
|
|
||||||
|
public init() {}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
use_frameworks!
|
||||||
|
source 'https://github.com/CocoaPods/Specs.git'
|
||||||
|
|
||||||
|
target 'SwaggerClient' do
|
||||||
|
pod "PetstoreClient", :path => "../"
|
||||||
|
|
||||||
|
target 'SwaggerClientTests' do
|
||||||
|
inherit! :search_paths
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
post_install do |installer|
|
||||||
|
installer.pods_project.targets.each do |target|
|
||||||
|
target.build_configurations.each do |configuration|
|
||||||
|
configuration.build_settings['SWIFT_VERSION'] = "3.0"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
PODS:
|
||||||
|
- Alamofire (4.5.0)
|
||||||
|
- PetstoreClient (0.0.1):
|
||||||
|
- Alamofire (~> 4.5)
|
||||||
|
|
||||||
|
DEPENDENCIES:
|
||||||
|
- PetstoreClient (from `../`)
|
||||||
|
|
||||||
|
EXTERNAL SOURCES:
|
||||||
|
PetstoreClient:
|
||||||
|
:path: ../
|
||||||
|
|
||||||
|
SPEC CHECKSUMS:
|
||||||
|
Alamofire: f28cdffd29de33a7bfa022cbd63ae95a27fae140
|
||||||
|
PetstoreClient: 77e3465a18f2380eff57e5075a2d59021308dde4
|
||||||
|
|
||||||
|
PODFILE CHECKSUM: 417049e9ed0e4680602b34d838294778389bd418
|
||||||
|
|
||||||
|
COCOAPODS: 1.1.1
|
||||||
19
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/LICENSE
generated
Normal file
19
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/LICENSE
generated
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
THE SOFTWARE.
|
||||||
1857
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/README.md
generated
Normal file
1857
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/README.md
generated
Normal file
File diff suppressed because it is too large
Load Diff
460
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/AFError.swift
generated
Normal file
460
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/AFError.swift
generated
Normal file
@@ -0,0 +1,460 @@
|
|||||||
|
//
|
||||||
|
// AFError.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// `AFError` is the error type returned by Alamofire. It encompasses a few different types of errors, each with
|
||||||
|
/// their own associated reasons.
|
||||||
|
///
|
||||||
|
/// - invalidURL: Returned when a `URLConvertible` type fails to create a valid `URL`.
|
||||||
|
/// - parameterEncodingFailed: Returned when a parameter encoding object throws an error during the encoding process.
|
||||||
|
/// - multipartEncodingFailed: Returned when some step in the multipart encoding process fails.
|
||||||
|
/// - responseValidationFailed: Returned when a `validate()` call fails.
|
||||||
|
/// - responseSerializationFailed: Returned when a response serializer encounters an error in the serialization process.
|
||||||
|
public enum AFError: Error {
|
||||||
|
/// The underlying reason the parameter encoding error occurred.
|
||||||
|
///
|
||||||
|
/// - missingURL: The URL request did not have a URL to encode.
|
||||||
|
/// - jsonEncodingFailed: JSON serialization failed with an underlying system error during the
|
||||||
|
/// encoding process.
|
||||||
|
/// - propertyListEncodingFailed: Property list serialization failed with an underlying system error during
|
||||||
|
/// encoding process.
|
||||||
|
public enum ParameterEncodingFailureReason {
|
||||||
|
case missingURL
|
||||||
|
case jsonEncodingFailed(error: Error)
|
||||||
|
case propertyListEncodingFailed(error: Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The underlying reason the multipart encoding error occurred.
|
||||||
|
///
|
||||||
|
/// - bodyPartURLInvalid: The `fileURL` provided for reading an encodable body part isn't a
|
||||||
|
/// file URL.
|
||||||
|
/// - bodyPartFilenameInvalid: The filename of the `fileURL` provided has either an empty
|
||||||
|
/// `lastPathComponent` or `pathExtension.
|
||||||
|
/// - bodyPartFileNotReachable: The file at the `fileURL` provided was not reachable.
|
||||||
|
/// - bodyPartFileNotReachableWithError: Attempting to check the reachability of the `fileURL` provided threw
|
||||||
|
/// an error.
|
||||||
|
/// - bodyPartFileIsDirectory: The file at the `fileURL` provided is actually a directory.
|
||||||
|
/// - bodyPartFileSizeNotAvailable: The size of the file at the `fileURL` provided was not returned by
|
||||||
|
/// the system.
|
||||||
|
/// - bodyPartFileSizeQueryFailedWithError: The attempt to find the size of the file at the `fileURL` provided
|
||||||
|
/// threw an error.
|
||||||
|
/// - bodyPartInputStreamCreationFailed: An `InputStream` could not be created for the provided `fileURL`.
|
||||||
|
/// - outputStreamCreationFailed: An `OutputStream` could not be created when attempting to write the
|
||||||
|
/// encoded data to disk.
|
||||||
|
/// - outputStreamFileAlreadyExists: The encoded body data could not be writtent disk because a file
|
||||||
|
/// already exists at the provided `fileURL`.
|
||||||
|
/// - outputStreamURLInvalid: The `fileURL` provided for writing the encoded body data to disk is
|
||||||
|
/// not a file URL.
|
||||||
|
/// - outputStreamWriteFailed: The attempt to write the encoded body data to disk failed with an
|
||||||
|
/// underlying error.
|
||||||
|
/// - inputStreamReadFailed: The attempt to read an encoded body part `InputStream` failed with
|
||||||
|
/// underlying system error.
|
||||||
|
public enum MultipartEncodingFailureReason {
|
||||||
|
case bodyPartURLInvalid(url: URL)
|
||||||
|
case bodyPartFilenameInvalid(in: URL)
|
||||||
|
case bodyPartFileNotReachable(at: URL)
|
||||||
|
case bodyPartFileNotReachableWithError(atURL: URL, error: Error)
|
||||||
|
case bodyPartFileIsDirectory(at: URL)
|
||||||
|
case bodyPartFileSizeNotAvailable(at: URL)
|
||||||
|
case bodyPartFileSizeQueryFailedWithError(forURL: URL, error: Error)
|
||||||
|
case bodyPartInputStreamCreationFailed(for: URL)
|
||||||
|
|
||||||
|
case outputStreamCreationFailed(for: URL)
|
||||||
|
case outputStreamFileAlreadyExists(at: URL)
|
||||||
|
case outputStreamURLInvalid(url: URL)
|
||||||
|
case outputStreamWriteFailed(error: Error)
|
||||||
|
|
||||||
|
case inputStreamReadFailed(error: Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The underlying reason the response validation error occurred.
|
||||||
|
///
|
||||||
|
/// - dataFileNil: The data file containing the server response did not exist.
|
||||||
|
/// - dataFileReadFailed: The data file containing the server response could not be read.
|
||||||
|
/// - missingContentType: The response did not contain a `Content-Type` and the `acceptableContentTypes`
|
||||||
|
/// provided did not contain wildcard type.
|
||||||
|
/// - unacceptableContentType: The response `Content-Type` did not match any type in the provided
|
||||||
|
/// `acceptableContentTypes`.
|
||||||
|
/// - unacceptableStatusCode: The response status code was not acceptable.
|
||||||
|
public enum ResponseValidationFailureReason {
|
||||||
|
case dataFileNil
|
||||||
|
case dataFileReadFailed(at: URL)
|
||||||
|
case missingContentType(acceptableContentTypes: [String])
|
||||||
|
case unacceptableContentType(acceptableContentTypes: [String], responseContentType: String)
|
||||||
|
case unacceptableStatusCode(code: Int)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The underlying reason the response serialization error occurred.
|
||||||
|
///
|
||||||
|
/// - inputDataNil: The server response contained no data.
|
||||||
|
/// - inputDataNilOrZeroLength: The server response contained no data or the data was zero length.
|
||||||
|
/// - inputFileNil: The file containing the server response did not exist.
|
||||||
|
/// - inputFileReadFailed: The file containing the server response could not be read.
|
||||||
|
/// - stringSerializationFailed: String serialization failed using the provided `String.Encoding`.
|
||||||
|
/// - jsonSerializationFailed: JSON serialization failed with an underlying system error.
|
||||||
|
/// - propertyListSerializationFailed: Property list serialization failed with an underlying system error.
|
||||||
|
public enum ResponseSerializationFailureReason {
|
||||||
|
case inputDataNil
|
||||||
|
case inputDataNilOrZeroLength
|
||||||
|
case inputFileNil
|
||||||
|
case inputFileReadFailed(at: URL)
|
||||||
|
case stringSerializationFailed(encoding: String.Encoding)
|
||||||
|
case jsonSerializationFailed(error: Error)
|
||||||
|
case propertyListSerializationFailed(error: Error)
|
||||||
|
}
|
||||||
|
|
||||||
|
case invalidURL(url: URLConvertible)
|
||||||
|
case parameterEncodingFailed(reason: ParameterEncodingFailureReason)
|
||||||
|
case multipartEncodingFailed(reason: MultipartEncodingFailureReason)
|
||||||
|
case responseValidationFailed(reason: ResponseValidationFailureReason)
|
||||||
|
case responseSerializationFailed(reason: ResponseSerializationFailureReason)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Adapt Error
|
||||||
|
|
||||||
|
struct AdaptError: Error {
|
||||||
|
let error: Error
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Error {
|
||||||
|
var underlyingAdaptError: Error? { return (self as? AdaptError)?.error }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Error Booleans
|
||||||
|
|
||||||
|
extension AFError {
|
||||||
|
/// Returns whether the AFError is an invalid URL error.
|
||||||
|
public var isInvalidURLError: Bool {
|
||||||
|
if case .invalidURL = self { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the AFError is a parameter encoding error. When `true`, the `underlyingError` property will
|
||||||
|
/// contain the associated value.
|
||||||
|
public var isParameterEncodingError: Bool {
|
||||||
|
if case .parameterEncodingFailed = self { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the AFError is a multipart encoding error. When `true`, the `url` and `underlyingError` properties
|
||||||
|
/// will contain the associated values.
|
||||||
|
public var isMultipartEncodingError: Bool {
|
||||||
|
if case .multipartEncodingFailed = self { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the `AFError` is a response validation error. When `true`, the `acceptableContentTypes`,
|
||||||
|
/// `responseContentType`, and `responseCode` properties will contain the associated values.
|
||||||
|
public var isResponseValidationError: Bool {
|
||||||
|
if case .responseValidationFailed = self { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns whether the `AFError` is a response serialization error. When `true`, the `failedStringEncoding` and
|
||||||
|
/// `underlyingError` properties will contain the associated values.
|
||||||
|
public var isResponseSerializationError: Bool {
|
||||||
|
if case .responseSerializationFailed = self { return true }
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Convenience Properties
|
||||||
|
|
||||||
|
extension AFError {
|
||||||
|
/// The `URLConvertible` associated with the error.
|
||||||
|
public var urlConvertible: URLConvertible? {
|
||||||
|
switch self {
|
||||||
|
case .invalidURL(let url):
|
||||||
|
return url
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `URL` associated with the error.
|
||||||
|
public var url: URL? {
|
||||||
|
switch self {
|
||||||
|
case .multipartEncodingFailed(let reason):
|
||||||
|
return reason.url
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `Error` returned by a system framework associated with a `.parameterEncodingFailed`,
|
||||||
|
/// `.multipartEncodingFailed` or `.responseSerializationFailed` error.
|
||||||
|
public var underlyingError: Error? {
|
||||||
|
switch self {
|
||||||
|
case .parameterEncodingFailed(let reason):
|
||||||
|
return reason.underlyingError
|
||||||
|
case .multipartEncodingFailed(let reason):
|
||||||
|
return reason.underlyingError
|
||||||
|
case .responseSerializationFailed(let reason):
|
||||||
|
return reason.underlyingError
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The acceptable `Content-Type`s of a `.responseValidationFailed` error.
|
||||||
|
public var acceptableContentTypes: [String]? {
|
||||||
|
switch self {
|
||||||
|
case .responseValidationFailed(let reason):
|
||||||
|
return reason.acceptableContentTypes
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The response `Content-Type` of a `.responseValidationFailed` error.
|
||||||
|
public var responseContentType: String? {
|
||||||
|
switch self {
|
||||||
|
case .responseValidationFailed(let reason):
|
||||||
|
return reason.responseContentType
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The response code of a `.responseValidationFailed` error.
|
||||||
|
public var responseCode: Int? {
|
||||||
|
switch self {
|
||||||
|
case .responseValidationFailed(let reason):
|
||||||
|
return reason.responseCode
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The `String.Encoding` associated with a failed `.stringResponse()` call.
|
||||||
|
public var failedStringEncoding: String.Encoding? {
|
||||||
|
switch self {
|
||||||
|
case .responseSerializationFailed(let reason):
|
||||||
|
return reason.failedStringEncoding
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ParameterEncodingFailureReason {
|
||||||
|
var underlyingError: Error? {
|
||||||
|
switch self {
|
||||||
|
case .jsonEncodingFailed(let error), .propertyListEncodingFailed(let error):
|
||||||
|
return error
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.MultipartEncodingFailureReason {
|
||||||
|
var url: URL? {
|
||||||
|
switch self {
|
||||||
|
case .bodyPartURLInvalid(let url), .bodyPartFilenameInvalid(let url), .bodyPartFileNotReachable(let url),
|
||||||
|
.bodyPartFileIsDirectory(let url), .bodyPartFileSizeNotAvailable(let url),
|
||||||
|
.bodyPartInputStreamCreationFailed(let url), .outputStreamCreationFailed(let url),
|
||||||
|
.outputStreamFileAlreadyExists(let url), .outputStreamURLInvalid(let url),
|
||||||
|
.bodyPartFileNotReachableWithError(let url, _), .bodyPartFileSizeQueryFailedWithError(let url, _):
|
||||||
|
return url
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var underlyingError: Error? {
|
||||||
|
switch self {
|
||||||
|
case .bodyPartFileNotReachableWithError(_, let error), .bodyPartFileSizeQueryFailedWithError(_, let error),
|
||||||
|
.outputStreamWriteFailed(let error), .inputStreamReadFailed(let error):
|
||||||
|
return error
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ResponseValidationFailureReason {
|
||||||
|
var acceptableContentTypes: [String]? {
|
||||||
|
switch self {
|
||||||
|
case .missingContentType(let types), .unacceptableContentType(let types, _):
|
||||||
|
return types
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseContentType: String? {
|
||||||
|
switch self {
|
||||||
|
case .unacceptableContentType(_, let responseType):
|
||||||
|
return responseType
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var responseCode: Int? {
|
||||||
|
switch self {
|
||||||
|
case .unacceptableStatusCode(let code):
|
||||||
|
return code
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ResponseSerializationFailureReason {
|
||||||
|
var failedStringEncoding: String.Encoding? {
|
||||||
|
switch self {
|
||||||
|
case .stringSerializationFailed(let encoding):
|
||||||
|
return encoding
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var underlyingError: Error? {
|
||||||
|
switch self {
|
||||||
|
case .jsonSerializationFailed(let error), .propertyListSerializationFailed(let error):
|
||||||
|
return error
|
||||||
|
default:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Error Descriptions
|
||||||
|
|
||||||
|
extension AFError: LocalizedError {
|
||||||
|
public var errorDescription: String? {
|
||||||
|
switch self {
|
||||||
|
case .invalidURL(let url):
|
||||||
|
return "URL is not valid: \(url)"
|
||||||
|
case .parameterEncodingFailed(let reason):
|
||||||
|
return reason.localizedDescription
|
||||||
|
case .multipartEncodingFailed(let reason):
|
||||||
|
return reason.localizedDescription
|
||||||
|
case .responseValidationFailed(let reason):
|
||||||
|
return reason.localizedDescription
|
||||||
|
case .responseSerializationFailed(let reason):
|
||||||
|
return reason.localizedDescription
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ParameterEncodingFailureReason {
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .missingURL:
|
||||||
|
return "URL request to encode was missing a URL"
|
||||||
|
case .jsonEncodingFailed(let error):
|
||||||
|
return "JSON could not be encoded because of error:\n\(error.localizedDescription)"
|
||||||
|
case .propertyListEncodingFailed(let error):
|
||||||
|
return "PropertyList could not be encoded because of error:\n\(error.localizedDescription)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.MultipartEncodingFailureReason {
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .bodyPartURLInvalid(let url):
|
||||||
|
return "The URL provided is not a file URL: \(url)"
|
||||||
|
case .bodyPartFilenameInvalid(let url):
|
||||||
|
return "The URL provided does not have a valid filename: \(url)"
|
||||||
|
case .bodyPartFileNotReachable(let url):
|
||||||
|
return "The URL provided is not reachable: \(url)"
|
||||||
|
case .bodyPartFileNotReachableWithError(let url, let error):
|
||||||
|
return (
|
||||||
|
"The system returned an error while checking the provided URL for " +
|
||||||
|
"reachability.\nURL: \(url)\nError: \(error)"
|
||||||
|
)
|
||||||
|
case .bodyPartFileIsDirectory(let url):
|
||||||
|
return "The URL provided is a directory: \(url)"
|
||||||
|
case .bodyPartFileSizeNotAvailable(let url):
|
||||||
|
return "Could not fetch the file size from the provided URL: \(url)"
|
||||||
|
case .bodyPartFileSizeQueryFailedWithError(let url, let error):
|
||||||
|
return (
|
||||||
|
"The system returned an error while attempting to fetch the file size from the " +
|
||||||
|
"provided URL.\nURL: \(url)\nError: \(error)"
|
||||||
|
)
|
||||||
|
case .bodyPartInputStreamCreationFailed(let url):
|
||||||
|
return "Failed to create an InputStream for the provided URL: \(url)"
|
||||||
|
case .outputStreamCreationFailed(let url):
|
||||||
|
return "Failed to create an OutputStream for URL: \(url)"
|
||||||
|
case .outputStreamFileAlreadyExists(let url):
|
||||||
|
return "A file already exists at the provided URL: \(url)"
|
||||||
|
case .outputStreamURLInvalid(let url):
|
||||||
|
return "The provided OutputStream URL is invalid: \(url)"
|
||||||
|
case .outputStreamWriteFailed(let error):
|
||||||
|
return "OutputStream write failed with error: \(error)"
|
||||||
|
case .inputStreamReadFailed(let error):
|
||||||
|
return "InputStream read failed with error: \(error)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ResponseSerializationFailureReason {
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .inputDataNil:
|
||||||
|
return "Response could not be serialized, input data was nil."
|
||||||
|
case .inputDataNilOrZeroLength:
|
||||||
|
return "Response could not be serialized, input data was nil or zero length."
|
||||||
|
case .inputFileNil:
|
||||||
|
return "Response could not be serialized, input file was nil."
|
||||||
|
case .inputFileReadFailed(let url):
|
||||||
|
return "Response could not be serialized, input file could not be read: \(url)."
|
||||||
|
case .stringSerializationFailed(let encoding):
|
||||||
|
return "String could not be serialized with encoding: \(encoding)."
|
||||||
|
case .jsonSerializationFailed(let error):
|
||||||
|
return "JSON could not be serialized because of error:\n\(error.localizedDescription)"
|
||||||
|
case .propertyListSerializationFailed(let error):
|
||||||
|
return "PropertyList could not be serialized because of error:\n\(error.localizedDescription)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension AFError.ResponseValidationFailureReason {
|
||||||
|
var localizedDescription: String {
|
||||||
|
switch self {
|
||||||
|
case .dataFileNil:
|
||||||
|
return "Response could not be validated, data file was nil."
|
||||||
|
case .dataFileReadFailed(let url):
|
||||||
|
return "Response could not be validated, data file could not be read: \(url)."
|
||||||
|
case .missingContentType(let types):
|
||||||
|
return (
|
||||||
|
"Response Content-Type was missing and acceptable content types " +
|
||||||
|
"(\(types.joined(separator: ","))) do not match \"*/*\"."
|
||||||
|
)
|
||||||
|
case .unacceptableContentType(let acceptableTypes, let responseType):
|
||||||
|
return (
|
||||||
|
"Response Content-Type \"\(responseType)\" does not match any acceptable types: " +
|
||||||
|
"\(acceptableTypes.joined(separator: ","))."
|
||||||
|
)
|
||||||
|
case .unacceptableStatusCode(let code):
|
||||||
|
return "Response status code was unacceptable: \(code)."
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
465
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Alamofire.swift
generated
Normal file
465
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Alamofire.swift
generated
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
//
|
||||||
|
// Alamofire.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Types adopting the `URLConvertible` protocol can be used to construct URLs, which are then used to construct
|
||||||
|
/// URL requests.
|
||||||
|
public protocol URLConvertible {
|
||||||
|
/// Returns a URL that conforms to RFC 2396 or throws an `Error`.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the type cannot be converted to a `URL`.
|
||||||
|
///
|
||||||
|
/// - returns: A URL or throws an `Error`.
|
||||||
|
func asURL() throws -> URL
|
||||||
|
}
|
||||||
|
|
||||||
|
extension String: URLConvertible {
|
||||||
|
/// Returns a URL if `self` represents a valid URL string that conforms to RFC 2396 or throws an `AFError`.
|
||||||
|
///
|
||||||
|
/// - throws: An `AFError.invalidURL` if `self` is not a valid URL string.
|
||||||
|
///
|
||||||
|
/// - returns: A URL or throws an `AFError`.
|
||||||
|
public func asURL() throws -> URL {
|
||||||
|
guard let url = URL(string: self) else { throw AFError.invalidURL(url: self) }
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension URL: URLConvertible {
|
||||||
|
/// Returns self.
|
||||||
|
public func asURL() throws -> URL { return self }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension URLComponents: URLConvertible {
|
||||||
|
/// Returns a URL if `url` is not nil, otherwise throws an `Error`.
|
||||||
|
///
|
||||||
|
/// - throws: An `AFError.invalidURL` if `url` is `nil`.
|
||||||
|
///
|
||||||
|
/// - returns: A URL or throws an `AFError`.
|
||||||
|
public func asURL() throws -> URL {
|
||||||
|
guard let url = url else { throw AFError.invalidURL(url: self) }
|
||||||
|
return url
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Types adopting the `URLRequestConvertible` protocol can be used to construct URL requests.
|
||||||
|
public protocol URLRequestConvertible {
|
||||||
|
/// Returns a URL request or throws if an `Error` was encountered.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the underlying `URLRequest` is `nil`.
|
||||||
|
///
|
||||||
|
/// - returns: A URL request.
|
||||||
|
func asURLRequest() throws -> URLRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
extension URLRequestConvertible {
|
||||||
|
/// The URL request.
|
||||||
|
public var urlRequest: URLRequest? { return try? asURLRequest() }
|
||||||
|
}
|
||||||
|
|
||||||
|
extension URLRequest: URLRequestConvertible {
|
||||||
|
/// Returns a URL request or throws if an `Error` was encountered.
|
||||||
|
public func asURLRequest() throws -> URLRequest { return self }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension URLRequest {
|
||||||
|
/// Creates an instance with the specified `method`, `urlString` and `headers`.
|
||||||
|
///
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The new `URLRequest` instance.
|
||||||
|
public init(url: URLConvertible, method: HTTPMethod, headers: HTTPHeaders? = nil) throws {
|
||||||
|
let url = try url.asURL()
|
||||||
|
|
||||||
|
self.init(url: url)
|
||||||
|
|
||||||
|
httpMethod = method.rawValue
|
||||||
|
|
||||||
|
if let headers = headers {
|
||||||
|
for (headerField, headerValue) in headers {
|
||||||
|
setValue(headerValue, forHTTPHeaderField: headerField)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func adapt(using adapter: RequestAdapter?) throws -> URLRequest {
|
||||||
|
guard let adapter = adapter else { return self }
|
||||||
|
return try adapter.adapt(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Data Request
|
||||||
|
|
||||||
|
/// Creates a `DataRequest` using the default `SessionManager` to retrieve the contents of the specified `url`,
|
||||||
|
/// `method`, `parameters`, `encoding` and `headers`.
|
||||||
|
///
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.get` by default.
|
||||||
|
/// - parameter parameters: The parameters. `nil` by default.
|
||||||
|
/// - parameter encoding: The parameter encoding. `URLEncoding.default` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `DataRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func request(
|
||||||
|
_ url: URLConvertible,
|
||||||
|
method: HTTPMethod = .get,
|
||||||
|
parameters: Parameters? = nil,
|
||||||
|
encoding: ParameterEncoding = URLEncoding.default,
|
||||||
|
headers: HTTPHeaders? = nil)
|
||||||
|
-> DataRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.request(
|
||||||
|
url,
|
||||||
|
method: method,
|
||||||
|
parameters: parameters,
|
||||||
|
encoding: encoding,
|
||||||
|
headers: headers
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `DataRequest` using the default `SessionManager` to retrieve the contents of a URL based on the
|
||||||
|
/// specified `urlRequest`.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The URL request
|
||||||
|
///
|
||||||
|
/// - returns: The created `DataRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func request(_ urlRequest: URLRequestConvertible) -> DataRequest {
|
||||||
|
return SessionManager.default.request(urlRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Download Request
|
||||||
|
|
||||||
|
// MARK: URL Request
|
||||||
|
|
||||||
|
/// Creates a `DownloadRequest` using the default `SessionManager` to retrieve the contents of the specified `url`,
|
||||||
|
/// `method`, `parameters`, `encoding`, `headers` and save them to the `destination`.
|
||||||
|
///
|
||||||
|
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
|
||||||
|
/// underlying URL session.
|
||||||
|
///
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.get` by default.
|
||||||
|
/// - parameter parameters: The parameters. `nil` by default.
|
||||||
|
/// - parameter encoding: The parameter encoding. `URLEncoding.default` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `DownloadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func download(
|
||||||
|
_ url: URLConvertible,
|
||||||
|
method: HTTPMethod = .get,
|
||||||
|
parameters: Parameters? = nil,
|
||||||
|
encoding: ParameterEncoding = URLEncoding.default,
|
||||||
|
headers: HTTPHeaders? = nil,
|
||||||
|
to destination: DownloadRequest.DownloadFileDestination? = nil)
|
||||||
|
-> DownloadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.download(
|
||||||
|
url,
|
||||||
|
method: method,
|
||||||
|
parameters: parameters,
|
||||||
|
encoding: encoding,
|
||||||
|
headers: headers,
|
||||||
|
to: destination
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `DownloadRequest` using the default `SessionManager` to retrieve the contents of a URL based on the
|
||||||
|
/// specified `urlRequest` and save them to the `destination`.
|
||||||
|
///
|
||||||
|
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
|
||||||
|
/// underlying URL session.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The URL request.
|
||||||
|
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `DownloadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func download(
|
||||||
|
_ urlRequest: URLRequestConvertible,
|
||||||
|
to destination: DownloadRequest.DownloadFileDestination? = nil)
|
||||||
|
-> DownloadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.download(urlRequest, to: destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Resume Data
|
||||||
|
|
||||||
|
/// Creates a `DownloadRequest` using the default `SessionManager` from the `resumeData` produced from a
|
||||||
|
/// previous request cancellation to retrieve the contents of the original request and save them to the `destination`.
|
||||||
|
///
|
||||||
|
/// If `destination` is not specified, the contents will remain in the temporary location determined by the
|
||||||
|
/// underlying URL session.
|
||||||
|
///
|
||||||
|
/// On the latest release of all the Apple platforms (iOS 10, macOS 10.12, tvOS 10, watchOS 3), `resumeData` is broken
|
||||||
|
/// on background URL session configurations. There's an underlying bug in the `resumeData` generation logic where the
|
||||||
|
/// data is written incorrectly and will always fail to resume the download. For more information about the bug and
|
||||||
|
/// possible workarounds, please refer to the following Stack Overflow post:
|
||||||
|
///
|
||||||
|
/// - http://stackoverflow.com/a/39347461/1342462
|
||||||
|
///
|
||||||
|
/// - parameter resumeData: The resume data. This is an opaque data blob produced by `URLSessionDownloadTask`
|
||||||
|
/// when a task is cancelled. See `URLSession -downloadTask(withResumeData:)` for additional
|
||||||
|
/// information.
|
||||||
|
/// - parameter destination: The closure used to determine the destination of the downloaded file. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `DownloadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func download(
|
||||||
|
resumingWith resumeData: Data,
|
||||||
|
to destination: DownloadRequest.DownloadFileDestination? = nil)
|
||||||
|
-> DownloadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.download(resumingWith: resumeData, to: destination)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Upload Request
|
||||||
|
|
||||||
|
// MARK: File
|
||||||
|
|
||||||
|
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
|
||||||
|
/// for uploading the `file`.
|
||||||
|
///
|
||||||
|
/// - parameter file: The file to upload.
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.post` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(
|
||||||
|
_ fileURL: URL,
|
||||||
|
to url: URLConvertible,
|
||||||
|
method: HTTPMethod = .post,
|
||||||
|
headers: HTTPHeaders? = nil)
|
||||||
|
-> UploadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.upload(fileURL, to: url, method: method, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
|
||||||
|
/// uploading the `file`.
|
||||||
|
///
|
||||||
|
/// - parameter file: The file to upload.
|
||||||
|
/// - parameter urlRequest: The URL request.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(_ fileURL: URL, with urlRequest: URLRequestConvertible) -> UploadRequest {
|
||||||
|
return SessionManager.default.upload(fileURL, with: urlRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Data
|
||||||
|
|
||||||
|
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
|
||||||
|
/// for uploading the `data`.
|
||||||
|
///
|
||||||
|
/// - parameter data: The data to upload.
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.post` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(
|
||||||
|
_ data: Data,
|
||||||
|
to url: URLConvertible,
|
||||||
|
method: HTTPMethod = .post,
|
||||||
|
headers: HTTPHeaders? = nil)
|
||||||
|
-> UploadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.upload(data, to: url, method: method, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
|
||||||
|
/// uploading the `data`.
|
||||||
|
///
|
||||||
|
/// - parameter data: The data to upload.
|
||||||
|
/// - parameter urlRequest: The URL request.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(_ data: Data, with urlRequest: URLRequestConvertible) -> UploadRequest {
|
||||||
|
return SessionManager.default.upload(data, with: urlRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: InputStream
|
||||||
|
|
||||||
|
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `url`, `method` and `headers`
|
||||||
|
/// for uploading the `stream`.
|
||||||
|
///
|
||||||
|
/// - parameter stream: The stream to upload.
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.post` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(
|
||||||
|
_ stream: InputStream,
|
||||||
|
to url: URLConvertible,
|
||||||
|
method: HTTPMethod = .post,
|
||||||
|
headers: HTTPHeaders? = nil)
|
||||||
|
-> UploadRequest
|
||||||
|
{
|
||||||
|
return SessionManager.default.upload(stream, to: url, method: method, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates an `UploadRequest` using the default `SessionManager` from the specified `urlRequest` for
|
||||||
|
/// uploading the `stream`.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The URL request.
|
||||||
|
/// - parameter stream: The stream to upload.
|
||||||
|
///
|
||||||
|
/// - returns: The created `UploadRequest`.
|
||||||
|
@discardableResult
|
||||||
|
public func upload(_ stream: InputStream, with urlRequest: URLRequestConvertible) -> UploadRequest {
|
||||||
|
return SessionManager.default.upload(stream, with: urlRequest)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: MultipartFormData
|
||||||
|
|
||||||
|
/// Encodes `multipartFormData` using `encodingMemoryThreshold` with the default `SessionManager` and calls
|
||||||
|
/// `encodingCompletion` with new `UploadRequest` using the `url`, `method` and `headers`.
|
||||||
|
///
|
||||||
|
/// It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
|
||||||
|
/// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
|
||||||
|
/// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
|
||||||
|
/// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
|
||||||
|
/// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
|
||||||
|
/// used for larger payloads such as video content.
|
||||||
|
///
|
||||||
|
/// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
|
||||||
|
/// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
|
||||||
|
/// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
|
||||||
|
/// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
|
||||||
|
/// technique was used.
|
||||||
|
///
|
||||||
|
/// - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
|
||||||
|
/// - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
|
||||||
|
/// `multipartFormDataEncodingMemoryThreshold` by default.
|
||||||
|
/// - parameter url: The URL.
|
||||||
|
/// - parameter method: The HTTP method. `.post` by default.
|
||||||
|
/// - parameter headers: The HTTP headers. `nil` by default.
|
||||||
|
/// - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
|
||||||
|
public func upload(
|
||||||
|
multipartFormData: @escaping (MultipartFormData) -> Void,
|
||||||
|
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
|
||||||
|
to url: URLConvertible,
|
||||||
|
method: HTTPMethod = .post,
|
||||||
|
headers: HTTPHeaders? = nil,
|
||||||
|
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
|
||||||
|
{
|
||||||
|
return SessionManager.default.upload(
|
||||||
|
multipartFormData: multipartFormData,
|
||||||
|
usingThreshold: encodingMemoryThreshold,
|
||||||
|
to: url,
|
||||||
|
method: method,
|
||||||
|
headers: headers,
|
||||||
|
encodingCompletion: encodingCompletion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Encodes `multipartFormData` using `encodingMemoryThreshold` and the default `SessionManager` and
|
||||||
|
/// calls `encodingCompletion` with new `UploadRequest` using the `urlRequest`.
|
||||||
|
///
|
||||||
|
/// It is important to understand the memory implications of uploading `MultipartFormData`. If the cummulative
|
||||||
|
/// payload is small, encoding the data in-memory and directly uploading to a server is the by far the most
|
||||||
|
/// efficient approach. However, if the payload is too large, encoding the data in-memory could cause your app to
|
||||||
|
/// be terminated. Larger payloads must first be written to disk using input and output streams to keep the memory
|
||||||
|
/// footprint low, then the data can be uploaded as a stream from the resulting file. Streaming from disk MUST be
|
||||||
|
/// used for larger payloads such as video content.
|
||||||
|
///
|
||||||
|
/// The `encodingMemoryThreshold` parameter allows Alamofire to automatically determine whether to encode in-memory
|
||||||
|
/// or stream from disk. If the content length of the `MultipartFormData` is below the `encodingMemoryThreshold`,
|
||||||
|
/// encoding takes place in-memory. If the content length exceeds the threshold, the data is streamed to disk
|
||||||
|
/// during the encoding process. Then the result is uploaded as data or as a stream depending on which encoding
|
||||||
|
/// technique was used.
|
||||||
|
///
|
||||||
|
/// - parameter multipartFormData: The closure used to append body parts to the `MultipartFormData`.
|
||||||
|
/// - parameter encodingMemoryThreshold: The encoding memory threshold in bytes.
|
||||||
|
/// `multipartFormDataEncodingMemoryThreshold` by default.
|
||||||
|
/// - parameter urlRequest: The URL request.
|
||||||
|
/// - parameter encodingCompletion: The closure called when the `MultipartFormData` encoding is complete.
|
||||||
|
public func upload(
|
||||||
|
multipartFormData: @escaping (MultipartFormData) -> Void,
|
||||||
|
usingThreshold encodingMemoryThreshold: UInt64 = SessionManager.multipartFormDataEncodingMemoryThreshold,
|
||||||
|
with urlRequest: URLRequestConvertible,
|
||||||
|
encodingCompletion: ((SessionManager.MultipartFormDataEncodingResult) -> Void)?)
|
||||||
|
{
|
||||||
|
return SessionManager.default.upload(
|
||||||
|
multipartFormData: multipartFormData,
|
||||||
|
usingThreshold: encodingMemoryThreshold,
|
||||||
|
with: urlRequest,
|
||||||
|
encodingCompletion: encodingCompletion
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !os(watchOS)
|
||||||
|
|
||||||
|
// MARK: - Stream Request
|
||||||
|
|
||||||
|
// MARK: Hostname and Port
|
||||||
|
|
||||||
|
/// Creates a `StreamRequest` using the default `SessionManager` for bidirectional streaming with the `hostname`
|
||||||
|
/// and `port`.
|
||||||
|
///
|
||||||
|
/// If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
|
||||||
|
///
|
||||||
|
/// - parameter hostName: The hostname of the server to connect to.
|
||||||
|
/// - parameter port: The port of the server to connect to.
|
||||||
|
///
|
||||||
|
/// - returns: The created `StreamRequest`.
|
||||||
|
@discardableResult
|
||||||
|
@available(iOS 9.0, macOS 10.11, tvOS 9.0, *)
|
||||||
|
public func stream(withHostName hostName: String, port: Int) -> StreamRequest {
|
||||||
|
return SessionManager.default.stream(withHostName: hostName, port: port)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: NetService
|
||||||
|
|
||||||
|
/// Creates a `StreamRequest` using the default `SessionManager` for bidirectional streaming with the `netService`.
|
||||||
|
///
|
||||||
|
/// If `startRequestsImmediately` is `true`, the request will have `resume()` called before being returned.
|
||||||
|
///
|
||||||
|
/// - parameter netService: The net service used to identify the endpoint.
|
||||||
|
///
|
||||||
|
/// - returns: The created `StreamRequest`.
|
||||||
|
@discardableResult
|
||||||
|
@available(iOS 9.0, macOS 10.11, tvOS 9.0, *)
|
||||||
|
public func stream(with netService: NetService) -> StreamRequest {
|
||||||
|
return SessionManager.default.stream(with: netService)
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
//
|
||||||
|
// DispatchQueue+Alamofire.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Dispatch
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension DispatchQueue {
|
||||||
|
static var userInteractive: DispatchQueue { return DispatchQueue.global(qos: .userInteractive) }
|
||||||
|
static var userInitiated: DispatchQueue { return DispatchQueue.global(qos: .userInitiated) }
|
||||||
|
static var utility: DispatchQueue { return DispatchQueue.global(qos: .utility) }
|
||||||
|
static var background: DispatchQueue { return DispatchQueue.global(qos: .background) }
|
||||||
|
|
||||||
|
func after(_ delay: TimeInterval, execute closure: @escaping () -> Void) {
|
||||||
|
asyncAfter(deadline: .now() + delay, execute: closure)
|
||||||
|
}
|
||||||
|
}
|
||||||
580
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/MultipartFormData.swift
generated
Normal file
580
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/MultipartFormData.swift
generated
Normal file
@@ -0,0 +1,580 @@
|
|||||||
|
//
|
||||||
|
// MultipartFormData.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
#if os(iOS) || os(watchOS) || os(tvOS)
|
||||||
|
import MobileCoreServices
|
||||||
|
#elseif os(macOS)
|
||||||
|
import CoreServices
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/// Constructs `multipart/form-data` for uploads within an HTTP or HTTPS body. There are currently two ways to encode
|
||||||
|
/// multipart form data. The first way is to encode the data directly in memory. This is very efficient, but can lead
|
||||||
|
/// to memory issues if the dataset is too large. The second way is designed for larger datasets and will write all the
|
||||||
|
/// data to a single file on disk with all the proper boundary segmentation. The second approach MUST be used for
|
||||||
|
/// larger datasets such as video content, otherwise your app may run out of memory when trying to encode the dataset.
|
||||||
|
///
|
||||||
|
/// For more information on `multipart/form-data` in general, please refer to the RFC-2388 and RFC-2045 specs as well
|
||||||
|
/// and the w3 form documentation.
|
||||||
|
///
|
||||||
|
/// - https://www.ietf.org/rfc/rfc2388.txt
|
||||||
|
/// - https://www.ietf.org/rfc/rfc2045.txt
|
||||||
|
/// - https://www.w3.org/TR/html401/interact/forms.html#h-17.13
|
||||||
|
open class MultipartFormData {
|
||||||
|
|
||||||
|
// MARK: - Helper Types
|
||||||
|
|
||||||
|
struct EncodingCharacters {
|
||||||
|
static let crlf = "\r\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BoundaryGenerator {
|
||||||
|
enum BoundaryType {
|
||||||
|
case initial, encapsulated, final
|
||||||
|
}
|
||||||
|
|
||||||
|
static func randomBoundary() -> String {
|
||||||
|
return String(format: "alamofire.boundary.%08x%08x", arc4random(), arc4random())
|
||||||
|
}
|
||||||
|
|
||||||
|
static func boundaryData(forBoundaryType boundaryType: BoundaryType, boundary: String) -> Data {
|
||||||
|
let boundaryText: String
|
||||||
|
|
||||||
|
switch boundaryType {
|
||||||
|
case .initial:
|
||||||
|
boundaryText = "--\(boundary)\(EncodingCharacters.crlf)"
|
||||||
|
case .encapsulated:
|
||||||
|
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)\(EncodingCharacters.crlf)"
|
||||||
|
case .final:
|
||||||
|
boundaryText = "\(EncodingCharacters.crlf)--\(boundary)--\(EncodingCharacters.crlf)"
|
||||||
|
}
|
||||||
|
|
||||||
|
return boundaryText.data(using: String.Encoding.utf8, allowLossyConversion: false)!
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class BodyPart {
|
||||||
|
let headers: HTTPHeaders
|
||||||
|
let bodyStream: InputStream
|
||||||
|
let bodyContentLength: UInt64
|
||||||
|
var hasInitialBoundary = false
|
||||||
|
var hasFinalBoundary = false
|
||||||
|
|
||||||
|
init(headers: HTTPHeaders, bodyStream: InputStream, bodyContentLength: UInt64) {
|
||||||
|
self.headers = headers
|
||||||
|
self.bodyStream = bodyStream
|
||||||
|
self.bodyContentLength = bodyContentLength
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
/// The `Content-Type` header value containing the boundary used to generate the `multipart/form-data`.
|
||||||
|
open lazy var contentType: String = "multipart/form-data; boundary=\(self.boundary)"
|
||||||
|
|
||||||
|
/// The content length of all body parts used to generate the `multipart/form-data` not including the boundaries.
|
||||||
|
public var contentLength: UInt64 { return bodyParts.reduce(0) { $0 + $1.bodyContentLength } }
|
||||||
|
|
||||||
|
/// The boundary used to separate the body parts in the encoded form data.
|
||||||
|
public let boundary: String
|
||||||
|
|
||||||
|
private var bodyParts: [BodyPart]
|
||||||
|
private var bodyPartError: AFError?
|
||||||
|
private let streamBufferSize: Int
|
||||||
|
|
||||||
|
// MARK: - Lifecycle
|
||||||
|
|
||||||
|
/// Creates a multipart form data object.
|
||||||
|
///
|
||||||
|
/// - returns: The multipart form data object.
|
||||||
|
public init() {
|
||||||
|
self.boundary = BoundaryGenerator.randomBoundary()
|
||||||
|
self.bodyParts = []
|
||||||
|
|
||||||
|
///
|
||||||
|
/// The optimal read/write buffer size in bytes for input and output streams is 1024 (1KB). For more
|
||||||
|
/// information, please refer to the following article:
|
||||||
|
/// - https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Streams/Articles/ReadingInputStreams.html
|
||||||
|
///
|
||||||
|
|
||||||
|
self.streamBufferSize = 1024
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Body Parts
|
||||||
|
|
||||||
|
/// Creates a body part from the data and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
|
||||||
|
/// - Encoded data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter data: The data to encode into the multipart form data.
|
||||||
|
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
|
||||||
|
public func append(_ data: Data, withName name: String) {
|
||||||
|
let headers = contentHeaders(withName: name)
|
||||||
|
let stream = InputStream(data: data)
|
||||||
|
let length = UInt64(data.count)
|
||||||
|
|
||||||
|
append(stream, withLength: length, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part from the data and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - `Content-Disposition: form-data; name=#{name}` (HTTP Header)
|
||||||
|
/// - `Content-Type: #{generated mimeType}` (HTTP Header)
|
||||||
|
/// - Encoded data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter data: The data to encode into the multipart form data.
|
||||||
|
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter mimeType: The MIME type to associate with the data content type in the `Content-Type` HTTP header.
|
||||||
|
public func append(_ data: Data, withName name: String, mimeType: String) {
|
||||||
|
let headers = contentHeaders(withName: name, mimeType: mimeType)
|
||||||
|
let stream = InputStream(data: data)
|
||||||
|
let length = UInt64(data.count)
|
||||||
|
|
||||||
|
append(stream, withLength: length, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part from the data and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
|
||||||
|
/// - `Content-Type: #{mimeType}` (HTTP Header)
|
||||||
|
/// - Encoded file data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter data: The data to encode into the multipart form data.
|
||||||
|
/// - parameter name: The name to associate with the data in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter fileName: The filename to associate with the data in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter mimeType: The MIME type to associate with the data in the `Content-Type` HTTP header.
|
||||||
|
public func append(_ data: Data, withName name: String, fileName: String, mimeType: String) {
|
||||||
|
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
|
||||||
|
let stream = InputStream(data: data)
|
||||||
|
let length = UInt64(data.count)
|
||||||
|
|
||||||
|
append(stream, withLength: length, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part from the file and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - `Content-Disposition: form-data; name=#{name}; filename=#{generated filename}` (HTTP Header)
|
||||||
|
/// - `Content-Type: #{generated mimeType}` (HTTP Header)
|
||||||
|
/// - Encoded file data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// The filename in the `Content-Disposition` HTTP header is generated from the last path component of the
|
||||||
|
/// `fileURL`. The `Content-Type` HTTP header MIME type is generated by mapping the `fileURL` extension to the
|
||||||
|
/// system associated MIME type.
|
||||||
|
///
|
||||||
|
/// - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
|
||||||
|
/// - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
|
||||||
|
public func append(_ fileURL: URL, withName name: String) {
|
||||||
|
let fileName = fileURL.lastPathComponent
|
||||||
|
let pathExtension = fileURL.pathExtension
|
||||||
|
|
||||||
|
if !fileName.isEmpty && !pathExtension.isEmpty {
|
||||||
|
let mime = mimeType(forPathExtension: pathExtension)
|
||||||
|
append(fileURL, withName: name, fileName: fileName, mimeType: mime)
|
||||||
|
} else {
|
||||||
|
setBodyPartError(withReason: .bodyPartFilenameInvalid(in: fileURL))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part from the file and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - Content-Disposition: form-data; name=#{name}; filename=#{filename} (HTTP Header)
|
||||||
|
/// - Content-Type: #{mimeType} (HTTP Header)
|
||||||
|
/// - Encoded file data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter fileURL: The URL of the file whose content will be encoded into the multipart form data.
|
||||||
|
/// - parameter name: The name to associate with the file content in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter fileName: The filename to associate with the file content in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter mimeType: The MIME type to associate with the file content in the `Content-Type` HTTP header.
|
||||||
|
public func append(_ fileURL: URL, withName name: String, fileName: String, mimeType: String) {
|
||||||
|
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// Check 1 - is file URL?
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
guard fileURL.isFileURL else {
|
||||||
|
setBodyPartError(withReason: .bodyPartURLInvalid(url: fileURL))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// Check 2 - is file URL reachable?
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
do {
|
||||||
|
let isReachable = try fileURL.checkPromisedItemIsReachable()
|
||||||
|
guard isReachable else {
|
||||||
|
setBodyPartError(withReason: .bodyPartFileNotReachable(at: fileURL))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
setBodyPartError(withReason: .bodyPartFileNotReachableWithError(atURL: fileURL, error: error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// Check 3 - is file URL a directory?
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
var isDirectory: ObjCBool = false
|
||||||
|
let path = fileURL.path
|
||||||
|
|
||||||
|
guard FileManager.default.fileExists(atPath: path, isDirectory: &isDirectory) && !isDirectory.boolValue else {
|
||||||
|
setBodyPartError(withReason: .bodyPartFileIsDirectory(at: fileURL))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// Check 4 - can the file size be extracted?
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
let bodyContentLength: UInt64
|
||||||
|
|
||||||
|
do {
|
||||||
|
guard let fileSize = try FileManager.default.attributesOfItem(atPath: path)[.size] as? NSNumber else {
|
||||||
|
setBodyPartError(withReason: .bodyPartFileSizeNotAvailable(at: fileURL))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
bodyContentLength = fileSize.uint64Value
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
setBodyPartError(withReason: .bodyPartFileSizeQueryFailedWithError(forURL: fileURL, error: error))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//============================================================
|
||||||
|
// Check 5 - can a stream be created from file URL?
|
||||||
|
//============================================================
|
||||||
|
|
||||||
|
guard let stream = InputStream(url: fileURL) else {
|
||||||
|
setBodyPartError(withReason: .bodyPartInputStreamCreationFailed(for: fileURL))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
append(stream, withLength: bodyContentLength, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part from the stream and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - `Content-Disposition: form-data; name=#{name}; filename=#{filename}` (HTTP Header)
|
||||||
|
/// - `Content-Type: #{mimeType}` (HTTP Header)
|
||||||
|
/// - Encoded stream data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter stream: The input stream to encode in the multipart form data.
|
||||||
|
/// - parameter length: The content length of the stream.
|
||||||
|
/// - parameter name: The name to associate with the stream content in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter fileName: The filename to associate with the stream content in the `Content-Disposition` HTTP header.
|
||||||
|
/// - parameter mimeType: The MIME type to associate with the stream content in the `Content-Type` HTTP header.
|
||||||
|
public func append(
|
||||||
|
_ stream: InputStream,
|
||||||
|
withLength length: UInt64,
|
||||||
|
name: String,
|
||||||
|
fileName: String,
|
||||||
|
mimeType: String)
|
||||||
|
{
|
||||||
|
let headers = contentHeaders(withName: name, fileName: fileName, mimeType: mimeType)
|
||||||
|
append(stream, withLength: length, headers: headers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a body part with the headers, stream and length and appends it to the multipart form data object.
|
||||||
|
///
|
||||||
|
/// The body part data will be encoded using the following format:
|
||||||
|
///
|
||||||
|
/// - HTTP headers
|
||||||
|
/// - Encoded stream data
|
||||||
|
/// - Multipart form boundary
|
||||||
|
///
|
||||||
|
/// - parameter stream: The input stream to encode in the multipart form data.
|
||||||
|
/// - parameter length: The content length of the stream.
|
||||||
|
/// - parameter headers: The HTTP headers for the body part.
|
||||||
|
public func append(_ stream: InputStream, withLength length: UInt64, headers: HTTPHeaders) {
|
||||||
|
let bodyPart = BodyPart(headers: headers, bodyStream: stream, bodyContentLength: length)
|
||||||
|
bodyParts.append(bodyPart)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Data Encoding
|
||||||
|
|
||||||
|
/// Encodes all the appended body parts into a single `Data` value.
|
||||||
|
///
|
||||||
|
/// It is important to note that this method will load all the appended body parts into memory all at the same
|
||||||
|
/// time. This method should only be used when the encoded data will have a small memory footprint. For large data
|
||||||
|
/// cases, please use the `writeEncodedDataToDisk(fileURL:completionHandler:)` method.
|
||||||
|
///
|
||||||
|
/// - throws: An `AFError` if encoding encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded `Data` if encoding is successful.
|
||||||
|
public func encode() throws -> Data {
|
||||||
|
if let bodyPartError = bodyPartError {
|
||||||
|
throw bodyPartError
|
||||||
|
}
|
||||||
|
|
||||||
|
var encoded = Data()
|
||||||
|
|
||||||
|
bodyParts.first?.hasInitialBoundary = true
|
||||||
|
bodyParts.last?.hasFinalBoundary = true
|
||||||
|
|
||||||
|
for bodyPart in bodyParts {
|
||||||
|
let encodedData = try encode(bodyPart)
|
||||||
|
encoded.append(encodedData)
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Writes the appended body parts into the given file URL.
|
||||||
|
///
|
||||||
|
/// This process is facilitated by reading and writing with input and output streams, respectively. Thus,
|
||||||
|
/// this approach is very memory efficient and should be used for large body part data.
|
||||||
|
///
|
||||||
|
/// - parameter fileURL: The file URL to write the multipart form data into.
|
||||||
|
///
|
||||||
|
/// - throws: An `AFError` if encoding encounters an error.
|
||||||
|
public func writeEncodedData(to fileURL: URL) throws {
|
||||||
|
if let bodyPartError = bodyPartError {
|
||||||
|
throw bodyPartError
|
||||||
|
}
|
||||||
|
|
||||||
|
if FileManager.default.fileExists(atPath: fileURL.path) {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .outputStreamFileAlreadyExists(at: fileURL))
|
||||||
|
} else if !fileURL.isFileURL {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .outputStreamURLInvalid(url: fileURL))
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let outputStream = OutputStream(url: fileURL, append: false) else {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .outputStreamCreationFailed(for: fileURL))
|
||||||
|
}
|
||||||
|
|
||||||
|
outputStream.open()
|
||||||
|
defer { outputStream.close() }
|
||||||
|
|
||||||
|
self.bodyParts.first?.hasInitialBoundary = true
|
||||||
|
self.bodyParts.last?.hasFinalBoundary = true
|
||||||
|
|
||||||
|
for bodyPart in self.bodyParts {
|
||||||
|
try write(bodyPart, to: outputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Body Part Encoding
|
||||||
|
|
||||||
|
private func encode(_ bodyPart: BodyPart) throws -> Data {
|
||||||
|
var encoded = Data()
|
||||||
|
|
||||||
|
let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
|
||||||
|
encoded.append(initialData)
|
||||||
|
|
||||||
|
let headerData = encodeHeaders(for: bodyPart)
|
||||||
|
encoded.append(headerData)
|
||||||
|
|
||||||
|
let bodyStreamData = try encodeBodyStream(for: bodyPart)
|
||||||
|
encoded.append(bodyStreamData)
|
||||||
|
|
||||||
|
if bodyPart.hasFinalBoundary {
|
||||||
|
encoded.append(finalBoundaryData())
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encodeHeaders(for bodyPart: BodyPart) -> Data {
|
||||||
|
var headerText = ""
|
||||||
|
|
||||||
|
for (key, value) in bodyPart.headers {
|
||||||
|
headerText += "\(key): \(value)\(EncodingCharacters.crlf)"
|
||||||
|
}
|
||||||
|
headerText += EncodingCharacters.crlf
|
||||||
|
|
||||||
|
return headerText.data(using: String.Encoding.utf8, allowLossyConversion: false)!
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encodeBodyStream(for bodyPart: BodyPart) throws -> Data {
|
||||||
|
let inputStream = bodyPart.bodyStream
|
||||||
|
inputStream.open()
|
||||||
|
defer { inputStream.close() }
|
||||||
|
|
||||||
|
var encoded = Data()
|
||||||
|
|
||||||
|
while inputStream.hasBytesAvailable {
|
||||||
|
var buffer = [UInt8](repeating: 0, count: streamBufferSize)
|
||||||
|
let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
|
||||||
|
|
||||||
|
if let error = inputStream.streamError {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: error))
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytesRead > 0 {
|
||||||
|
encoded.append(buffer, count: bytesRead)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return encoded
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Writing Body Part to Output Stream
|
||||||
|
|
||||||
|
private func write(_ bodyPart: BodyPart, to outputStream: OutputStream) throws {
|
||||||
|
try writeInitialBoundaryData(for: bodyPart, to: outputStream)
|
||||||
|
try writeHeaderData(for: bodyPart, to: outputStream)
|
||||||
|
try writeBodyStream(for: bodyPart, to: outputStream)
|
||||||
|
try writeFinalBoundaryData(for: bodyPart, to: outputStream)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func writeInitialBoundaryData(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
|
||||||
|
let initialData = bodyPart.hasInitialBoundary ? initialBoundaryData() : encapsulatedBoundaryData()
|
||||||
|
return try write(initialData, to: outputStream)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func writeHeaderData(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
|
||||||
|
let headerData = encodeHeaders(for: bodyPart)
|
||||||
|
return try write(headerData, to: outputStream)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func writeBodyStream(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
|
||||||
|
let inputStream = bodyPart.bodyStream
|
||||||
|
|
||||||
|
inputStream.open()
|
||||||
|
defer { inputStream.close() }
|
||||||
|
|
||||||
|
while inputStream.hasBytesAvailable {
|
||||||
|
var buffer = [UInt8](repeating: 0, count: streamBufferSize)
|
||||||
|
let bytesRead = inputStream.read(&buffer, maxLength: streamBufferSize)
|
||||||
|
|
||||||
|
if let streamError = inputStream.streamError {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .inputStreamReadFailed(error: streamError))
|
||||||
|
}
|
||||||
|
|
||||||
|
if bytesRead > 0 {
|
||||||
|
if buffer.count != bytesRead {
|
||||||
|
buffer = Array(buffer[0..<bytesRead])
|
||||||
|
}
|
||||||
|
|
||||||
|
try write(&buffer, to: outputStream)
|
||||||
|
} else {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func writeFinalBoundaryData(for bodyPart: BodyPart, to outputStream: OutputStream) throws {
|
||||||
|
if bodyPart.hasFinalBoundary {
|
||||||
|
return try write(finalBoundaryData(), to: outputStream)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Writing Buffered Data to Output Stream
|
||||||
|
|
||||||
|
private func write(_ data: Data, to outputStream: OutputStream) throws {
|
||||||
|
var buffer = [UInt8](repeating: 0, count: data.count)
|
||||||
|
data.copyBytes(to: &buffer, count: data.count)
|
||||||
|
|
||||||
|
return try write(&buffer, to: outputStream)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func write(_ buffer: inout [UInt8], to outputStream: OutputStream) throws {
|
||||||
|
var bytesToWrite = buffer.count
|
||||||
|
|
||||||
|
while bytesToWrite > 0, outputStream.hasSpaceAvailable {
|
||||||
|
let bytesWritten = outputStream.write(buffer, maxLength: bytesToWrite)
|
||||||
|
|
||||||
|
if let error = outputStream.streamError {
|
||||||
|
throw AFError.multipartEncodingFailed(reason: .outputStreamWriteFailed(error: error))
|
||||||
|
}
|
||||||
|
|
||||||
|
bytesToWrite -= bytesWritten
|
||||||
|
|
||||||
|
if bytesToWrite > 0 {
|
||||||
|
buffer = Array(buffer[bytesWritten..<buffer.count])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Mime Type
|
||||||
|
|
||||||
|
private func mimeType(forPathExtension pathExtension: String) -> String {
|
||||||
|
if
|
||||||
|
let id = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),
|
||||||
|
let contentType = UTTypeCopyPreferredTagWithClass(id, kUTTagClassMIMEType)?.takeRetainedValue()
|
||||||
|
{
|
||||||
|
return contentType as String
|
||||||
|
}
|
||||||
|
|
||||||
|
return "application/octet-stream"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Content Headers
|
||||||
|
|
||||||
|
private func contentHeaders(withName name: String, fileName: String? = nil, mimeType: String? = nil) -> [String: String] {
|
||||||
|
var disposition = "form-data; name=\"\(name)\""
|
||||||
|
if let fileName = fileName { disposition += "; filename=\"\(fileName)\"" }
|
||||||
|
|
||||||
|
var headers = ["Content-Disposition": disposition]
|
||||||
|
if let mimeType = mimeType { headers["Content-Type"] = mimeType }
|
||||||
|
|
||||||
|
return headers
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Boundary Encoding
|
||||||
|
|
||||||
|
private func initialBoundaryData() -> Data {
|
||||||
|
return BoundaryGenerator.boundaryData(forBoundaryType: .initial, boundary: boundary)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encapsulatedBoundaryData() -> Data {
|
||||||
|
return BoundaryGenerator.boundaryData(forBoundaryType: .encapsulated, boundary: boundary)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func finalBoundaryData() -> Data {
|
||||||
|
return BoundaryGenerator.boundaryData(forBoundaryType: .final, boundary: boundary)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Private - Errors
|
||||||
|
|
||||||
|
private func setBodyPartError(withReason reason: AFError.MultipartEncodingFailureReason) {
|
||||||
|
guard bodyPartError == nil else { return }
|
||||||
|
bodyPartError = AFError.multipartEncodingFailed(reason: reason)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,233 @@
|
|||||||
|
//
|
||||||
|
// NetworkReachabilityManager.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
#if !os(watchOS)
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
import SystemConfiguration
|
||||||
|
|
||||||
|
/// The `NetworkReachabilityManager` class listens for reachability changes of hosts and addresses for both WWAN and
|
||||||
|
/// WiFi network interfaces.
|
||||||
|
///
|
||||||
|
/// Reachability can be used to determine background information about why a network operation failed, or to retry
|
||||||
|
/// network requests when a connection is established. It should not be used to prevent a user from initiating a network
|
||||||
|
/// request, as it's possible that an initial request may be required to establish reachability.
|
||||||
|
public class NetworkReachabilityManager {
|
||||||
|
/// Defines the various states of network reachability.
|
||||||
|
///
|
||||||
|
/// - unknown: It is unknown whether the network is reachable.
|
||||||
|
/// - notReachable: The network is not reachable.
|
||||||
|
/// - reachable: The network is reachable.
|
||||||
|
public enum NetworkReachabilityStatus {
|
||||||
|
case unknown
|
||||||
|
case notReachable
|
||||||
|
case reachable(ConnectionType)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Defines the various connection types detected by reachability flags.
|
||||||
|
///
|
||||||
|
/// - ethernetOrWiFi: The connection type is either over Ethernet or WiFi.
|
||||||
|
/// - wwan: The connection type is a WWAN connection.
|
||||||
|
public enum ConnectionType {
|
||||||
|
case ethernetOrWiFi
|
||||||
|
case wwan
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A closure executed when the network reachability status changes. The closure takes a single argument: the
|
||||||
|
/// network reachability status.
|
||||||
|
public typealias Listener = (NetworkReachabilityStatus) -> Void
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
/// Whether the network is currently reachable.
|
||||||
|
public var isReachable: Bool { return isReachableOnWWAN || isReachableOnEthernetOrWiFi }
|
||||||
|
|
||||||
|
/// Whether the network is currently reachable over the WWAN interface.
|
||||||
|
public var isReachableOnWWAN: Bool { return networkReachabilityStatus == .reachable(.wwan) }
|
||||||
|
|
||||||
|
/// Whether the network is currently reachable over Ethernet or WiFi interface.
|
||||||
|
public var isReachableOnEthernetOrWiFi: Bool { return networkReachabilityStatus == .reachable(.ethernetOrWiFi) }
|
||||||
|
|
||||||
|
/// The current network reachability status.
|
||||||
|
public var networkReachabilityStatus: NetworkReachabilityStatus {
|
||||||
|
guard let flags = self.flags else { return .unknown }
|
||||||
|
return networkReachabilityStatusForFlags(flags)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The dispatch queue to execute the `listener` closure on.
|
||||||
|
public var listenerQueue: DispatchQueue = DispatchQueue.main
|
||||||
|
|
||||||
|
/// A closure executed when the network reachability status changes.
|
||||||
|
public var listener: Listener?
|
||||||
|
|
||||||
|
private var flags: SCNetworkReachabilityFlags? {
|
||||||
|
var flags = SCNetworkReachabilityFlags()
|
||||||
|
|
||||||
|
if SCNetworkReachabilityGetFlags(reachability, &flags) {
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
private let reachability: SCNetworkReachability
|
||||||
|
private var previousFlags: SCNetworkReachabilityFlags
|
||||||
|
|
||||||
|
// MARK: - Initialization
|
||||||
|
|
||||||
|
/// Creates a `NetworkReachabilityManager` instance with the specified host.
|
||||||
|
///
|
||||||
|
/// - parameter host: The host used to evaluate network reachability.
|
||||||
|
///
|
||||||
|
/// - returns: The new `NetworkReachabilityManager` instance.
|
||||||
|
public convenience init?(host: String) {
|
||||||
|
guard let reachability = SCNetworkReachabilityCreateWithName(nil, host) else { return nil }
|
||||||
|
self.init(reachability: reachability)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a `NetworkReachabilityManager` instance that monitors the address 0.0.0.0.
|
||||||
|
///
|
||||||
|
/// Reachability treats the 0.0.0.0 address as a special token that causes it to monitor the general routing
|
||||||
|
/// status of the device, both IPv4 and IPv6.
|
||||||
|
///
|
||||||
|
/// - returns: The new `NetworkReachabilityManager` instance.
|
||||||
|
public convenience init?() {
|
||||||
|
var address = sockaddr_in()
|
||||||
|
address.sin_len = UInt8(MemoryLayout<sockaddr_in>.size)
|
||||||
|
address.sin_family = sa_family_t(AF_INET)
|
||||||
|
|
||||||
|
guard let reachability = withUnsafePointer(to: &address, { pointer in
|
||||||
|
return pointer.withMemoryRebound(to: sockaddr.self, capacity: MemoryLayout<sockaddr>.size) {
|
||||||
|
return SCNetworkReachabilityCreateWithAddress(nil, $0)
|
||||||
|
}
|
||||||
|
}) else { return nil }
|
||||||
|
|
||||||
|
self.init(reachability: reachability)
|
||||||
|
}
|
||||||
|
|
||||||
|
private init(reachability: SCNetworkReachability) {
|
||||||
|
self.reachability = reachability
|
||||||
|
self.previousFlags = SCNetworkReachabilityFlags()
|
||||||
|
}
|
||||||
|
|
||||||
|
deinit {
|
||||||
|
stopListening()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Listening
|
||||||
|
|
||||||
|
/// Starts listening for changes in network reachability status.
|
||||||
|
///
|
||||||
|
/// - returns: `true` if listening was started successfully, `false` otherwise.
|
||||||
|
@discardableResult
|
||||||
|
public func startListening() -> Bool {
|
||||||
|
var context = SCNetworkReachabilityContext(version: 0, info: nil, retain: nil, release: nil, copyDescription: nil)
|
||||||
|
context.info = Unmanaged.passUnretained(self).toOpaque()
|
||||||
|
|
||||||
|
let callbackEnabled = SCNetworkReachabilitySetCallback(
|
||||||
|
reachability,
|
||||||
|
{ (_, flags, info) in
|
||||||
|
let reachability = Unmanaged<NetworkReachabilityManager>.fromOpaque(info!).takeUnretainedValue()
|
||||||
|
reachability.notifyListener(flags)
|
||||||
|
},
|
||||||
|
&context
|
||||||
|
)
|
||||||
|
|
||||||
|
let queueEnabled = SCNetworkReachabilitySetDispatchQueue(reachability, listenerQueue)
|
||||||
|
|
||||||
|
listenerQueue.async {
|
||||||
|
self.previousFlags = SCNetworkReachabilityFlags()
|
||||||
|
self.notifyListener(self.flags ?? SCNetworkReachabilityFlags())
|
||||||
|
}
|
||||||
|
|
||||||
|
return callbackEnabled && queueEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Stops listening for changes in network reachability status.
|
||||||
|
public func stopListening() {
|
||||||
|
SCNetworkReachabilitySetCallback(reachability, nil, nil)
|
||||||
|
SCNetworkReachabilitySetDispatchQueue(reachability, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Internal - Listener Notification
|
||||||
|
|
||||||
|
func notifyListener(_ flags: SCNetworkReachabilityFlags) {
|
||||||
|
guard previousFlags != flags else { return }
|
||||||
|
previousFlags = flags
|
||||||
|
|
||||||
|
listener?(networkReachabilityStatusForFlags(flags))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Internal - Network Reachability Status
|
||||||
|
|
||||||
|
func networkReachabilityStatusForFlags(_ flags: SCNetworkReachabilityFlags) -> NetworkReachabilityStatus {
|
||||||
|
guard isNetworkReachable(with: flags) else { return .notReachable }
|
||||||
|
|
||||||
|
var networkStatus: NetworkReachabilityStatus = .reachable(.ethernetOrWiFi)
|
||||||
|
|
||||||
|
#if os(iOS)
|
||||||
|
if flags.contains(.isWWAN) { networkStatus = .reachable(.wwan) }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return networkStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
func isNetworkReachable(with flags: SCNetworkReachabilityFlags) -> Bool {
|
||||||
|
let isReachable = flags.contains(.reachable)
|
||||||
|
let needsConnection = flags.contains(.connectionRequired)
|
||||||
|
let canConnectAutomatically = flags.contains(.connectionOnDemand) || flags.contains(.connectionOnTraffic)
|
||||||
|
let canConnectWithoutUserInteraction = canConnectAutomatically && !flags.contains(.interventionRequired)
|
||||||
|
|
||||||
|
return isReachable && (!needsConnection || canConnectWithoutUserInteraction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension NetworkReachabilityManager.NetworkReachabilityStatus: Equatable {}
|
||||||
|
|
||||||
|
/// Returns whether the two network reachability status values are equal.
|
||||||
|
///
|
||||||
|
/// - parameter lhs: The left-hand side value to compare.
|
||||||
|
/// - parameter rhs: The right-hand side value to compare.
|
||||||
|
///
|
||||||
|
/// - returns: `true` if the two values are equal, `false` otherwise.
|
||||||
|
public func ==(
|
||||||
|
lhs: NetworkReachabilityManager.NetworkReachabilityStatus,
|
||||||
|
rhs: NetworkReachabilityManager.NetworkReachabilityStatus)
|
||||||
|
-> Bool
|
||||||
|
{
|
||||||
|
switch (lhs, rhs) {
|
||||||
|
case (.unknown, .unknown):
|
||||||
|
return true
|
||||||
|
case (.notReachable, .notReachable):
|
||||||
|
return true
|
||||||
|
case let (.reachable(lhsConnectionType), .reachable(rhsConnectionType)):
|
||||||
|
return lhsConnectionType == rhsConnectionType
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
52
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Notifications.swift
generated
Normal file
52
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Notifications.swift
generated
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
//
|
||||||
|
// Notifications.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
extension Notification.Name {
|
||||||
|
/// Used as a namespace for all `URLSessionTask` related notifications.
|
||||||
|
public struct Task {
|
||||||
|
/// Posted when a `URLSessionTask` is resumed. The notification `object` contains the resumed `URLSessionTask`.
|
||||||
|
public static let DidResume = Notification.Name(rawValue: "org.alamofire.notification.name.task.didResume")
|
||||||
|
|
||||||
|
/// Posted when a `URLSessionTask` is suspended. The notification `object` contains the suspended `URLSessionTask`.
|
||||||
|
public static let DidSuspend = Notification.Name(rawValue: "org.alamofire.notification.name.task.didSuspend")
|
||||||
|
|
||||||
|
/// Posted when a `URLSessionTask` is cancelled. The notification `object` contains the cancelled `URLSessionTask`.
|
||||||
|
public static let DidCancel = Notification.Name(rawValue: "org.alamofire.notification.name.task.didCancel")
|
||||||
|
|
||||||
|
/// Posted when a `URLSessionTask` is completed. The notification `object` contains the completed `URLSessionTask`.
|
||||||
|
public static let DidComplete = Notification.Name(rawValue: "org.alamofire.notification.name.task.didComplete")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension Notification {
|
||||||
|
/// Used as a namespace for all `Notification` user info dictionary keys.
|
||||||
|
public struct Key {
|
||||||
|
/// User info dictionary key representing the `URLSessionTask` associated with the notification.
|
||||||
|
public static let Task = "org.alamofire.notification.key.task"
|
||||||
|
}
|
||||||
|
}
|
||||||
436
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/ParameterEncoding.swift
generated
Normal file
436
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/ParameterEncoding.swift
generated
Normal file
@@ -0,0 +1,436 @@
|
|||||||
|
//
|
||||||
|
// ParameterEncoding.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// HTTP method definitions.
|
||||||
|
///
|
||||||
|
/// See https://tools.ietf.org/html/rfc7231#section-4.3
|
||||||
|
public enum HTTPMethod: String {
|
||||||
|
case options = "OPTIONS"
|
||||||
|
case get = "GET"
|
||||||
|
case head = "HEAD"
|
||||||
|
case post = "POST"
|
||||||
|
case put = "PUT"
|
||||||
|
case patch = "PATCH"
|
||||||
|
case delete = "DELETE"
|
||||||
|
case trace = "TRACE"
|
||||||
|
case connect = "CONNECT"
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// A dictionary of parameters to apply to a `URLRequest`.
|
||||||
|
public typealias Parameters = [String: Any]
|
||||||
|
|
||||||
|
/// A type used to define how a set of parameters are applied to a `URLRequest`.
|
||||||
|
public protocol ParameterEncoding {
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply.
|
||||||
|
///
|
||||||
|
/// - throws: An `AFError.parameterEncodingFailed` error if encoding fails.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Creates a url-encoded query string to be set as or appended to any existing URL query string or set as the HTTP
|
||||||
|
/// body of the URL request. Whether the query string is set or appended to any existing URL query string or set as
|
||||||
|
/// the HTTP body depends on the destination of the encoding.
|
||||||
|
///
|
||||||
|
/// The `Content-Type` HTTP header field of an encoded request with HTTP body is set to
|
||||||
|
/// `application/x-www-form-urlencoded; charset=utf-8`. Since there is no published specification for how to encode
|
||||||
|
/// collection types, the convention of appending `[]` to the key for array values (`foo[]=1&foo[]=2`), and appending
|
||||||
|
/// the key surrounded by square brackets for nested dictionary values (`foo[bar]=baz`).
|
||||||
|
public struct URLEncoding: ParameterEncoding {
|
||||||
|
|
||||||
|
// MARK: Helper Types
|
||||||
|
|
||||||
|
/// Defines whether the url-encoded query string is applied to the existing query string or HTTP body of the
|
||||||
|
/// resulting URL request.
|
||||||
|
///
|
||||||
|
/// - methodDependent: Applies encoded query string result to existing query string for `GET`, `HEAD` and `DELETE`
|
||||||
|
/// requests and sets as the HTTP body for requests with any other HTTP method.
|
||||||
|
/// - queryString: Sets or appends encoded query string result to existing query string.
|
||||||
|
/// - httpBody: Sets encoded query string result as the HTTP body of the URL request.
|
||||||
|
public enum Destination {
|
||||||
|
case methodDependent, queryString, httpBody
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// Returns a default `URLEncoding` instance.
|
||||||
|
public static var `default`: URLEncoding { return URLEncoding() }
|
||||||
|
|
||||||
|
/// Returns a `URLEncoding` instance with a `.methodDependent` destination.
|
||||||
|
public static var methodDependent: URLEncoding { return URLEncoding() }
|
||||||
|
|
||||||
|
/// Returns a `URLEncoding` instance with a `.queryString` destination.
|
||||||
|
public static var queryString: URLEncoding { return URLEncoding(destination: .queryString) }
|
||||||
|
|
||||||
|
/// Returns a `URLEncoding` instance with an `.httpBody` destination.
|
||||||
|
public static var httpBody: URLEncoding { return URLEncoding(destination: .httpBody) }
|
||||||
|
|
||||||
|
/// The destination defining where the encoded query string is to be applied to the URL request.
|
||||||
|
public let destination: Destination
|
||||||
|
|
||||||
|
// MARK: Initialization
|
||||||
|
|
||||||
|
/// Creates a `URLEncoding` instance using the specified destination.
|
||||||
|
///
|
||||||
|
/// - parameter destination: The destination defining where the encoded query string is to be applied.
|
||||||
|
///
|
||||||
|
/// - returns: The new `URLEncoding` instance.
|
||||||
|
public init(destination: Destination = .methodDependent) {
|
||||||
|
self.destination = destination
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Encoding
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let parameters = parameters else { return urlRequest }
|
||||||
|
|
||||||
|
if let method = HTTPMethod(rawValue: urlRequest.httpMethod ?? "GET"), encodesParametersInURL(with: method) {
|
||||||
|
guard let url = urlRequest.url else {
|
||||||
|
throw AFError.parameterEncodingFailed(reason: .missingURL)
|
||||||
|
}
|
||||||
|
|
||||||
|
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
|
||||||
|
let percentEncodedQuery = (urlComponents.percentEncodedQuery.map { $0 + "&" } ?? "") + query(parameters)
|
||||||
|
urlComponents.percentEncodedQuery = percentEncodedQuery
|
||||||
|
urlRequest.url = urlComponents.url
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/x-www-form-urlencoded; charset=utf-8", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = query(parameters).data(using: .utf8, allowLossyConversion: false)
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates percent-escaped, URL encoded query string components from the given key-value pair using recursion.
|
||||||
|
///
|
||||||
|
/// - parameter key: The key of the query component.
|
||||||
|
/// - parameter value: The value of the query component.
|
||||||
|
///
|
||||||
|
/// - returns: The percent-escaped, URL encoded query string components.
|
||||||
|
public func queryComponents(fromKey key: String, value: Any) -> [(String, String)] {
|
||||||
|
var components: [(String, String)] = []
|
||||||
|
|
||||||
|
if let dictionary = value as? [String: Any] {
|
||||||
|
for (nestedKey, value) in dictionary {
|
||||||
|
components += queryComponents(fromKey: "\(key)[\(nestedKey)]", value: value)
|
||||||
|
}
|
||||||
|
} else if let array = value as? [Any] {
|
||||||
|
for value in array {
|
||||||
|
components += queryComponents(fromKey: "\(key)[]", value: value)
|
||||||
|
}
|
||||||
|
} else if let value = value as? NSNumber {
|
||||||
|
if value.isBool {
|
||||||
|
components.append((escape(key), escape((value.boolValue ? "1" : "0"))))
|
||||||
|
} else {
|
||||||
|
components.append((escape(key), escape("\(value)")))
|
||||||
|
}
|
||||||
|
} else if let bool = value as? Bool {
|
||||||
|
components.append((escape(key), escape((bool ? "1" : "0"))))
|
||||||
|
} else {
|
||||||
|
components.append((escape(key), escape("\(value)")))
|
||||||
|
}
|
||||||
|
|
||||||
|
return components
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a percent-escaped string following RFC 3986 for a query string key or value.
|
||||||
|
///
|
||||||
|
/// RFC 3986 states that the following characters are "reserved" characters.
|
||||||
|
///
|
||||||
|
/// - General Delimiters: ":", "#", "[", "]", "@", "?", "/"
|
||||||
|
/// - Sub-Delimiters: "!", "$", "&", "'", "(", ")", "*", "+", ",", ";", "="
|
||||||
|
///
|
||||||
|
/// In RFC 3986 - Section 3.4, it states that the "?" and "/" characters should not be escaped to allow
|
||||||
|
/// query strings to include a URL. Therefore, all "reserved" characters with the exception of "?" and "/"
|
||||||
|
/// should be percent-escaped in the query string.
|
||||||
|
///
|
||||||
|
/// - parameter string: The string to be percent-escaped.
|
||||||
|
///
|
||||||
|
/// - returns: The percent-escaped string.
|
||||||
|
public func escape(_ string: String) -> String {
|
||||||
|
let generalDelimitersToEncode = ":#[]@" // does not include "?" or "/" due to RFC 3986 - Section 3.4
|
||||||
|
let subDelimitersToEncode = "!$&'()*+,;="
|
||||||
|
|
||||||
|
var allowedCharacterSet = CharacterSet.urlQueryAllowed
|
||||||
|
allowedCharacterSet.remove(charactersIn: "\(generalDelimitersToEncode)\(subDelimitersToEncode)")
|
||||||
|
|
||||||
|
var escaped = ""
|
||||||
|
|
||||||
|
//==========================================================================================================
|
||||||
|
//
|
||||||
|
// Batching is required for escaping due to an internal bug in iOS 8.1 and 8.2. Encoding more than a few
|
||||||
|
// hundred Chinese characters causes various malloc error crashes. To avoid this issue until iOS 8 is no
|
||||||
|
// longer supported, batching MUST be used for encoding. This introduces roughly a 20% overhead. For more
|
||||||
|
// info, please refer to:
|
||||||
|
//
|
||||||
|
// - https://github.com/Alamofire/Alamofire/issues/206
|
||||||
|
//
|
||||||
|
//==========================================================================================================
|
||||||
|
|
||||||
|
if #available(iOS 8.3, *) {
|
||||||
|
escaped = string.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? string
|
||||||
|
} else {
|
||||||
|
let batchSize = 50
|
||||||
|
var index = string.startIndex
|
||||||
|
|
||||||
|
while index != string.endIndex {
|
||||||
|
let startIndex = index
|
||||||
|
let endIndex = string.index(index, offsetBy: batchSize, limitedBy: string.endIndex) ?? string.endIndex
|
||||||
|
let range = startIndex..<endIndex
|
||||||
|
|
||||||
|
let substring = string.substring(with: range)
|
||||||
|
|
||||||
|
escaped += substring.addingPercentEncoding(withAllowedCharacters: allowedCharacterSet) ?? substring
|
||||||
|
|
||||||
|
index = endIndex
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return escaped
|
||||||
|
}
|
||||||
|
|
||||||
|
private func query(_ parameters: [String: Any]) -> String {
|
||||||
|
var components: [(String, String)] = []
|
||||||
|
|
||||||
|
for key in parameters.keys.sorted(by: <) {
|
||||||
|
let value = parameters[key]!
|
||||||
|
components += queryComponents(fromKey: key, value: value)
|
||||||
|
}
|
||||||
|
#if swift(>=4.0)
|
||||||
|
return components.map { "\($0.0)=\($0.1)" }.joined(separator: "&")
|
||||||
|
#else
|
||||||
|
return components.map { "\($0)=\($1)" }.joined(separator: "&")
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
private func encodesParametersInURL(with method: HTTPMethod) -> Bool {
|
||||||
|
switch destination {
|
||||||
|
case .queryString:
|
||||||
|
return true
|
||||||
|
case .httpBody:
|
||||||
|
return false
|
||||||
|
default:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
switch method {
|
||||||
|
case .get, .head, .delete:
|
||||||
|
return true
|
||||||
|
default:
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Uses `JSONSerialization` to create a JSON representation of the parameters object, which is set as the body of the
|
||||||
|
/// request. The `Content-Type` HTTP header field of an encoded request is set to `application/json`.
|
||||||
|
public struct JSONEncoding: ParameterEncoding {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// Returns a `JSONEncoding` instance with default writing options.
|
||||||
|
public static var `default`: JSONEncoding { return JSONEncoding() }
|
||||||
|
|
||||||
|
/// Returns a `JSONEncoding` instance with `.prettyPrinted` writing options.
|
||||||
|
public static var prettyPrinted: JSONEncoding { return JSONEncoding(options: .prettyPrinted) }
|
||||||
|
|
||||||
|
/// The options for writing the parameters as JSON data.
|
||||||
|
public let options: JSONSerialization.WritingOptions
|
||||||
|
|
||||||
|
// MARK: Initialization
|
||||||
|
|
||||||
|
/// Creates a `JSONEncoding` instance using the specified options.
|
||||||
|
///
|
||||||
|
/// - parameter options: The options for writing the parameters as JSON data.
|
||||||
|
///
|
||||||
|
/// - returns: The new `JSONEncoding` instance.
|
||||||
|
public init(options: JSONSerialization.WritingOptions = []) {
|
||||||
|
self.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Encoding
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let parameters = parameters else { return urlRequest }
|
||||||
|
|
||||||
|
do {
|
||||||
|
let data = try JSONSerialization.data(withJSONObject: parameters, options: options)
|
||||||
|
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = data
|
||||||
|
} catch {
|
||||||
|
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding the JSON object and setting the resulting data on the HTTP body.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to apply the JSON object to.
|
||||||
|
/// - parameter jsonObject: The JSON object to apply to the request.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, withJSONObject jsonObject: Any? = nil) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let jsonObject = jsonObject else { return urlRequest }
|
||||||
|
|
||||||
|
do {
|
||||||
|
let data = try JSONSerialization.data(withJSONObject: jsonObject, options: options)
|
||||||
|
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = data
|
||||||
|
} catch {
|
||||||
|
throw AFError.parameterEncodingFailed(reason: .jsonEncodingFailed(error: error))
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Uses `PropertyListSerialization` to create a plist representation of the parameters object, according to the
|
||||||
|
/// associated format and write options values, which is set as the body of the request. The `Content-Type` HTTP header
|
||||||
|
/// field of an encoded request is set to `application/x-plist`.
|
||||||
|
public struct PropertyListEncoding: ParameterEncoding {
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// Returns a default `PropertyListEncoding` instance.
|
||||||
|
public static var `default`: PropertyListEncoding { return PropertyListEncoding() }
|
||||||
|
|
||||||
|
/// Returns a `PropertyListEncoding` instance with xml formatting and default writing options.
|
||||||
|
public static var xml: PropertyListEncoding { return PropertyListEncoding(format: .xml) }
|
||||||
|
|
||||||
|
/// Returns a `PropertyListEncoding` instance with binary formatting and default writing options.
|
||||||
|
public static var binary: PropertyListEncoding { return PropertyListEncoding(format: .binary) }
|
||||||
|
|
||||||
|
/// The property list serialization format.
|
||||||
|
public let format: PropertyListSerialization.PropertyListFormat
|
||||||
|
|
||||||
|
/// The options for writing the parameters as plist data.
|
||||||
|
public let options: PropertyListSerialization.WriteOptions
|
||||||
|
|
||||||
|
// MARK: Initialization
|
||||||
|
|
||||||
|
/// Creates a `PropertyListEncoding` instance using the specified format and options.
|
||||||
|
///
|
||||||
|
/// - parameter format: The property list serialization format.
|
||||||
|
/// - parameter options: The options for writing the parameters as plist data.
|
||||||
|
///
|
||||||
|
/// - returns: The new `PropertyListEncoding` instance.
|
||||||
|
public init(
|
||||||
|
format: PropertyListSerialization.PropertyListFormat = .xml,
|
||||||
|
options: PropertyListSerialization.WriteOptions = 0)
|
||||||
|
{
|
||||||
|
self.format = format
|
||||||
|
self.options = options
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Encoding
|
||||||
|
|
||||||
|
/// Creates a URL request by encoding parameters and applying them onto an existing request.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The request to have parameters applied.
|
||||||
|
/// - parameter parameters: The parameters to apply.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the encoding process encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The encoded request.
|
||||||
|
public func encode(_ urlRequest: URLRequestConvertible, with parameters: Parameters?) throws -> URLRequest {
|
||||||
|
var urlRequest = try urlRequest.asURLRequest()
|
||||||
|
|
||||||
|
guard let parameters = parameters else { return urlRequest }
|
||||||
|
|
||||||
|
do {
|
||||||
|
let data = try PropertyListSerialization.data(
|
||||||
|
fromPropertyList: parameters,
|
||||||
|
format: format,
|
||||||
|
options: options
|
||||||
|
)
|
||||||
|
|
||||||
|
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||||
|
urlRequest.setValue("application/x-plist", forHTTPHeaderField: "Content-Type")
|
||||||
|
}
|
||||||
|
|
||||||
|
urlRequest.httpBody = data
|
||||||
|
} catch {
|
||||||
|
throw AFError.parameterEncodingFailed(reason: .propertyListEncodingFailed(error: error))
|
||||||
|
}
|
||||||
|
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension NSNumber {
|
||||||
|
fileprivate var isBool: Bool { return CFBooleanGetTypeID() == CFGetTypeID(self) }
|
||||||
|
}
|
||||||
647
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Request.swift
generated
Normal file
647
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Request.swift
generated
Normal file
@@ -0,0 +1,647 @@
|
|||||||
|
//
|
||||||
|
// Request.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// A type that can inspect and optionally adapt a `URLRequest` in some manner if necessary.
|
||||||
|
public protocol RequestAdapter {
|
||||||
|
/// Inspects and adapts the specified `URLRequest` in some manner if necessary and returns the result.
|
||||||
|
///
|
||||||
|
/// - parameter urlRequest: The URL request to adapt.
|
||||||
|
///
|
||||||
|
/// - throws: An `Error` if the adaptation encounters an error.
|
||||||
|
///
|
||||||
|
/// - returns: The adapted `URLRequest`.
|
||||||
|
func adapt(_ urlRequest: URLRequest) throws -> URLRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// A closure executed when the `RequestRetrier` determines whether a `Request` should be retried or not.
|
||||||
|
public typealias RequestRetryCompletion = (_ shouldRetry: Bool, _ timeDelay: TimeInterval) -> Void
|
||||||
|
|
||||||
|
/// A type that determines whether a request should be retried after being executed by the specified session manager
|
||||||
|
/// and encountering an error.
|
||||||
|
public protocol RequestRetrier {
|
||||||
|
/// Determines whether the `Request` should be retried by calling the `completion` closure.
|
||||||
|
///
|
||||||
|
/// This operation is fully asynchronous. Any amount of time can be taken to determine whether the request needs
|
||||||
|
/// to be retried. The one requirement is that the completion closure is called to ensure the request is properly
|
||||||
|
/// cleaned up after.
|
||||||
|
///
|
||||||
|
/// - parameter manager: The session manager the request was executed on.
|
||||||
|
/// - parameter request: The request that failed due to the encountered error.
|
||||||
|
/// - parameter error: The error encountered when executing the request.
|
||||||
|
/// - parameter completion: The completion closure to be executed when retry decision has been determined.
|
||||||
|
func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
protocol TaskConvertible {
|
||||||
|
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A dictionary of headers to apply to a `URLRequest`.
|
||||||
|
public typealias HTTPHeaders = [String: String]
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Responsible for sending a request and receiving the response and associated data from the server, as well as
|
||||||
|
/// managing its underlying `URLSessionTask`.
|
||||||
|
open class Request {
|
||||||
|
|
||||||
|
// MARK: Helper Types
|
||||||
|
|
||||||
|
/// A closure executed when monitoring upload or download progress of a request.
|
||||||
|
public typealias ProgressHandler = (Progress) -> Void
|
||||||
|
|
||||||
|
enum RequestTask {
|
||||||
|
case data(TaskConvertible?, URLSessionTask?)
|
||||||
|
case download(TaskConvertible?, URLSessionTask?)
|
||||||
|
case upload(TaskConvertible?, URLSessionTask?)
|
||||||
|
case stream(TaskConvertible?, URLSessionTask?)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// The delegate for the underlying task.
|
||||||
|
open internal(set) var delegate: TaskDelegate {
|
||||||
|
get {
|
||||||
|
taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
|
||||||
|
return taskDelegate
|
||||||
|
}
|
||||||
|
set {
|
||||||
|
taskDelegateLock.lock() ; defer { taskDelegateLock.unlock() }
|
||||||
|
taskDelegate = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The underlying task.
|
||||||
|
open var task: URLSessionTask? { return delegate.task }
|
||||||
|
|
||||||
|
/// The session belonging to the underlying task.
|
||||||
|
open let session: URLSession
|
||||||
|
|
||||||
|
/// The request sent or to be sent to the server.
|
||||||
|
open var request: URLRequest? { return task?.originalRequest }
|
||||||
|
|
||||||
|
/// The response received from the server, if any.
|
||||||
|
open var response: HTTPURLResponse? { return task?.response as? HTTPURLResponse }
|
||||||
|
|
||||||
|
/// The number of times the request has been retried.
|
||||||
|
open internal(set) var retryCount: UInt = 0
|
||||||
|
|
||||||
|
let originalTask: TaskConvertible?
|
||||||
|
|
||||||
|
var startTime: CFAbsoluteTime?
|
||||||
|
var endTime: CFAbsoluteTime?
|
||||||
|
|
||||||
|
var validations: [() -> Void] = []
|
||||||
|
|
||||||
|
private var taskDelegate: TaskDelegate
|
||||||
|
private var taskDelegateLock = NSLock()
|
||||||
|
|
||||||
|
// MARK: Lifecycle
|
||||||
|
|
||||||
|
init(session: URLSession, requestTask: RequestTask, error: Error? = nil) {
|
||||||
|
self.session = session
|
||||||
|
|
||||||
|
switch requestTask {
|
||||||
|
case .data(let originalTask, let task):
|
||||||
|
taskDelegate = DataTaskDelegate(task: task)
|
||||||
|
self.originalTask = originalTask
|
||||||
|
case .download(let originalTask, let task):
|
||||||
|
taskDelegate = DownloadTaskDelegate(task: task)
|
||||||
|
self.originalTask = originalTask
|
||||||
|
case .upload(let originalTask, let task):
|
||||||
|
taskDelegate = UploadTaskDelegate(task: task)
|
||||||
|
self.originalTask = originalTask
|
||||||
|
case .stream(let originalTask, let task):
|
||||||
|
taskDelegate = TaskDelegate(task: task)
|
||||||
|
self.originalTask = originalTask
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate.error = error
|
||||||
|
delegate.queue.addOperation { self.endTime = CFAbsoluteTimeGetCurrent() }
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Authentication
|
||||||
|
|
||||||
|
/// Associates an HTTP Basic credential with the request.
|
||||||
|
///
|
||||||
|
/// - parameter user: The user.
|
||||||
|
/// - parameter password: The password.
|
||||||
|
/// - parameter persistence: The URL credential persistence. `.ForSession` by default.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func authenticate(
|
||||||
|
user: String,
|
||||||
|
password: String,
|
||||||
|
persistence: URLCredential.Persistence = .forSession)
|
||||||
|
-> Self
|
||||||
|
{
|
||||||
|
let credential = URLCredential(user: user, password: password, persistence: persistence)
|
||||||
|
return authenticate(usingCredential: credential)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Associates a specified credential with the request.
|
||||||
|
///
|
||||||
|
/// - parameter credential: The credential.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func authenticate(usingCredential credential: URLCredential) -> Self {
|
||||||
|
delegate.credential = credential
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a base64 encoded basic authentication credential as an authorization header tuple.
|
||||||
|
///
|
||||||
|
/// - parameter user: The user.
|
||||||
|
/// - parameter password: The password.
|
||||||
|
///
|
||||||
|
/// - returns: A tuple with Authorization header and credential value if encoding succeeds, `nil` otherwise.
|
||||||
|
open static func authorizationHeader(user: String, password: String) -> (key: String, value: String)? {
|
||||||
|
guard let data = "\(user):\(password)".data(using: .utf8) else { return nil }
|
||||||
|
|
||||||
|
let credential = data.base64EncodedString(options: [])
|
||||||
|
|
||||||
|
return (key: "Authorization", value: "Basic \(credential)")
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: State
|
||||||
|
|
||||||
|
/// Resumes the request.
|
||||||
|
open func resume() {
|
||||||
|
guard let task = task else { delegate.queue.isSuspended = false ; return }
|
||||||
|
|
||||||
|
if startTime == nil { startTime = CFAbsoluteTimeGetCurrent() }
|
||||||
|
|
||||||
|
task.resume()
|
||||||
|
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name.Task.DidResume,
|
||||||
|
object: self,
|
||||||
|
userInfo: [Notification.Key.Task: task]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Suspends the request.
|
||||||
|
open func suspend() {
|
||||||
|
guard let task = task else { return }
|
||||||
|
|
||||||
|
task.suspend()
|
||||||
|
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name.Task.DidSuspend,
|
||||||
|
object: self,
|
||||||
|
userInfo: [Notification.Key.Task: task]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Cancels the request.
|
||||||
|
open func cancel() {
|
||||||
|
guard let task = task else { return }
|
||||||
|
|
||||||
|
task.cancel()
|
||||||
|
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name.Task.DidCancel,
|
||||||
|
object: self,
|
||||||
|
userInfo: [Notification.Key.Task: task]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - CustomStringConvertible
|
||||||
|
|
||||||
|
extension Request: CustomStringConvertible {
|
||||||
|
/// The textual representation used when written to an output stream, which includes the HTTP method and URL, as
|
||||||
|
/// well as the response status code if a response has been received.
|
||||||
|
open var description: String {
|
||||||
|
var components: [String] = []
|
||||||
|
|
||||||
|
if let HTTPMethod = request?.httpMethod {
|
||||||
|
components.append(HTTPMethod)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let urlString = request?.url?.absoluteString {
|
||||||
|
components.append(urlString)
|
||||||
|
}
|
||||||
|
|
||||||
|
if let response = response {
|
||||||
|
components.append("(\(response.statusCode))")
|
||||||
|
}
|
||||||
|
|
||||||
|
return components.joined(separator: " ")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - CustomDebugStringConvertible
|
||||||
|
|
||||||
|
extension Request: CustomDebugStringConvertible {
|
||||||
|
/// The textual representation used when written to an output stream, in the form of a cURL command.
|
||||||
|
open var debugDescription: String {
|
||||||
|
return cURLRepresentation()
|
||||||
|
}
|
||||||
|
|
||||||
|
func cURLRepresentation() -> String {
|
||||||
|
var components = ["$ curl -v"]
|
||||||
|
|
||||||
|
guard let request = self.request,
|
||||||
|
let url = request.url,
|
||||||
|
let host = url.host
|
||||||
|
else {
|
||||||
|
return "$ curl command could not be created"
|
||||||
|
}
|
||||||
|
|
||||||
|
if let httpMethod = request.httpMethod, httpMethod != "GET" {
|
||||||
|
components.append("-X \(httpMethod)")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let credentialStorage = self.session.configuration.urlCredentialStorage {
|
||||||
|
let protectionSpace = URLProtectionSpace(
|
||||||
|
host: host,
|
||||||
|
port: url.port ?? 0,
|
||||||
|
protocol: url.scheme,
|
||||||
|
realm: host,
|
||||||
|
authenticationMethod: NSURLAuthenticationMethodHTTPBasic
|
||||||
|
)
|
||||||
|
|
||||||
|
if let credentials = credentialStorage.credentials(for: protectionSpace)?.values {
|
||||||
|
for credential in credentials {
|
||||||
|
components.append("-u \(credential.user!):\(credential.password!)")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if let credential = delegate.credential {
|
||||||
|
components.append("-u \(credential.user!):\(credential.password!)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if session.configuration.httpShouldSetCookies {
|
||||||
|
if
|
||||||
|
let cookieStorage = session.configuration.httpCookieStorage,
|
||||||
|
let cookies = cookieStorage.cookies(for: url), !cookies.isEmpty
|
||||||
|
{
|
||||||
|
let string = cookies.reduce("") { $0 + "\($1.name)=\($1.value);" }
|
||||||
|
components.append("-b \"\(string.substring(to: string.characters.index(before: string.endIndex)))\"")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var headers: [AnyHashable: Any] = [:]
|
||||||
|
|
||||||
|
if let additionalHeaders = session.configuration.httpAdditionalHeaders {
|
||||||
|
for (field, value) in additionalHeaders where field != AnyHashable("Cookie") {
|
||||||
|
headers[field] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let headerFields = request.allHTTPHeaderFields {
|
||||||
|
for (field, value) in headerFields where field != "Cookie" {
|
||||||
|
headers[field] = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (field, value) in headers {
|
||||||
|
components.append("-H \"\(field): \(value)\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
if let httpBodyData = request.httpBody, let httpBody = String(data: httpBodyData, encoding: .utf8) {
|
||||||
|
var escapedBody = httpBody.replacingOccurrences(of: "\\\"", with: "\\\\\"")
|
||||||
|
escapedBody = escapedBody.replacingOccurrences(of: "\"", with: "\\\"")
|
||||||
|
|
||||||
|
components.append("-d \"\(escapedBody)\"")
|
||||||
|
}
|
||||||
|
|
||||||
|
components.append("\"\(url.absoluteString)\"")
|
||||||
|
|
||||||
|
return components.joined(separator: " \\\n\t")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Specific type of `Request` that manages an underlying `URLSessionDataTask`.
|
||||||
|
open class DataRequest: Request {
|
||||||
|
|
||||||
|
// MARK: Helper Types
|
||||||
|
|
||||||
|
struct Requestable: TaskConvertible {
|
||||||
|
let urlRequest: URLRequest
|
||||||
|
|
||||||
|
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
|
||||||
|
do {
|
||||||
|
let urlRequest = try self.urlRequest.adapt(using: adapter)
|
||||||
|
return queue.sync { session.dataTask(with: urlRequest) }
|
||||||
|
} catch {
|
||||||
|
throw AdaptError(error: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// The request sent or to be sent to the server.
|
||||||
|
open override var request: URLRequest? {
|
||||||
|
if let request = super.request { return request }
|
||||||
|
if let requestable = originalTask as? Requestable { return requestable.urlRequest }
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The progress of fetching the response data from the server for the request.
|
||||||
|
open var progress: Progress { return dataDelegate.progress }
|
||||||
|
|
||||||
|
var dataDelegate: DataTaskDelegate { return delegate as! DataTaskDelegate }
|
||||||
|
|
||||||
|
// MARK: Stream
|
||||||
|
|
||||||
|
/// Sets a closure to be called periodically during the lifecycle of the request as data is read from the server.
|
||||||
|
///
|
||||||
|
/// This closure returns the bytes most recently received from the server, not including data from previous calls.
|
||||||
|
/// If this closure is set, data will only be available within this closure, and will not be saved elsewhere. It is
|
||||||
|
/// also important to note that the server data in any `Response` object will be `nil`.
|
||||||
|
///
|
||||||
|
/// - parameter closure: The code to be executed periodically during the lifecycle of the request.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func stream(closure: ((Data) -> Void)? = nil) -> Self {
|
||||||
|
dataDelegate.dataStream = closure
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Progress
|
||||||
|
|
||||||
|
/// Sets a closure to be called periodically during the lifecycle of the `Request` as data is read from the server.
|
||||||
|
///
|
||||||
|
/// - parameter queue: The dispatch queue to execute the closure on.
|
||||||
|
/// - parameter closure: The code to be executed periodically as data is read from the server.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func downloadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self {
|
||||||
|
dataDelegate.progressHandler = (closure, queue)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Specific type of `Request` that manages an underlying `URLSessionDownloadTask`.
|
||||||
|
open class DownloadRequest: Request {
|
||||||
|
|
||||||
|
// MARK: Helper Types
|
||||||
|
|
||||||
|
/// A collection of options to be executed prior to moving a downloaded file from the temporary URL to the
|
||||||
|
/// destination URL.
|
||||||
|
public struct DownloadOptions: OptionSet {
|
||||||
|
/// Returns the raw bitmask value of the option and satisfies the `RawRepresentable` protocol.
|
||||||
|
public let rawValue: UInt
|
||||||
|
|
||||||
|
/// A `DownloadOptions` flag that creates intermediate directories for the destination URL if specified.
|
||||||
|
public static let createIntermediateDirectories = DownloadOptions(rawValue: 1 << 0)
|
||||||
|
|
||||||
|
/// A `DownloadOptions` flag that removes a previous file from the destination URL if specified.
|
||||||
|
public static let removePreviousFile = DownloadOptions(rawValue: 1 << 1)
|
||||||
|
|
||||||
|
/// Creates a `DownloadFileDestinationOptions` instance with the specified raw value.
|
||||||
|
///
|
||||||
|
/// - parameter rawValue: The raw bitmask value for the option.
|
||||||
|
///
|
||||||
|
/// - returns: A new log level instance.
|
||||||
|
public init(rawValue: UInt) {
|
||||||
|
self.rawValue = rawValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A closure executed once a download request has successfully completed in order to determine where to move the
|
||||||
|
/// temporary file written to during the download process. The closure takes two arguments: the temporary file URL
|
||||||
|
/// and the URL response, and returns a two arguments: the file URL where the temporary file should be moved and
|
||||||
|
/// the options defining how the file should be moved.
|
||||||
|
public typealias DownloadFileDestination = (
|
||||||
|
_ temporaryURL: URL,
|
||||||
|
_ response: HTTPURLResponse)
|
||||||
|
-> (destinationURL: URL, options: DownloadOptions)
|
||||||
|
|
||||||
|
enum Downloadable: TaskConvertible {
|
||||||
|
case request(URLRequest)
|
||||||
|
case resumeData(Data)
|
||||||
|
|
||||||
|
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
|
||||||
|
do {
|
||||||
|
let task: URLSessionTask
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case let .request(urlRequest):
|
||||||
|
let urlRequest = try urlRequest.adapt(using: adapter)
|
||||||
|
task = queue.sync { session.downloadTask(with: urlRequest) }
|
||||||
|
case let .resumeData(resumeData):
|
||||||
|
task = queue.sync { session.downloadTask(withResumeData: resumeData) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return task
|
||||||
|
} catch {
|
||||||
|
throw AdaptError(error: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// The request sent or to be sent to the server.
|
||||||
|
open override var request: URLRequest? {
|
||||||
|
if let request = super.request { return request }
|
||||||
|
|
||||||
|
if let downloadable = originalTask as? Downloadable, case let .request(urlRequest) = downloadable {
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The resume data of the underlying download task if available after a failure.
|
||||||
|
open var resumeData: Data? { return downloadDelegate.resumeData }
|
||||||
|
|
||||||
|
/// The progress of downloading the response data from the server for the request.
|
||||||
|
open var progress: Progress { return downloadDelegate.progress }
|
||||||
|
|
||||||
|
var downloadDelegate: DownloadTaskDelegate { return delegate as! DownloadTaskDelegate }
|
||||||
|
|
||||||
|
// MARK: State
|
||||||
|
|
||||||
|
/// Cancels the request.
|
||||||
|
open override func cancel() {
|
||||||
|
downloadDelegate.downloadTask.cancel { self.downloadDelegate.resumeData = $0 }
|
||||||
|
|
||||||
|
NotificationCenter.default.post(
|
||||||
|
name: Notification.Name.Task.DidCancel,
|
||||||
|
object: self,
|
||||||
|
userInfo: [Notification.Key.Task: task as Any]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Progress
|
||||||
|
|
||||||
|
/// Sets a closure to be called periodically during the lifecycle of the `Request` as data is read from the server.
|
||||||
|
///
|
||||||
|
/// - parameter queue: The dispatch queue to execute the closure on.
|
||||||
|
/// - parameter closure: The code to be executed periodically as data is read from the server.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func downloadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self {
|
||||||
|
downloadDelegate.progressHandler = (closure, queue)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Destination
|
||||||
|
|
||||||
|
/// Creates a download file destination closure which uses the default file manager to move the temporary file to a
|
||||||
|
/// file URL in the first available directory with the specified search path directory and search path domain mask.
|
||||||
|
///
|
||||||
|
/// - parameter directory: The search path directory. `.DocumentDirectory` by default.
|
||||||
|
/// - parameter domain: The search path domain mask. `.UserDomainMask` by default.
|
||||||
|
///
|
||||||
|
/// - returns: A download file destination closure.
|
||||||
|
open class func suggestedDownloadDestination(
|
||||||
|
for directory: FileManager.SearchPathDirectory = .documentDirectory,
|
||||||
|
in domain: FileManager.SearchPathDomainMask = .userDomainMask)
|
||||||
|
-> DownloadFileDestination
|
||||||
|
{
|
||||||
|
return { temporaryURL, response in
|
||||||
|
let directoryURLs = FileManager.default.urls(for: directory, in: domain)
|
||||||
|
|
||||||
|
if !directoryURLs.isEmpty {
|
||||||
|
return (directoryURLs[0].appendingPathComponent(response.suggestedFilename!), [])
|
||||||
|
}
|
||||||
|
|
||||||
|
return (temporaryURL, [])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Specific type of `Request` that manages an underlying `URLSessionUploadTask`.
|
||||||
|
open class UploadRequest: DataRequest {
|
||||||
|
|
||||||
|
// MARK: Helper Types
|
||||||
|
|
||||||
|
enum Uploadable: TaskConvertible {
|
||||||
|
case data(Data, URLRequest)
|
||||||
|
case file(URL, URLRequest)
|
||||||
|
case stream(InputStream, URLRequest)
|
||||||
|
|
||||||
|
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
|
||||||
|
do {
|
||||||
|
let task: URLSessionTask
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case let .data(data, urlRequest):
|
||||||
|
let urlRequest = try urlRequest.adapt(using: adapter)
|
||||||
|
task = queue.sync { session.uploadTask(with: urlRequest, from: data) }
|
||||||
|
case let .file(url, urlRequest):
|
||||||
|
let urlRequest = try urlRequest.adapt(using: adapter)
|
||||||
|
task = queue.sync { session.uploadTask(with: urlRequest, fromFile: url) }
|
||||||
|
case let .stream(_, urlRequest):
|
||||||
|
let urlRequest = try urlRequest.adapt(using: adapter)
|
||||||
|
task = queue.sync { session.uploadTask(withStreamedRequest: urlRequest) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return task
|
||||||
|
} catch {
|
||||||
|
throw AdaptError(error: error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: Properties
|
||||||
|
|
||||||
|
/// The request sent or to be sent to the server.
|
||||||
|
open override var request: URLRequest? {
|
||||||
|
if let request = super.request { return request }
|
||||||
|
|
||||||
|
guard let uploadable = originalTask as? Uploadable else { return nil }
|
||||||
|
|
||||||
|
switch uploadable {
|
||||||
|
case .data(_, let urlRequest), .file(_, let urlRequest), .stream(_, let urlRequest):
|
||||||
|
return urlRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The progress of uploading the payload to the server for the upload request.
|
||||||
|
open var uploadProgress: Progress { return uploadDelegate.uploadProgress }
|
||||||
|
|
||||||
|
var uploadDelegate: UploadTaskDelegate { return delegate as! UploadTaskDelegate }
|
||||||
|
|
||||||
|
// MARK: Upload Progress
|
||||||
|
|
||||||
|
/// Sets a closure to be called periodically during the lifecycle of the `UploadRequest` as data is sent to
|
||||||
|
/// the server.
|
||||||
|
///
|
||||||
|
/// After the data is sent to the server, the `progress(queue:closure:)` APIs can be used to monitor the progress
|
||||||
|
/// of data being read from the server.
|
||||||
|
///
|
||||||
|
/// - parameter queue: The dispatch queue to execute the closure on.
|
||||||
|
/// - parameter closure: The code to be executed periodically as data is sent to the server.
|
||||||
|
///
|
||||||
|
/// - returns: The request.
|
||||||
|
@discardableResult
|
||||||
|
open func uploadProgress(queue: DispatchQueue = DispatchQueue.main, closure: @escaping ProgressHandler) -> Self {
|
||||||
|
uploadDelegate.uploadProgressHandler = (closure, queue)
|
||||||
|
return self
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
#if !os(watchOS)
|
||||||
|
|
||||||
|
/// Specific type of `Request` that manages an underlying `URLSessionStreamTask`.
|
||||||
|
@available(iOS 9.0, macOS 10.11, tvOS 9.0, *)
|
||||||
|
open class StreamRequest: Request {
|
||||||
|
enum Streamable: TaskConvertible {
|
||||||
|
case stream(hostName: String, port: Int)
|
||||||
|
case netService(NetService)
|
||||||
|
|
||||||
|
func task(session: URLSession, adapter: RequestAdapter?, queue: DispatchQueue) throws -> URLSessionTask {
|
||||||
|
let task: URLSessionTask
|
||||||
|
|
||||||
|
switch self {
|
||||||
|
case let .stream(hostName, port):
|
||||||
|
task = queue.sync { session.streamTask(withHostName: hostName, port: port) }
|
||||||
|
case let .netService(netService):
|
||||||
|
task = queue.sync { session.streamTask(with: netService) }
|
||||||
|
}
|
||||||
|
|
||||||
|
return task
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
465
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Response.swift
generated
Normal file
465
samples/client/petstore/swift4/default/SwaggerClientTests/Pods/Alamofire/Source/Response.swift
generated
Normal file
@@ -0,0 +1,465 @@
|
|||||||
|
//
|
||||||
|
// Response.swift
|
||||||
|
//
|
||||||
|
// Copyright (c) 2014-2016 Alamofire Software Foundation (http://alamofire.org/)
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to deal
|
||||||
|
// in the Software without restriction, including without limitation the rights
|
||||||
|
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
// copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
|
// THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
/// Used to store all data associated with an non-serialized response of a data or upload request.
|
||||||
|
public struct DefaultDataResponse {
|
||||||
|
/// The URL request sent to the server.
|
||||||
|
public let request: URLRequest?
|
||||||
|
|
||||||
|
/// The server's response to the URL request.
|
||||||
|
public let response: HTTPURLResponse?
|
||||||
|
|
||||||
|
/// The data returned by the server.
|
||||||
|
public let data: Data?
|
||||||
|
|
||||||
|
/// The error encountered while executing or validating the request.
|
||||||
|
public let error: Error?
|
||||||
|
|
||||||
|
/// The timeline of the complete lifecycle of the request.
|
||||||
|
public let timeline: Timeline
|
||||||
|
|
||||||
|
var _metrics: AnyObject?
|
||||||
|
|
||||||
|
/// Creates a `DefaultDataResponse` instance from the specified parameters.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - request: The URL request sent to the server.
|
||||||
|
/// - response: The server's response to the URL request.
|
||||||
|
/// - data: The data returned by the server.
|
||||||
|
/// - error: The error encountered while executing or validating the request.
|
||||||
|
/// - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
|
||||||
|
/// - metrics: The task metrics containing the request / response statistics. `nil` by default.
|
||||||
|
public init(
|
||||||
|
request: URLRequest?,
|
||||||
|
response: HTTPURLResponse?,
|
||||||
|
data: Data?,
|
||||||
|
error: Error?,
|
||||||
|
timeline: Timeline = Timeline(),
|
||||||
|
metrics: AnyObject? = nil)
|
||||||
|
{
|
||||||
|
self.request = request
|
||||||
|
self.response = response
|
||||||
|
self.data = data
|
||||||
|
self.error = error
|
||||||
|
self.timeline = timeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Used to store all data associated with a serialized response of a data or upload request.
|
||||||
|
public struct DataResponse<Value> {
|
||||||
|
/// The URL request sent to the server.
|
||||||
|
public let request: URLRequest?
|
||||||
|
|
||||||
|
/// The server's response to the URL request.
|
||||||
|
public let response: HTTPURLResponse?
|
||||||
|
|
||||||
|
/// The data returned by the server.
|
||||||
|
public let data: Data?
|
||||||
|
|
||||||
|
/// The result of response serialization.
|
||||||
|
public let result: Result<Value>
|
||||||
|
|
||||||
|
/// The timeline of the complete lifecycle of the request.
|
||||||
|
public let timeline: Timeline
|
||||||
|
|
||||||
|
/// Returns the associated value of the result if it is a success, `nil` otherwise.
|
||||||
|
public var value: Value? { return result.value }
|
||||||
|
|
||||||
|
/// Returns the associated error value if the result if it is a failure, `nil` otherwise.
|
||||||
|
public var error: Error? { return result.error }
|
||||||
|
|
||||||
|
var _metrics: AnyObject?
|
||||||
|
|
||||||
|
/// Creates a `DataResponse` instance with the specified parameters derived from response serialization.
|
||||||
|
///
|
||||||
|
/// - parameter request: The URL request sent to the server.
|
||||||
|
/// - parameter response: The server's response to the URL request.
|
||||||
|
/// - parameter data: The data returned by the server.
|
||||||
|
/// - parameter result: The result of response serialization.
|
||||||
|
/// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
|
||||||
|
///
|
||||||
|
/// - returns: The new `DataResponse` instance.
|
||||||
|
public init(
|
||||||
|
request: URLRequest?,
|
||||||
|
response: HTTPURLResponse?,
|
||||||
|
data: Data?,
|
||||||
|
result: Result<Value>,
|
||||||
|
timeline: Timeline = Timeline())
|
||||||
|
{
|
||||||
|
self.request = request
|
||||||
|
self.response = response
|
||||||
|
self.data = data
|
||||||
|
self.result = result
|
||||||
|
self.timeline = timeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension DataResponse: CustomStringConvertible, CustomDebugStringConvertible {
|
||||||
|
/// The textual representation used when written to an output stream, which includes whether the result was a
|
||||||
|
/// success or failure.
|
||||||
|
public var description: String {
|
||||||
|
return result.debugDescription
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The debug textual representation used when written to an output stream, which includes the URL request, the URL
|
||||||
|
/// response, the server data, the response serialization result and the timeline.
|
||||||
|
public var debugDescription: String {
|
||||||
|
var output: [String] = []
|
||||||
|
|
||||||
|
output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
|
||||||
|
output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
|
||||||
|
output.append("[Data]: \(data?.count ?? 0) bytes")
|
||||||
|
output.append("[Result]: \(result.debugDescription)")
|
||||||
|
output.append("[Timeline]: \(timeline.debugDescription)")
|
||||||
|
|
||||||
|
return output.joined(separator: "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension DataResponse {
|
||||||
|
/// Evaluates the specified closure when the result of this `DataResponse` is a success, passing the unwrapped
|
||||||
|
/// result value as a parameter.
|
||||||
|
///
|
||||||
|
/// Use the `map` method with a closure that does not throw. For example:
|
||||||
|
///
|
||||||
|
/// let possibleData: DataResponse<Data> = ...
|
||||||
|
/// let possibleInt = possibleData.map { $0.count }
|
||||||
|
///
|
||||||
|
/// - parameter transform: A closure that takes the success value of the instance's result.
|
||||||
|
///
|
||||||
|
/// - returns: A `DataResponse` whose result wraps the value returned by the given closure. If this instance's
|
||||||
|
/// result is a failure, returns a response wrapping the same failure.
|
||||||
|
public func map<T>(_ transform: (Value) -> T) -> DataResponse<T> {
|
||||||
|
var response = DataResponse<T>(
|
||||||
|
request: request,
|
||||||
|
response: self.response,
|
||||||
|
data: data,
|
||||||
|
result: result.map(transform),
|
||||||
|
timeline: timeline
|
||||||
|
)
|
||||||
|
|
||||||
|
response._metrics = _metrics
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluates the given closure when the result of this `DataResponse` is a success, passing the unwrapped result
|
||||||
|
/// value as a parameter.
|
||||||
|
///
|
||||||
|
/// Use the `flatMap` method with a closure that may throw an error. For example:
|
||||||
|
///
|
||||||
|
/// let possibleData: DataResponse<Data> = ...
|
||||||
|
/// let possibleObject = possibleData.flatMap {
|
||||||
|
/// try JSONSerialization.jsonObject(with: $0)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// - parameter transform: A closure that takes the success value of the instance's result.
|
||||||
|
///
|
||||||
|
/// - returns: A success or failure `DataResponse` depending on the result of the given closure. If this instance's
|
||||||
|
/// result is a failure, returns the same failure.
|
||||||
|
public func flatMap<T>(_ transform: (Value) throws -> T) -> DataResponse<T> {
|
||||||
|
var response = DataResponse<T>(
|
||||||
|
request: request,
|
||||||
|
response: self.response,
|
||||||
|
data: data,
|
||||||
|
result: result.flatMap(transform),
|
||||||
|
timeline: timeline
|
||||||
|
)
|
||||||
|
|
||||||
|
response._metrics = _metrics
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Used to store all data associated with an non-serialized response of a download request.
|
||||||
|
public struct DefaultDownloadResponse {
|
||||||
|
/// The URL request sent to the server.
|
||||||
|
public let request: URLRequest?
|
||||||
|
|
||||||
|
/// The server's response to the URL request.
|
||||||
|
public let response: HTTPURLResponse?
|
||||||
|
|
||||||
|
/// The temporary destination URL of the data returned from the server.
|
||||||
|
public let temporaryURL: URL?
|
||||||
|
|
||||||
|
/// The final destination URL of the data returned from the server if it was moved.
|
||||||
|
public let destinationURL: URL?
|
||||||
|
|
||||||
|
/// The resume data generated if the request was cancelled.
|
||||||
|
public let resumeData: Data?
|
||||||
|
|
||||||
|
/// The error encountered while executing or validating the request.
|
||||||
|
public let error: Error?
|
||||||
|
|
||||||
|
/// The timeline of the complete lifecycle of the request.
|
||||||
|
public let timeline: Timeline
|
||||||
|
|
||||||
|
var _metrics: AnyObject?
|
||||||
|
|
||||||
|
/// Creates a `DefaultDownloadResponse` instance from the specified parameters.
|
||||||
|
///
|
||||||
|
/// - Parameters:
|
||||||
|
/// - request: The URL request sent to the server.
|
||||||
|
/// - response: The server's response to the URL request.
|
||||||
|
/// - temporaryURL: The temporary destination URL of the data returned from the server.
|
||||||
|
/// - destinationURL: The final destination URL of the data returned from the server if it was moved.
|
||||||
|
/// - resumeData: The resume data generated if the request was cancelled.
|
||||||
|
/// - error: The error encountered while executing or validating the request.
|
||||||
|
/// - timeline: The timeline of the complete lifecycle of the request. `Timeline()` by default.
|
||||||
|
/// - metrics: The task metrics containing the request / response statistics. `nil` by default.
|
||||||
|
public init(
|
||||||
|
request: URLRequest?,
|
||||||
|
response: HTTPURLResponse?,
|
||||||
|
temporaryURL: URL?,
|
||||||
|
destinationURL: URL?,
|
||||||
|
resumeData: Data?,
|
||||||
|
error: Error?,
|
||||||
|
timeline: Timeline = Timeline(),
|
||||||
|
metrics: AnyObject? = nil)
|
||||||
|
{
|
||||||
|
self.request = request
|
||||||
|
self.response = response
|
||||||
|
self.temporaryURL = temporaryURL
|
||||||
|
self.destinationURL = destinationURL
|
||||||
|
self.resumeData = resumeData
|
||||||
|
self.error = error
|
||||||
|
self.timeline = timeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
/// Used to store all data associated with a serialized response of a download request.
|
||||||
|
public struct DownloadResponse<Value> {
|
||||||
|
/// The URL request sent to the server.
|
||||||
|
public let request: URLRequest?
|
||||||
|
|
||||||
|
/// The server's response to the URL request.
|
||||||
|
public let response: HTTPURLResponse?
|
||||||
|
|
||||||
|
/// The temporary destination URL of the data returned from the server.
|
||||||
|
public let temporaryURL: URL?
|
||||||
|
|
||||||
|
/// The final destination URL of the data returned from the server if it was moved.
|
||||||
|
public let destinationURL: URL?
|
||||||
|
|
||||||
|
/// The resume data generated if the request was cancelled.
|
||||||
|
public let resumeData: Data?
|
||||||
|
|
||||||
|
/// The result of response serialization.
|
||||||
|
public let result: Result<Value>
|
||||||
|
|
||||||
|
/// The timeline of the complete lifecycle of the request.
|
||||||
|
public let timeline: Timeline
|
||||||
|
|
||||||
|
/// Returns the associated value of the result if it is a success, `nil` otherwise.
|
||||||
|
public var value: Value? { return result.value }
|
||||||
|
|
||||||
|
/// Returns the associated error value if the result if it is a failure, `nil` otherwise.
|
||||||
|
public var error: Error? { return result.error }
|
||||||
|
|
||||||
|
var _metrics: AnyObject?
|
||||||
|
|
||||||
|
/// Creates a `DownloadResponse` instance with the specified parameters derived from response serialization.
|
||||||
|
///
|
||||||
|
/// - parameter request: The URL request sent to the server.
|
||||||
|
/// - parameter response: The server's response to the URL request.
|
||||||
|
/// - parameter temporaryURL: The temporary destination URL of the data returned from the server.
|
||||||
|
/// - parameter destinationURL: The final destination URL of the data returned from the server if it was moved.
|
||||||
|
/// - parameter resumeData: The resume data generated if the request was cancelled.
|
||||||
|
/// - parameter result: The result of response serialization.
|
||||||
|
/// - parameter timeline: The timeline of the complete lifecycle of the `Request`. Defaults to `Timeline()`.
|
||||||
|
///
|
||||||
|
/// - returns: The new `DownloadResponse` instance.
|
||||||
|
public init(
|
||||||
|
request: URLRequest?,
|
||||||
|
response: HTTPURLResponse?,
|
||||||
|
temporaryURL: URL?,
|
||||||
|
destinationURL: URL?,
|
||||||
|
resumeData: Data?,
|
||||||
|
result: Result<Value>,
|
||||||
|
timeline: Timeline = Timeline())
|
||||||
|
{
|
||||||
|
self.request = request
|
||||||
|
self.response = response
|
||||||
|
self.temporaryURL = temporaryURL
|
||||||
|
self.destinationURL = destinationURL
|
||||||
|
self.resumeData = resumeData
|
||||||
|
self.result = result
|
||||||
|
self.timeline = timeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension DownloadResponse: CustomStringConvertible, CustomDebugStringConvertible {
|
||||||
|
/// The textual representation used when written to an output stream, which includes whether the result was a
|
||||||
|
/// success or failure.
|
||||||
|
public var description: String {
|
||||||
|
return result.debugDescription
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The debug textual representation used when written to an output stream, which includes the URL request, the URL
|
||||||
|
/// response, the temporary and destination URLs, the resume data, the response serialization result and the
|
||||||
|
/// timeline.
|
||||||
|
public var debugDescription: String {
|
||||||
|
var output: [String] = []
|
||||||
|
|
||||||
|
output.append(request != nil ? "[Request]: \(request!.httpMethod ?? "GET") \(request!)" : "[Request]: nil")
|
||||||
|
output.append(response != nil ? "[Response]: \(response!)" : "[Response]: nil")
|
||||||
|
output.append("[TemporaryURL]: \(temporaryURL?.path ?? "nil")")
|
||||||
|
output.append("[DestinationURL]: \(destinationURL?.path ?? "nil")")
|
||||||
|
output.append("[ResumeData]: \(resumeData?.count ?? 0) bytes")
|
||||||
|
output.append("[Result]: \(result.debugDescription)")
|
||||||
|
output.append("[Timeline]: \(timeline.debugDescription)")
|
||||||
|
|
||||||
|
return output.joined(separator: "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
extension DownloadResponse {
|
||||||
|
/// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped
|
||||||
|
/// result value as a parameter.
|
||||||
|
///
|
||||||
|
/// Use the `map` method with a closure that does not throw. For example:
|
||||||
|
///
|
||||||
|
/// let possibleData: DownloadResponse<Data> = ...
|
||||||
|
/// let possibleInt = possibleData.map { $0.count }
|
||||||
|
///
|
||||||
|
/// - parameter transform: A closure that takes the success value of the instance's result.
|
||||||
|
///
|
||||||
|
/// - returns: A `DownloadResponse` whose result wraps the value returned by the given closure. If this instance's
|
||||||
|
/// result is a failure, returns a response wrapping the same failure.
|
||||||
|
public func map<T>(_ transform: (Value) -> T) -> DownloadResponse<T> {
|
||||||
|
var response = DownloadResponse<T>(
|
||||||
|
request: request,
|
||||||
|
response: self.response,
|
||||||
|
temporaryURL: temporaryURL,
|
||||||
|
destinationURL: destinationURL,
|
||||||
|
resumeData: resumeData,
|
||||||
|
result: result.map(transform),
|
||||||
|
timeline: timeline
|
||||||
|
)
|
||||||
|
|
||||||
|
response._metrics = _metrics
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Evaluates the given closure when the result of this `DownloadResponse` is a success, passing the unwrapped
|
||||||
|
/// result value as a parameter.
|
||||||
|
///
|
||||||
|
/// Use the `flatMap` method with a closure that may throw an error. For example:
|
||||||
|
///
|
||||||
|
/// let possibleData: DownloadResponse<Data> = ...
|
||||||
|
/// let possibleObject = possibleData.flatMap {
|
||||||
|
/// try JSONSerialization.jsonObject(with: $0)
|
||||||
|
/// }
|
||||||
|
///
|
||||||
|
/// - parameter transform: A closure that takes the success value of the instance's result.
|
||||||
|
///
|
||||||
|
/// - returns: A success or failure `DownloadResponse` depending on the result of the given closure. If this
|
||||||
|
/// instance's result is a failure, returns the same failure.
|
||||||
|
public func flatMap<T>(_ transform: (Value) throws -> T) -> DownloadResponse<T> {
|
||||||
|
var response = DownloadResponse<T>(
|
||||||
|
request: request,
|
||||||
|
response: self.response,
|
||||||
|
temporaryURL: temporaryURL,
|
||||||
|
destinationURL: destinationURL,
|
||||||
|
resumeData: resumeData,
|
||||||
|
result: result.flatMap(transform),
|
||||||
|
timeline: timeline
|
||||||
|
)
|
||||||
|
|
||||||
|
response._metrics = _metrics
|
||||||
|
|
||||||
|
return response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
protocol Response {
|
||||||
|
/// The task metrics containing the request / response statistics.
|
||||||
|
var _metrics: AnyObject? { get set }
|
||||||
|
mutating func add(_ metrics: AnyObject?)
|
||||||
|
}
|
||||||
|
|
||||||
|
extension Response {
|
||||||
|
mutating func add(_ metrics: AnyObject?) {
|
||||||
|
#if !os(watchOS)
|
||||||
|
guard #available(iOS 10.0, macOS 10.12, tvOS 10.0, *) else { return }
|
||||||
|
guard let metrics = metrics as? URLSessionTaskMetrics else { return }
|
||||||
|
|
||||||
|
_metrics = metrics
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: -
|
||||||
|
|
||||||
|
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
|
||||||
|
extension DefaultDataResponse: Response {
|
||||||
|
#if !os(watchOS)
|
||||||
|
/// The task metrics containing the request / response statistics.
|
||||||
|
public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
|
||||||
|
extension DataResponse: Response {
|
||||||
|
#if !os(watchOS)
|
||||||
|
/// The task metrics containing the request / response statistics.
|
||||||
|
public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
|
||||||
|
extension DefaultDownloadResponse: Response {
|
||||||
|
#if !os(watchOS)
|
||||||
|
/// The task metrics containing the request / response statistics.
|
||||||
|
public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
@available(iOS 10.0, macOS 10.12, tvOS 10.0, *)
|
||||||
|
extension DownloadResponse: Response {
|
||||||
|
#if !os(watchOS)
|
||||||
|
/// The task metrics containing the request / response statistics.
|
||||||
|
public var metrics: URLSessionTaskMetrics? { return _metrics as? URLSessionTaskMetrics }
|
||||||
|
#endif
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user