Merge pull request #3624 from ButterflyNetwork/swift-better-errors

[Swift] Include HTTP status code and body data in response errors
This commit is contained in:
wing328 2016-08-24 23:39:37 +08:00 committed by GitHub
commit 8c2267cd3d
22 changed files with 397 additions and 387 deletions

View File

@ -63,7 +63,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
self.processRequest(uploadRequest, managerId, completion)
case .Failure(let encodingError):
completion(response: nil, error: encodingError)
completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError))
}
}
)
@ -89,6 +89,46 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
let validatedRequest = request.validate()
switch T.self {
case is String.Type:
validatedRequest.responseString(completionHandler: { (stringResponse) in
cleanupRequest()
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()
@ -96,7 +136,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: dataResponse.result.error
error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
)
return
}
@ -114,7 +154,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
cleanupRequest()
if response.result.isFailure {
completion(response: nil, error: response.result.error)
completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!))
return
}
@ -133,7 +173,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
return
}
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])))
}
}
}

View File

@ -10,18 +10,22 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject
}
public enum ErrorResponse : ErrorType {
case Error(Int, NSData?, ErrorType)
}
public class Response<T> {
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 {

View File

@ -108,13 +108,13 @@ public class PetAPI: APIBase {
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example={
- examples: [{contentType=application/json, example={
"name" : "Puma",
"type" : "Dog",
"color" : "Black",
"gender" : "Female",
"breed" : "Mixed"
}, contentType=application/json}]
}}]
- parameter status: (query) Status values that need to be considered for filter (optional, default to available)
@ -157,20 +157,20 @@ public class PetAPI: APIBase {
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
- examples: [{contentType=application/json, example=[ {
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
} ]}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -179,21 +179,21 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
</Pet>}]
- examples: [{contentType=application/json, example=[ {
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
} ]}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -202,7 +202,7 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
</Pet>}]
- parameter tags: (query) Tags to filter by (optional)
@ -242,26 +242,26 @@ public class PetAPI: APIBase {
Find pet by ID
- GET /pet/{petId}
- Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
- API Key:
- type: apiKey api_key
- name: api_key
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example={
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
- API Key:
- type: apiKey api_key
- name: api_key
- examples: [{contentType=application/json, example={
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
}}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -270,21 +270,21 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example={
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
</Pet>}]
- examples: [{contentType=application/json, example={
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
}}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -293,7 +293,7 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
</Pet>}]
- parameter petId: (path) ID of pet that needs to be fetched

View File

@ -67,12 +67,12 @@ public class StoreAPI: APIBase {
- API Key:
- type: apiKey api_key
- name: api_key
- examples: [{example={
- examples: [{contentType=application/json, example={
"key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@d1e580af, contentType=application/xml}]
- examples: [{example={
}}, {contentType=application/xml, example=not implemented io.swagger.models.properties.MapProperty@d1e580af}]
- examples: [{contentType=application/json, example={
"key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@d1e580af, contentType=application/xml}]
}}, {contentType=application/xml, example=not implemented io.swagger.models.properties.MapProperty@d1e580af}]
- returns: RequestBuilder<[String:Int32]>
*/
@ -108,36 +108,36 @@ public class StoreAPI: APIBase {
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={
"id" : 123456789,
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
</Order>}]
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
</Order>}]
- parameter orderId: (path) ID of pet that needs to be fetched
@ -176,36 +176,36 @@ public class StoreAPI: APIBase {
Place an order for a pet
- POST /store/order
-
- examples: [{example={
"id" : 123456789,
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
</Order>}]
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
</Order>}]
- parameter body: (body) order placed for purchasing the pet (optional)

View File

@ -167,16 +167,16 @@ public class UserAPI: APIBase {
Get user by user name
- GET /user/{username}
-
- examples: [{example={
"id" : 123456789,
"lastName" : "aeiou",
"phone" : "aeiou",
"username" : "aeiou",
"email" : "aeiou",
"userStatus" : 123,
- examples: [{contentType=application/json, example={
"firstName" : "aeiou",
"password" : "aeiou"
}, contentType=application/json}, {example=<User>
"lastName" : "aeiou",
"password" : "aeiou",
"userStatus" : 123,
"phone" : "aeiou",
"id" : 123456789,
"email" : "aeiou",
"username" : "aeiou"
}}, {contentType=application/xml, example=<User>
<id>123456</id>
<username>string</username>
<firstName>string</firstName>
@ -185,17 +185,17 @@ public class UserAPI: APIBase {
<password>string</password>
<phone>string</phone>
<userStatus>0</userStatus>
</User>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
"lastName" : "aeiou",
"phone" : "aeiou",
"username" : "aeiou",
"email" : "aeiou",
"userStatus" : 123,
</User>}]
- examples: [{contentType=application/json, example={
"firstName" : "aeiou",
"password" : "aeiou"
}, contentType=application/json}, {example=<User>
"lastName" : "aeiou",
"password" : "aeiou",
"userStatus" : 123,
"phone" : "aeiou",
"id" : 123456789,
"email" : "aeiou",
"username" : "aeiou"
}}, {contentType=application/xml, example=<User>
<id>123456</id>
<username>string</username>
<firstName>string</firstName>
@ -204,7 +204,7 @@ public class UserAPI: APIBase {
<password>string</password>
<phone>string</phone>
<userStatus>0</userStatus>
</User>, contentType=application/xml}]
</User>}]
- parameter username: (path) The name that needs to be fetched. Use user1 for testing.
@ -244,8 +244,8 @@ public class UserAPI: APIBase {
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}]
- examples: [{contentType=application/json, example="aeiou"}, {contentType=application/xml, example=string}]
- examples: [{contentType=application/json, example="aeiou"}, {contentType=application/xml, example=string}]
- parameter username: (query) The user name for login (optional)
- parameter password: (query) The password for login in clear text (optional)

View File

@ -63,7 +63,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
self.processRequest(uploadRequest, managerId, completion)
case .Failure(let encodingError):
completion(response: nil, error: encodingError)
completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError))
}
}
)
@ -89,6 +89,46 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
let validatedRequest = request.validate()
switch T.self {
case is String.Type:
validatedRequest.responseString(completionHandler: { (stringResponse) in
cleanupRequest()
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()
@ -96,7 +136,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: dataResponse.result.error
error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
)
return
}
@ -114,7 +154,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
cleanupRequest()
if response.result.isFailure {
completion(response: nil, error: response.result.error)
completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!))
return
}
@ -133,7 +173,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
return
}
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])))
}
}
}

