Efficiently structuring data with protocol oriented approach in Swift

 Clash Royale CLAN TAG#URR8PPP
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
0
down vote
favorite
I need to integrate some server API calling in which I'm likely to get response as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Verification Message from API",
 "result": 
 "values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
 ]
 
 
Sometimes the response will be as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Update Message from API",
 "result": 
 "values": [
 
 "update_status": true
 
 ]
 
 
As you can see, mostly all the fields of the response body are pretty much same. The only distinction is going to be in the section:
"values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
]
or,
"values": [
 
 "update_status": true
 
]
I have followed the Protocol Oriented Programming (POP) pattern for my use case.
Solution:
struct Value 
 let verifyStatus: Bool?
 let updateStatus: Bool?
 let tokenKey: String?
extension Value: Codable 
 private enum ValueCodingKeys: String, CodingKey 
 case verifyStatus = "verify_status"
 case updateStatus = "update_status"
 case tokenKey = "token_key"
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ValueCodingKeys.self)
 try container.encode(verifyStatus, forKey: .verifyStatus)
 try container.encode(updateStatus, forKey: .updateStatus)
 try container.encode(tokenKey, forKey: .tokenKey)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ValueCodingKeys.self)
 verifyStatus = try container.decodeIfPresent(Bool.self, forKey: .verifyStatus)
 updateStatus = try container.decodeIfPresent(Bool.self, forKey: .updateStatus)
 tokenKey = try container.decodeIfPresent(String.self, forKey: .tokenKey)
 
protocol Resultable 
 var values: [Value] get 
struct Result: Resultable 
 let values: [Value]
extension Result: Codable 
 private enum ResultCodingKeys: String, CodingKey 
 case values
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResultCodingKeys.self)
 try container.encode(values, forKey: .values)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResultCodingKeys.self)
 values = try container.decode([Value].self, forKey: .values)
 
protocol Responsable 
 var code: Int get 
 var status: String get 
 var message: String get 
 var result: Result get 
struct Response: Responsable 
 let code: Int
 let status: String
 let message: String
 let result: Result
extension Response: Codable 
 private enum ResponeCodingKeys: String, CodingKey 
 case code
 case status
 case message
 case result
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResponeCodingKeys.self)
 try container.encode(code, forKey: .code)
 try container.encode(status, forKey: .status)
 try container.encode(message, forKey: .message)
 try container.encode(result, forKey: .result)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResponeCodingKeys.self)
 code = try container.decode(Int.self, forKey: .code)
 status = try container.decode(String.self, forKey: .status)
 message = try container.decode(String.self, forKey: .message)
 result = try container.decode(Result.self, forKey: .result)
 
I think I'm over-complicating the solution. Is there any better solution to achieve this?
Do I really have to have two
protocoldefined?
json swift protocols
add a comment |Â
up vote
0
down vote
favorite
I need to integrate some server API calling in which I'm likely to get response as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Verification Message from API",
 "result": 
 "values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
 ]
 
 
Sometimes the response will be as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Update Message from API",
 "result": 
 "values": [
 
 "update_status": true
 
 ]
 
 
As you can see, mostly all the fields of the response body are pretty much same. The only distinction is going to be in the section:
"values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
]
or,
"values": [
 
 "update_status": true
 
]
I have followed the Protocol Oriented Programming (POP) pattern for my use case.
Solution:
struct Value 
 let verifyStatus: Bool?
 let updateStatus: Bool?
 let tokenKey: String?
extension Value: Codable 
 private enum ValueCodingKeys: String, CodingKey 
 case verifyStatus = "verify_status"
 case updateStatus = "update_status"
 case tokenKey = "token_key"
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ValueCodingKeys.self)
 try container.encode(verifyStatus, forKey: .verifyStatus)
 try container.encode(updateStatus, forKey: .updateStatus)
 try container.encode(tokenKey, forKey: .tokenKey)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ValueCodingKeys.self)
 verifyStatus = try container.decodeIfPresent(Bool.self, forKey: .verifyStatus)
 updateStatus = try container.decodeIfPresent(Bool.self, forKey: .updateStatus)
 tokenKey = try container.decodeIfPresent(String.self, forKey: .tokenKey)
 
