forked from loafle/openapi-generator-original
[swift5] Add support for oneOfs (#8714)
* [swift5] Add support for oneOfs * Generate a sample Swift project with oneOfs * Update Swift Samples
This commit is contained in:
parent
4e48dae8e4
commit
6c40192706
10
bin/configs/swift5-oneOf.yaml
Normal file
10
bin/configs/swift5-oneOf.yaml
Normal file
@ -0,0 +1,10 @@
|
||||
generatorName: swift5
|
||||
outputDir: samples/client/petstore/swift5/oneOf
|
||||
inputSpec: modules/openapi-generator/src/test/resources/3_0/oneOf.yaml
|
||||
templateDir: modules/openapi-generator/src/main/resources/swift5
|
||||
generateAliasAsModel: true
|
||||
additionalProperties:
|
||||
podAuthors: ""
|
||||
podSummary: PetstoreClient
|
||||
projectName: PetstoreClient
|
||||
podHomepage: https://github.com/openapitools/openapi-generator
|
@ -95,6 +95,7 @@ public class Swift5ClientCodegen extends DefaultCodegen implements CodegenConfig
|
||||
*/
|
||||
public Swift5ClientCodegen() {
|
||||
super();
|
||||
this.useOneOfInterfaces = true;
|
||||
|
||||
generatorMetadata = GeneratorMetadata.newBuilder(generatorMetadata)
|
||||
.stability(Stability.BETA)
|
||||
|
@ -12,7 +12,8 @@ import AnyCodable
|
||||
{{#description}}
|
||||
|
||||
/** {{description}} */{{/description}}{{#isDeprecated}}
|
||||
@available(*, deprecated, message: "This schema is deprecated."){{/isDeprecated}}{{#isArray}}
|
||||
@available(*, deprecated, message: "This schema is deprecated."){{/isDeprecated}}{{#vendorExtensions.x-is-one-of-interface}}
|
||||
{{> modelOneOf}}{{/vendorExtensions.x-is-one-of-interface}}{{^vendorExtensions.x-is-one-of-interface}}{{#isArray}}
|
||||
{{> modelArray}}{{/isArray}}{{^isArray}}{{#isEnum}}
|
||||
{{> modelEnum}}{{/isEnum}}{{^isEnum}}
|
||||
{{> modelObject}}{{/isEnum}}{{/isArray}}{{/model}}{{/models}}
|
||||
{{> modelObject}}{{/isEnum}}{{/isArray}}{{/vendorExtensions.x-is-one-of-interface}}{{/model}}{{/models}}
|
||||
|
31
modules/openapi-generator/src/main/resources/swift5/modelOneOf.mustache
vendored
Normal file
31
modules/openapi-generator/src/main/resources/swift5/modelOneOf.mustache
vendored
Normal file
@ -0,0 +1,31 @@
|
||||
public enum {{classname}}: Codable {
|
||||
{{#oneOf}}
|
||||
case type{{.}}({{.}})
|
||||
{{/oneOf}}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
switch self {
|
||||
{{#oneOf}}
|
||||
case .type{{.}}(let value):
|
||||
try container.encode(value)
|
||||
{{/oneOf}}
|
||||
}
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
{{#oneOf}}
|
||||
{{#-first}}
|
||||
if let value = try? container.decode({{.}}.self) {
|
||||
{{/-first}}
|
||||
{{^-first}}
|
||||
} else if let value = try? container.decode({{.}}.self) {
|
||||
{{/-first}}
|
||||
self = .type{{.}}(value)
|
||||
{{/oneOf}}
|
||||
} else {
|
||||
throw DecodingError.typeMismatch(Self.Type.self, .init(codingPath: decoder.codingPath, debugDescription: "Unable to decode instance of {{classname}}"))
|
||||
}
|
||||
}
|
||||
}
|
63
samples/client/petstore/swift5/oneOf/.gitignore
vendored
Normal file
63
samples/client/petstore/swift5/oneOf/.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 @@
|
||||
# OpenAPI Generator Ignore
|
||||
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
|
||||
|
||||
# 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 OpenAPI Generator 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,26 @@
|
||||
.gitignore
|
||||
Cartfile
|
||||
Package.swift
|
||||
PetstoreClient.podspec
|
||||
PetstoreClient/Classes/OpenAPIs/APIHelper.swift
|
||||
PetstoreClient/Classes/OpenAPIs/APIs.swift
|
||||
PetstoreClient/Classes/OpenAPIs/APIs/DefaultAPI.swift
|
||||
PetstoreClient/Classes/OpenAPIs/CodableHelper.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Configuration.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Extensions.swift
|
||||
PetstoreClient/Classes/OpenAPIs/JSONDataEncoding.swift
|
||||
PetstoreClient/Classes/OpenAPIs/JSONEncodingHelper.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Models.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Models/Apple.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Models/Banana.swift
|
||||
PetstoreClient/Classes/OpenAPIs/Models/Fruit.swift
|
||||
PetstoreClient/Classes/OpenAPIs/OpenISO8601DateFormatter.swift
|
||||
PetstoreClient/Classes/OpenAPIs/SynchronizedDictionary.swift
|
||||
PetstoreClient/Classes/OpenAPIs/URLSessionImplementations.swift
|
||||
README.md
|
||||
docs/Apple.md
|
||||
docs/Banana.md
|
||||
docs/DefaultAPI.md
|
||||
docs/Fruit.md
|
||||
git_push.sh
|
||||
project.yml
|
@ -0,0 +1 @@
|
||||
5.2.0-SNAPSHOT
|
2
samples/client/petstore/swift5/oneOf/Cartfile
Normal file
2
samples/client/petstore/swift5/oneOf/Cartfile
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
github "Flight-School/AnyCodable" ~> 0.4.0
|
33
samples/client/petstore/swift5/oneOf/Package.swift
Normal file
33
samples/client/petstore/swift5/oneOf/Package.swift
Normal file
@ -0,0 +1,33 @@
|
||||
// swift-tools-version:5.1
|
||||
|
||||
import PackageDescription
|
||||
|
||||
let package = Package(
|
||||
name: "PetstoreClient",
|
||||
platforms: [
|
||||
.iOS(.v9),
|
||||
.macOS(.v10_11),
|
||||
.tvOS(.v9),
|
||||
.watchOS(.v3),
|
||||
],
|
||||
products: [
|
||||
// Products define the executables and libraries produced by a package, and make them visible to other packages.
|
||||
.library(
|
||||
name: "PetstoreClient",
|
||||
targets: ["PetstoreClient"]
|
||||
),
|
||||
],
|
||||
dependencies: [
|
||||
// Dependencies declare other packages that this package depends on.
|
||||
.package(url: "https://github.com/Flight-School/AnyCodable", .exact("0.4.0")),
|
||||
],
|
||||
targets: [
|
||||
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
|
||||
// Targets can depend on other targets in this package, and on products in packages which this package depends on.
|
||||
.target(
|
||||
name: "PetstoreClient",
|
||||
dependencies: ["AnyCodable", ],
|
||||
path: "PetstoreClient/Classes"
|
||||
),
|
||||
]
|
||||
)
|
15
samples/client/petstore/swift5/oneOf/PetstoreClient.podspec
Normal file
15
samples/client/petstore/swift5/oneOf/PetstoreClient.podspec
Normal file
@ -0,0 +1,15 @@
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'PetstoreClient'
|
||||
s.ios.deployment_target = '9.0'
|
||||
s.osx.deployment_target = '10.11'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
s.watchos.deployment_target = '3.0'
|
||||
s.version = '0.0.1'
|
||||
s.source = { :git => 'git@github.com:OpenAPITools/openapi-generator.git', :tag => 'v0.0.1' }
|
||||
s.authors = ''
|
||||
s.license = 'Proprietary'
|
||||
s.homepage = 'https://github.com/openapitools/openapi-generator'
|
||||
s.summary = 'PetstoreClient'
|
||||
s.source_files = 'PetstoreClient/Classes/**/*.swift'
|
||||
s.dependency 'AnyCodable-FlightSchool', '~> 0.4.0'
|
||||
end
|
@ -0,0 +1,71 @@
|
||||
// APIHelper.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct APIHelper {
|
||||
public static func rejectNil(_ source: [String: Any?]) -> [String: Any]? {
|
||||
let destination = source.reduce(into: [String: Any]()) { result, item in
|
||||
if let value = item.value {
|
||||
result[item.key] = value
|
||||
}
|
||||
}
|
||||
|
||||
if destination.isEmpty {
|
||||
return nil
|
||||
}
|
||||
return destination
|
||||
}
|
||||
|
||||
public static func rejectNilHeaders(_ source: [String: Any?]) -> [String: String] {
|
||||
return source.reduce(into: [String: String]()) { result, item in
|
||||
if let collection = item.value as? [Any?] {
|
||||
result[item.key] = collection.filter { $0 != nil }.map { "\($0!)" }.joined(separator: ",")
|
||||
} else if let value: Any = item.value {
|
||||
result[item.key] = "\(value)"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func convertBoolToString(_ source: [String: Any]?) -> [String: Any]? {
|
||||
guard let source = source else {
|
||||
return nil
|
||||
}
|
||||
|
||||
return source.reduce(into: [String: Any]()) { result, item in
|
||||
switch item.value {
|
||||
case let x as Bool:
|
||||
result[item.key] = x.description
|
||||
default:
|
||||
result[item.key] = item.value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static func mapValueToPathItem(_ source: Any) -> Any {
|
||||
if let collection = source as? [Any?] {
|
||||
return collection.filter { $0 != nil }.map { "\($0!)" }.joined(separator: ",")
|
||||
}
|
||||
return source
|
||||
}
|
||||
|
||||
public static func mapValuesToQueryItems(_ source: [String: Any?]) -> [URLQueryItem]? {
|
||||
let destination = source.filter { $0.value != nil }.reduce(into: [URLQueryItem]()) { result, item in
|
||||
if let collection = item.value as? [Any?] {
|
||||
collection.filter { $0 != nil }.map { "\($0!)" }.forEach { value in
|
||||
result.append(URLQueryItem(name: item.key, value: value))
|
||||
}
|
||||
} else if let value = item.value {
|
||||
result.append(URLQueryItem(name: item.key, value: "\(value)"))
|
||||
}
|
||||
}
|
||||
|
||||
if destination.isEmpty {
|
||||
return nil
|
||||
}
|
||||
return destination
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
// APIs.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class PetstoreClientAPI {
|
||||
public static var basePath = "http://localhost"
|
||||
public static var credential: URLCredential?
|
||||
public static var customHeaders: [String: String] = [:]
|
||||
public static var requestBuilderFactory: RequestBuilderFactory = URLSessionRequestBuilderFactory()
|
||||
public static var apiResponseQueue: DispatchQueue = .main
|
||||
}
|
||||
|
||||
open class RequestBuilder<T> {
|
||||
var credential: URLCredential?
|
||||
var headers: [String: String]
|
||||
public let parameters: [String: Any]?
|
||||
public let method: String
|
||||
public let URLString: String
|
||||
|
||||
/// Optional block to obtain a reference to the request's progress instance when available.
|
||||
/// With the URLSession http client the request's progress only works on iOS 11.0, macOS 10.13, macCatalyst 13.0, tvOS 11.0, watchOS 4.0.
|
||||
/// If you need to get the request's progress in older OS versions, please use Alamofire http client.
|
||||
public var onProgressReady: ((Progress) -> Void)?
|
||||
|
||||
required public init(method: String, URLString: String, parameters: [String: Any]?, headers: [String: String] = [:]) {
|
||||
self.method = method
|
||||
self.URLString = URLString
|
||||
self.parameters = parameters
|
||||
self.headers = headers
|
||||
|
||||
addHeaders(PetstoreClientAPI.customHeaders)
|
||||
}
|
||||
|
||||
open func addHeaders(_ aHeaders: [String: String]) {
|
||||
for (header, value) in aHeaders {
|
||||
headers[header] = value
|
||||
}
|
||||
}
|
||||
|
||||
open func execute(_ apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result<Response<T>, Error>) -> Void) { }
|
||||
|
||||
public func addHeader(name: String, value: String) -> Self {
|
||||
if !value.isEmpty {
|
||||
headers[name] = value
|
||||
}
|
||||
return self
|
||||
}
|
||||
|
||||
open func addCredential() -> 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,49 @@
|
||||
//
|
||||
// DefaultAPI.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class DefaultAPI {
|
||||
/**
|
||||
|
||||
- parameter apiResponseQueue: The queue on which api response is dispatched.
|
||||
- parameter completion: completion handler to receive the data and the error objects
|
||||
*/
|
||||
open class func rootGet(apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, completion: @escaping ((_ data: Fruit?, _ error: Error?) -> Void)) {
|
||||
rootGetWithRequestBuilder().execute(apiResponseQueue) { result -> Void in
|
||||
switch result {
|
||||
case let .success(response):
|
||||
completion(response.body, nil)
|
||||
case let .failure(error):
|
||||
completion(nil, error)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
- GET /
|
||||
- returns: RequestBuilder<Fruit>
|
||||
*/
|
||||
open class func rootGetWithRequestBuilder() -> RequestBuilder<Fruit> {
|
||||
let path = "/"
|
||||
let URLString = PetstoreClientAPI.basePath + path
|
||||
let parameters: [String: Any]? = nil
|
||||
|
||||
let urlComponents = URLComponents(string: URLString)
|
||||
|
||||
let nillableHeaders: [String: Any?] = [
|
||||
:
|
||||
]
|
||||
|
||||
let headerParameters = APIHelper.rejectNilHeaders(nillableHeaders)
|
||||
|
||||
let requestBuilder: RequestBuilder<Fruit>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder()
|
||||
|
||||
return requestBuilder.init(method: "GET", URLString: (urlComponents?.string ?? URLString), parameters: parameters, headers: headerParameters)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
//
|
||||
// CodableHelper.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class CodableHelper {
|
||||
private static var customDateFormatter: DateFormatter?
|
||||
private static var defaultDateFormatter: DateFormatter = OpenISO8601DateFormatter()
|
||||
|
||||
private static var customJSONDecoder: JSONDecoder?
|
||||
private static var defaultJSONDecoder: JSONDecoder = {
|
||||
let decoder = JSONDecoder()
|
||||
decoder.dateDecodingStrategy = .formatted(CodableHelper.dateFormatter)
|
||||
return decoder
|
||||
}()
|
||||
|
||||
private static var customJSONEncoder: JSONEncoder?
|
||||
private static var defaultJSONEncoder: JSONEncoder = {
|
||||
let encoder = JSONEncoder()
|
||||
encoder.dateEncodingStrategy = .formatted(CodableHelper.dateFormatter)
|
||||
encoder.outputFormatting = .prettyPrinted
|
||||
return encoder
|
||||
}()
|
||||
|
||||
public static var dateFormatter: DateFormatter {
|
||||
get { return customDateFormatter ?? defaultDateFormatter }
|
||||
set { customDateFormatter = newValue }
|
||||
}
|
||||
public static var jsonDecoder: JSONDecoder {
|
||||
get { return customJSONDecoder ?? defaultJSONDecoder }
|
||||
set { customJSONDecoder = newValue }
|
||||
}
|
||||
public static var jsonEncoder: JSONEncoder {
|
||||
get { return customJSONEncoder ?? defaultJSONEncoder }
|
||||
set { customJSONEncoder = newValue }
|
||||
}
|
||||
|
||||
open class func decode<T>(_ type: T.Type, from data: Data) -> Swift.Result<T, Error> where T: Decodable {
|
||||
return Swift.Result { try jsonDecoder.decode(type, from: data) }
|
||||
}
|
||||
|
||||
open class func encode<T>(_ value: T) -> Swift.Result<Data, Error> where T: Encodable {
|
||||
return Swift.Result { try jsonEncoder.encode(value) }
|
||||
}
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
// Configuration.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
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.
|
||||
@available(*, unavailable, message: "To set a different date format, use CodableHelper.dateFormatter instead.")
|
||||
public static var dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||
}
|
@ -0,0 +1,231 @@
|
||||
// Extensions.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if canImport(AnyCodable)
|
||||
import AnyCodable
|
||||
#endif
|
||||
|
||||
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 }
|
||||
}
|
||||
|
||||
extension RawRepresentable where RawValue: JSONEncodable {
|
||||
func encodeToJSON() -> Any { return self.rawValue 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 Set: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
return Array(self).encodeToJSON()
|
||||
}
|
||||
}
|
||||
|
||||
extension Dictionary: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
var dictionary = [AnyHashable: Any]()
|
||||
for (key, value) in self {
|
||||
dictionary[key] = encodeIfPossible(value)
|
||||
}
|
||||
return dictionary as Any
|
||||
}
|
||||
}
|
||||
|
||||
extension Data: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
return self.base64EncodedString(options: Data.Base64EncodingOptions())
|
||||
}
|
||||
}
|
||||
|
||||
extension Date: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
return CodableHelper.dateFormatter.string(from: self) as Any
|
||||
}
|
||||
}
|
||||
|
||||
extension URL: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
return self
|
||||
}
|
||||
}
|
||||
|
||||
extension UUID: JSONEncodable {
|
||||
func encodeToJSON() -> Any {
|
||||
return self.uuidString
|
||||
}
|
||||
}
|
||||
|
||||
extension String: CodingKey {
|
||||
|
||||
public var stringValue: String {
|
||||
return self
|
||||
}
|
||||
|
||||
public init?(stringValue: String) {
|
||||
self.init(stringLiteral: stringValue)
|
||||
}
|
||||
|
||||
public var intValue: Int? {
|
||||
return nil
|
||||
}
|
||||
|
||||
public init?(intValue: Int) {
|
||||
return nil
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension KeyedEncodingContainerProtocol {
|
||||
|
||||
public mutating func encodeArray<T>(_ values: [T], forKey key: Self.Key) throws where T: Encodable {
|
||||
var arrayContainer = nestedUnkeyedContainer(forKey: key)
|
||||
try arrayContainer.encode(contentsOf: values)
|
||||
}
|
||||
|
||||
public mutating func encodeArrayIfPresent<T>(_ values: [T]?, forKey key: Self.Key) throws where T: Encodable {
|
||||
if let values = values {
|
||||
try encodeArray(values, forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func encodeMap<T>(_ pairs: [Self.Key: T]) throws where T: Encodable {
|
||||
for (key, value) in pairs {
|
||||
try encode(value, forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
public mutating func encodeMapIfPresent<T>(_ pairs: [Self.Key: T]?) throws where T: Encodable {
|
||||
if let pairs = pairs {
|
||||
try encodeMap(pairs)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension KeyedDecodingContainerProtocol {
|
||||
|
||||
public func decodeArray<T>(_ type: T.Type, forKey key: Self.Key) throws -> [T] where T: Decodable {
|
||||
var tmpArray = [T]()
|
||||
|
||||
var nestedContainer = try nestedUnkeyedContainer(forKey: key)
|
||||
while !nestedContainer.isAtEnd {
|
||||
let arrayValue = try nestedContainer.decode(T.self)
|
||||
tmpArray.append(arrayValue)
|
||||
}
|
||||
|
||||
return tmpArray
|
||||
}
|
||||
|
||||
public func decodeArrayIfPresent<T>(_ type: T.Type, forKey key: Self.Key) throws -> [T]? where T: Decodable {
|
||||
var tmpArray: [T]?
|
||||
|
||||
if contains(key) {
|
||||
tmpArray = try decodeArray(T.self, forKey: key)
|
||||
}
|
||||
|
||||
return tmpArray
|
||||
}
|
||||
|
||||
public func decodeMap<T>(_ type: T.Type, excludedKeys: Set<Self.Key>) throws -> [Self.Key: T] where T: Decodable {
|
||||
var map: [Self.Key: T] = [:]
|
||||
|
||||
for key in allKeys {
|
||||
if !excludedKeys.contains(key) {
|
||||
let value = try decode(T.self, forKey: key)
|
||||
map[key] = value
|
||||
}
|
||||
}
|
||||
|
||||
return map
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension HTTPURLResponse {
|
||||
var isStatusCodeSuccessful: Bool {
|
||||
return Array(200 ..< 300).contains(statusCode)
|
||||
}
|
||||
}
|
||||
|
||||
#if canImport(AnyCodable)
|
||||
extension AnyCodable: Hashable {
|
||||
public func hash(into hasher: inout Hasher) {
|
||||
switch value {
|
||||
case let value as Bool:
|
||||
hasher.combine(value)
|
||||
case let value as Int:
|
||||
hasher.combine(value)
|
||||
case let value as Int8:
|
||||
hasher.combine(value)
|
||||
case let value as Int16:
|
||||
hasher.combine(value)
|
||||
case let value as Int32:
|
||||
hasher.combine(value)
|
||||
case let value as Int64:
|
||||
hasher.combine(value)
|
||||
case let value as UInt:
|
||||
hasher.combine(value)
|
||||
case let value as UInt8:
|
||||
hasher.combine(value)
|
||||
case let value as UInt16:
|
||||
hasher.combine(value)
|
||||
case let value as UInt32:
|
||||
hasher.combine(value)
|
||||
case let value as UInt64:
|
||||
hasher.combine(value)
|
||||
case let value as Float:
|
||||
hasher.combine(value)
|
||||
case let value as Double:
|
||||
hasher.combine(value)
|
||||
case let value as String:
|
||||
hasher.combine(value)
|
||||
case let value as [String: AnyCodable]:
|
||||
hasher.combine(value)
|
||||
case let value as [AnyCodable]:
|
||||
hasher.combine(value)
|
||||
default:
|
||||
hasher.combine(0)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
@ -0,0 +1,53 @@
|
||||
//
|
||||
// JSONDataEncoding.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct JSONDataEncoding {
|
||||
|
||||
// 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: URLRequest, with parameters: [String: Any]?) -> URLRequest {
|
||||
var urlRequest = urlRequest
|
||||
|
||||
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?) -> [String: Any]? {
|
||||
var returnedParams: [String: Any]?
|
||||
if let jsonData = jsonData, !jsonData.isEmpty {
|
||||
var params: [String: Any] = [:]
|
||||
params[jsonDataKey] = jsonData
|
||||
returnedParams = params
|
||||
}
|
||||
return returnedParams
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
//
|
||||
// JSONEncodingHelper.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
open class JSONEncodingHelper {
|
||||
|
||||
open class func encodingParameters<T: Encodable>(forEncodableObject encodableObj: T?) -> [String: Any]? {
|
||||
var params: [String: Any]?
|
||||
|
||||
// Encode the Encodable object
|
||||
if let encodableObj = encodableObj {
|
||||
let encodeResult = CodableHelper.encode(encodableObj)
|
||||
do {
|
||||
let data = try encodeResult.get()
|
||||
params = JSONDataEncoding.encodingParameters(jsonData: data)
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
open class func encodingParameters(forEncodableObject encodableObj: Any?) -> [String: Any]? {
|
||||
var params: [String: Any]?
|
||||
|
||||
if let encodableObj = encodableObj {
|
||||
do {
|
||||
let data = try JSONSerialization.data(withJSONObject: encodableObj, options: .prettyPrinted)
|
||||
params = JSONDataEncoding.encodingParameters(jsonData: data)
|
||||
} catch {
|
||||
print(error.localizedDescription)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return params
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,54 @@
|
||||
// Models.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
protocol JSONEncodable {
|
||||
func encodeToJSON() -> Any
|
||||
}
|
||||
|
||||
public enum ErrorResponse: Error {
|
||||
case error(Int, Data?, URLResponse?, Error)
|
||||
}
|
||||
|
||||
public enum DownloadException: Error {
|
||||
case responseDataMissing
|
||||
case responseFailed
|
||||
case requestMissing
|
||||
case requestMissingPath
|
||||
case requestMissingURL
|
||||
}
|
||||
|
||||
public enum DecodableRequestBuilderError: Error {
|
||||
case emptyDataResponse
|
||||
case nilHTTPResponse
|
||||
case unsuccessfulHTTPStatusCode
|
||||
case jsonDecoding(DecodingError)
|
||||
case generalError(Error)
|
||||
}
|
||||
|
||||
open class Response<T> {
|
||||
public let statusCode: Int
|
||||
public let header: [String: String]
|
||||
public 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 {
|
||||
if let key = key.base as? String, let value = value as? String {
|
||||
header[key] = value
|
||||
}
|
||||
}
|
||||
self.init(statusCode: response.statusCode, header: header, body: body)
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Apple.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if canImport(AnyCodable)
|
||||
import AnyCodable
|
||||
#endif
|
||||
|
||||
public struct Apple: Codable, Hashable {
|
||||
|
||||
public var kind: String?
|
||||
|
||||
public init(kind: String? = nil) {
|
||||
self.kind = kind
|
||||
}
|
||||
|
||||
public enum CodingKeys: String, CodingKey, CaseIterable {
|
||||
case kind
|
||||
}
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(kind, forKey: .kind)
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
//
|
||||
// Banana.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if canImport(AnyCodable)
|
||||
import AnyCodable
|
||||
#endif
|
||||
|
||||
public struct Banana: Codable, Hashable {
|
||||
|
||||
public var count: Double?
|
||||
|
||||
public init(count: Double? = nil) {
|
||||
self.count = count
|
||||
}
|
||||
|
||||
public enum CodingKeys: String, CodingKey, CaseIterable {
|
||||
case count
|
||||
}
|
||||
|
||||
// Encodable protocol methods
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encodeIfPresent(count, forKey: .count)
|
||||
}
|
||||
}
|
@ -0,0 +1,38 @@
|
||||
//
|
||||
// Fruit.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if canImport(AnyCodable)
|
||||
import AnyCodable
|
||||
#endif
|
||||
|
||||
public enum Fruit: Codable {
|
||||
case typeApple(Apple)
|
||||
case typeBanana(Banana)
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
switch self {
|
||||
case .typeApple(let value):
|
||||
try container.encode(value)
|
||||
case .typeBanana(let value):
|
||||
try container.encode(value)
|
||||
}
|
||||
}
|
||||
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
if let value = try? container.decode(Apple.self) {
|
||||
self = .typeApple(value)
|
||||
} else if let value = try? container.decode(Banana.self) {
|
||||
self = .typeBanana(value)
|
||||
} else {
|
||||
throw DecodingError.typeMismatch(Self.Type.self, .init(codingPath: decoder.codingPath, debugDescription: "Unable to decode instance of Fruit"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,44 @@
|
||||
//
|
||||
// OpenISO8601DateFormatter.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
// https://stackoverflow.com/a/50281094/976628
|
||||
public class OpenISO8601DateFormatter: DateFormatter {
|
||||
static let withoutSeconds: DateFormatter = {
|
||||
let formatter = DateFormatter()
|
||||
formatter.calendar = Calendar(identifier: .iso8601)
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
formatter.timeZone = TimeZone(secondsFromGMT: 0)
|
||||
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZZZZZ"
|
||||
return formatter
|
||||
}()
|
||||
|
||||
private func setup() {
|
||||
calendar = Calendar(identifier: .iso8601)
|
||||
locale = Locale(identifier: "en_US_POSIX")
|
||||
timeZone = TimeZone(secondsFromGMT: 0)
|
||||
dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ"
|
||||
}
|
||||
|
||||
override init() {
|
||||
super.init()
|
||||
setup()
|
||||
}
|
||||
|
||||
required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setup()
|
||||
}
|
||||
|
||||
override public func date(from string: String) -> Date? {
|
||||
if let result = super.date(from: string) {
|
||||
return result
|
||||
}
|
||||
return OpenISO8601DateFormatter.withoutSeconds.date(from: string)
|
||||
}
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
// SynchronizedDictionary.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
internal struct SynchronizedDictionary<K: Hashable, V> {
|
||||
|
||||
private var dictionary = [K: V]()
|
||||
private let queue = DispatchQueue(
|
||||
label: "SynchronizedDictionary",
|
||||
qos: DispatchQoS.userInitiated,
|
||||
attributes: [DispatchQueue.Attributes.concurrent],
|
||||
autoreleaseFrequency: DispatchQueue.AutoreleaseFrequency.inherit,
|
||||
target: nil
|
||||
)
|
||||
|
||||
internal subscript(key: K) -> V? {
|
||||
get {
|
||||
var value: V?
|
||||
|
||||
queue.sync {
|
||||
value = self.dictionary[key]
|
||||
}
|
||||
|
||||
return value
|
||||
}
|
||||
set {
|
||||
queue.sync(flags: DispatchWorkItemFlags.barrier) {
|
||||
self.dictionary[key] = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,606 @@
|
||||
// URLSessionImplementations.swift
|
||||
//
|
||||
// Generated by openapi-generator
|
||||
// https://openapi-generator.tech
|
||||
//
|
||||
|
||||
import Foundation
|
||||
#if !os(macOS)
|
||||
import MobileCoreServices
|
||||
#endif
|
||||
|
||||
class URLSessionRequestBuilderFactory: RequestBuilderFactory {
|
||||
func getNonDecodableBuilder<T>() -> RequestBuilder<T>.Type {
|
||||
return URLSessionRequestBuilder<T>.self
|
||||
}
|
||||
|
||||
func getBuilder<T: Decodable>() -> RequestBuilder<T>.Type {
|
||||
return URLSessionDecodableRequestBuilder<T>.self
|
||||
}
|
||||
}
|
||||
|
||||
// Store the URLSession to retain its reference
|
||||
private var urlSessionStore = SynchronizedDictionary<String, URLSession>()
|
||||
|
||||
open class URLSessionRequestBuilder<T>: RequestBuilder<T> {
|
||||
|
||||
/**
|
||||
May be assigned if you want to control the authentication challenges.
|
||||
*/
|
||||
public var taskDidReceiveChallenge: ((URLSession, URLSessionTask, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))?
|
||||
|
||||
/**
|
||||
May be assigned if you want to do any of those things:
|
||||
- control the task completion
|
||||
- intercept and handle errors like authorization
|
||||
- retry the request.
|
||||
*/
|
||||
@available(*, deprecated, message: "Please override execute() method to intercept and handle errors like authorization or retry the request. Check the Wiki for more info. https://github.com/OpenAPITools/openapi-generator/wiki/FAQ#how-do-i-implement-bearer-token-authentication-with-urlsession-on-the-swift-api-client")
|
||||
public var taskCompletionShouldRetry: ((Data?, URLResponse?, Error?, @escaping (Bool) -> Void) -> Void)?
|
||||
|
||||
required public init(method: String, URLString: String, parameters: [String: Any]?, headers: [String: String] = [:]) {
|
||||
super.init(method: method, URLString: URLString, parameters: parameters, headers: headers)
|
||||
}
|
||||
|
||||
/**
|
||||
May be overridden by a subclass if you want to control the URLSession
|
||||
configuration.
|
||||
*/
|
||||
open func createURLSession() -> URLSession {
|
||||
let configuration = URLSessionConfiguration.default
|
||||
configuration.httpAdditionalHeaders = buildHeaders()
|
||||
let sessionDelegate = SessionDelegate()
|
||||
sessionDelegate.credential = credential
|
||||
sessionDelegate.taskDidReceiveChallenge = taskDidReceiveChallenge
|
||||
return URLSession(configuration: configuration, delegate: sessionDelegate, delegateQueue: nil)
|
||||
}
|
||||
|
||||
/**
|
||||
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 URLRequest
|
||||
configuration (e.g. to override the cache policy).
|
||||
*/
|
||||
open func createURLRequest(urlSession: URLSession, method: HTTPMethod, encoding: ParameterEncoding, headers: [String: String]) throws -> URLRequest {
|
||||
|
||||
guard let url = URL(string: URLString) else {
|
||||
throw DownloadException.requestMissingURL
|
||||
}
|
||||
|
||||
var originalRequest = URLRequest(url: url)
|
||||
|
||||
originalRequest.httpMethod = method.rawValue
|
||||
|
||||
headers.forEach { key, value in
|
||||
originalRequest.setValue(value, forHTTPHeaderField: key)
|
||||
}
|
||||
|
||||
buildHeaders().forEach { key, value in
|
||||
originalRequest.setValue(value, forHTTPHeaderField: key)
|
||||
}
|
||||
|
||||
let modifiedRequest = try encoding.encode(originalRequest, with: parameters)
|
||||
|
||||
return modifiedRequest
|
||||
}
|
||||
|
||||
override open func execute(_ apiResponseQueue: DispatchQueue = PetstoreClientAPI.apiResponseQueue, _ completion: @escaping (_ result: Swift.Result<Response<T>, Error>) -> Void) {
|
||||
let urlSessionId = UUID().uuidString
|
||||
// Create a new manager for each request to customize its request header
|
||||
let urlSession = createURLSession()
|
||||
urlSessionStore[urlSessionId] = urlSession
|
||||
|
||||
guard let xMethod = HTTPMethod(rawValue: method) else {
|
||||
fatalError("Unsuported Http method - \(method)")
|
||||
}
|
||||
|
||||
let encoding: ParameterEncoding
|
||||
|
||||
switch xMethod {
|
||||
case .get, .head:
|
||||
encoding = URLEncoding()
|
||||
|
||||
case .options, .post, .put, .patch, .delete, .trace, .connect:
|
||||
let contentType = headers["Content-Type"] ?? "application/json"
|
||||
|
||||
if contentType == "application/json" {
|
||||
encoding = JSONDataEncoding()
|
||||
} else if contentType == "multipart/form-data" {
|
||||
encoding = FormDataEncoding(contentTypeForFormPart: contentTypeForFormPart(fileURL:))
|
||||
} else if contentType == "application/x-www-form-urlencoded" {
|
||||
encoding = FormURLEncoding()
|
||||
} else {
|
||||
fatalError("Unsuported Media Type - \(contentType)")
|
||||
}
|
||||
}
|
||||
|
||||
let cleanupRequest = {
|
||||
urlSessionStore[urlSessionId]?.finishTasksAndInvalidate()
|
||||
urlSessionStore[urlSessionId] = nil
|
||||
}
|
||||
|
||||
do {
|
||||
let request = try createURLRequest(urlSession: urlSession, method: xMethod, encoding: encoding, headers: headers)
|
||||
|
||||
let dataTask = urlSession.dataTask(with: request) { data, response, error in
|
||||
|
||||
if let taskCompletionShouldRetry = self.taskCompletionShouldRetry {
|
||||
|
||||
taskCompletionShouldRetry(data, response, error) { shouldRetry in
|
||||
|
||||
if shouldRetry {
|
||||
cleanupRequest()
|
||||
self.execute(apiResponseQueue, completion)
|
||||
} else {
|
||||
apiResponseQueue.async {
|
||||
self.processRequestResponse(urlRequest: request, data: data, response: response, error: error, completion: completion)
|
||||
cleanupRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
apiResponseQueue.async {
|
||||
self.processRequestResponse(urlRequest: request, data: data, response: response, error: error, completion: completion)
|
||||
cleanupRequest()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if #available(iOS 11.0, macOS 10.13, macCatalyst 13.0, tvOS 11.0, watchOS 4.0, *) {
|
||||
onProgressReady?(dataTask.progress)
|
||||
}
|
||||
|
||||
dataTask.resume()
|
||||
|
||||
} catch {
|
||||
apiResponseQueue.async {
|
||||
cleanupRequest()
|
||||
completion(.failure(ErrorResponse.error(415, nil, nil, error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate func processRequestResponse(urlRequest: URLRequest, data: Data?, response: URLResponse?, error: Error?, completion: @escaping (_ result: Swift.Result<Response<T>, Error>) -> Void) {
|
||||
|
||||
if let error = error {
|
||||
completion(.failure(ErrorResponse.error(-1, data, response, error)))
|
||||
return
|
||||
}
|
||||
|
||||
guard let httpResponse = response as? HTTPURLResponse else {
|
||||
completion(.failure(ErrorResponse.error(-2, data, response, DecodableRequestBuilderError.nilHTTPResponse)))
|
||||
return
|
||||
}
|
||||
|
||||
guard httpResponse.isStatusCodeSuccessful else {
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, data, response, DecodableRequestBuilderError.unsuccessfulHTTPStatusCode)))
|
||||
return
|
||||
}
|
||||
|
||||
switch T.self {
|
||||
case is String.Type:
|
||||
|
||||
let body = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
|
||||
|
||||
completion(.success(Response<T>(response: httpResponse, body: body as? T)))
|
||||
|
||||
case is URL.Type:
|
||||
do {
|
||||
|
||||
guard error == nil else {
|
||||
throw DownloadException.responseFailed
|
||||
}
|
||||
|
||||
guard let data = data else {
|
||||
throw DownloadException.responseDataMissing
|
||||
}
|
||||
|
||||
let fileManager = FileManager.default
|
||||
let documentsDirectory = fileManager.urls(for: .documentDirectory, in: .userDomainMask)[0]
|
||||
let requestURL = try getURL(from: urlRequest)
|
||||
|
||||
var requestPath = try getPath(from: requestURL)
|
||||
|
||||
if let headerFileName = getFileName(fromContentDisposition: httpResponse.allHeaderFields["Content-Disposition"] as? String) {
|
||||
requestPath = requestPath.appending("/\(headerFileName)")
|
||||
}
|
||||
|
||||
let filePath = documentsDirectory.appendingPathComponent(requestPath)
|
||||
let directoryPath = filePath.deletingLastPathComponent().path
|
||||
|
||||
try fileManager.createDirectory(atPath: directoryPath, withIntermediateDirectories: true, attributes: nil)
|
||||
try data.write(to: filePath, options: .atomic)
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: filePath as? T)))
|
||||
|
||||
} catch let requestParserError as DownloadException {
|
||||
completion(.failure(ErrorResponse.error(400, data, response, requestParserError)))
|
||||
} catch {
|
||||
completion(.failure(ErrorResponse.error(400, data, response, error)))
|
||||
}
|
||||
|
||||
case is Void.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: nil)))
|
||||
|
||||
default:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: data as? T)))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open func buildHeaders() -> [String: String] {
|
||||
var httpHeaders: [String: String] = [:]
|
||||
for (key, value) in headers {
|
||||
httpHeaders[key] = value
|
||||
}
|
||||
for (key, value) in PetstoreClientAPI.customHeaders {
|
||||
httpHeaders[key] = value
|
||||
}
|
||||
return httpHeaders
|
||||
}
|
||||
|
||||
fileprivate func getFileName(fromContentDisposition contentDisposition: String?) -> String? {
|
||||
|
||||
guard let contentDisposition = contentDisposition else {
|
||||
return nil
|
||||
}
|
||||
|
||||
let items = contentDisposition.components(separatedBy: ";")
|
||||
|
||||
var filename: String?
|
||||
|
||||
for contentItem in items {
|
||||
|
||||
let filenameKey = "filename="
|
||||
guard let range = contentItem.range(of: filenameKey) else {
|
||||
break
|
||||
}
|
||||
|
||||
filename = contentItem
|
||||
return filename?
|
||||
.replacingCharacters(in: range, with: "")
|
||||
.replacingOccurrences(of: "\"", with: "")
|
||||
.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
}
|
||||
|
||||
return filename
|
||||
|
||||
}
|
||||
|
||||
fileprivate func getPath(from url: URL) throws -> String {
|
||||
|
||||
guard var path = URLComponents(url: url, resolvingAgainstBaseURL: true)?.path else {
|
||||
throw DownloadException.requestMissingPath
|
||||
}
|
||||
|
||||
if path.hasPrefix("/") {
|
||||
path.remove(at: path.startIndex)
|
||||
}
|
||||
|
||||
return path
|
||||
|
||||
}
|
||||
|
||||
fileprivate func getURL(from urlRequest: URLRequest) throws -> URL {
|
||||
|
||||
guard let url = urlRequest.url else {
|
||||
throw DownloadException.requestMissingURL
|
||||
}
|
||||
|
||||
return url
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
open class URLSessionDecodableRequestBuilder<T: Decodable>: URLSessionRequestBuilder<T> {
|
||||
override fileprivate func processRequestResponse(urlRequest: URLRequest, data: Data?, response: URLResponse?, error: Error?, completion: @escaping (_ result: Swift.Result<Response<T>, Error>) -> Void) {
|
||||
|
||||
if let error = error {
|
||||
completion(.failure(ErrorResponse.error(-1, data, response, error)))
|
||||
return
|
||||
}
|
||||
|
||||
guard let httpResponse = response as? HTTPURLResponse else {
|
||||
completion(.failure(ErrorResponse.error(-2, data, response, DecodableRequestBuilderError.nilHTTPResponse)))
|
||||
return
|
||||
}
|
||||
|
||||
guard httpResponse.isStatusCodeSuccessful else {
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, data, response, DecodableRequestBuilderError.unsuccessfulHTTPStatusCode)))
|
||||
return
|
||||
}
|
||||
|
||||
switch T.self {
|
||||
case is String.Type:
|
||||
|
||||
let body = data.flatMap { String(data: $0, encoding: .utf8) } ?? ""
|
||||
|
||||
completion(.success(Response<T>(response: httpResponse, body: body as? T)))
|
||||
|
||||
case is Void.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: nil)))
|
||||
|
||||
case is Data.Type:
|
||||
|
||||
completion(.success(Response(response: httpResponse, body: data as? T)))
|
||||
|
||||
default:
|
||||
|
||||
guard let data = data, !data.isEmpty else {
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, nil, response, DecodableRequestBuilderError.emptyDataResponse)))
|
||||
return
|
||||
}
|
||||
|
||||
let decodeResult = CodableHelper.decode(T.self, from: data)
|
||||
|
||||
switch decodeResult {
|
||||
case let .success(decodableObj):
|
||||
completion(.success(Response(response: httpResponse, body: decodableObj)))
|
||||
case let .failure(error):
|
||||
completion(.failure(ErrorResponse.error(httpResponse.statusCode, data, response, error)))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SessionDelegate: NSObject, URLSessionDelegate, URLSessionDataDelegate {
|
||||
|
||||
var credential: URLCredential?
|
||||
|
||||
var taskDidReceiveChallenge: ((URLSession, URLSessionTask, URLAuthenticationChallenge) -> (URLSession.AuthChallengeDisposition, URLCredential?))?
|
||||
|
||||
func urlSession(_ session: URLSession, task: URLSessionTask, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
|
||||
|
||||
var disposition: URLSession.AuthChallengeDisposition = .performDefaultHandling
|
||||
|
||||
var credential: URLCredential?
|
||||
|
||||
if let taskDidReceiveChallenge = taskDidReceiveChallenge {
|
||||
(disposition, credential) = taskDidReceiveChallenge(session, task, challenge)
|
||||
} else {
|
||||
if challenge.previousFailureCount > 0 {
|
||||
disposition = .rejectProtectionSpace
|
||||
} else {
|
||||
credential = self.credential ?? session.configuration.urlCredentialStorage?.defaultCredential(for: challenge.protectionSpace)
|
||||
|
||||
if credential != nil {
|
||||
disposition = .useCredential
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
completionHandler(disposition, credential)
|
||||
}
|
||||
}
|
||||
|
||||
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"
|
||||
}
|
||||
|
||||
public protocol ParameterEncoding {
|
||||
func encode(_ urlRequest: URLRequest, with parameters: [String: Any]?) throws -> URLRequest
|
||||
}
|
||||
|
||||
private class URLEncoding: ParameterEncoding {
|
||||
func encode(_ urlRequest: URLRequest, with parameters: [String: Any]?) throws -> URLRequest {
|
||||
|
||||
var urlRequest = urlRequest
|
||||
|
||||
guard let parameters = parameters else { return urlRequest }
|
||||
|
||||
guard let url = urlRequest.url else {
|
||||
throw DownloadException.requestMissingURL
|
||||
}
|
||||
|
||||
if var urlComponents = URLComponents(url: url, resolvingAgainstBaseURL: false), !parameters.isEmpty {
|
||||
urlComponents.queryItems = APIHelper.mapValuesToQueryItems(parameters)
|
||||
urlRequest.url = urlComponents.url
|
||||
}
|
||||
|
||||
return urlRequest
|
||||
}
|
||||
}
|
||||
|
||||
private class FormDataEncoding: ParameterEncoding {
|
||||
|
||||
let contentTypeForFormPart: (_ fileURL: URL) -> String?
|
||||
|
||||
init(contentTypeForFormPart: @escaping (_ fileURL: URL) -> String?) {
|
||||
self.contentTypeForFormPart = contentTypeForFormPart
|
||||
}
|
||||
|
||||
func encode(_ urlRequest: URLRequest, with parameters: [String: Any]?) throws -> URLRequest {
|
||||
|
||||
var urlRequest = urlRequest
|
||||
|
||||
guard let parameters = parameters, !parameters.isEmpty else {
|
||||
return urlRequest
|
||||
}
|
||||
|
||||
let boundary = "Boundary-\(UUID().uuidString)"
|
||||
|
||||
urlRequest.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
|
||||
|
||||
for (key, value) in parameters {
|
||||
switch value {
|
||||
case let fileURL as URL:
|
||||
|
||||
urlRequest = try configureFileUploadRequest(
|
||||
urlRequest: urlRequest,
|
||||
boundary: boundary,
|
||||
name: key,
|
||||
fileURL: fileURL
|
||||
)
|
||||
|
||||
case let string as String:
|
||||
|
||||
if let data = string.data(using: .utf8) {
|
||||
urlRequest = configureDataUploadRequest(
|
||||
urlRequest: urlRequest,
|
||||
boundary: boundary,
|
||||
name: key,
|
||||
data: data
|
||||
)
|
||||
}
|
||||
|
||||
case let number as NSNumber:
|
||||
|
||||
if let data = number.stringValue.data(using: .utf8) {
|
||||
urlRequest = configureDataUploadRequest(
|
||||
urlRequest: urlRequest,
|
||||
boundary: boundary,
|
||||
name: key,
|
||||
data: data
|
||||
)
|
||||
}
|
||||
|
||||
default:
|
||||
fatalError("Unprocessable value \(value) with key \(key)")
|
||||
}
|
||||
}
|
||||
|
||||
var body = urlRequest.httpBody.orEmpty
|
||||
|
||||
body.append("\r\n--\(boundary)--\r\n")
|
||||
|
||||
urlRequest.httpBody = body
|
||||
|
||||
return urlRequest
|
||||
}
|
||||
|
||||
private func configureFileUploadRequest(urlRequest: URLRequest, boundary: String, name: String, fileURL: URL) throws -> URLRequest {
|
||||
|
||||
var urlRequest = urlRequest
|
||||
|
||||
var body = urlRequest.httpBody.orEmpty
|
||||
|
||||
let fileData = try Data(contentsOf: fileURL)
|
||||
|
||||
let mimetype = contentTypeForFormPart(fileURL) ?? mimeType(for: fileURL)
|
||||
|
||||
let fileName = fileURL.lastPathComponent
|
||||
|
||||
// If we already added something then we need an additional newline.
|
||||
if body.count > 0 {
|
||||
body.append("\r\n")
|
||||
}
|
||||
|
||||
// Value boundary.
|
||||
body.append("--\(boundary)\r\n")
|
||||
|
||||
// Value headers.
|
||||
body.append("Content-Disposition: form-data; name=\"\(name)\"; filename=\"\(fileName)\"\r\n")
|
||||
body.append("Content-Type: \(mimetype)\r\n")
|
||||
|
||||
// Separate headers and body.
|
||||
body.append("\r\n")
|
||||
|
||||
// The value data.
|
||||
body.append(fileData)
|
||||
|
||||
urlRequest.httpBody = body
|
||||
|
||||
return urlRequest
|
||||
}
|
||||
|
||||
private func configureDataUploadRequest(urlRequest: URLRequest, boundary: String, name: String, data: Data) -> URLRequest {
|
||||
|
||||
var urlRequest = urlRequest
|
||||
|
||||
var body = urlRequest.httpBody.orEmpty
|
||||
|
||||
// If we already added something then we need an additional newline.
|
||||
if body.count > 0 {
|
||||
body.append("\r\n")
|
||||
}
|
||||
|
||||
// Value boundary.
|
||||
body.append("--\(boundary)\r\n")
|
||||
|
||||
// Value headers.
|
||||
body.append("Content-Disposition: form-data; name=\"\(name)\"\r\n")
|
||||
|
||||
// Separate headers and body.
|
||||
body.append("\r\n")
|
||||
|
||||
// The value data.
|
||||
body.append(data)
|
||||
|
||||
urlRequest.httpBody = body
|
||||
|
||||
return urlRequest
|
||||
|
||||
}
|
||||
|
||||
func mimeType(for url: URL) -> String {
|
||||
let pathExtension = url.pathExtension
|
||||
|
||||
if let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as NSString, nil)?.takeRetainedValue() {
|
||||
if let mimetype = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
|
||||
return mimetype as String
|
||||
}
|
||||
}
|
||||
return "application/octet-stream"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private class FormURLEncoding: ParameterEncoding {
|
||||
func encode(_ urlRequest: URLRequest, with parameters: [String: Any]?) throws -> URLRequest {
|
||||
|
||||
var urlRequest = urlRequest
|
||||
|
||||
var requestBodyComponents = URLComponents()
|
||||
requestBodyComponents.queryItems = APIHelper.mapValuesToQueryItems(parameters ?? [:])
|
||||
|
||||
if urlRequest.value(forHTTPHeaderField: "Content-Type") == nil {
|
||||
urlRequest.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
|
||||
}
|
||||
|
||||
urlRequest.httpBody = requestBodyComponents.query?.data(using: .utf8)
|
||||
|
||||
return urlRequest
|
||||
}
|
||||
}
|
||||
|
||||
private extension Data {
|
||||
/// Append string to Data
|
||||
///
|
||||
/// Rather than littering my code with calls to `dataUsingEncoding` to convert strings to Data, and then add that data to the Data, this wraps it in a nice convenient little extension to Data. This converts using UTF-8.
|
||||
///
|
||||
/// - parameter string: The string to be added to the `Data`.
|
||||
|
||||
mutating func append(_ string: String) {
|
||||
if let data = string.data(using: .utf8) {
|
||||
append(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private extension Optional where Wrapped == Data {
|
||||
var orEmpty: Data {
|
||||
self ?? Data()
|
||||
}
|
||||
}
|
||||
|
||||
extension JSONDataEncoding: ParameterEncoding {}
|
46
samples/client/petstore/swift5/oneOf/README.md
Normal file
46
samples/client/petstore/swift5/oneOf/README.md
Normal file
@ -0,0 +1,46 @@
|
||||
# Swift5 API client for PetstoreClient
|
||||
|
||||
No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
|
||||
|
||||
## Overview
|
||||
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate an API client.
|
||||
|
||||
- API version: 0.0.1
|
||||
- Package version:
|
||||
- Build package: org.openapitools.codegen.languages.Swift5ClientCodegen
|
||||
|
||||
## Installation
|
||||
|
||||
### Carthage
|
||||
|
||||
Run `carthage update`
|
||||
|
||||
### CocoaPods
|
||||
|
||||
Run `pod install`
|
||||
|
||||
## Documentation for API Endpoints
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Class | Method | HTTP request | Description
|
||||
------------ | ------------- | ------------- | -------------
|
||||
*DefaultAPI* | [**rootGet**](docs/DefaultAPI.md#rootget) | **GET** / |
|
||||
|
||||
|
||||
## Documentation For Models
|
||||
|
||||
- [Apple](docs/Apple.md)
|
||||
- [Banana](docs/Banana.md)
|
||||
- [Fruit](docs/Fruit.md)
|
||||
|
||||
|
||||
## Documentation For Authorization
|
||||
|
||||
All endpoints do not require authorization.
|
||||
|
||||
|
||||
## Author
|
||||
|
||||
|
||||
|
11
samples/client/petstore/swift5/oneOf/docs/Apple.md
Normal file
11
samples/client/petstore/swift5/oneOf/docs/Apple.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Apple
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**kind** | **String** | | [optional]
|
||||
**color** | **String** | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
11
samples/client/petstore/swift5/oneOf/docs/Banana.md
Normal file
11
samples/client/petstore/swift5/oneOf/docs/Banana.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Banana
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**count** | **Double** | | [optional]
|
||||
**color** | **String** | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
52
samples/client/petstore/swift5/oneOf/docs/DefaultAPI.md
Normal file
52
samples/client/petstore/swift5/oneOf/docs/DefaultAPI.md
Normal file
@ -0,0 +1,52 @@
|
||||
# DefaultAPI
|
||||
|
||||
All URIs are relative to *http://localhost*
|
||||
|
||||
Method | HTTP request | Description
|
||||
------------- | ------------- | -------------
|
||||
[**rootGet**](DefaultAPI.md#rootget) | **GET** / |
|
||||
|
||||
|
||||
# **rootGet**
|
||||
```swift
|
||||
open class func rootGet(completion: @escaping (_ data: Fruit?, _ error: Error?) -> Void)
|
||||
```
|
||||
|
||||
|
||||
|
||||
### Example
|
||||
```swift
|
||||
// The following code samples are still beta. For any issue, please report via http://github.com/OpenAPITools/openapi-generator/issues/new
|
||||
import PetstoreClient
|
||||
|
||||
|
||||
DefaultAPI.rootGet() { (response, error) in
|
||||
guard error == nil else {
|
||||
print(error)
|
||||
return
|
||||
}
|
||||
|
||||
if (response) {
|
||||
dump(response)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Parameters
|
||||
This endpoint does not need any parameter.
|
||||
|
||||
### Return type
|
||||
|
||||
[**Fruit**](Fruit.md)
|
||||
|
||||
### Authorization
|
||||
|
||||
No authorization required
|
||||
|
||||
### HTTP request headers
|
||||
|
||||
- **Content-Type**: Not defined
|
||||
- **Accept**: application/json
|
||||
|
||||
[[Back to top]](#) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to Model list]](../README.md#documentation-for-models) [[Back to README]](../README.md)
|
||||
|
12
samples/client/petstore/swift5/oneOf/docs/Fruit.md
Normal file
12
samples/client/petstore/swift5/oneOf/docs/Fruit.md
Normal file
@ -0,0 +1,12 @@
|
||||
# Fruit
|
||||
|
||||
## Properties
|
||||
Name | Type | Description | Notes
|
||||
------------ | ------------- | ------------- | -------------
|
||||
**color** | **String** | | [optional]
|
||||
**kind** | **String** | | [optional]
|
||||
**count** | **Double** | | [optional]
|
||||
|
||||
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
|
||||
|
||||
|
58
samples/client/petstore/swift5/oneOf/git_push.sh
Normal file
58
samples/client/petstore/swift5/oneOf/git_push.sh
Normal file
@ -0,0 +1,58 @@
|
||||
#!/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 openapi-pestore-perl "minor update" "gitlab.com"
|
||||
|
||||
git_user_id=$1
|
||||
git_repo_id=$2
|
||||
release_note=$3
|
||||
git_host=$4
|
||||
|
||||
if [ "$git_host" = "" ]; then
|
||||
git_host="github.com"
|
||||
echo "[INFO] No command line input provided. Set \$git_host to $git_host"
|
||||
fi
|
||||
|
||||
if [ "$git_user_id" = "" ]; then
|
||||
git_user_id="GIT_USER_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_user_id to $git_user_id"
|
||||
fi
|
||||
|
||||
if [ "$git_repo_id" = "" ]; then
|
||||
git_repo_id="GIT_REPO_ID"
|
||||
echo "[INFO] No command line input provided. Set \$git_repo_id to $git_repo_id"
|
||||
fi
|
||||
|
||||
if [ "$release_note" = "" ]; then
|
||||
release_note="Minor update"
|
||||
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 credential in your environment."
|
||||
git remote add origin https://${git_host}/${git_user_id}/${git_repo_id}.git
|
||||
else
|
||||
git remote add origin https://${git_user_id}:${GIT_TOKEN}@${git_host}/${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://${git_host}/${git_user_id}/${git_repo_id}.git"
|
||||
git push origin master 2>&1 | grep -v 'To https'
|
||||
|
15
samples/client/petstore/swift5/oneOf/project.yml
Normal file
15
samples/client/petstore/swift5/oneOf/project.yml
Normal file
@ -0,0 +1,15 @@
|
||||
name: PetstoreClient
|
||||
targets:
|
||||
PetstoreClient:
|
||||
type: framework
|
||||
platform: iOS
|
||||
deploymentTarget: "9.0"
|
||||
sources: [PetstoreClient]
|
||||
info:
|
||||
path: ./Info.plist
|
||||
version: 0.0.1
|
||||
settings:
|
||||
APPLICATION_EXTENSION_API_ONLY: true
|
||||
scheme: {}
|
||||
dependencies:
|
||||
- carthage: AnyCodable
|
Loading…
x
Reference in New Issue
Block a user