[Swift] Handle binary data types

This commit is contained in:
Jason Gavris 2016-06-30 14:31:31 -04:00
parent ef857176a6
commit 4f0b7dfaed
10 changed files with 174 additions and 51 deletions

View File

@ -703,6 +703,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig {
example = "2013-10-20T19:20:30+01:00";
}
example = "@\"" + escapeText(example) + "\"";
} else if ("NSData".equalsIgnoreCase(type)) {
example = "1234";
} else if (!languageSpecificPrimitives.contains(type)) {
// type is a model class, e.g. User
type = type.replace("*", "");

View File

@ -87,6 +87,7 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
);
defaultIncludes = new HashSet<String>(
Arrays.asList(
"NSData",
"NSDate",
"NSURL", // for file
"NSUUID",
@ -129,10 +130,8 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
typeMapping.put("double", "Double");
typeMapping.put("object", "AnyObject");
typeMapping.put("file", "NSURL");
//TODO binary should be mapped to byte array
// mapped to String as a workaround
typeMapping.put("binary", "String");
typeMapping.put("ByteArray", "String");
typeMapping.put("binary", "NSData");
typeMapping.put("ByteArray", "NSData");
typeMapping.put("UUID", "NSUUID");
importMapping = new HashMap<String, String>();
@ -258,6 +257,11 @@ public class SwiftCodegen extends DefaultCodegen implements CodegenConfig {
return toModelName(type);
}
@Override
public boolean isDataTypeBinary(final String dataType) {
return dataType != null && dataType.equals("NSData");
}
/**
* Output the proper model name (capitalized)
*

View File

@ -82,8 +82,36 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential)
}
request.validate().responseJSON(options: .AllowFragments) { response in
let cleanupRequest = {
managerStore.removeValueForKey(managerId)
}
let validatedRequest = request.validate()
switch T.self {
case is NSData.Type:
validatedRequest.responseData({ (dataResponse) in
cleanupRequest()
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: 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: response.result.error)
@ -108,6 +136,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
}
}
}
private func buildHeaders() -> [String: AnyObject] {
var httpHeaders = Manager.defaultHTTPHeaders

View File

@ -59,6 +59,11 @@ extension Dictionary: JSONEncodable {
}
}
extension NSData: JSONEncodable {
func encodeToJSON() -> AnyObject {
return self.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
}
}
private let dateFormatter: NSDateFormatter = {
let fmt = NSDateFormatter()

View File

@ -68,6 +68,9 @@ class Decoders {
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] {

View File

@ -1,5 +1,12 @@
package io.swagger.codegen.languages;
package io.swagger.codegen.swift;
import io.swagger.codegen.CodegenOperation;
import io.swagger.codegen.DefaultCodegen;
import io.swagger.codegen.InlineModelResolver;
import io.swagger.codegen.languages.SwiftCodegen;
import io.swagger.models.Operation;
import io.swagger.models.Swagger;
import io.swagger.parser.SwaggerParser;
import org.testng.Assert;
import org.testng.annotations.Test;
@ -42,6 +49,20 @@ public class SwiftCodegenTest {
Assert.assertEquals(swiftCodegen.toSwiftyEnumName("entry_name"), "EntryName");
}
@Test(description = "returns NSData when response format is binary")
public void binaryDataTest() {
final Swagger model = new SwaggerParser().read("src/test/resources/2_0/binaryDataTest.json");
final DefaultCodegen codegen = new SwiftCodegen();
final String path = "/tests/binaryResponse";
final Operation p = model.getPaths().get(path).getPost();
final CodegenOperation op = codegen.fromOperation(path, "post", p, model.getDefinitions());
Assert.assertEquals(op.returnType, "NSData");
Assert.assertEquals(op.bodyParam.dataType, "NSData");
Assert.assertTrue(op.bodyParam.isBinary);
Assert.assertTrue(op.responses.get(0).isBinary);
}
@Test
public void testDefaultPodAuthors() throws Exception {
// Given

View File

@ -18,6 +18,8 @@ public class SwiftModelTest {
.property("id", new LongProperty())
.property("name", new StringProperty())
.property("createdAt", new DateTimeProperty())
.property("binary", new BinaryProperty())
.property("byte", new ByteArrayProperty())
.property("uuid", new UUIDProperty())
.required("id")
.required("name")
@ -28,7 +30,7 @@ public class SwiftModelTest {
Assert.assertEquals(cm.name, "sample");
Assert.assertEquals(cm.classname, "Sample");
Assert.assertEquals(cm.description, "a sample model");
Assert.assertEquals(cm.vars.size(), 4);
Assert.assertEquals(cm.vars.size(), 6);
Assert.assertEquals(cm.discriminator,"test");
final CodegenProperty property1 = cm.vars.get(0);
@ -64,14 +66,34 @@ public class SwiftModelTest {
Assert.assertTrue(property3.isNotContainer);
final CodegenProperty property4 = cm.vars.get(3);
Assert.assertEquals(property4.baseName, "uuid");
Assert.assertEquals(property4.datatype, "NSUUID");
Assert.assertEquals(property4.name, "uuid");
Assert.assertEquals(property4.baseName, "binary");
Assert.assertEquals(property4.datatype, "NSData");
Assert.assertEquals(property4.name, "binary");
Assert.assertNull(property4.defaultValue);
Assert.assertEquals(property4.baseType, "NSUUID");
Assert.assertNull(property4.hasMore);
Assert.assertEquals(property4.baseType, "NSData");
Assert.assertTrue(property4.hasMore);
Assert.assertNull(property4.required);
Assert.assertTrue(property4.isNotContainer);
final CodegenProperty property5 = cm.vars.get(4);
Assert.assertEquals(property5.baseName, "byte");
Assert.assertEquals(property5.datatype, "NSData");
Assert.assertEquals(property5.name, "byte");
Assert.assertNull(property5.defaultValue);
Assert.assertEquals(property5.baseType, "NSData");
Assert.assertTrue(property5.hasMore);
Assert.assertNull(property5.required);
Assert.assertTrue(property5.isNotContainer);
final CodegenProperty property6 = cm.vars.get(5);
Assert.assertEquals(property6.baseName, "uuid");
Assert.assertEquals(property6.datatype, "NSUUID");
Assert.assertEquals(property6.name, "uuid");
Assert.assertNull(property6.defaultValue);
Assert.assertEquals(property6.baseType, "NSUUID");
Assert.assertNull(property6.hasMore);
Assert.assertNull(property6.required);
Assert.assertTrue(property6.isNotContainer);
}
}

View File

@ -82,8 +82,36 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
request.authenticate(usingCredential: credential)
}
request.validate().responseJSON(options: .AllowFragments) { response in
let cleanupRequest = {
managerStore.removeValueForKey(managerId)
}
let validatedRequest = request.validate()
switch T.self {
case is NSData.Type:
validatedRequest.responseData({ (dataResponse) in
cleanupRequest()
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: 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: response.result.error)
@ -108,6 +136,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
}
}
}
private func buildHeaders() -> [String: AnyObject] {
var httpHeaders = Manager.defaultHTTPHeaders

View File

@ -58,6 +58,11 @@ extension Dictionary: JSONEncodable {
}
}
extension NSData: JSONEncodable {
func encodeToJSON() -> AnyObject {
return self.base64EncodedStringWithOptions(NSDataBase64EncodingOptions())
}
}
private let dateFormatter: NSDateFormatter = {
let fmt = NSDateFormatter()

View File

@ -68,6 +68,9 @@ class Decoders {
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] {