protocol Resultable 
 var values: [Value] get 
struct Result: Resultable 
 let values: [Value]
extension Result: Codable 
 private enum ResultCodingKeys: String, CodingKey 
 case values
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResultCodingKeys.self)
 try container.encode(values, forKey: .values)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResultCodingKeys.self)
 values = try container.decode([Value].self, forKey: .values)
 
protocol Responsable 
 var code: Int get 
 var status: String get 
 var message: String get 
 var result: Result get 
struct Response: Responsable 
 let code: Int
 let status: String
 let message: String
 let result: Result
extension Response: Codable 
 private enum ResponeCodingKeys: String, CodingKey 
 case code
 case status
 case message
 case result
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResponeCodingKeys.self)
 try container.encode(code, forKey: .code)
 try container.encode(status, forKey: .status)
 try container.encode(message, forKey: .message)
 try container.encode(result, forKey: .result)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResponeCodingKeys.self)
 code = try container.decode(Int.self, forKey: .code)
 status = try container.decode(String.self, forKey: .status)
 message = try container.decode(String.self, forKey: .message)
 result = try container.decode(Result.self, forKey: .result)
 
I think I'm over-complicating the solution. Is there any better solution to achieve this?
Do I really have to have two
protocoldefined?
json swift protocols
add a comment |Â
up vote
0
down vote
favorite
up vote
0
down vote
favorite
I need to integrate some server API calling in which I'm likely to get response as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Verification Message from API",
 "result": 
 "values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
 ]
 
 
Sometimes the response will be as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Update Message from API",
 "result": 
 "values": [
 
 "update_status": true
 
 ]
 
 
As you can see, mostly all the fields of the response body are pretty much same. The only distinction is going to be in the section:
"values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
]
or,
"values": [
 
 "update_status": true
 
]
I have followed the Protocol Oriented Programming (POP) pattern for my use case.
Solution:
struct Value 
 let verifyStatus: Bool?
 let updateStatus: Bool?
 let tokenKey: String?
extension Value: Codable 
 private enum ValueCodingKeys: String, CodingKey 
 case verifyStatus = "verify_status"
 case updateStatus = "update_status"
 case tokenKey = "token_key"
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ValueCodingKeys.self)
 try container.encode(verifyStatus, forKey: .verifyStatus)
 try container.encode(updateStatus, forKey: .updateStatus)
 try container.encode(tokenKey, forKey: .tokenKey)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ValueCodingKeys.self)
 verifyStatus = try container.decodeIfPresent(Bool.self, forKey: .verifyStatus)
 updateStatus = try container.decodeIfPresent(Bool.self, forKey: .updateStatus)
 tokenKey = try container.decodeIfPresent(String.self, forKey: .tokenKey)
 
protocol Resultable 
 var values: [Value] get 
struct Result: Resultable 
 let values: [Value]
extension Result: Codable 
 private enum ResultCodingKeys: String, CodingKey 
 case values
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResultCodingKeys.self)
 try container.encode(values, forKey: .values)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResultCodingKeys.self)
 values = try container.decode([Value].self, forKey: .values)
 
protocol Responsable 
 var code: Int get 
 var status: String get 
 var message: String get 
 var result: Result get 
struct Response: Responsable 
 let code: Int
 let status: String
 let message: String
 let result: Result
extension Response: Codable 
 private enum ResponeCodingKeys: String, CodingKey 
 case code
 case status
 case message
 case result
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResponeCodingKeys.self)
 try container.encode(code, forKey: .code)
 try container.encode(status, forKey: .status)
 try container.encode(message, forKey: .message)
 try container.encode(result, forKey: .result)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResponeCodingKeys.self)
 code = try container.decode(Int.self, forKey: .code)
 status = try container.decode(String.self, forKey: .status)
 message = try container.decode(String.self, forKey: .message)
 result = try container.decode(Result.self, forKey: .result)
 
