diff --git a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java index ce3ec0650129..ddd4d0c53ff1 100644 --- a/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java +++ b/modules/swagger-codegen/src/main/java/io/swagger/codegen/languages/ObjcClientCodegen.java @@ -145,6 +145,8 @@ public class ObjcClientCodegen extends DefaultCodegen implements CodegenConfig { supportingFiles.add(new SupportingFile("SWGQueryParamCollection.m", sourceFolder, "SWGQueryParamCollection.m")); supportingFiles.add(new SupportingFile("SWGApiClient-header.mustache", sourceFolder, "SWGApiClient.h")); supportingFiles.add(new SupportingFile("SWGApiClient-body.mustache", sourceFolder, "SWGApiClient.m")); + supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-header.mustache", sourceFolder, "SWGJSONResponseSerializer.h")); + supportingFiles.add(new SupportingFile("SWGJSONResponseSerializer-body.mustache", sourceFolder, "SWGJSONResponseSerializer.m")); supportingFiles.add(new SupportingFile("SWGFile.h", sourceFolder, "SWGFile.h")); supportingFiles.add(new SupportingFile("SWGFile.m", sourceFolder, "SWGFile.m")); supportingFiles.add(new SupportingFile("JSONValueTransformer+ISO8601.m", sourceFolder, "JSONValueTransformer+ISO8601.m")); diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache index a0c9c63d27c5..39ad87c76bb1 100644 --- a/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache +++ b/modules/swagger-codegen/src/main/resources/objc/SWGApiClient-body.mustache @@ -359,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // return nil if data is nil + if (!data) { + return nil; + } + // remove "*" from class, if ends with "*" if ([class hasSuffix:@"*"]) { class = [class substringToIndex:[class length] - 1]; diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache new file mode 100644 index 000000000000..80fd09f6954d --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-body.mustache @@ -0,0 +1,28 @@ +#import "SWGJSONResponseSerializer.h" + +static BOOL JSONParseError(NSError *error) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 3840) { + return YES; + } + + return NO; +} + +@implementation SWGJSONResponseSerializer + +- (id) responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error { + NSDictionary *responseJson = [super responseObjectForResponse:response data:data error:error]; + + // if response data is not a valid json, return string of data. + if (JSONParseError(*error)) { + *error = nil; + NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return responseString; + } + + return responseJson; +} + +@end diff --git a/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache new file mode 100644 index 000000000000..16cda1222172 --- /dev/null +++ b/modules/swagger-codegen/src/main/resources/objc/SWGJSONResponseSerializer-header.mustache @@ -0,0 +1,6 @@ +#import +#import + +@interface SWGJSONResponseSerializer : AFJSONResponseSerializer + +@end diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m index 8ea2e7ee0fcc..d2864afe51d6 100644 --- a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/StoreApiTest.m @@ -32,10 +32,7 @@ XCTFail(@"failed to fetch inventory"); } - NSSet *expectKeys = [NSSet setWithArray:@[@"confused", @"string", @"available"]]; - NSSet *keys = [NSSet setWithArray:[output allKeys]]; - - XCTAssertEqualObjects(expectKeys, keys); + XCTAssertNotNil(output.allKeys); [expectation fulfill]; }]; diff --git a/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m new file mode 100644 index 000000000000..b703797a2807 --- /dev/null +++ b/samples/client/petstore/objc/PetstoreClient/PetstoreClientTests/UserApiTest.m @@ -0,0 +1,47 @@ +#import +#import +#import "SWGUserApi.h" + +@interface UserApiTest : XCTestCase + +@property (nonatomic) SWGUserApi *api; + +@end + +@implementation UserApiTest + +- (void)setUp { + [super setUp]; + self.api = [[SWGUserApi alloc] init]; +} + +- (void)tearDown { + [super tearDown]; +} + +- (void)testLoginUser { + XCTestExpectation *expectation = [self expectationWithDescription:@"test login user"]; + + [self.api loginUserWithCompletionBlock:@"test username" password:@"test password" completionHandler:^(NSString *output, NSError *error) { + if (error) { + XCTFail(@"got error %@", error); + } + + if (!output) { + XCTFail(@"response can't be nil"); + } + + NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"logged in user" + options:0 + error:nil]; + NSTextCheckingResult *match = [regex firstMatchInString:output + options:0 + range:NSMakeRange(0, [output length])]; + XCTAssertNotNil(match); + [expectation fulfill]; + }]; + + [self waitForExpectationsWithTimeout:10.0 handler:nil]; +} + +@end diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj index ffb619530518..ac15f78e3572 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient.xcodeproj/project.pbxproj @@ -10,7 +10,9 @@ BA525648922D4C0E9F44D4F1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 73DA4F1067C343C3962F1542 /* libPods.a */; }; CF0560EB1B1855CF00C0D4EC /* SWGConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */; }; CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF31D0981B105E4B00509935 /* SWGApiClientTest.m */; }; + CF5B6E2D1B2BD70800862A1C /* UserApiTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */; }; CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */ = {isa = PBXBuildFile; fileRef = CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */; }; + CFCEFE511B2C1330006313BE /* SWGJSONResponseSerializer.m in Sources */ = {isa = PBXBuildFile; fileRef = CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */; }; CFD1B6701B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */ = {isa = PBXBuildFile; fileRef = CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */; }; EA66999A1811D2FA00A70D03 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA6699991811D2FA00A70D03 /* Foundation.framework */; }; @@ -61,7 +63,10 @@ CF0560E91B1855CF00C0D4EC /* SWGConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGConfiguration.h; sourceTree = ""; }; CF0560EA1B1855CF00C0D4EC /* SWGConfiguration.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGConfiguration.m; sourceTree = ""; }; CF31D0981B105E4B00509935 /* SWGApiClientTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGApiClientTest.m; sourceTree = ""; }; + CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UserApiTest.m; sourceTree = ""; }; CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = StoreApiTest.m; sourceTree = ""; }; + CFCEFE4F1B2C1330006313BE /* SWGJSONResponseSerializer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SWGJSONResponseSerializer.h; sourceTree = ""; }; + CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SWGJSONResponseSerializer.m; sourceTree = ""; }; CFD1B66E1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "JSONValueTransformer+ISO8601.h"; sourceTree = ""; }; CFD1B66F1B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "JSONValueTransformer+ISO8601.m"; sourceTree = ""; }; E2B6DA00BE52336E23783686 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "../Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; @@ -214,6 +219,7 @@ isa = PBXGroup; children = ( EA8CD3EB1AC274BE00C47D0B /* PetApiTest.h */, + CF5B6E2C1B2BD70800862A1C /* UserApiTest.m */, CFB37D051B2B11DC00D2E5F1 /* StoreApiTest.m */, CF31D0981B105E4B00509935 /* SWGApiClientTest.m */, EA6699C71811D2FB00A70D03 /* PetApiTest.m */, @@ -251,6 +257,8 @@ EAEA85D61811D3AE00F06E69 /* SWGOrder.h */, EAEA85D71811D3AE00F06E69 /* SWGOrder.m */, EAB26B0E1AC8E692002F5C7A /* SWGPet.h */, + CFCEFE4F1B2C1330006313BE /* SWGJSONResponseSerializer.h */, + CFCEFE501B2C1330006313BE /* SWGJSONResponseSerializer.m */, EAEA85D91811D3AE00F06E69 /* SWGPet.m */, EAEA85DA1811D3AE00F06E69 /* SWGPetApi.h */, EAEA85DB1811D3AE00F06E69 /* SWGPetApi.m */, @@ -418,6 +426,7 @@ EAEA85E91811D3AE00F06E69 /* SWGOrder.m in Sources */, EAEA85E81811D3AE00F06E69 /* SWGObject.m in Sources */, EA8B8AA41AC6683700638FBB /* SWGQueryParamCollection.m in Sources */, + CFCEFE511B2C1330006313BE /* SWGJSONResponseSerializer.m in Sources */, EAEA85E71811D3AE00F06E69 /* SWGFile.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -429,6 +438,7 @@ EAB26B0C1AC8DF78002F5C7A /* PetApiTest.h in Sources */, CFD1B6711B05EC7D00DCCD51 /* JSONValueTransformer+ISO8601.m in Sources */, EAB26B0D1AC8DF78002F5C7A /* PetApiTest.m in Sources */, + CF5B6E2D1B2BD70800862A1C /* UserApiTest.m in Sources */, CFB37D061B2B11DD00D2E5F1 /* StoreApiTest.m in Sources */, CF31D0991B105E4B00509935 /* SWGApiClientTest.m in Sources */, ); diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m index 56d0a8f621fa..5ba0fe183826 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClient/ViewController.m @@ -9,6 +9,7 @@ #import "ViewController.h" #import "SWGPetApi.h" #import "SWGStoreApi.h" +#import "SWGUserApi.h" #import "SWGConfiguration.h" @interface ViewController () @@ -55,6 +56,11 @@ // } ]; */ + SWGUserApi *api = [[SWGUserApi alloc] init]; + [api loginUserWithCompletionBlock:@"username" password:@"password" completionHandler:^(NSString *output, NSError *error) { + NSLog(@"output => %@", output); + NSLog(@"error => %@", error); + }]; } - (void)didReceiveMemoryWarning diff --git a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m index 597cf2fb714c..c68b3e2a42ec 100644 --- a/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m +++ b/samples/client/petstore/objc/SwaggerClient/SwaggerClientTests/SWGApiClientTest.m @@ -160,9 +160,15 @@ XCTAssertEqualObjects([result[@"pet"] _id], @119); // pure object - result = [self.apiClient deserialize:nil class:@"NSObject*"]; + result = [self.apiClient deserialize:@"" class:@"NSObject*"]; XCTAssertTrue([result isKindOfClass:[NSObject class]]); + + // NSString + data = @"test string"; + result = [self.apiClient deserialize:data class:@"NSString*"]; + + XCTAssertTrue([result isKindOfClass:[NSString class]]); } @end diff --git a/samples/client/petstore/objc/client/SWGApiClient.m b/samples/client/petstore/objc/client/SWGApiClient.m index a0c9c63d27c5..39ad87c76bb1 100644 --- a/samples/client/petstore/objc/client/SWGApiClient.m +++ b/samples/client/petstore/objc/client/SWGApiClient.m @@ -359,6 +359,11 @@ static bool loggingEnabled = true; NSMutableArray *resultArray = nil; NSMutableDictionary *resultDict = nil; + // return nil if data is nil + if (!data) { + return nil; + } + // remove "*" from class, if ends with "*" if ([class hasSuffix:@"*"]) { class = [class substringToIndex:[class length] - 1]; diff --git a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h new file mode 100644 index 000000000000..16cda1222172 --- /dev/null +++ b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.h @@ -0,0 +1,6 @@ +#import +#import + +@interface SWGJSONResponseSerializer : AFJSONResponseSerializer + +@end diff --git a/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m new file mode 100644 index 000000000000..80fd09f6954d --- /dev/null +++ b/samples/client/petstore/objc/client/SWGJSONResponseSerializer.m @@ -0,0 +1,28 @@ +#import "SWGJSONResponseSerializer.h" + +static BOOL JSONParseError(NSError *error) { + if ([error.domain isEqualToString:NSCocoaErrorDomain] && error.code == 3840) { + return YES; + } + + return NO; +} + +@implementation SWGJSONResponseSerializer + +- (id) responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error { + NSDictionary *responseJson = [super responseObjectForResponse:response data:data error:error]; + + // if response data is not a valid json, return string of data. + if (JSONParseError(*error)) { + *error = nil; + NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + return responseString; + } + + return responseJson; +} + +@end