From 7be35bb02eecb73d8488dc4d16871cd8bbba2707 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 26 May 2015 10:59:55 +0900 Subject: [PATCH 01/17] Change method name to avoid name collision --- .../src/main/resources/swift/APIs.mustache | 2 +- .../main/resources/swift/Extensions.mustache | 29 ++++++++++++++----- .../src/main/resources/swift/Models.mustache | 2 +- .../src/main/resources/swift/api.mustache | 2 +- .../src/main/resources/swift/model.mustache | 6 ++-- 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache index aa39ccfcbdd..d9fcb84c125 100644 --- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache @@ -15,7 +15,7 @@ class {{projectName}}API { class APIBase { func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { - let encoded: AnyObject? = encodable?.encode() + let encoded: AnyObject? = encodable?.encodeToJSON() if encoded! is [AnyObject] { var dictionary = [String:AnyObject]() diff --git a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache index c937db23fe3..a06ebae7026 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache @@ -8,41 +8,41 @@ import Alamofire import PromiseKit extension Bool: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Float: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Int: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension Double: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } extension String: JSONEncodable { - func encode() -> AnyObject { return self } + func encodeToJSON() -> AnyObject { return self } } private func encodeIfPossible(object: T) -> AnyObject { if object is JSONEncodable { - return (object as! JSONEncodable).encode() + return (object as! JSONEncodable).encodeToJSON() } else { return object as! AnyObject } } extension Array: JSONEncodable { - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { return self.map(encodeIfPossible) } } extension Dictionary: JSONEncodable { - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { var dictionary = [NSObject:AnyObject]() for (key, value) in self { dictionary[key as! NSObject] = encodeIfPossible(value) @@ -50,3 +50,16 @@ extension Dictionary: JSONEncodable { return dictionary } } + + +private let dateFormatter: NSDateFormatter = { + let dateFormatter = NSDateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd" + return dateFormatter +}() + +extension NSDate: JSONEncodable { + func encodeToJSON() -> AnyObject { + return dateFormatter.stringFromDate(self) + } +} diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 37c497ddcb9..587b710326b 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -7,7 +7,7 @@ import Foundation protocol JSONEncodable { - func encode() -> AnyObject + func encodeToJSON() -> AnyObject } class Response { diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index e24bdae6773..8c40c3f5be7 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -35,7 +35,7 @@ extension {{projectName}}API { path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{^required}}?{{/required}}.encode() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index a964882c97c..06f10146cf6 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -22,12 +22,12 @@ class {{classname}}: JSONEncodable { {{/vars}} // MARK: JSONEncodable - func encode() -> AnyObject { + func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encode(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From d08acf72984669cd9adfd70ae0e620a9439ec327 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:25:46 +0900 Subject: [PATCH 02/17] Add a dateTime formatter candidate --- .../src/main/resources/swift/Models.mustache | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 587b710326b..31c055b54dc 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -97,17 +97,24 @@ class Decoders { static private func initialize() { dispatch_once(&once) { - let dateTimeFormatter = NSDateFormatter() - dateTimeFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss'Z'" - let dateFormatter = NSDateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd" + let formatters = [ + "yyyy-MM-dd", + "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ].map { (format: String) -> NSDateFormatter in + let formatter = NSDateFormatter() + formatter.dateFormat = format + return formatter + } // Decoder for NSDate Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in let sourceString = source as! String - if count(sourceString) == 10 { - return dateFormatter.dateFromString(sourceString)! + for formatter in formatters { + if let date = formatter.dateFromString(sourceString) { + return date + } } - return dateTimeFormatter.dateFromString(sourceString)! + fatalError("formatter failed to parse \(sourceString)") } {{#models}}{{#model}} // Decoder for {{{classname}}} From a7c91d610f60c1554edde152b76073c3dc07d251 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:26:01 +0900 Subject: [PATCH 03/17] Add error response body to NSError --- .../src/main/resources/swift/AlamofireImplementations.mustache | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index 244d816332c..37edceea13c 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -45,7 +45,8 @@ class AlamofireRequestBuilder: RequestBuilder { } if res!.statusCode >= 400 { //TODO: Add error entity - let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: [:]) + let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] + let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) defer.reject(error) return } From 495e528eecd6df3e1cce3322cbc3f4cb0b46e43c Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 12:30:58 +0900 Subject: [PATCH 04/17] Add generated code --- samples/client/petstore/swift/Cartfile | 2 + .../Classes/Swaggers/APIHelper.swift | 21 ++ .../Classes/Swaggers/APIs.swift | 66 +++++ .../Classes/Swaggers/APIs/PetAPI.swift | 225 ++++++++++++++++++ .../Classes/Swaggers/APIs/StoreAPI.swift | 114 +++++++++ .../Classes/Swaggers/APIs/UserAPI.swift | 206 ++++++++++++++++ .../Swaggers/AlamofireImplementations.swift | 80 +++++++ .../Classes/Swaggers/Extensions.swift | 65 +++++ .../Classes/Swaggers/Models.swift | 185 ++++++++++++++ .../Classes/Swaggers/Models/Category.swift | 25 ++ .../Classes/Swaggers/Models/Order.swift | 40 ++++ .../Classes/Swaggers/Models/Pet.swift | 40 ++++ .../Classes/Swaggers/Models/Tag.swift | 25 ++ .../Classes/Swaggers/Models/User.swift | 38 +++ 14 files changed, 1132 insertions(+) create mode 100644 samples/client/petstore/swift/Cartfile create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift create mode 100644 samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift diff --git a/samples/client/petstore/swift/Cartfile b/samples/client/petstore/swift/Cartfile new file mode 100644 index 00000000000..af74617bcf2 --- /dev/null +++ b/samples/client/petstore/swift/Cartfile @@ -0,0 +1,2 @@ +github "Alamofire/Alamofire" >= 1.2 +github "mxcl/PromiseKit" >=1.5.3 diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift new file mode 100644 index 00000000000..418f1c8512b --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIHelper.swift @@ -0,0 +1,21 @@ +// APIHelper.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +class APIHelper { + static func rejectNil(source: [String:AnyObject?]) -> [String:AnyObject]? { + var destination = [String:AnyObject]() + for (key, nillableValue) in source { + if let value: AnyObject = nillableValue { + destination[key] = value + } + } + + if destination.isEmpty { + return nil + } + return destination + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift new file mode 100644 index 00000000000..75138ff689a --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift @@ -0,0 +1,66 @@ +// APIs.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation +import PromiseKit + +class PetstoreClientAPI { + static let basePath = "http://petstore.swagger.io/v2" + static var credential: NSURLCredential? + static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() +} + +class APIBase { + func toParameters(encodable: JSONEncodable?) -> [String: AnyObject]? { + let encoded: AnyObject? = encodable?.encodeToJSON() + + if encoded! is [AnyObject] { + var dictionary = [String:AnyObject]() + for (index, item) in enumerate(encoded as! [AnyObject]) { + dictionary["\(index)"] = item + } + return dictionary + } else { + return encoded as? [String:AnyObject] + } + } +} + +class RequestBuilder { + var credential: NSURLCredential? + var headers: [String:String] = [:] + let parameters: [String:AnyObject]? + let isBody: Bool + let method: String + let URLString: String + + required init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) { + self.method = method + self.URLString = URLString + self.parameters = parameters + self.isBody = isBody + } + + func execute() -> Promise> { fatalError("Not implemented") } + + func addHeader(#name: String, value: String) -> Self { + if !value.isEmpty { + headers[name] = value + } + return self + } + + func addCredential() -> Self { + self.credential = PetstoreClientAPI.credential + return self + } +} + +protocol RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type +} + + diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift new file mode 100644 index 00000000000..48e5f439159 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -0,0 +1,225 @@ +// +// PetAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class PetAPI: APIBase { + + /** + + Update an existing pet + + - PUT /pet + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@5fd7e9cb] + + :param: body (body) Pet object that needs to be added to the store + + :returns: Promise> + */ + func updatePet(#body: Pet?) -> RequestBuilder { + let path = "/pet" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "PUT", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Add a new pet to the store + + - POST /pet + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@58363f95] + + :param: body (body) Pet object that needs to be added to the store + + :returns: Promise> + */ + func addPet(#body: Pet?) -> RequestBuilder { + let path = "/pet" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Finds Pets by status + + - GET /pet/findByStatus + - Multiple status values can be provided with comma seperated strings + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@51887c71] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: status (query) Status values that need to be considered for filter + + :returns: Promise> + */ + func findPetsByStatus(#status: [String]?) -> RequestBuilder<[Pet]> { + let path = "/pet/findByStatus" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "status": status + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Finds Pets by tags + + - GET /pet/findByTags + - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4ede45aa] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: tags (query) Tags to filter by + + :returns: Promise> + */ + func findPetsByTags(#tags: [String]?) -> RequestBuilder<[Pet]> { + let path = "/pet/findByTags" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "tags": tags + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[Pet]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Find pet by ID + + - GET /pet/{petId} + - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + + :param: petId (path) ID of pet that needs to be fetched + + :returns: Promise> + */ + func getPetById(#petId: Int) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Updates a pet in the store with form data + + - POST /pet/{petId} + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@795525a1] + + :param: petId (path) ID of pet that needs to be updated + :param: name (form) Updated name of the pet + :param: status (form) Updated status of the pet + + :returns: Promise> + */ + func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Deletes a pet + + - DELETE /pet/{petId} + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4519ab42] + + :param: petId (path) Pet id to delete + + :returns: Promise> + */ + func deletePet(#petId: Int) -> RequestBuilder { + var path = "/pet/{petId}" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + /** + + uploads an image + + - POST /pet/{petId}/uploadImage + - + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@183a9d7f] + + :param: petId (path) ID of pet to update + :param: additionalMetadata (form) Additional data to pass to server + :param: file (form) file to upload + + :returns: Promise> + */ + func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + var path = "/pet/{petId}/uploadImage" + path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift new file mode 100644 index 00000000000..8ffedbdb39b --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -0,0 +1,114 @@ +// +// StoreAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class StoreAPI: APIBase { + + /** + + Returns pet inventories by status + + - GET /store/inventory + - Returns a map of status codes to quantities + - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@303a0946] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + + :returns: Promise> + */ + func getInventory() -> RequestBuilder<[String:Int]> { + let path = "/store/inventory" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder<[String:Int]>.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Place an order for a pet + + - POST /store/order + - + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + + :param: body (body) order placed for purchasing the pet + + :returns: Promise> + */ + func placeOrder(#body: Order?) -> RequestBuilder { + let path = "/store/order" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Find purchase order by ID + + - GET /store/order/{orderId} + - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + + :param: orderId (path) ID of pet that needs to be fetched + + :returns: Promise> + */ + func getOrderById(#orderId: String) -> RequestBuilder { + var path = "/store/order/{orderId}" + path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Delete purchase order by ID + + - DELETE /store/order/{orderId} + - For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + + :param: orderId (path) ID of the order that needs to be deleted + + :returns: Promise> + */ + func deleteOrder(#orderId: String) -> RequestBuilder { + var path = "/store/order/{orderId}" + path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift new file mode 100644 index 00000000000..aed405c7bb0 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -0,0 +1,206 @@ +// +// UserAPI.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension PetstoreClientAPI { + + class UserAPI: APIBase { + + /** + + Create user + + - POST /user + - This can only be done by the logged in user. + + :param: body (body) Created user object + + :returns: Promise> + */ + func createUser(#body: User?) -> RequestBuilder { + let path = "/user" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Creates list of users with given input array + + - POST /user/createWithArray + - + + :param: body (body) List of user object + + :returns: Promise> + */ + func createUsersWithArrayInput(#body: [User]?) -> RequestBuilder { + let path = "/user/createWithArray" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Creates list of users with given input array + + - POST /user/createWithList + - + + :param: body (body) List of user object + + :returns: Promise> + */ + func createUsersWithListInput(#body: [User]?) -> RequestBuilder { + let path = "/user/createWithList" + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "POST", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Logs user into the system + + - GET /user/login + - + - examples: [{example="aeiou", contentType=application/json}, {example=string, contentType=application/xml}] + - examples: [{example="aeiou", contentType=application/json}, {example=string, contentType=application/xml}] + + :param: username (query) The user name for login + :param: password (query) The password for login in clear text + + :returns: Promise> + */ + func loginUser(#username: String?, password: String?) -> RequestBuilder { + let path = "/user/login" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [ + "username": username, + "password": password + ] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: false) + } + + /** + + Logs out current logged in user session + + - GET /user/logout + - + + :returns: Promise> + */ + func logoutUser() -> RequestBuilder { + let path = "/user/logout" + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Get user by user name + + - GET /user/{username} + - + - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + + :param: username (path) The name that needs to be fetched. Use user1 for testing. + + :returns: Promise> + */ + func getUserByName(#username: String) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "GET", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Updated user + + - PUT /user/{username} + - This can only be done by the logged in user. + + :param: username (path) name that need to be deleted + :param: body (body) Updated user object + + :returns: Promise> + */ + func updateUser(#username: String, body: User?) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let parameters = body?.encodeToJSON() as? [String:AnyObject] + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "PUT", URLString: url, parameters: parameters, isBody: true) + } + + /** + + Delete user + + - DELETE /user/{username} + - This can only be done by the logged in user. + + :param: username (path) The name that needs to be deleted + + :returns: Promise> + */ + func deleteUser(#username: String) -> RequestBuilder { + var path = "/user/{username}" + path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) + let url = PetstoreClientAPI.basePath + path + + let nillableParameters: [String:AnyObject?] = [:] + let parameters = APIHelper.rejectNil(nillableParameters) + + let requestBuilder: RequestBuilder.Type = PetstoreClientAPI.requestBuilderFactory.getBuilder() + + return requestBuilder(method: "DELETE", URLString: url, parameters: parameters, isBody: true) + } + + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift new file mode 100644 index 00000000000..37edceea13c --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift @@ -0,0 +1,80 @@ +// AlamofireImplementations.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +class AlamofireRequestBuilderFactory: RequestBuilderFactory { + func getBuilder() -> RequestBuilder.Type { + return AlamofireRequestBuilder.self + } +} + +// Store manager to retain its reference +private var managerStore: [String: Alamofire.Manager] = [:] + +class AlamofireRequestBuilder: RequestBuilder { + required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool) { + super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) + } + + override func execute() -> Promise> { + let managerId = NSUUID().UUIDString + // Create a new manager for each request to customize its request header + let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() + configuration.HTTPAdditionalHeaders = buildHeaders() + let manager = Alamofire.Manager(configuration: configuration) + managerStore[managerId] = manager + + let encoding = isBody ? Alamofire.ParameterEncoding.JSON : Alamofire.ParameterEncoding.URL + let request = manager.request(Alamofire.Method(rawValue: method)!, URLString, parameters: parameters, encoding: encoding) + if let credential = self.credential { + request.authenticate(usingCredential: credential) + } + + let defer = Promise>.defer() + request.responseJSON(options: .AllowFragments) { (req, res, json, error) in + managerStore.removeValueForKey(managerId) + + if let error = error { + defer.reject(error) + return + } + if res!.statusCode >= 400 { + //TODO: Add error entity + let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] + let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) + defer.reject(error) + return + } + + if () is T { + let response = Response(response: res!, body: () as! T) + defer.fulfill(response) + return + } + if let json: AnyObject = json { + let body = Decoders.decode(clazz: T.self, source: json) + let response = Response(response: res!, body: body) + defer.fulfill(response) + return + } + + defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + } + return defer.promise + } + + private func buildHeaders() -> [String: AnyObject] { + var httpHeaders = Manager.defaultHTTPHeaders + for (key, value) in self.headers { + httpHeaders[key] = value + } + return httpHeaders + } +} + + diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift new file mode 100644 index 00000000000..a06ebae7026 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift @@ -0,0 +1,65 @@ +// Extensions.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Alamofire +import PromiseKit + +extension Bool: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Float: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Int: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension Double: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +extension String: JSONEncodable { + func encodeToJSON() -> AnyObject { return self } +} + +private func encodeIfPossible(object: T) -> AnyObject { + if object is JSONEncodable { + return (object as! JSONEncodable).encodeToJSON() + } else { + return object as! AnyObject + } +} + +extension Array: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.map(encodeIfPossible) + } +} + +extension Dictionary: JSONEncodable { + func encodeToJSON() -> AnyObject { + var dictionary = [NSObject:AnyObject]() + for (key, value) in self { + dictionary[key as! NSObject] = encodeIfPossible(value) + } + return dictionary + } +} + + +private let dateFormatter: NSDateFormatter = { + let dateFormatter = NSDateFormatter() + dateFormatter.dateFormat = "yyyy-MM-dd" + return dateFormatter +}() + +extension NSDate: JSONEncodable { + func encodeToJSON() -> AnyObject { + return dateFormatter.stringFromDate(self) + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift new file mode 100644 index 00000000000..54e38e75bfe --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift @@ -0,0 +1,185 @@ +// Models.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + +protocol JSONEncodable { + func encodeToJSON() -> AnyObject +} + +class Response { + let statusCode: Int + let header: [String: String] + let body: T + + init(statusCode: Int, header: [String: String], body: T) { + self.statusCode = statusCode + self.header = header + self.body = body + } + + convenience init(response: NSHTTPURLResponse, 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) + } +} + +private var once = dispatch_once_t() +class Decoders { + static private var decoders = Dictionary AnyObject)>() + + static func addDecoder(#clazz: T.Type, decoder: ((AnyObject) -> T)) { + let key = "\(T.self)" + decoders[key] = { decoder($0) as! AnyObject } + } + + static func decode(#clazz: [T].Type, source: AnyObject) -> [T] { + let array = source as! [AnyObject] + return array.map { Decoders.decode(clazz: T.self, source: $0) } + } + + static func decode(#clazz: [Key:T].Type, source: AnyObject) -> [Key:T] { + let sourceDictinoary = source as! [Key: AnyObject] + var dictionary = [Key:T]() + for (key, value) in sourceDictinoary { + dictionary[key] = Decoders.decode(clazz: T.self, source: value) + } + return dictionary + } + + static func decode(#clazz: T.Type, source: AnyObject) -> T { + initialize() + if source is T { + return source as! T + } + + let key = "\(T.self)" + if let decoder = decoders[key] { + return decoder(source) as! T + } else { + fatalError("Source \(source) is not convertible to type \(clazz): Maybe swagger file is insufficient") + } + } + + static func decodeOptional(#clazz: T.Type, source: AnyObject?) -> T? { + if source is NSNull { + return nil + } + return source.map { (source: AnyObject) -> T in + Decoders.decode(clazz: clazz, source: source) + } + } + + static func decodeOptional(#clazz: [T].Type, source: AnyObject?) -> [T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static func decodeOptional(#clazz: [Key:T].Type, source: AnyObject?) -> [Key:T]? { + if source is NSNull { + return nil + } + return source.map { (someSource: AnyObject) -> [Key:T] in + Decoders.decode(clazz: clazz, source: someSource) + } + } + + static private func initialize() { + dispatch_once(&once) { + let formatters = [ + "yyyy-MM-dd", + "yyyy-MM-dd'T'HH:mm:ssZZZZZ", + "yyyy-MM-dd'T'HH:mm:ss'Z'" + ].map { (format: String) -> NSDateFormatter in + let formatter = NSDateFormatter() + formatter.dateFormat = format + return formatter + } + // Decoder for NSDate + Decoders.addDecoder(clazz: NSDate.self) { (source: AnyObject) -> NSDate in + let sourceString = source as! String + for formatter in formatters { + if let date = formatter.dateFromString(sourceString) { + return date + } + } + fatalError("formatter failed to parse \(sourceString)") + } + + // Decoder for User + Decoders.addDecoder(clazz: User.self) { (source: AnyObject) -> User in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = User() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.username = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["username"]) + instance.firstName = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["firstName"]) + instance.lastName = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["lastName"]) + instance.email = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["email"]) + instance.password = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["password"]) + instance.phone = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["phone"]) + instance.userStatus = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["userStatus"]) + return instance + } + + + // Decoder for Category + Decoders.addDecoder(clazz: Category.self) { (source: AnyObject) -> Category in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Category() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + return instance + } + + + // Decoder for Pet + Decoders.addDecoder(clazz: Pet.self) { (source: AnyObject) -> Pet in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Pet() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.category = Decoders.decodeOptional(clazz: Category.self, source: sourceDictionary["category"]) + instance.name = Decoders.decode(clazz: String.self, source: sourceDictionary["name"]!) + instance.photoUrls = Decoders.decode(clazz: Array.self, source: sourceDictionary["photoUrls"]!) + instance.tags = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["tags"]) + instance.status = (sourceDictionary["status"] as? String).map { Pet.Status(rawValue: $0)! } + return instance + } + + + // Decoder for Tag + Decoders.addDecoder(clazz: Tag.self) { (source: AnyObject) -> Tag in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Tag() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + return instance + } + + + // Decoder for Order + Decoders.addDecoder(clazz: Order.self) { (source: AnyObject) -> Order in + let sourceDictionary = source as! [NSObject:AnyObject] + var instance = Order() + instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) + instance.petId = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["petId"]) + instance.quantity = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["quantity"]) + instance.shipDate = Decoders.decodeOptional(clazz: NSDate.self, source: sourceDictionary["shipDate"]) + instance.status = (sourceDictionary["status"] as? String).map { Order.Status(rawValue: $0)! } + instance.complete = Decoders.decodeOptional(clazz: Bool.self, source: sourceDictionary["complete"]) + return instance + } + + } + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift new file mode 100644 index 00000000000..eab3e7b9e01 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Category.swift @@ -0,0 +1,25 @@ +// +// Category.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Category: JSONEncodable { + + var id: Int? + var name: String? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["name"] = self.name + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift new file mode 100644 index 00000000000..11884502bc1 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Order.swift @@ -0,0 +1,40 @@ +// +// Order.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Order: JSONEncodable { + + enum Status: String { + case Placed = "placed" + case Approved = "approved" + case Delivered = "delivered" + } + + var id: Int? + var petId: Int? + var quantity: Int? + var shipDate: NSDate? + /** Order Status */ + var status: Status? + var complete: Bool? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["petId"] = self.petId + nillableDictionary["quantity"] = self.quantity + nillableDictionary["shipDate"] = self.shipDate?.encodeToJSON() + nillableDictionary["status"] = self.status?.rawValue + nillableDictionary["complete"] = self.complete + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift new file mode 100644 index 00000000000..ff66ea2ea43 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift @@ -0,0 +1,40 @@ +// +// Pet.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Pet: JSONEncodable { + + enum Status: String { + case Available = "available" + case Pending = "pending" + case Sold = "sold" + } + + var id: Int? + var category: Category? + var name: String! + var photoUrls: [String]! + var tags: [Tag]? + /** pet status in the store */ + var status: Status? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["category"] = self.category?.encodeToJSON() + nillableDictionary["name"] = self.name + nillableDictionary["photoUrls"] = self.photoUrls.encodeToJSON() + nillableDictionary["tags"] = self.tags?.encodeToJSON() + nillableDictionary["status"] = self.status?.rawValue + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift new file mode 100644 index 00000000000..2951506a0dc --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Tag.swift @@ -0,0 +1,25 @@ +// +// Tag.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class Tag: JSONEncodable { + + var id: Int? + var name: String? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["name"] = self.name + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift new file mode 100644 index 00000000000..f2461238dc7 --- /dev/null +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/User.swift @@ -0,0 +1,38 @@ +// +// User.swift +// +// Generated by swagger-codegen +// https://github.com/swagger-api/swagger-codegen +// + +import Foundation + + +class User: JSONEncodable { + + var id: Int? + var username: String? + var firstName: String? + var lastName: String? + var email: String? + var password: String? + var phone: String? + /** User Status */ + var userStatus: Int? + + + // MARK: JSONEncodable + func encodeToJSON() -> AnyObject { + var nillableDictionary = [String:AnyObject?]() + nillableDictionary["id"] = self.id + nillableDictionary["username"] = self.username + nillableDictionary["firstName"] = self.firstName + nillableDictionary["lastName"] = self.lastName + nillableDictionary["email"] = self.email + nillableDictionary["password"] = self.password + nillableDictionary["phone"] = self.phone + nillableDictionary["userStatus"] = self.userStatus + let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] + return dictionary + } +} From db01ec801f73a5c2caf6f85b6e79ef45f4c26baf Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:01:57 +0900 Subject: [PATCH 05/17] Add suppressRequired functionality --- .../codegen/languages/SwiftGenerator.java | 256 ++++++++++++++++++ .../src/main/resources/swift/Models.mustache | 4 +- .../src/main/resources/swift/api.mustache | 4 +- .../src/main/resources/swift/model.mustache | 10 +- 4 files changed, 265 insertions(+), 9 deletions(-) create mode 100644 modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java new file mode 100644 index 00000000000..697bdefef8f --- /dev/null +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -0,0 +1,256 @@ +package com.wordnik.swagger.codegen.languages; + +import com.google.common.base.Predicate; +import com.google.common.collect.Iterators; +import com.google.common.collect.Lists; +import com.wordnik.swagger.codegen.*; +import com.wordnik.swagger.models.Model; +import com.wordnik.swagger.models.Operation; +import com.wordnik.swagger.models.parameters.HeaderParameter; +import com.wordnik.swagger.models.parameters.Parameter; +import com.wordnik.swagger.models.properties.*; +import org.apache.commons.lang.StringUtils; + +import javax.annotation.Nullable; +import java.util.*; +import java.io.File; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { + private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected String sourceFolder = "Classes/Swaggers"; + + public CodegenType getTag() { + return CodegenType.CLIENT; + } + + public String getName() { + return "swift"; + } + + public String getHelp() { + return "Generates a swift client library."; + } + + public SwiftGenerator() { + super(); + outputFolder = "generated-code/swift"; + modelTemplateFiles.put("model.mustache", ".swift"); + apiTemplateFiles.put("api.mustache", ".swift"); + templateDir = "swift"; + apiPackage = "/APIs"; + modelPackage = "/Models"; + + // Inject application name + String appName = System.getProperty("appName"); + if (appName == null) { + appName = "SwaggerClient"; + } + additionalProperties.put("projectName", appName); + + // Inject base url override + String basePathOverride = System.getProperty("basePathOverride"); + if (basePathOverride != null) { + additionalProperties.put("basePathOverride", basePathOverride); + } + + // Make all the variable optional + String suppressRequired = System.getProperty("suppressRequired"); + if (suppressRequired != null) { + additionalProperties.put("suppressRequired", suppressRequired); + } + + sourceFolder = appName + "/" + sourceFolder; + + 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("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); + + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "Int", + "Float", + "Double", + "Bool", + "Void", + "String", + "Character") + ); + defaultIncludes = new HashSet( + Arrays.asList( + "NSDate", + "Array", + "Dictionary", + "Set", + "Any", + "Empty", + "AnyObject") + ); + reservedWords = new HashSet( + Arrays.asList( + "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") + ); + + typeMapping = new HashMap(); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Dictionary"); + typeMapping.put("date", "NSDate"); + typeMapping.put("Date", "NSDate"); + typeMapping.put("DateTime", "NSDate"); + typeMapping.put("boolean", "Bool"); + typeMapping.put("string", "String"); + typeMapping.put("char", "Character"); + typeMapping.put("short", "Int"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Int"); + typeMapping.put("integer", "Int"); + typeMapping.put("Integer", "Int"); + typeMapping.put("float", "Float"); + typeMapping.put("number", "Double"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "AnyObject"); + typeMapping.put("file", "NSData"); + + importMapping = new HashMap(); + } + + @Override + public String escapeReservedWord(String name) { + return "_" + name; // add an underscore to the name + } + + @Override + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + } + + @Override + public String apiFileFolder() { + return outputFolder + "/" + 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 = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) + return toModelName(type); + } else + type = swaggerType; + return toModelName(type); + } + + @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 "[String:" + inner + "]"; + } else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return "[" + inner + "]"; + } + return null; + } + + @Override + public CodegenProperty fromProperty(String name, Property p) { + CodegenProperty codegenProperty = super.fromProperty(name, p); + if (codegenProperty.isEnum) { + List> swiftEnums = new ArrayList>(); + List values = (List) codegenProperty.allowableValues.get("values"); + for (String value : values) { + Map map = new HashMap(); + map.put("enum", StringUtils.capitalize(value)); + map.put("raw", value); + swiftEnums.add(map); + } + codegenProperty.allowableValues.put("values", swiftEnums); + codegenProperty.datatypeWithEnum = + StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + } + return codegenProperty; + } + + @Override + public String toApiName(String name) { + if(name.length() == 0) + return "DefaultAPI"; + return initialCaps(name) + "API"; + } + + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { + path = normalizePath(path); + List parameters = operation.getParameters(); + parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { + @Override + public boolean apply(@Nullable Parameter parameter) { + return !(parameter instanceof HeaderParameter); + } + })); + operation.setParameters(parameters); + return super.fromOperation(path, httpMethod, operation, definitions); + } + + private static String normalizePath(String path) { + StringBuilder builder = new StringBuilder(); + + int cursor = 0; + Matcher matcher = PATH_PARAM_PATTERN.matcher(path); + boolean found = matcher.find(); + while (found) { + String stringBeforeMatch = path.substring(cursor, matcher.start()); + builder.append(stringBeforeMatch); + + String group = matcher.group().substring(1, matcher.group().length() - 1); + group = camelize(group, true); + builder + .append("{") + .append(group) + .append("}"); + + cursor = matcher.end(); + found = matcher.find(); + } + + String stringAfterMatch = path.substring(cursor); + builder.append(stringAfterMatch); + + return builder.toString(); + } +} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index 31c055b54dc..a62c2f2c9b8 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#required}}!{{/required}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{^required}}Optional{{/required}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#required}}!{{/required}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index 8c40c3f5be7..abfea5e10fb 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -30,12 +30,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 06f10146cf6..6de26a5a1a9 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable { } {{/isEnum}}{{/vars}} {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatype}}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} + {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ + {{/description}}var {{name}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/vars}} // MARK: JSONEncodable func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{^required}}?{{/required}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From c9a9b0ad2b5d3aeb597e37f9d0d020fd306973fb Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:02:29 +0900 Subject: [PATCH 06/17] Refine authMethods description --- modules/swagger-codegen/src/main/resources/swift/api.mustache | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index abfea5e10fb..e458e6d7bca 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -21,7 +21,9 @@ extension {{projectName}}API { - {{{notes}}}{{/notes}}{{#subresourceOperation}} - subresourceOperation: {{subresourceOperation}}{{/subresourceOperation}}{{#defaultResponse}} - defaultResponse: {{defaultResponse}}{{/defaultResponse}}{{#authMethods}} - - authMethods: {{authMethods}}{{/authMethods}}{{#responseHeaders}} + - {{#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}} From ff88f7175d9cad4f45719dac9670bf8a055f6e43 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:08:08 +0900 Subject: [PATCH 07/17] Update models --- .../Classes/Swaggers/APIs/PetAPI.swift | 36 ++++++++++++++----- .../Classes/Swaggers/APIs/StoreAPI.swift | 16 +++++---- 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index 48e5f439159..efd14dfaaea 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -18,7 +18,9 @@ extension PetstoreClientAPI { - PUT /pet - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@5fd7e9cb] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: body (body) Pet object that needs to be added to the store @@ -41,7 +43,9 @@ extension PetstoreClientAPI { - POST /pet - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@58363f95] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: body (body) Pet object that needs to be added to the store @@ -64,7 +68,9 @@ extension PetstoreClientAPI { - GET /pet/findByStatus - Multiple status values can be provided with comma seperated strings - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@51887c71] + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -92,7 +98,9 @@ extension PetstoreClientAPI { - GET /pet/findByTags - Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing. - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4ede45aa] + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -120,8 +128,12 @@ extension PetstoreClientAPI { - GET /pet/{petId} - Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@62afc459, com.wordnik.swagger.codegen.CodegenSecurity@183e1ad] + - API Key: + - type: apiKey api_key + - name: api_key + - OAuth: + - type: oauth2 + - name: petstore_auth - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] @@ -148,7 +160,9 @@ extension PetstoreClientAPI { - POST /pet/{petId} - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@795525a1] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) ID of pet that needs to be updated :param: name (form) Updated name of the pet @@ -175,7 +189,9 @@ extension PetstoreClientAPI { - DELETE /pet/{petId} - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@4519ab42] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) Pet id to delete @@ -200,7 +216,9 @@ extension PetstoreClientAPI { - POST /pet/{petId}/uploadImage - - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@183a9d7f] + - OAuth: + - type: oauth2 + - name: petstore_auth :param: petId (path) ID of pet to update :param: additionalMetadata (form) Additional data to pass to server diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index 8ffedbdb39b..033fe10abea 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -18,9 +18,11 @@ extension PetstoreClientAPI { - GET /store/inventory - Returns a map of status codes to quantities - - authMethods: [com.wordnik.swagger.codegen.CodegenSecurity@303a0946] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@2e030ea9, contentType=application/xml}] + - API Key: + - type: apiKey api_key + - name: api_key + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] :returns: Promise> */ @@ -42,8 +44,8 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.397+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.400Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -66,8 +68,8 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T03:28:27.402+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T12:28:27.402Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched From e0109afc60aae68995a21d071191828ce73c59c7 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:23:54 +0900 Subject: [PATCH 08/17] Fix typo --- .../src/main/resources/swift/Models.mustache | 4 ++-- .../swagger-codegen/src/main/resources/swift/api.mustache | 4 ++-- .../swagger-codegen/src/main/resources/swift/model.mustache | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index a62c2f2c9b8..b2f72e483ad 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^supressRequired}}{{#required}}!{{/required}}{{/supressRequired}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index e458e6d7bca..fc009c63f2a 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -32,12 +32,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 6de26a5a1a9..2302a6f44a5 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -25,9 +25,9 @@ class {{classname}}: JSONEncodable { func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{#supressRequired}}?{{/supressRequired}}{{^supressRequired}}{{^required}}?{{/required}}{{/supressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } From 9e47042122eab0e3c39cedf3c1800091109c3c44 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Wed, 27 May 2015 13:24:08 +0900 Subject: [PATCH 09/17] Update models --- .../Classes/Swaggers/APIs/PetAPI.swift | 8 ++++---- .../Classes/Swaggers/APIs/StoreAPI.swift | 16 ++++++++-------- .../Classes/Swaggers/APIs/UserAPI.swift | 6 +++--- .../PetstoreClient/Classes/Swaggers/Models.swift | 4 ++-- .../Classes/Swaggers/Models/Pet.swift | 6 +++--- 5 files changed, 20 insertions(+), 20 deletions(-) diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index efd14dfaaea..b136a04f8d2 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -141,7 +141,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func getPetById(#petId: Int) -> RequestBuilder { + func getPetById(#petId: Int?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -170,7 +170,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { + func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -197,7 +197,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deletePet(#petId: Int) -> RequestBuilder { + func deletePet(#petId: Int?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -226,7 +226,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder { var path = "/pet/{petId}/uploadImage" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index 033fe10abea..ed0c5a87889 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -21,8 +21,8 @@ extension PetstoreClientAPI { - API Key: - type: apiKey api_key - name: api_key - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@710b8fa2, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] + - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] :returns: Promise> */ @@ -44,8 +44,8 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.188+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.190Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -68,14 +68,14 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:07:45.191+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:07:45.192Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getOrderById(#orderId: String) -> RequestBuilder { + func getOrderById(#orderId: String?) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -99,7 +99,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteOrder(#orderId: String) -> RequestBuilder { + func deleteOrder(#orderId: String?) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift index aed405c7bb0..812d823459d 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -141,7 +141,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func getUserByName(#username: String) -> RequestBuilder { + func getUserByName(#username: String?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -166,7 +166,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updateUser(#username: String, body: User?) -> RequestBuilder { + func updateUser(#username: String?, body: User?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -189,7 +189,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteUser(#username: String) -> RequestBuilder { + func deleteUser(#username: String?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift index 54e38e75bfe..d8ef5b109c2 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models.swift @@ -149,8 +149,8 @@ class Decoders { var instance = Pet() instance.id = Decoders.decodeOptional(clazz: Int.self, source: sourceDictionary["id"]) instance.category = Decoders.decodeOptional(clazz: Category.self, source: sourceDictionary["category"]) - instance.name = Decoders.decode(clazz: String.self, source: sourceDictionary["name"]!) - instance.photoUrls = Decoders.decode(clazz: Array.self, source: sourceDictionary["photoUrls"]!) + instance.name = Decoders.decodeOptional(clazz: String.self, source: sourceDictionary["name"]) + instance.photoUrls = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["photoUrls"]) instance.tags = Decoders.decodeOptional(clazz: Array.self, source: sourceDictionary["tags"]) instance.status = (sourceDictionary["status"] as? String).map { Pet.Status(rawValue: $0)! } return instance diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift index ff66ea2ea43..0baac38a285 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Models/Pet.swift @@ -18,8 +18,8 @@ class Pet: JSONEncodable { var id: Int? var category: Category? - var name: String! - var photoUrls: [String]! + var name: String? + var photoUrls: [String]? var tags: [Tag]? /** pet status in the store */ var status: Status? @@ -31,7 +31,7 @@ class Pet: JSONEncodable { nillableDictionary["id"] = self.id nillableDictionary["category"] = self.category?.encodeToJSON() nillableDictionary["name"] = self.name - nillableDictionary["photoUrls"] = self.photoUrls.encodeToJSON() + nillableDictionary["photoUrls"] = self.photoUrls?.encodeToJSON() nillableDictionary["tags"] = self.tags?.encodeToJSON() nillableDictionary["status"] = self.status?.rawValue let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] From 8540ac71c8562959ab1b2cb71d1d50f0e97a2104 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:04:22 +0900 Subject: [PATCH 10/17] Update swift code generation script --- bin/swift-petstore.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bin/swift-petstore.sh b/bin/swift-petstore.sh index ce6a7e702f0..4436ed8774d 100755 --- a/bin/swift-petstore.sh +++ b/bin/swift-petstore.sh @@ -28,4 +28,4 @@ fi export JAVA_OPTS="${JAVA_OPTS} -XX:MaxPermSize=256M -Xmx1024M -DloggerPath=conf/log4j.properties" ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift" -java -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags +java -DsuppressRequired=true -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags From 24465d2df493b501845e191f1b0dca74449b9a94 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:04:45 +0900 Subject: [PATCH 11/17] Change model naming --- .../wordnik/swagger/codegen/languages/SwiftGenerator.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java index 697bdefef8f..f67834c5540 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -127,7 +127,7 @@ public SwiftGenerator() { @Override public String escapeReservedWord(String name) { - return "_" + name; // add an underscore to the name + return "Swagger" + name; // add an underscore to the name } @Override @@ -202,6 +202,9 @@ public CodegenProperty fromProperty(String name, Property p) { codegenProperty.allowableValues.put("values", swiftEnums); codegenProperty.datatypeWithEnum = StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { + codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); + } } return codegenProperty; } From bcab55e3efc07feeaafb301d681937b873ea07a0 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:05:02 +0900 Subject: [PATCH 12/17] Tighten parameter requirement --- modules/swagger-codegen/src/main/resources/swift/api.mustache | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/swagger-codegen/src/main/resources/swift/api.mustache b/modules/swagger-codegen/src/main/resources/swift/api.mustache index fc009c63f2a..3caec601879 100644 --- a/modules/swagger-codegen/src/main/resources/swift/api.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/api.mustache @@ -32,12 +32,12 @@ extension {{projectName}}API { :returns: Promise> {{description}} */ - func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { + func {{operationId}}({{#allParams}}{{^secondaryParam}}#{{/secondaryParam}}{{paramName}}: {{{dataType}}}{{^required}}?{{/required}}{{#hasMore}}, {{/hasMore}}{{/allParams}}) -> RequestBuilder<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}Void{{/returnType}}> { {{^pathParams}}let{{/pathParams}}{{#pathParams}}{{^secondaryParam}}var{{/secondaryParam}}{{/pathParams}} path = "{{path}}"{{#pathParams}} path = path.stringByReplacingOccurrencesOfString("{{=<% %>=}}{<%paramName%>}<%={{ }}=%>", withString: "\({{paramName}})", options: .LiteralSearch, range: nil){{/pathParams}} let url = {{projectName}}API.basePath + path {{#bodyParam}} - let parameters = {{paramName}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} + let parameters = {{paramName}}{{^required}}?{{/required}}.encodeToJSON() as? [String:AnyObject]{{/bodyParam}}{{^bodyParam}} let nillableParameters: [String:AnyObject?] = {{^queryParams}}[:]{{/queryParams}}{{#queryParams}}{{^secondaryParam}}[{{/secondaryParam}} "{{paramName}}": {{paramName}}{{#hasMore}},{{/hasMore}}{{^hasMore}} ]{{/hasMore}}{{/queryParams}} From febaa340e3cadea6f5689589dd7c207cef8bdbd9 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Mon, 22 Jun 2015 19:05:32 +0900 Subject: [PATCH 13/17] Treat object as String (temporary measure) --- .../com/wordnik/swagger/codegen/languages/SwiftGenerator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java index f67834c5540..4f2bb6fa24b 100644 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java @@ -119,7 +119,7 @@ public SwiftGenerator() { typeMapping.put("float", "Float"); typeMapping.put("number", "Double"); typeMapping.put("double", "Double"); - typeMapping.put("object", "AnyObject"); + typeMapping.put("object", "String"); typeMapping.put("file", "NSData"); importMapping = new HashMap(); From fa3a9a9d61a880a9dbf8589edf1dd40b81093c69 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 10:22:05 +0900 Subject: [PATCH 14/17] Change class package --- .../codegen/languages/SwiftGenerator.java | 259 ----------- .../codegen/languages/SwiftGenerator.java | 422 +++++++++--------- 2 files changed, 209 insertions(+), 472 deletions(-) delete mode 100644 modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java diff --git a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java deleted file mode 100644 index 4f2bb6fa24b..00000000000 --- a/modules/swagger-codegen/src/main/java/com/wordnik/swagger/codegen/languages/SwiftGenerator.java +++ /dev/null @@ -1,259 +0,0 @@ -package com.wordnik.swagger.codegen.languages; - -import com.google.common.base.Predicate; -import com.google.common.collect.Iterators; -import com.google.common.collect.Lists; -import com.wordnik.swagger.codegen.*; -import com.wordnik.swagger.models.Model; -import com.wordnik.swagger.models.Operation; -import com.wordnik.swagger.models.parameters.HeaderParameter; -import com.wordnik.swagger.models.parameters.Parameter; -import com.wordnik.swagger.models.properties.*; -import org.apache.commons.lang.StringUtils; - -import javax.annotation.Nullable; -import java.util.*; -import java.io.File; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { - private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; - - public CodegenType getTag() { - return CodegenType.CLIENT; - } - - public String getName() { - return "swift"; - } - - public String getHelp() { - return "Generates a swift client library."; - } - - public SwiftGenerator() { - super(); - outputFolder = "generated-code/swift"; - modelTemplateFiles.put("model.mustache", ".swift"); - apiTemplateFiles.put("api.mustache", ".swift"); - templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; - - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); - - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } - - // Make all the variable optional - String suppressRequired = System.getProperty("suppressRequired"); - if (suppressRequired != null) { - additionalProperties.put("suppressRequired", suppressRequired); - } - - sourceFolder = appName + "/" + sourceFolder; - - 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("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - - languageSpecificPrimitives = new HashSet( - Arrays.asList( - "Int", - "Float", - "Double", - "Bool", - "Void", - "String", - "Character") - ); - defaultIncludes = new HashSet( - Arrays.asList( - "NSDate", - "Array", - "Dictionary", - "Set", - "Any", - "Empty", - "AnyObject") - ); - reservedWords = new HashSet( - Arrays.asList( - "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") - ); - - typeMapping = new HashMap(); - typeMapping.put("array", "Array"); - typeMapping.put("List", "Array"); - typeMapping.put("map", "Dictionary"); - typeMapping.put("date", "NSDate"); - typeMapping.put("Date", "NSDate"); - typeMapping.put("DateTime", "NSDate"); - typeMapping.put("boolean", "Bool"); - typeMapping.put("string", "String"); - typeMapping.put("char", "Character"); - typeMapping.put("short", "Int"); - typeMapping.put("int", "Int"); - typeMapping.put("long", "Int"); - typeMapping.put("integer", "Int"); - typeMapping.put("Integer", "Int"); - typeMapping.put("float", "Float"); - typeMapping.put("number", "Double"); - typeMapping.put("double", "Double"); - typeMapping.put("object", "String"); - typeMapping.put("file", "NSData"); - - importMapping = new HashMap(); - } - - @Override - public String escapeReservedWord(String name) { - return "Swagger" + name; // add an underscore to the name - } - - @Override - public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); - } - - @Override - public String apiFileFolder() { - return outputFolder + "/" + 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 = null; - if (typeMapping.containsKey(swaggerType)) { - type = typeMapping.get(swaggerType); - if (languageSpecificPrimitives.contains(type)) - return toModelName(type); - } else - type = swaggerType; - return toModelName(type); - } - - @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 "[String:" + inner + "]"; - } else if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - String inner = getSwaggerType(ap.getItems()); - return "[" + inner + "]"; - } - return null; - } - - @Override - public CodegenProperty fromProperty(String name, Property p) { - CodegenProperty codegenProperty = super.fromProperty(name, p); - if (codegenProperty.isEnum) { - List> swiftEnums = new ArrayList>(); - List values = (List) codegenProperty.allowableValues.get("values"); - for (String value : values) { - Map map = new HashMap(); - map.put("enum", StringUtils.capitalize(value)); - map.put("raw", value); - swiftEnums.add(map); - } - codegenProperty.allowableValues.put("values", swiftEnums); - codegenProperty.datatypeWithEnum = - StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); - if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { - codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); - } - } - return codegenProperty; - } - - @Override - public String toApiName(String name) { - if(name.length() == 0) - return "DefaultAPI"; - return initialCaps(name) + "API"; - } - - @Override - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { - path = normalizePath(path); - List parameters = operation.getParameters(); - parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { - @Override - public boolean apply(@Nullable Parameter parameter) { - return !(parameter instanceof HeaderParameter); - } - })); - operation.setParameters(parameters); - return super.fromOperation(path, httpMethod, operation, definitions); - } - - private static String normalizePath(String path) { - StringBuilder builder = new StringBuilder(); - - int cursor = 0; - Matcher matcher = PATH_PARAM_PATTERN.matcher(path); - boolean found = matcher.find(); - while (found) { - String stringBeforeMatch = path.substring(cursor, matcher.start()); - builder.append(stringBeforeMatch); - - String group = matcher.group().substring(1, matcher.group().length() - 1); - group = camelize(group, true); - builder - .append("{") - .append(group) - .append("}"); - - cursor = matcher.end(); - found = matcher.find(); - } - - String stringAfterMatch = path.substring(cursor); - builder.append(stringAfterMatch); - - return builder.toString(); - } -} \ No newline at end of file diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java index 2b384f36a7d..15ca6dc1556 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java @@ -3,12 +3,7 @@ import com.google.common.base.Predicate; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; -import io.swagger.codegen.CodegenConfig; -import io.swagger.codegen.CodegenOperation; -import io.swagger.codegen.CodegenProperty; -import io.swagger.codegen.CodegenType; -import io.swagger.codegen.DefaultCodegen; -import io.swagger.codegen.SupportingFile; +import io.swagger.codegen.*; import io.swagger.models.Model; import io.swagger.models.Operation; import io.swagger.models.parameters.HeaderParameter; @@ -19,247 +14,248 @@ import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; +import java.util.*; import java.io.File; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { - private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; + private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected String sourceFolder = "Classes/Swaggers"; - public SwiftGenerator() { - super(); - outputFolder = "generated-code/swift"; - modelTemplateFiles.put("model.mustache", ".swift"); - apiTemplateFiles.put("api.mustache", ".swift"); - templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; + public CodegenType getTag() { + return CodegenType.CLIENT; + } - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); + public String getName() { + return "swift"; + } - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } + public String getHelp() { + return "Generates a swift client library."; + } - sourceFolder = appName + "/" + sourceFolder; + public SwiftGenerator() { + super(); + outputFolder = "generated-code/swift"; + modelTemplateFiles.put("model.mustache", ".swift"); + apiTemplateFiles.put("api.mustache", ".swift"); + templateDir = "swift"; + apiPackage = "/APIs"; + modelPackage = "/Models"; - 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("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - - languageSpecificPrimitives = new HashSet( - Arrays.asList( - "Int", - "Float", - "Double", - "Bool", - "Void", - "String", - "Character") - ); - defaultIncludes = new HashSet( - Arrays.asList( - "NSDate", - "Array", - "Dictionary", - "Set", - "Any", - "Empty", - "AnyObject") - ); - reservedWords = new HashSet( - Arrays.asList( - "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") - ); + // Inject application name + String appName = System.getProperty("appName"); + if (appName == null) { + appName = "SwaggerClient"; + } + additionalProperties.put("projectName", appName); - typeMapping = new HashMap(); - typeMapping.put("array", "Array"); - typeMapping.put("List", "Array"); - typeMapping.put("map", "Dictionary"); - typeMapping.put("date", "NSDate"); - typeMapping.put("Date", "NSDate"); - typeMapping.put("DateTime", "NSDate"); - typeMapping.put("boolean", "Bool"); - typeMapping.put("string", "String"); - typeMapping.put("char", "Character"); - typeMapping.put("short", "Int"); - typeMapping.put("int", "Int"); - typeMapping.put("long", "Int"); - typeMapping.put("integer", "Int"); - typeMapping.put("Integer", "Int"); - typeMapping.put("float", "Float"); - typeMapping.put("number", "Double"); - typeMapping.put("double", "Double"); - typeMapping.put("object", "AnyObject"); - typeMapping.put("file", "NSData"); + // Inject base url override + String basePathOverride = System.getProperty("basePathOverride"); + if (basePathOverride != null) { + additionalProperties.put("basePathOverride", basePathOverride); + } - importMapping = new HashMap(); + // Make all the variable optional + String suppressRequired = System.getProperty("suppressRequired"); + if (suppressRequired != null) { + additionalProperties.put("suppressRequired", suppressRequired); } - private static String normalizePath(String path) { - StringBuilder builder = new StringBuilder(); + sourceFolder = appName + "/" + sourceFolder; - int cursor = 0; - Matcher matcher = PATH_PARAM_PATTERN.matcher(path); - boolean found = matcher.find(); - while (found) { - String stringBeforeMatch = path.substring(cursor, matcher.start()); - builder.append(stringBeforeMatch); + 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("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - String group = matcher.group().substring(1, matcher.group().length() - 1); - group = camelize(group, true); - builder - .append("{") - .append(group) - .append("}"); + languageSpecificPrimitives = new HashSet( + Arrays.asList( + "Int", + "Float", + "Double", + "Bool", + "Void", + "String", + "Character") + ); + defaultIncludes = new HashSet( + Arrays.asList( + "NSDate", + "Array", + "Dictionary", + "Set", + "Any", + "Empty", + "AnyObject") + ); + reservedWords = new HashSet( + Arrays.asList( + "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") + ); - cursor = matcher.end(); - found = matcher.find(); - } + typeMapping = new HashMap(); + typeMapping.put("array", "Array"); + typeMapping.put("List", "Array"); + typeMapping.put("map", "Dictionary"); + typeMapping.put("date", "NSDate"); + typeMapping.put("Date", "NSDate"); + typeMapping.put("DateTime", "NSDate"); + typeMapping.put("boolean", "Bool"); + typeMapping.put("string", "String"); + typeMapping.put("char", "Character"); + typeMapping.put("short", "Int"); + typeMapping.put("int", "Int"); + typeMapping.put("long", "Int"); + typeMapping.put("integer", "Int"); + typeMapping.put("Integer", "Int"); + typeMapping.put("float", "Float"); + typeMapping.put("number", "Double"); + typeMapping.put("double", "Double"); + typeMapping.put("object", "String"); + typeMapping.put("file", "NSData"); - String stringAfterMatch = path.substring(cursor); - builder.append(stringAfterMatch); + importMapping = new HashMap(); + } - return builder.toString(); - } + @Override + public String escapeReservedWord(String name) { + return "Swagger" + name; // add an underscore to the name + } - public CodegenType getTag() { - return CodegenType.CLIENT; - } + @Override + public String modelFileFolder() { + return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + } - public String getName() { - return "swift"; - } + @Override + public String apiFileFolder() { + return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + } - public String getHelp() { - return "Generates a swift client library."; + @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 escapeReservedWord(String name) { - return "_" + name; // add an underscore to the name - } + @Override + public String getSwaggerType(Property p) { + String swaggerType = super.getSwaggerType(p); + String type = null; + if (typeMapping.containsKey(swaggerType)) { + type = typeMapping.get(swaggerType); + if (languageSpecificPrimitives.contains(type)) + return toModelName(type); + } else + type = swaggerType; + return toModelName(type); + } - @Override - public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); - } + @Override + public String toDefaultValue(Property p) { + // nil + return null; + } - @Override - public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + @Override + public String toInstantiationType(Property p) { + if (p instanceof MapProperty) { + MapProperty ap = (MapProperty) p; + String inner = getSwaggerType(ap.getAdditionalProperties()); + return "[String:" + inner + "]"; + } else if (p instanceof ArrayProperty) { + ArrayProperty ap = (ArrayProperty) p; + String inner = getSwaggerType(ap.getItems()); + return "[" + inner + "]"; } + return null; + } - @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 CodegenProperty fromProperty(String name, Property p) { + CodegenProperty codegenProperty = super.fromProperty(name, p); + if (codegenProperty.isEnum) { + List> swiftEnums = new ArrayList>(); + List values = (List) codegenProperty.allowableValues.get("values"); + for (String value : values) { + Map map = new HashMap(); + map.put("enum", StringUtils.capitalize(value)); + map.put("raw", value); + swiftEnums.add(map); + } + codegenProperty.allowableValues.put("values", swiftEnums); + codegenProperty.datatypeWithEnum = + StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); + if (reservedWords.contains(codegenProperty.datatypeWithEnum)) { + codegenProperty.datatypeWithEnum = escapeReservedWord(codegenProperty.datatypeWithEnum); + } } + return codegenProperty; + } - @Override - public String getSwaggerType(Property p) { - String swaggerType = super.getSwaggerType(p); - String type = null; - if (typeMapping.containsKey(swaggerType)) { - type = typeMapping.get(swaggerType); - if (languageSpecificPrimitives.contains(type)) { - return toModelName(type); - } - } else { - type = swaggerType; - } - return toModelName(type); - } + @Override + public String toApiName(String name) { + if(name.length() == 0) + return "DefaultAPI"; + return initialCaps(name) + "API"; + } - @Override - public String toDefaultValue(Property p) { - // nil - return null; - } + @Override + public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { + path = normalizePath(path); + List parameters = operation.getParameters(); + parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { + @Override + public boolean apply(@Nullable Parameter parameter) { + return !(parameter instanceof HeaderParameter); + } + })); + operation.setParameters(parameters); + return super.fromOperation(path, httpMethod, operation, definitions); + } - @Override - public String toInstantiationType(Property p) { - if (p instanceof MapProperty) { - MapProperty ap = (MapProperty) p; - String inner = getSwaggerType(ap.getAdditionalProperties()); - return "[String:" + inner + "]"; - } else if (p instanceof ArrayProperty) { - ArrayProperty ap = (ArrayProperty) p; - String inner = getSwaggerType(ap.getItems()); - return "[" + inner + "]"; - } - return null; - } + private static String normalizePath(String path) { + StringBuilder builder = new StringBuilder(); - @Override - public CodegenProperty fromProperty(String name, Property p) { - CodegenProperty codegenProperty = super.fromProperty(name, p); - if (codegenProperty.isEnum) { - List> swiftEnums = new ArrayList>(); - List values = (List) codegenProperty.allowableValues.get("values"); - for (String value : values) { - Map map = new HashMap(); - map.put("enum", StringUtils.capitalize(value)); - map.put("raw", value); - swiftEnums.add(map); - } - codegenProperty.allowableValues.put("values", swiftEnums); - codegenProperty.datatypeWithEnum = - StringUtils.left(codegenProperty.datatypeWithEnum, codegenProperty.datatypeWithEnum.length() - "Enum".length()); - } - return codegenProperty; - } + int cursor = 0; + Matcher matcher = PATH_PARAM_PATTERN.matcher(path); + boolean found = matcher.find(); + while (found) { + String stringBeforeMatch = path.substring(cursor, matcher.start()); + builder.append(stringBeforeMatch); - @Override - public String toApiName(String name) { - if (name.length() == 0) { - return "DefaultAPI"; - } - return initialCaps(name) + "API"; - } + String group = matcher.group().substring(1, matcher.group().length() - 1); + group = camelize(group, true); + builder + .append("{") + .append(group) + .append("}"); - @Override - public CodegenOperation fromOperation(String path, String httpMethod, Operation operation, Map definitions) { - path = normalizePath(path); - List parameters = operation.getParameters(); - parameters = Lists.newArrayList(Iterators.filter(parameters.iterator(), new Predicate() { - @Override - public boolean apply(@Nullable Parameter parameter) { - return !(parameter instanceof HeaderParameter); - } - })); - operation.setParameters(parameters); - return super.fromOperation(path, httpMethod, operation, definitions); + cursor = matcher.end(); + found = matcher.find(); } + + String stringAfterMatch = path.substring(cursor); + builder.append(stringAfterMatch); + + return builder.toString(); + } } \ No newline at end of file From 79e31a5761860edaa860b2f359340d2032ac35e3 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 11:59:49 +0900 Subject: [PATCH 15/17] Add a workaround against void forcibly being converted to string --- .../main/resources/swift/AlamofireImplementations.mustache | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index 37edceea13c..edc7a51a169 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -61,6 +61,12 @@ class AlamofireRequestBuilder: RequestBuilder { let response = Response(response: res!, body: body) defer.fulfill(response) return + } else if "" is T { + // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release + // https://github.com/swagger-api/swagger-parser/pull/34 + let response = Response(response: res!, body: "" as! T) + defer.fulfill(response) + return } defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) From aec4af1b8824cdb8b63d65760fd5dd87b86f1732 Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Tue, 23 Jun 2015 16:10:21 +0900 Subject: [PATCH 16/17] Replace slash with File.separator --- .../swagger/codegen/languages/SwiftGenerator.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java index 15ca6dc1556..96f0666df52 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java @@ -21,7 +21,7 @@ public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); - protected String sourceFolder = "Classes/Swaggers"; + protected String sourceFolder = "Classes" + File.separator + "Swaggers"; public CodegenType getTag() { return CodegenType.CLIENT; @@ -37,12 +37,12 @@ public String getHelp() { public SwiftGenerator() { super(); - outputFolder = "generated-code/swift"; + outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); apiTemplateFiles.put("api.mustache", ".swift"); templateDir = "swift"; - apiPackage = "/APIs"; - modelPackage = "/Models"; + apiPackage = File.separator + "APIs"; + modelPackage = File.separator + "Models"; // Inject application name String appName = System.getProperty("appName"); @@ -63,7 +63,7 @@ public SwiftGenerator() { additionalProperties.put("suppressRequired", suppressRequired); } - sourceFolder = appName + "/" + sourceFolder; + sourceFolder = appName + File.separator + sourceFolder; supportingFiles.add(new SupportingFile("Cartfile.mustache", "", "Cartfile")); supportingFiles.add(new SupportingFile("APIHelper.mustache", sourceFolder, "APIHelper.swift")); @@ -134,12 +134,12 @@ public String escapeReservedWord(String name) { @Override public String modelFileFolder() { - return outputFolder + "/" + sourceFolder + modelPackage().replace('.', File.separatorChar); + return outputFolder + File.separator + sourceFolder + modelPackage().replace('.', File.separatorChar); } @Override public String apiFileFolder() { - return outputFolder + "/" + sourceFolder + apiPackage().replace('.', File.separatorChar); + return outputFolder + File.separator + sourceFolder + apiPackage().replace('.', File.separatorChar); } @Override From 91af76cf4187f2f60c3e200cbca3a4ce5364b7ec Mon Sep 17 00:00:00 2001 From: kubo_takaichi Date: Sat, 27 Jun 2015 21:04:01 +0900 Subject: [PATCH 17/17] Use CLI option --- README.md | 2 +- bin/swift-petstore.json | 4 + bin/swift-petstore.sh | 4 +- ...{SwiftGenerator.java => SwiftCodegen.java} | 85 ++++++++---- .../services/io.swagger.codegen.CodegenConfig | 2 +- .../src/main/resources/swift/APIs.mustache | 10 +- .../swift/AlamofireImplementations.mustache | 18 +-- .../main/resources/swift/Extensions.mustache | 18 ++- .../src/main/resources/swift/Models.mustache | 4 +- .../src/main/resources/swift/model.mustache | 10 +- .../petstore/swift/PetstoreClient/Cartfile | 2 - .../Classes/Swaggers/APIs.swift | 10 +- .../Classes/Swaggers/APIs/PetAPI.swift | 128 ++++++++++++++++-- .../Classes/Swaggers/APIs/StoreAPI.swift | 76 +++++++++-- .../Classes/Swaggers/APIs/UserAPI.swift | 18 ++- .../Swaggers/AlamofireImplementations.swift | 22 +-- .../Classes/Swaggers/Extensions.swift | 14 ++ 17 files changed, 326 insertions(+), 101 deletions(-) create mode 100644 bin/swift-petstore.json rename modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/{SwiftGenerator.java => SwiftCodegen.java} (78%) delete mode 100644 samples/client/petstore/swift/PetstoreClient/Cartfile diff --git a/README.md b/README.md index f2c44ebf718..2fb525528a3 100644 --- a/README.md +++ b/README.md @@ -183,7 +183,7 @@ StaticDocCodegen.java StaticHtmlGenerator.java SwaggerGenerator.java SwaggerYamlGenerator.java -SwiftGenerator.java +SwiftCodegen.java TizenClientCodegen.java ``` diff --git a/bin/swift-petstore.json b/bin/swift-petstore.json new file mode 100644 index 00000000000..700fdeff061 --- /dev/null +++ b/bin/swift-petstore.json @@ -0,0 +1,4 @@ +{ + "projectName": "PetstoreClient", + "responseAs": "PromiseKit" +} \ No newline at end of file diff --git a/bin/swift-petstore.sh b/bin/swift-petstore.sh index 4436ed8774d..96433e5b72d 100755 --- a/bin/swift-petstore.sh +++ b/bin/swift-petstore.sh @@ -26,6 +26,6 @@ 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/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -o samples/client/petstore/swift" +ags="$@ generate -t modules/swagger-codegen/src/main/resources/swift -i modules/swagger-codegen/src/test/resources/2_0/petstore.json -l swift -c ./bin/swift-petstore.json -o samples/client/petstore/swift" -java -DsuppressRequired=true -DappName=PetstoreClient $JAVA_OPTS -jar $executable $ags +java $JAVA_OPTS -jar $executable $ags diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java similarity index 78% rename from modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java rename to modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java index 96f0666df52..5d4f5f341a7 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftGenerator.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/SwiftCodegen.java @@ -11,6 +11,7 @@ import io.swagger.models.properties.ArrayProperty; import io.swagger.models.properties.MapProperty; import io.swagger.models.properties.Property; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import javax.annotation.Nullable; @@ -19,8 +20,13 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -public class SwiftGenerator extends DefaultCodegen implements CodegenConfig { +public class SwiftCodegen extends DefaultCodegen implements CodegenConfig { private static final Pattern PATH_PARAM_PATTERN = Pattern.compile("\\{[a-zA-Z_]+\\}"); + protected static final String LIBRARY_PROMISE_KIT = "PromiseKit"; + protected static final String[] RESPONSE_LIBRARIES = { LIBRARY_PROMISE_KIT }; + protected String projectName = "SwaggerClient"; + protected boolean unwrapRequired = false; + protected String[] responseAs = new String[0]; protected String sourceFolder = "Classes" + File.separator + "Swaggers"; public CodegenType getTag() { @@ -35,7 +41,7 @@ public String getHelp() { return "Generates a swift client library."; } - public SwiftGenerator() { + public SwiftCodegen() { super(); outputFolder = "generated-code" + File.separator + "swift"; modelTemplateFiles.put("model.mustache", ".swift"); @@ -44,34 +50,6 @@ public SwiftGenerator() { apiPackage = File.separator + "APIs"; modelPackage = File.separator + "Models"; - // Inject application name - String appName = System.getProperty("appName"); - if (appName == null) { - appName = "SwaggerClient"; - } - additionalProperties.put("projectName", appName); - - // Inject base url override - String basePathOverride = System.getProperty("basePathOverride"); - if (basePathOverride != null) { - additionalProperties.put("basePathOverride", basePathOverride); - } - - // Make all the variable optional - String suppressRequired = System.getProperty("suppressRequired"); - if (suppressRequired != null) { - additionalProperties.put("suppressRequired", suppressRequired); - } - - sourceFolder = appName + File.separator + sourceFolder; - - 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("Extensions.mustache", sourceFolder, "Extensions.swift")); - supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); - supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); - languageSpecificPrimitives = new HashSet( Arrays.asList( "Int", @@ -125,6 +103,53 @@ public SwiftGenerator() { typeMapping.put("file", "NSData"); importMapping = new HashMap(); + + cliOptions.add(new CliOption("projectName", "Project name in Xcode")); + cliOptions.add(new CliOption("responseAs", "Optionally use libraries to manage response. Currently " + + StringUtils.join(RESPONSE_LIBRARIES, ", ") + " are available.")); + cliOptions.add(new CliOption("unwrapRequired", "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")); + } + + @Override + public void processOpts() { + super.processOpts(); + + // Setup project name + if (additionalProperties.containsKey("projectName")) { + projectName = (String) additionalProperties.get("projectName"); + } else { + additionalProperties.put("projectName", projectName); + } + sourceFolder = projectName + File.separator + sourceFolder; + + // Setup unwrapRequired option, which makes all the properties with "required" non-optional + if (additionalProperties.containsKey("unwrapRequired")) { + unwrapRequired = Boolean.parseBoolean(String.valueOf(additionalProperties.get("unwrapRequired"))); + } + additionalProperties.put("unwrapRequired", unwrapRequired); + + // Setup unwrapRequired option, which makes all the properties with "required" non-optional + if (additionalProperties.containsKey("responseAs")) { + Object responseAsObject = additionalProperties.get("responseAs"); + if (responseAsObject instanceof String) { + responseAs = ((String)responseAsObject).split(","); + } else { + responseAs = (String[]) responseAsObject; + } + } + additionalProperties.put("responseAs", responseAs); + if (ArrayUtils.contains(responseAs, LIBRARY_PROMISE_KIT)) { + additionalProperties.put("usePromiseKit", true); + } + + 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("Extensions.mustache", sourceFolder, "Extensions.swift")); + supportingFiles.add(new SupportingFile("Models.mustache", sourceFolder, "Models.swift")); + supportingFiles.add(new SupportingFile("APIs.mustache", sourceFolder, "APIs.swift")); } @Override diff --git a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig index 7360129285e..29c7ed0f729 100644 --- a/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig +++ b/modules/swagger-codegen/src/main/resources/META-INF/services/io.swagger.codegen.CodegenConfig @@ -21,7 +21,7 @@ io.swagger.codegen.languages.StaticDocCodegen io.swagger.codegen.languages.StaticHtmlGenerator io.swagger.codegen.languages.SwaggerGenerator io.swagger.codegen.languages.SwaggerYamlGenerator -io.swagger.codegen.languages.SwiftGenerator +io.swagger.codegen.languages.SwiftCodegen io.swagger.codegen.languages.TizenClientCodegen io.swagger.codegen.languages.TypeScriptAngularClientCodegen io.swagger.codegen.languages.TypeScriptNodeClientCodegen diff --git a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache index d9fcb84c125..e473915cf24 100644 --- a/modules/swagger-codegen/src/main/resources/swift/APIs.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/APIs.mustache @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class {{projectName}}API { - static let basePath = "{{^basePathOverride}}{{basePath}}{{/basePathOverride}}{{basePathOverride}}" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = {{projectName}}API.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache index edc7a51a169..61e2bf2886d 100644 --- a/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/AlamofireImplementations.mustache @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,43 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) let response = Response(response: res!, body: body) - defer.fulfill(response) + completion(response: response, erorr: nil) return } else if "" is T { // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release // https://github.com/swagger-api/swagger-parser/pull/34 let response = Response(response: res!, body: "" as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } - defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) } - return defer.promise } private func buildHeaders() -> [String: AnyObject] { @@ -83,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache index a06ebae7026..801e90514ff 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Extensions.mustache @@ -4,8 +4,8 @@ // https://github.com/swagger-api/swagger-codegen // -import Alamofire -import PromiseKit +import Alamofire{{#usePromiseKit}} +import PromiseKit{{/usePromiseKit}} extension Bool: JSONEncodable { func encodeToJSON() -> AnyObject { return self } @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +{{#usePromiseKit}}extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +}{{/usePromiseKit}} diff --git a/modules/swagger-codegen/src/main/resources/swift/Models.mustache b/modules/swagger-codegen/src/main/resources/swift/Models.mustache index b2f72e483ad..f832cdab9a4 100644 --- a/modules/swagger-codegen/src/main/resources/swift/Models.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/Models.mustache @@ -121,8 +121,8 @@ class Decoders { Decoders.addDecoder(clazz: {{{classname}}}.self) { (source: AnyObject) -> {{{classname}}} in let sourceDictionary = source as! [NSObject:AnyObject] var instance = {{classname}}(){{#vars}}{{#isEnum}} - instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}} {{/isEnum}}{{^isEnum}} - instance.{{name}} = Decoders.decode{{#suppressRequired}}Optional{{/suppressRequired}}{{^suppressRequired}}{{^required}}Optional{{/required}}{{/suppressRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{^suppressRequired}}{{#required}}!{{/required}}{{/suppressRequired}}){{/isEnum}}{{/vars}} + instance.{{name}} = (sourceDictionary["{{name}}"] as? String).map { {{classname}}.{{datatypeWithEnum}}(rawValue: $0)! }{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}} {{/isEnum}}{{^isEnum}} + instance.{{name}} = Decoders.decode{{^unwrapRequired}}Optional{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}Optional{{/required}}{{/unwrapRequired}}(clazz: {{{baseType}}}.self, source: sourceDictionary["{{name}}"]{{#unwrapRequired}}{{#required}}!{{/required}}{{/unwrapRequired}}){{/isEnum}}{{/vars}} return instance }{{/model}} {{/models}} diff --git a/modules/swagger-codegen/src/main/resources/swift/model.mustache b/modules/swagger-codegen/src/main/resources/swift/model.mustache index 2302a6f44a5..bcd4702fb3b 100644 --- a/modules/swagger-codegen/src/main/resources/swift/model.mustache +++ b/modules/swagger-codegen/src/main/resources/swift/model.mustache @@ -17,17 +17,17 @@ class {{classname}}: JSONEncodable { } {{/isEnum}}{{/vars}} {{#vars}}{{#isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ - {{/description}}var {{name}}: {{{datatype}}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/suppressRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} + {{/description}}var {{name}}: {{{datatypeWithEnum}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}}{{^isEnum}}{{#description}}/** {{description}} */ + {{/description}}var {{name}}: {{{datatype}}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{#required}}!{{/required}}{{/unwrapRequired}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}{{/isEnum}} {{/vars}} // MARK: JSONEncodable func encodeToJSON() -> AnyObject { var nillableDictionary = [String:AnyObject?](){{#vars}}{{#isNotContainer}}{{#isPrimitiveType}}{{^isEnum}} nillableDictionary["{{name}}"] = self.{{name}}{{/isEnum}}{{/isPrimitiveType}}{{#isEnum}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} - nillableDictionary["{{name}}"] = self.{{name}}{{#suppressRequired}}?{{/suppressRequired}}{{^suppressRequired}}{{^required}}?{{/required}}{{/suppressRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.rawValue{{/isEnum}}{{^isPrimitiveType}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isPrimitiveType}}{{/isNotContainer}}{{#isContainer}} + nillableDictionary["{{name}}"] = self.{{name}}{{^unwrapRequired}}?{{/unwrapRequired}}{{#unwrapRequired}}{{^required}}?{{/required}}{{/unwrapRequired}}.encodeToJSON(){{/isContainer}}{{/vars}} let dictionary: [String:AnyObject] = APIHelper.rejectNil(nillableDictionary) ?? [:] return dictionary } diff --git a/samples/client/petstore/swift/PetstoreClient/Cartfile b/samples/client/petstore/swift/PetstoreClient/Cartfile deleted file mode 100644 index 245a690a74b..00000000000 --- a/samples/client/petstore/swift/PetstoreClient/Cartfile +++ /dev/null @@ -1,2 +0,0 @@ -github "Alamofire/Alamofire" >= 1.2 -github "mxcl/PromiseKit" \ No newline at end of file diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift index 75138ff689a..e473915cf24 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs.swift @@ -5,10 +5,9 @@ // import Foundation -import PromiseKit -class PetstoreClientAPI { - static let basePath = "http://petstore.swagger.io/v2" +class OneteamAPI { + static let basePath = "http://ec2-52-68-31-200.ap-northeast-1.compute.amazonaws.com/" static var credential: NSURLCredential? static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() } @@ -44,7 +43,7 @@ class RequestBuilder { self.isBody = isBody } - func execute() -> Promise> { fatalError("Not implemented") } + func execute(completion: (response: Response?, erorr: NSError?) -> Void) { } func addHeader(#name: String, value: String) -> Self { if !value.isEmpty { @@ -54,7 +53,7 @@ class RequestBuilder { } func addCredential() -> Self { - self.credential = PetstoreClientAPI.credential + self.credential = OneteamAPI.credential return self } } @@ -63,4 +62,3 @@ protocol RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift index b136a04f8d2..5202240bbc9 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/PetAPI.swift @@ -71,8 +71,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: status (query) Status values that need to be considered for filter @@ -101,8 +137,44 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example=[ {\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n} ], contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example=[ { + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +} ], contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: tags (query) Tags to filter by @@ -134,14 +206,50 @@ extension PetstoreClientAPI { - OAuth: - type: oauth2 - name: petstore_auth - - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] - - examples: [{example={\n "tags" : [ {\n "id" : 123456789,\n "name" : "aeiou"\n } ],\n "id" : 123456789,\n "category" : {\n "id" : 123456789,\n "name" : "aeiou"\n },\n "status" : "aeiou",\n "name" : "doggie",\n "photoUrls" : [ "aeiou" ]\n}, contentType=application/json}, {example=\n 123456\n \n 123456\n string\n \n doggie\n string\n \n 123456\n string\n \n string\n, contentType=application/xml}] + - examples: [{example={ + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +}, contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] + - examples: [{example={ + "tags" : [ { + "id" : 123456789, + "name" : "aeiou" + } ], + "id" : 123456789, + "category" : { + "id" : 123456789, + "name" : "aeiou" + }, + "status" : "aeiou", + "name" : "doggie", + "photoUrls" : [ "aeiou" ] +}, contentType=application/json}, {example= + 123456 + doggie + string + string +, contentType=application/xml}] :param: petId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getPetById(#petId: Int?) -> RequestBuilder { + func getPetById(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -170,7 +278,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updatePetWithForm(#petId: String?, name: String?, status: String?) -> RequestBuilder { + func updatePetWithForm(#petId: String, name: String?, status: String?) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -197,7 +305,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deletePet(#petId: Int?) -> RequestBuilder { + func deletePet(#petId: Int) -> RequestBuilder { var path = "/pet/{petId}" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -226,7 +334,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func uploadFile(#petId: Int?, additionalMetadata: String?, file: NSData?) -> RequestBuilder { + func uploadFile(#petId: Int, additionalMetadata: String?, file: NSData?) -> RequestBuilder { var path = "/pet/{petId}/uploadImage" path = path.stringByReplacingOccurrencesOfString("{petId}", withString: "\(petId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift index ed0c5a87889..ad122129939 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/StoreAPI.swift @@ -21,8 +21,12 @@ extension PetstoreClientAPI { - API Key: - type: apiKey api_key - name: api_key - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] - - examples: [{example={\n "key" : 123\n}, contentType=application/json}, {example=not implemented com.wordnik.swagger.models.properties.MapProperty@5c7e707e, contentType=application/xml}] + - examples: [{example={ + "key" : 123 +}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}] + - examples: [{example={ + "key" : 123 +}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@3e, contentType=application/xml}] :returns: Promise> */ @@ -44,8 +48,36 @@ extension PetstoreClientAPI { - POST /store/order - - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.814+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.817Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.102+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.102+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.105Z + string + true +, contentType=application/xml}] :param: body (body) order placed for purchasing the pet @@ -68,14 +100,42 @@ extension PetstoreClientAPI { - GET /store/order/{orderId} - For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "petId" : 123456789,\n "complete" : true,\n "status" : "aeiou",\n "quantity" : 123,\n "shipDate" : "2015-05-27T04:22:21.818+0000"\n}, contentType=application/json}, {example=\n 123456\n 123456\n 0\n 2015-05-27T13:22:21.818Z\n string\n true\n, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.106+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, contentType=application/xml}] + - examples: [{example={ + "id" : 123456789, + "petId" : 123456789, + "complete" : true, + "status" : "aeiou", + "quantity" : 123, + "shipDate" : "2015-06-27T13:41:28.106+0000" +}, contentType=application/json}, {example= + 123456 + 123456 + 0 + 2015-06-27T22:41:28.106Z + string + true +, contentType=application/xml}] :param: orderId (path) ID of pet that needs to be fetched :returns: Promise> */ - func getOrderById(#orderId: String?) -> RequestBuilder { + func getOrderById(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -99,7 +159,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteOrder(#orderId: String?) -> RequestBuilder { + func deleteOrder(#orderId: String) -> RequestBuilder { var path = "/store/order/{orderId}" path = path.stringByReplacingOccurrencesOfString("{orderId}", withString: "\(orderId)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift index 812d823459d..9c283396214 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/APIs/UserAPI.swift @@ -134,14 +134,22 @@ extension PetstoreClientAPI { - GET /user/{username} - - - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] - - examples: [{example={\n "id" : 123456789,\n "lastName" : "aeiou",\n "phone" : "aeiou",\n "username" : "aeiou",\n "email" : "aeiou",\n "userStatus" : 123,\n "firstName" : "aeiou",\n "password" : "aeiou"\n}, contentType=application/json}, {example=\n 123456\n string\n string\n string\n string\n string\n string\n 0\n, contentType=application/xml}] + - examples: [{example={ + "id" : 1, + "username" : "johnp", + "firstName" : "John", + "lastName" : "Public", + "email" : "johnp@swagger.io", + "password" : "-secret-", + "phone" : "0123456789", + "userStatus" : 0 +}, contentType=application/json}] :param: username (path) The name that needs to be fetched. Use user1 for testing. :returns: Promise> */ - func getUserByName(#username: String?) -> RequestBuilder { + func getUserByName(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -166,7 +174,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func updateUser(#username: String?, body: User?) -> RequestBuilder { + func updateUser(#username: String, body: User?) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path @@ -189,7 +197,7 @@ extension PetstoreClientAPI { :returns: Promise> */ - func deleteUser(#username: String?) -> RequestBuilder { + func deleteUser(#username: String) -> RequestBuilder { var path = "/user/{username}" path = path.stringByReplacingOccurrencesOfString("{username}", withString: "\(username)", options: .LiteralSearch, range: nil) let url = PetstoreClientAPI.basePath + path diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift index 37edceea13c..61e2bf2886d 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/AlamofireImplementations.swift @@ -5,7 +5,6 @@ // import Alamofire -import PromiseKit class AlamofireRequestBuilderFactory: RequestBuilderFactory { func getBuilder() -> RequestBuilder.Type { @@ -21,7 +20,7 @@ class AlamofireRequestBuilder: RequestBuilder { super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) } - override func execute() -> Promise> { + override func execute(completion: (response: Response?, erorr: NSError?) -> Void) { let managerId = NSUUID().UUIDString // Create a new manager for each request to customize its request header let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() @@ -35,37 +34,41 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - let defer = Promise>.defer() request.responseJSON(options: .AllowFragments) { (req, res, json, error) in managerStore.removeValueForKey(managerId) if let error = error { - defer.reject(error) + completion(response: nil, erorr: error) return } if res!.statusCode >= 400 { //TODO: Add error entity let userInfo: [NSObject : AnyObject] = (json != nil) ? ["data": json!] : [:] let error = NSError(domain: res!.URL!.URLString, code: res!.statusCode, userInfo: userInfo) - defer.reject(error) + completion(response: nil, erorr: error) return } if () is T { let response = Response(response: res!, body: () as! T) - defer.fulfill(response) + completion(response: response, erorr: nil) return } if let json: AnyObject = json { let body = Decoders.decode(clazz: T.self, source: json) let response = Response(response: res!, body: body) - defer.fulfill(response) + completion(response: response, erorr: nil) + return + } else if "" is T { + // swagger-parser currently doesn't support void, which will be fixed in future swagger-parser release + // https://github.com/swagger-api/swagger-parser/pull/34 + let response = Response(response: res!, body: "" as! T) + completion(response: response, erorr: nil) return } - defer.reject(NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + completion(response: nil, erorr: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) } - return defer.promise } private func buildHeaders() -> [String: AnyObject] { @@ -77,4 +80,3 @@ class AlamofireRequestBuilder: RequestBuilder { } } - diff --git a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift index a06ebae7026..80af4351f04 100644 --- a/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift +++ b/samples/client/petstore/swift/PetstoreClient/Classes/Swaggers/Extensions.swift @@ -63,3 +63,17 @@ extension NSDate: JSONEncodable { return dateFormatter.stringFromDate(self) } } + +extension RequestBuilder { + func execute() -> Promise> { + let deferred = Promise>.defer() + self.execute { (response: Response?, error: NSError?) in + if let response = response { + deferred.fulfill(response) + } else { + deferred.reject(error!) + } + } + return deferred.promise + } +}