I think I'm over-complicating the solution. Is there any better solution to achieve this?
Do I really have to have two
protocoldefined?
json swift protocols
I need to integrate some server API calling in which I'm likely to get response as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Verification Message from API",
 "result": 
 "values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
 ]
 
 
Sometimes the response will be as:
+ Response 200 (application/json)
+ Body
 
 "code": 0,
 "status": "ok",
 "message": "Update Message from API",
 "result": 
 "values": [
 
 "update_status": true
 
 ]
 
 
As you can see, mostly all the fields of the response body are pretty much same. The only distinction is going to be in the section:
"values": [
 
 "verify_status": true,
 "token_key": "sure1ff45jk7858b8ae88a77fa30"
 
]
or,
"values": [
 
 "update_status": true
 
]
I have followed the Protocol Oriented Programming (POP) pattern for my use case.
Solution:
struct Value 
 let verifyStatus: Bool?
 let updateStatus: Bool?
 let tokenKey: String?
extension Value: Codable 
 private enum ValueCodingKeys: String, CodingKey 
 case verifyStatus = "verify_status"
 case updateStatus = "update_status"
 case tokenKey = "token_key"
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ValueCodingKeys.self)
 try container.encode(verifyStatus, forKey: .verifyStatus)
 try container.encode(updateStatus, forKey: .updateStatus)
 try container.encode(tokenKey, forKey: .tokenKey)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ValueCodingKeys.self)
 verifyStatus = try container.decodeIfPresent(Bool.self, forKey: .verifyStatus)
 updateStatus = try container.decodeIfPresent(Bool.self, forKey: .updateStatus)
 tokenKey = try container.decodeIfPresent(String.self, forKey: .tokenKey)
 
protocol Resultable 
 var values: [Value] get 
struct Result: Resultable 
 let values: [Value]
extension Result: Codable 
 private enum ResultCodingKeys: String, CodingKey 
 case values
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResultCodingKeys.self)
 try container.encode(values, forKey: .values)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResultCodingKeys.self)
 values = try container.decode([Value].self, forKey: .values)
 
protocol Responsable 
 var code: Int get 
 var status: String get 
 var message: String get 
 var result: Result get 
struct Response: Responsable 
 let code: Int
 let status: String
 let message: String
 let result: Result
extension Response: Codable 
 private enum ResponeCodingKeys: String, CodingKey 
 case code
 case status
 case message
 case result
 
 func encode(to encoder: Encoder) throws 
 var container = encoder.container(keyedBy: ResponeCodingKeys.self)
 try container.encode(code, forKey: .code)
 try container.encode(status, forKey: .status)
 try container.encode(message, forKey: .message)
 try container.encode(result, forKey: .result)
 
 init(from decoder: Decoder) throws 
 let container = try decoder.container(keyedBy: ResponeCodingKeys.self)
 code = try container.decode(Int.self, forKey: .code)
 status = try container.decode(String.self, forKey: .status)
 message = try container.decode(String.self, forKey: .message)
 result = try container.decode(Result.self, forKey: .result)
 
I think I'm over-complicating the solution. Is there any better solution to achieve this?
Do I really have to have two
protocoldefined?
json swift protocols
asked Feb 6 at 15:29


nayem
1012
1012
add a comment |Â
add a comment |Â
 1 Answer
 1
 
active
oldest
votes
up vote
1
down vote
Your intuition is correct: you don't need either the Resultable or the Responsable protocol. The reason is that each protocol only has one type that conforms to it. Protocols are great for sharing functionality among multiple types (using protocol extensions) or defining a set of guaranteed properties and behaviors common to a group of types. But the benefits only come when there is more than one type conforming to the protocol. Since your code only has one type conforming to each protocol, it's better for now to not have the protocol.
Also, this isn't part of your question but it might be worth investigating whether your implementation of Response is tied too closely to the structure of your JSON. As it is, a client would have to dig pretty far into a response's result value to get any useful information out of it. Redefining Result could bring the information forward and make things much easier on the client. For example:
enum Result 
 case verify(status: Bool, tokenKey: String)
 case update(status: Bool)
