我的代码是这样的:
enum API {
case login(phone:String, password:String, deviceID:String)
}
extension API:TargetType {
var task: Task {
switch self {
case let .login(phone, password, deviceID):
///How to get the parameter name here?
///For example:"phone", "password", "deviceID"
///Can this be generated automatically?
let parameters =
["phone":phone,
"password:":password,
"deviceID":deviceID]
return .requestParameters(parameters, encoding: JSONEncoding.default);
}
}
}
在Switch情况下如何获取参数名称? 例如:“电话”,“密码”,“设备ID” 可以自动生成吗?
如何避免按字面意义写“ phone”和其他字典键,并使编译器从关联的值标签生成它们。
也许完成后就是这样
func parameters(_ api:API) -> [String, Any] {
}
switch self {
case .login:
return .requestParameters(parameters(self), encoding: JSONEncoding.default);
}
看来暂时不可能完成。
谁是英雄?
答案 0 :(得分:2)
您可以将枚举案例的所有关联值分配给单个变量,然后使用它们的标签访问单独的值。
enum API {
case login(phone:String, password:String, deviceID:String)
}
extension API:TargetType {
var task: Task {
switch self {
case let .token(params)
let parameters =
["phone":params.phone,
"password:":params.password,
"deviceID":params.deviceID]
return .requestParameters(parameters, encoding: JSONEncoding.default);
}
}
}
顺便说一句,.token
不是.login
吗?您定义的.token
API
中没有enum
情况。
如果要生成Dictionary
键以匹配相关值标签的String
表示,则无法自动完成,但是作为一种变通方法,您可以使用{{ 1}}原始值,并将其用于String
键。
Dictionary
答案 1 :(得分:0)
有一些代码可以获取标签以及枚举的所有值。
public extension Enum {
public var associated: (label: String, value: Any?, values: Dictionary<String,Any>?) {
get {
let mirror = Mirror(reflecting: self)
if mirror.displayStyle == .enum {
if let associated = mirror.children.first {
let values = Mirror(reflecting: associated.value).children
var dict = Dictionary<String,Any>()
for i in values {
dict[i.label ?? ""] = i.value
}
return (associated.label!, associated.value, dict)
}
print("WARNING: Enum option of \(self) does not have an associated value")
return ("\(self)", nil, nil)
}
print("WARNING: You can only extend an enum with the EnumExtension")
return ("\(self)", nil, nil)
}
}
}
然后,您将可以获取枚举的.associated.label和.associated.value。在您的情况下,您的.value将是一个tupple。然后,您将需要使用.associated.values。不幸的是,您不会获得这些值的字段名称。因为它是个tupple,所以您将获得诸如.0,.1和.2。之类的字段名称。据我所知,无法获得实际的字段名称。
因此,在您的情况下,您的代码将如下所示:
enum API {
case login(phone:String, password:String, deviceID:String)
}
extension API:TargetType {
var task: Task {
return .requestParameters(self.associated.values, encoding: JSONEncoding.default);
}
}
但是,您仍然需要一些功能,以将键为.0,.1和.2的self.associated.values值转换为您喜欢的名称。我认为唯一的选择是让您自己进行映射。您可以使用该函数扩展枚举。
如果您想看到更多的枚举帮助器,请查看Stuff/Enum
答案 2 :(得分:-1)
您的开关应如下所示:
switch self {
case .login(let phone, let password, let deviceID)
let parameters =
["phone":phone,
"password:":password,
"deviceID":deviceID]
return .requestParameters(parameters, encoding: JSONEncoding.default);
}
Swift自动为您生成声明的变量
答案 3 :(得分:-1)
您可以查看有关Reflection in Swift的信息 您可以使其自动生成如下参数:
class ParameterAble {
func getParameters() -> [String: Any] {
var param = [String: Any]()
let childen = Mirror(reflecting: self).children
for item in childen {
guard let key = item.label else {
continue
}
param[key] = item.value
}
return param
}
}
class LoginData: ParameterAble {
var phone: String
var password: String
var deviceID: String
init(phone: String, password: String, deviceID: String) {
self.phone = phone
self.password = password
self.deviceID = deviceID
}
}
enum API {
case login(data: LoginData)
}
extension API {
var task: [String: Any] {
switch self {
case let .login(data):
return data.getParameters()
}
}
}
let loginData = LoginData(phone: "fooPhone", password: "fooPass", deviceID:
"fooId")
let login = API.login(data: loginData)
print(login.task)
这是输出:[“ phone”:“ fooPhone”,“ deviceID”:“ fooId”,“ password”:“ fooPass”]
您可以在Playground中尝试