diff --git a/samples/client/petstore-security-test/swift/SwaggerClient.podspec b/samples/client/petstore-security-test/swift/SwaggerClient.podspec index 4786bf4084e..e3b018276fd 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient.podspec +++ b/samples/client/petstore-security-test/swift/SwaggerClient.podspec @@ -4,7 +4,10 @@ Pod::Spec.new do |s| s.osx.deployment_target = '10.9' s.version = '0.0.1' s.source = { :git => 'git@github.com:swagger-api/swagger-mustache.git', :tag => 'v1.0.0' } - s.license = 'Apache License, Version 2.0' + s.authors = 'Swagger Codegen' + s.license = 'Proprietary' + s.homepage = 'https://github.com/swagger-api/swagger-codegen' + s.summary = 'SwaggerClient Swift SDK' s.source_files = 'SwaggerClient/Classes/Swaggers/**/*.swift' - s.dependency 'Alamofire', '~> 3.1.5' + s.dependency 'Alamofire', '~> 3.4.1' end diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIHelper.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIHelper.swift index 23e727b6b54..b91cd27851a 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIHelper.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIHelper.swift @@ -19,6 +19,16 @@ class APIHelper { return destination } + static func rejectNilHeaders(source: [String:AnyObject?]) -> [String:String] { + var destination = [String:String]() + for (key, nillableValue) in source { + if let value: AnyObject = nillableValue { + destination[key] = "\(value)" + } + } + return destination + } + static func convertBoolToString(source: [String: AnyObject]?) -> [String:AnyObject]? { guard let source = source else { return nil diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs.swift index afc7afbc094..b8aadc03d95 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs.swift @@ -7,7 +7,7 @@ import Foundation public class SwaggerClientAPI { - public static var basePath = "https://petstore.swagger.io *_/ ' \" =end \\r\\n \\n \\r/v2 *_/ ' \" =end \\r\\n \\n \\r" + public static var basePath = "https://petstore.swagger.io *_/ ' \" =end -- \\r\\n \\n \\r/v2 *_/ ' \" =end -- \\r\\n \\n \\r" public static var credential: NSURLCredential? public static var customHeaders: [String:String] = [:] static var requestBuilderFactory: RequestBuilderFactory = AlamofireRequestBuilderFactory() @@ -31,17 +31,21 @@ public class APIBase { public class RequestBuilder { var credential: NSURLCredential? - var headers: [String:String] = [:] + var headers: [String:String] let parameters: [String:AnyObject]? let isBody: Bool let method: String let URLString: String - required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool) { + /// Optional block to obtain a reference to the request's progress instance when available. + public var onProgressReady: ((NSProgress) -> ())? + + required public init(method: String, URLString: String, parameters: [String:AnyObject]?, isBody: Bool, headers: [String:String] = [:]) { self.method = method self.URLString = URLString self.parameters = parameters self.isBody = isBody + self.headers = headers addHeaders(SwaggerClientAPI.customHeaders) } diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs/FakeAPI.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs/FakeAPI.swift index 0d35a764773..cd0a1acdd63 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs/FakeAPI.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/APIs/FakeAPI.swift @@ -11,9 +11,9 @@ import Alamofire public class FakeAPI: APIBase { /** - To test code injection *_/ ' \" =end \\r\\n \\n \\r + To test code injection *_/ ' \" =end -- \\r\\n \\n \\r - - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \" =end \\r\\n \\n \\r (optional) + - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \" =end -- \\r\\n \\n \\r (optional) - parameter completion: completion handler to receive the data and the error objects */ public class func testCodeInjectEndRnNR(testCodeInjectEndRnNR testCodeInjectEndRnNR: String? = nil, completion: ((error: ErrorType?) -> Void)) { @@ -24,10 +24,10 @@ public class FakeAPI: APIBase { /** - To test code injection *_/ ' \" =end \\r\\n \\n \\r + To test code injection *_/ ' \" =end -- \\r\\n \\n \\r - PUT /fake - - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \" =end \\r\\n \\n \\r (optional) + - parameter testCodeInjectEndRnNR: (form) To test code injection *_/ ' \" =end -- \\r\\n \\n \\r (optional) - returns: RequestBuilder */ @@ -36,7 +36,7 @@ public class FakeAPI: APIBase { let URLString = SwaggerClientAPI.basePath + path let nillableParameters: [String:AnyObject?] = [ - "test code inject */ ' " =end \r\n \n \r": testCodeInjectEndRnNR + "test code inject */ ' " =end -- \r\n \n \r": testCodeInjectEndRnNR ] let parameters = APIHelper.rejectNil(nillableParameters) diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/AlamofireImplementations.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/AlamofireImplementations.swift index 2faa0a6f24d..66971688891 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/AlamofireImplementations.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/AlamofireImplementations.swift @@ -12,12 +12,37 @@ class AlamofireRequestBuilderFactory: RequestBuilderFactory { } } +public struct SynchronizedDictionary { + + private var dictionary = [K: V]() + private let queue = dispatch_queue_create("SynchronizedDictionary", DISPATCH_QUEUE_CONCURRENT) + + public subscript(key: K) -> V? { + get { + var value: V? + + dispatch_sync(queue) { + value = self.dictionary[key] + } + + return value + } + + set { + dispatch_barrier_sync(queue) { + self.dictionary[key] = newValue + } + } + } + +} + // Store manager to retain its reference -private var managerStore: [String: Alamofire.Manager] = [:] +private var managerStore = SynchronizedDictionary() class AlamofireRequestBuilder: RequestBuilder { - required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool) { - super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody) + required init(method: String, URLString: String, parameters: [String : AnyObject]?, isBody: Bool, headers: [String : String] = [:]) { + super.init(method: method, URLString: URLString, parameters: parameters, isBody: isBody, headers: headers) } override func execute(completion: (response: Response?, error: ErrorType?) -> Void) { @@ -57,15 +82,22 @@ class AlamofireRequestBuilder: RequestBuilder { encodingMemoryThreshold: Manager.MultipartFormDataEncodingMemoryThreshold, encodingCompletion: { encodingResult in switch encodingResult { - case .Success(let upload, _, _): - self.processRequest(upload, managerId, completion) + case .Success(let uploadRequest, _, _): + if let onProgressReady = self.onProgressReady { + onProgressReady(uploadRequest.progress) + } + self.processRequest(uploadRequest, managerId, completion) case .Failure(let encodingError): - completion(response: nil, error: encodingError) + completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError)) } } ) } else { - processRequest(manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding), managerId, completion) + let request = manager.request(xMethod!, URLString, parameters: parameters, encoding: encoding) + if let onProgressReady = self.onProgressReady { + onProgressReady(request.progress) + } + processRequest(request, managerId, completion) } } @@ -75,30 +107,99 @@ class AlamofireRequestBuilder: RequestBuilder { request.authenticate(usingCredential: credential) } - request.validate().responseJSON(options: .AllowFragments) { response in - managerStore.removeValueForKey(managerId) + let cleanupRequest = { + managerStore[managerId] = nil + } - if response.result.isFailure { - completion(response: nil, error: response.result.error) - return - } + let validatedRequest = request.validate() - if () is T { - completion(response: Response(response: response.response!, body: () as! T), error: nil) - return - } - if let json: AnyObject = response.result.value { - let body = Decoders.decode(clazz: T.self, source: json) - completion(response: Response(response: response.response!, body: body), error: 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 - completion(response: Response(response: response.response!, body: "" as! T), error: nil) - return - } + switch T.self { + case is String.Type: + validatedRequest.responseString(completionHandler: { (stringResponse) in + cleanupRequest() - completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])) + if stringResponse.result.isFailure { + completion( + response: nil, + error: ErrorResponse.Error(stringResponse.response?.statusCode ?? 500, stringResponse.data, stringResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: stringResponse.response!, + body: (stringResponse.result.value ?? "") as! T + ), + error: nil + ) + }) + case is Void.Type: + validatedRequest.responseData(completionHandler: { (voidResponse) in + cleanupRequest() + + if voidResponse.result.isFailure { + completion( + response: nil, + error: ErrorResponse.Error(voidResponse.response?.statusCode ?? 500, voidResponse.data, voidResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: voidResponse.response!, + body: nil + ), + error: nil + ) + }) + case is NSData.Type: + validatedRequest.responseData(completionHandler: { (dataResponse) in + cleanupRequest() + + if (dataResponse.result.isFailure) { + completion( + response: nil, + error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!) + ) + return + } + + completion( + response: Response( + response: dataResponse.response!, + body: dataResponse.data as! T + ), + error: nil + ) + }) + default: + validatedRequest.responseJSON(options: .AllowFragments) { response in + cleanupRequest() + + if response.result.isFailure { + completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!)) + return + } + + if () is T { + completion(response: Response(response: response.response!, body: () as! T), error: nil) + return + } + if let json: AnyObject = response.result.value { + let body = Decoders.decode(clazz: T.self, source: json) + completion(response: Response(response: response.response!, body: body), error: 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 + completion(response: Response(response: response.response!, body: "" as! T), error: nil) + return + } + + completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))) + } } } diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Extensions.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Extensions.swift index fed87969388..c974cc40b36 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Extensions.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Extensions.swift @@ -58,11 +58,17 @@ extension Dictionary: JSONEncodable { } } +extension NSData: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.base64EncodedStringWithOptions(NSDataBase64EncodingOptions()) + } +} private let dateFormatter: NSDateFormatter = { - let dateFormatter = NSDateFormatter() - dateFormatter.dateFormat = "yyyy-MM-dd" - return dateFormatter + let fmt = NSDateFormatter() + fmt.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZZZZZ" + fmt.locale = NSLocale(localeIdentifier: "en_US_POSIX") + return fmt }() extension NSDate: JSONEncodable { @@ -71,4 +77,10 @@ extension NSDate: JSONEncodable { } } +extension NSUUID: JSONEncodable { + func encodeToJSON() -> AnyObject { + return self.UUIDString + } +} + diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models.swift index 3f70e2a1c5e..47aec6ef918 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models.swift @@ -10,18 +10,22 @@ protocol JSONEncodable { func encodeToJSON() -> AnyObject } +public enum ErrorResponse : ErrorType { + case Error(Int, NSData?, ErrorType) +} + public class Response { public let statusCode: Int public let header: [String: String] - public let body: T + public let body: T? - public init(statusCode: Int, header: [String: String], body: T) { + public init(statusCode: Int, header: [String: String], body: T?) { self.statusCode = statusCode self.header = header self.body = body } - public convenience init(response: NSHTTPURLResponse, body: T) { + public convenience init(response: NSHTTPURLResponse, body: T?) { let rawHeader = response.allHeaderFields var header = [String:String]() for (key, value) in rawHeader { @@ -62,9 +66,15 @@ class Decoders { if T.self is Int64.Type && source is NSNumber { return source.longLongValue as! T; } + if T.self is NSUUID.Type && source is String { + return NSUUID(UUIDString: source as! String) as! T + } if source is T { return source as! T } + if T.self is NSData.Type && source is String { + return NSData(base64EncodedString: source as! String, options: NSDataBase64DecodingOptions()) as! T + } let key = "\(T.self)" if let decoder = decoders[key] { @@ -111,6 +121,7 @@ class Decoders { "yyyy-MM-dd'T'HH:mm:ss.SSS" ].map { (format: String) -> NSDateFormatter in let formatter = NSDateFormatter() + formatter.locale = NSLocale(localeIdentifier:"en_US_POSIX") formatter.dateFormat = format return formatter } diff --git a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models/Return.swift b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models/Return.swift index 30c76776b83..862cfa0687f 100644 --- a/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models/Return.swift +++ b/samples/client/petstore-security-test/swift/SwaggerClient/Classes/Swaggers/Models/Return.swift @@ -8,9 +8,9 @@ import Foundation -/** Model for testing reserved words *_/ ' \" =end \\r\\n \\n \\r */ +/** Model for testing reserved words *_/ ' \" =end -- \\r\\n \\n \\r */ public class Return: JSONEncodable { - /** property description *_/ ' \" =end \\r\\n \\n \\r */ + /** property description *_/ ' \" =end -- \\r\\n \\n \\r */ public var _return: Int32? public init() {}