struct Response 
 let code: Int
 let status: String
 let message: String
 let result: Result
The Codable implementation would be more complicated, but I think greater simplicity at the call site is worth the effort. 
 
 
 
 
 
 
 Well, that's a pretty good explanation about- protocol. I appreciate your effort to look at this. But with your other proposal with- enumgot me something to be confused. What do I do with the- valuesproperty inside the- resultproperty if I'm going to implement it your suggested way? More precisely, how would I deserialize the- verifyStatus- updateStatus- tokenKeyinto the- result?
 â nayem
 Feb 8 at 17:17
 
 
 
 
 
 
 
 
 
 I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
 â proxpero
 Feb 9 at 15:54
 
 
 
add a comment |Â
 1 Answer
 1
 
active
oldest
votes
 1 Answer
 1
 
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
1
down vote
Your intuition is correct: you don't need either the Resultable or the Responsable protocol. The reason is that each protocol only has one type that conforms to it. Protocols are great for sharing functionality among multiple types (using protocol extensions) or defining a set of guaranteed properties and behaviors common to a group of types. But the benefits only come when there is more than one type conforming to the protocol. Since your code only has one type conforming to each protocol, it's better for now to not have the protocol.
Also, this isn't part of your question but it might be worth investigating whether your implementation of Response is tied too closely to the structure of your JSON. As it is, a client would have to dig pretty far into a response's result value to get any useful information out of it. Redefining Result could bring the information forward and make things much easier on the client. For example:
enum Result 
 case verify(status: Bool, tokenKey: String)
 case update(status: Bool)
struct Response 
 let code: Int
 let status: String
 let message: String
 let result: Result
The Codable implementation would be more complicated, but I think greater simplicity at the call site is worth the effort. 
 
 
 
 
 
 
 Well, that's a pretty good explanation about- protocol. I appreciate your effort to look at this. But with your other proposal with- enumgot me something to be confused. What do I do with the- valuesproperty inside the- resultproperty if I'm going to implement it your suggested way? More precisely, how would I deserialize the- verifyStatus- updateStatus- tokenKeyinto the- result?
 â nayem
 Feb 8 at 17:17
 
 
 
 
 
 
 
 
 
 I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
 â proxpero
 Feb 9 at 15:54
 
 
 
add a comment |Â
up vote
1
down vote
Your intuition is correct: you don't need either the Resultable or the Responsable protocol. The reason is that each protocol only has one type that conforms to it. Protocols are great for sharing functionality among multiple types (using protocol extensions) or defining a set of guaranteed properties and behaviors common to a group of types. But the benefits only come when there is more than one type conforming to the protocol. Since your code only has one type conforming to each protocol, it's better for now to not have the protocol.
Also, this isn't part of your question but it might be worth investigating whether your implementation of Response is tied too closely to the structure of your JSON. As it is, a client would have to dig pretty far into a response's result value to get any useful information out of it. Redefining Result could bring the information forward and make things much easier on the client. For example:
enum Result 
 case verify(status: Bool, tokenKey: String)
 case update(status: Bool)
struct Response 
 let code: Int
 let status: String
 let message: String
 let result: Result
The Codable implementation would be more complicated, but I think greater simplicity at the call site is worth the effort. 
 
 
 
 
 
 
 Well, that's a pretty good explanation about- protocol. I appreciate your effort to look at this. But with your other proposal with- enumgot me something to be confused. What do I do with the- valuesproperty inside the- resultproperty if I'm going to implement it your suggested way? More precisely, how would I deserialize the- verifyStatus- updateStatus- tokenKeyinto the- result?
 â nayem
 Feb 8 at 17:17
 
 
 
 
 
 
 
 
 
 I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
 â proxpero
 Feb 9 at 15:54
 
 
 