View File

@ -10,18 +10,22 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject
}
public enum ErrorResponse : ErrorType {
case Error(Int, NSData?, ErrorType)
}
public class Response<T> {
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 {

View File

@ -16,4 +16,4 @@ SPEC CHECKSUMS:
PODFILE CHECKSUM: 84472aca2a88b7f7ed9fcd63e9f5fdb5ad4aab94
COCOAPODS: 1.0.0
COCOAPODS: 1.0.1

View File

@ -48,8 +48,8 @@ EOM
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"

View File

@ -48,8 +48,8 @@ EOM
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .storyboard`.storyboardc" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.xib)
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}"
echo "ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile ${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib $RESOURCE_PATH --sdk ${SDKROOT} ${TARGET_DEVICE_ARGS}"
ibtool --reference-external-strings-file --errors --warnings --notices --minimum-deployment-target ${!DEPLOYMENT_TARGET_SETTING_NAME} --output-format human-readable-text --compile "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$RESOURCE_PATH\" .xib`.nib" "$RESOURCE_PATH" --sdk "${SDKROOT}" ${TARGET_DEVICE_ARGS}
;;
*.framework)
echo "mkdir -p ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"

View File

@ -143,7 +143,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 6D4EFBAE1C692C6300B96B06 /* Build configuration list for PBXNativeTarget "SwaggerClient" */;
buildPhases = (
CF310079E3CB0BE5BE604471 /* 📦 Check Pods Manifest.lock */,
CF310079E3CB0BE5BE604471 /* [CP] Check Pods Manifest.lock */,
1F03F780DC2D9727E5E64BA9 /* [CP] Check Pods Manifest.lock */,
6D4EFB8D1C692C6300B96B06 /* Sources */,
6D4EFB8E1C692C6300B96B06 /* Frameworks */,
@ -166,7 +166,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 6D4EFBB11C692C6300B96B06 /* Build configuration list for PBXNativeTarget "SwaggerClientTests" */;
buildPhases = (
B4DB169E5F018305D6759D34 /* 📦 Check Pods Manifest.lock */,
B4DB169E5F018305D6759D34 /* [CP] Check Pods Manifest.lock */,
79FE27B09B2DD354C831BD49 /* [CP] Check Pods Manifest.lock */,
6D4EFBA11C692C6300B96B06 /* Sources */,
6D4EFBA21C692C6300B96B06 /* Frameworks */,
@ -365,14 +365,14 @@
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-SwaggerClient/Pods-SwaggerClient-resources.sh\"\n";
showEnvVarsInLog = 0;
};
B4DB169E5F018305D6759D34 /* 📦 Check Pods Manifest.lock */ = {
B4DB169E5F018305D6759D34 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
@ -380,14 +380,14 @@
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
CF310079E3CB0BE5BE604471 /* 📦 Check Pods Manifest.lock */ = {
CF310079E3CB0BE5BE604471 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Check Pods Manifest.lock";
name = "[CP] Check Pods Manifest.lock";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;

View File

@ -72,16 +72,11 @@ class PetAPITests: XCTestCase {
let expectation = self.expectationWithDescription("testDeletePet")
PetAPI.deletePet(petId: 1000) { (error) in
// The server gives us no data back so Alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
guard let error = error where error._code == -6006 else {
guard error == nil else {
XCTFail("error deleting pet")
return
}
expectation.fulfill()
}

View File

@ -74,16 +74,11 @@ class StoreAPITests: XCTestCase {
let expectation = self.expectationWithDescription("testDeleteOrder")
StoreAPI.deleteOrder(orderId: "1000") { (error) in
// The server gives us no data back so Alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
guard let error = error where error._code == -6006 else {
guard error == nil else {
XCTFail("error deleting order")
return
}
expectation.fulfill()
}

View File

@ -28,15 +28,11 @@ class UserAPITests: XCTestCase {
let expectation = self.expectationWithDescription("testLogin")
UserAPI.loginUser(username: "swiftTester", password: "swift") { (_, error) in
// The server isn't returning JSON - and currently the alamofire implementation
// always parses responses as JSON, so making an exception for this here
// Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0."
// UserInfo={NSDebugDescription=Invalid value around character 0.}
guard let error = error where error._code == 3840 else {
guard error == nil else {
XCTFail("error logging in")
return
}
expectation.fulfill()
}
@ -47,16 +43,11 @@ class UserAPITests: XCTestCase {
let expectation = self.expectationWithDescription("testLogout")
UserAPI.logoutUser { (error) in
// The server gives us no data back so Alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
guard let error = error where error._code == -6006 else {
guard error == nil else {
XCTFail("error logging out")
return
}
expectation.fulfill()
}
@ -77,16 +68,11 @@ class UserAPITests: XCTestCase {
newUser.userStatus = 0
UserAPI.createUser(body: newUser) { (error) in
// The server gives us no data back so Alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
guard let error = error where error._code == -6006 else {
guard error == nil else {
XCTFail("error creating user")
return
}
expectation.fulfill()
}
@ -121,16 +107,11 @@ class UserAPITests: XCTestCase {
let expectation = self.expectationWithDescription("testDeleteUser")
UserAPI.deleteUser(username: "test@test.com") { (error) in
// The server gives us no data back so Alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
guard let error = error where error._code == -6006 else {
guard error == nil else {
XCTFail("error deleting user")
return
}
expectation.fulfill()
}

View File

@ -160,13 +160,13 @@ public class PetAPI: APIBase {
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example={
- examples: [{contentType=application/json, example={
"name" : "Puma",
"type" : "Dog",
"color" : "Black",
"gender" : "Female",
"breed" : "Mixed"
}, contentType=application/json}]
}}]
- parameter status: (query) Status values that need to be considered for filter (optional, default to available)
@ -226,20 +226,20 @@ public class PetAPI: APIBase {
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
- examples: [{contentType=application/json, example=[ {
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
} ]}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -248,21 +248,21 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example=[ {
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
</Pet>}]
- examples: [{contentType=application/json, example=[ {
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
} ], contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
} ]}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -271,7 +271,7 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
</Pet>}]
- parameter tags: (query) Tags to filter by (optional)
@ -328,26 +328,26 @@ public class PetAPI: APIBase {
Find pet by ID
- GET /pet/{petId}
- Returns a pet when ID < 10. ID > 10 or nonintegers will simulate API error conditions
- API Key:
- type: apiKey api_key
- name: api_key
- OAuth:
- type: oauth2
- name: petstore_auth
- examples: [{example={
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
- API Key:
- type: apiKey api_key
- name: api_key
- examples: [{contentType=application/json, example={
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
}}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -356,21 +356,21 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
- examples: [{example={
"tags" : [ {
"id" : 123456789,
"name" : "aeiou"
} ],
</Pet>}]
- examples: [{contentType=application/json, example={
"photoUrls" : [ "aeiou" ],
"name" : "doggie",
"id" : 123456789,
"category" : {
"id" : 123456789,
"name" : "aeiou"
"name" : "aeiou",
"id" : 123456789
},
"status" : "aeiou",
"name" : "doggie",
"photoUrls" : [ "aeiou" ]
}, contentType=application/json}, {example=<Pet>
"tags" : [ {
"name" : "aeiou",
"id" : 123456789
} ],
"status" : "aeiou"
}}, {contentType=application/xml, example=<Pet>
<id>123456</id>
<name>doggie</name>
<photoUrls>
@ -379,7 +379,7 @@ public class PetAPI: APIBase {
<tags>
</tags>
<status>string</status>
</Pet>, contentType=application/xml}]
</Pet>}]
- parameter petId: (path) ID of pet that needs to be fetched

View File

@ -101,12 +101,12 @@ public class StoreAPI: APIBase {
- API Key:
- type: apiKey api_key
- name: api_key
- examples: [{example={
- examples: [{contentType=application/json, example={
"key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@d1e580af, contentType=application/xml}]
- examples: [{example={
}}, {contentType=application/xml, example=not implemented io.swagger.models.properties.MapProperty@d1e580af}]
- examples: [{contentType=application/json, example={
"key" : 123
}, contentType=application/json}, {example=not implemented io.swagger.models.properties.MapProperty@d1e580af, contentType=application/xml}]
}}, {contentType=application/xml, example=not implemented io.swagger.models.properties.MapProperty@d1e580af}]
- returns: RequestBuilder<[String:Int32]>
*/
@ -159,36 +159,36 @@ public class StoreAPI: APIBase {
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={
"id" : 123456789,
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
</Order>}]
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
</Order>}]
- parameter orderId: (path) ID of pet that needs to be fetched
@ -244,36 +244,36 @@ public class StoreAPI: APIBase {
Place an order for a pet
- POST /store/order
-
- examples: [{example={
"id" : 123456789,
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
</Order>}]
- examples: [{contentType=application/json, example={
"petId" : 123456789,
"complete" : true,
"status" : "aeiou",
"quantity" : 123,
"shipDate" : "2000-01-23T04:56:07.000+00:00"
}, contentType=application/json}, {example=<Order>
"id" : 123456789,
"shipDate" : "2000-01-23T04:56:07.000+00:00",
"complete" : true,
"status" : "aeiou"
}}, {contentType=application/xml, example=<Order>
<id>123456</id>
<petId>123456</petId>
<quantity>0</quantity>
<shipDate>2000-01-23T04:56:07.000Z</shipDate>
<status>string</status>
<complete>true</complete>
</Order>, contentType=application/xml}]
</Order>}]
- parameter body: (body) order placed for purchasing the pet (optional)

View File

@ -253,16 +253,16 @@ public class UserAPI: APIBase {
Get user by user name
- GET /user/{username}
-
- examples: [{example={
"id" : 123456789,
"lastName" : "aeiou",
"phone" : "aeiou",
"username" : "aeiou",
"email" : "aeiou",
"userStatus" : 123,
- examples: [{contentType=application/json, example={
"firstName" : "aeiou",
"password" : "aeiou"
}, contentType=application/json}, {example=<User>
"lastName" : "aeiou",
"password" : "aeiou",
"userStatus" : 123,
"phone" : "aeiou",
"id" : 123456789,
"email" : "aeiou",
"username" : "aeiou"
}}, {contentType=application/xml, example=<User>
<id>123456</id>
<username>string</username>
<firstName>string</firstName>
@ -271,17 +271,17 @@ public class UserAPI: APIBase {
<password>string</password>
<phone>string</phone>
<userStatus>0</userStatus>
</User>, contentType=application/xml}]
- examples: [{example={
"id" : 123456789,
"lastName" : "aeiou",
"phone" : "aeiou",
"username" : "aeiou",
"email" : "aeiou",
"userStatus" : 123,
</User>}]
- examples: [{contentType=application/json, example={
"firstName" : "aeiou",
"password" : "aeiou"
}, contentType=application/json}, {example=<User>
"lastName" : "aeiou",
"password" : "aeiou",
"userStatus" : 123,
"phone" : "aeiou",
"id" : 123456789,
"email" : "aeiou",
"username" : "aeiou"
}}, {contentType=application/xml, example=<User>
<id>123456</id>
<username>string</username>
<firstName>string</firstName>
@ -290,7 +290,7 @@ public class UserAPI: APIBase {
<password>string</password>
<phone>string</phone>
<userStatus>0</userStatus>
</User>, contentType=application/xml}]
</User>}]
- parameter username: (path) The name that needs to be fetched. Use user1 for testing.
@ -348,8 +348,8 @@ public class UserAPI: APIBase {
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}]
- examples: [{contentType=application/json, example="aeiou"}, {contentType=application/xml, example=string}]
- examples: [{contentType=application/json, example="aeiou"}, {contentType=application/xml, example=string}]
- parameter username: (query) The user name for login (optional)
- parameter password: (query) The password for login in clear text (optional)

View File

@ -63,7 +63,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
}
self.processRequest(uploadRequest, managerId, completion)
case .Failure(let encodingError):
completion(response: nil, error: encodingError)
completion(response: nil, error: ErrorResponse.Error(415, nil, encodingError))
}
}
)
@ -89,6 +89,46 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
let validatedRequest = request.validate()
switch T.self {
case is String.Type:
validatedRequest.responseString(completionHandler: { (stringResponse) in
cleanupRequest()
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()
@ -96,7 +136,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
if (dataResponse.result.isFailure) {
completion(
response: nil,
error: dataResponse.result.error
error: ErrorResponse.Error(dataResponse.response?.statusCode ?? 500, dataResponse.data, dataResponse.result.error!)
)
return
}
@ -114,7 +154,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
cleanupRequest()
if response.result.isFailure {
completion(response: nil, error: response.result.error)
completion(response: nil, error: ErrorResponse.Error(response.response?.statusCode ?? 500, response.data, response.result.error!))
return
}
@ -133,7 +173,7 @@ class AlamofireRequestBuilder<T>: RequestBuilder<T> {
return
}
completion(response: nil, error: NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"]))
completion(response: nil, error: ErrorResponse.Error(500, nil, NSError(domain: "localhost", code: 500, userInfo: ["reason": "unreacheable code"])))
}
}
}

View File

@ -10,18 +10,22 @@ protocol JSONEncodable {
func encodeToJSON() -> AnyObject
}
public enum ErrorResponse : ErrorType {
case Error(Int, NSData?, ErrorType)
}
public class Response<T> {
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 {

View File

@ -61,22 +61,8 @@ class PetAPITests: XCTestCase {
func test3DeletePet() {
let expectation = self.expectationWithDescription("testDeletePet")
PetAPI.deletePet(petId: 1000).always {
// expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server gives us no data back so alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
let error = errorType as NSError
if error.code == -6006 {
expectation.fulfill()
} else {
XCTFail("error logging out")
}
PetAPI.deletePet(petId: 1000).then {
expectation.fulfill()
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}

View File

@ -62,21 +62,7 @@ class StoreAPITests: XCTestCase {
func test3DeleteOrder() {
let expectation = self.expectationWithDescription("testDeleteOrder")
StoreAPI.deleteOrder(orderId: "1000").then {
expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server gives us no data back so alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
let error = errorType as NSError
if error.code == -6006 {
expectation.fulfill()
} else {
XCTFail("error deleting order")
}
expectation.fulfill()
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}

View File

@ -14,34 +14,11 @@ import XCTest
class UserAPITests: XCTestCase {
let testTimeout = 10.0
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testLogin() {
let expectation = self.expectationWithDescription("testLogin")
UserAPI.loginUser(username: "swiftTester", password: "swift").then { _ -> Void in
expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server isn't returning JSON - and currently the alamofire implementation
// always parses responses as JSON, so making an exception for this here
// Error Domain=NSCocoaErrorDomain Code=3840 "Invalid value around character 0."
// UserInfo={NSDebugDescription=Invalid value around character 0.}
let error = errorType as NSError
if error.code == 3840 {
expectation.fulfill()
} else {
XCTFail("error logging in")
}
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}
@ -49,21 +26,7 @@ class UserAPITests: XCTestCase {
func testLogout() {
let expectation = self.expectationWithDescription("testLogout")
UserAPI.logoutUser().then {
expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server gives us no data back so alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
let error = errorType as NSError
if error.code == -6006 {
expectation.fulfill()
} else {
XCTFail("error logging out")
}
expectation.fulfill()
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}
@ -80,21 +43,7 @@ class UserAPITests: XCTestCase {
newUser.username = "test@test.com"
newUser.userStatus = 0
UserAPI.createUser(body: newUser).then {
expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server gives us no data back so alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
let error = errorType as NSError
if error.code == -6006 {
expectation.fulfill()
} else {
XCTFail("error creating user")
}
expectation.fulfill()
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}
@ -120,21 +69,7 @@ class UserAPITests: XCTestCase {
func test3DeleteUser() {
let expectation = self.expectationWithDescription("testDeleteUser")
UserAPI.deleteUser(username: "test@test.com").then {
expectation.fulfill()
}.always {
// Noop for now
}.error { errorType -> Void in
// The server gives us no data back so alamofire parsing fails - at least
// verify that is the error we get here
// Error Domain=com.alamofire.error Code=-6006 "JSON could not be serialized. Input data was nil or zero
// length." UserInfo={NSLocalizedFailureReason=JSON could not be serialized. Input data was nil or zero
// length.}
let error = errorType as NSError
if error.code == -6006 {
expectation.fulfill()
} else {
XCTFail("error logging out")
}
expectation.fulfill()
}
self.waitForExpectationsWithTimeout(testTimeout, handler: nil)
}