add a comment |Â
up vote
1
down vote
up vote
1
down vote
Your intuition is correct: you don't need either the Resultable or the Responsable protocol. The reason is that each protocol only has one type that conforms to it. Protocols are great for sharing functionality among multiple types (using protocol extensions) or defining a set of guaranteed properties and behaviors common to a group of types. But the benefits only come when there is more than one type conforming to the protocol. Since your code only has one type conforming to each protocol, it's better for now to not have the protocol.
Also, this isn't part of your question but it might be worth investigating whether your implementation of Response is tied too closely to the structure of your JSON. As it is, a client would have to dig pretty far into a response's result value to get any useful information out of it. Redefining Result could bring the information forward and make things much easier on the client. For example:
enum Result 
 case verify(status: Bool, tokenKey: String)
 case update(status: Bool)
struct Response 
 let code: Int
 let status: String
 let message: String
 let result: Result
The Codable implementation would be more complicated, but I think greater simplicity at the call site is worth the effort. 
Your intuition is correct: you don't need either the Resultable or the Responsable protocol. The reason is that each protocol only has one type that conforms to it. Protocols are great for sharing functionality among multiple types (using protocol extensions) or defining a set of guaranteed properties and behaviors common to a group of types. But the benefits only come when there is more than one type conforming to the protocol. Since your code only has one type conforming to each protocol, it's better for now to not have the protocol.
Also, this isn't part of your question but it might be worth investigating whether your implementation of Response is tied too closely to the structure of your JSON. As it is, a client would have to dig pretty far into a response's result value to get any useful information out of it. Redefining Result could bring the information forward and make things much easier on the client. For example:
enum Result 
 case verify(status: Bool, tokenKey: String)
 case update(status: Bool)
struct Response 
 let code: Int
 let status: String
 let message: String
 let result: Result
The Codable implementation would be more complicated, but I think greater simplicity at the call site is worth the effort. 
answered Feb 7 at 16:24


proxpero
1111
1111
 
 
 
 
 
 
 Well, that's a pretty good explanation about- protocol. I appreciate your effort to look at this. But with your other proposal with- enumgot me something to be confused. What do I do with the- valuesproperty inside the- resultproperty if I'm going to implement it your suggested way? More precisely, how would I deserialize the- verifyStatus- updateStatus- tokenKeyinto the- result?
 â nayem
 Feb 8 at 17:17
 
 
 
 
 
 
 
 
 
 I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
 â proxpero
 Feb 9 at 15:54
 
 
 
add a comment |Â
 
 
 
 
 
 
 Well, that's a pretty good explanation about- protocol. I appreciate your effort to look at this. But with your other proposal with- enumgot me something to be confused. What do I do with the- valuesproperty inside the- resultproperty if I'm going to implement it your suggested way? More precisely, how would I deserialize the- verifyStatus- updateStatus- tokenKeyinto the- result?
 â nayem
 Feb 8 at 17:17
 
 
 
 
 
 
 
 
 
 I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
 â proxpero
 Feb 9 at 15:54
 
 
 
Well, that's a pretty good explanation about
protocol. I appreciate your effort to look at this. But with your other proposal with enum got me something to be confused. What do I do with the values property inside the result property if I'm going to implement it your suggested way? More precisely, how would I deserialize the verifyStatus updateStatus tokenKey into the result?â nayem
Feb 8 at 17:17
Well, that's a pretty good explanation about
protocol. I appreciate your effort to look at this. But with your other proposal with enum got me something to be confused. What do I do with the values property inside the result property if I'm going to implement it your suggested way? More precisely, how would I deserialize the verifyStatus updateStatus tokenKey into the result?â nayem
Feb 8 at 17:17
I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
â proxpero
Feb 9 at 15:54
I think that's best asked as a separate question on Stack Overflow. You'll probably need to do something like this: stackoverflow.com/a/45147203/277905 but you'll have to extract /inject the values from the json array when you decode/encode them.
â proxpero
Feb 9 at 15:54
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f186924%2fefficiently-structuring-data-with-protocol-oriented-approach-in-swift%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password