Che*_*ong 14 dictionary class object swift
例如:
class Test {
var name: String;
var age: Int;
var height: Double;
func convertToDict() -> [String: AnyObject] { ..... }
}
let test = Test();
test.name = "Alex";
test.age = 30;
test.height = 170;
let dict = test.convertToDict();
Run Code Online (Sandbox Code Playgroud)
dict将有内容:
{"name": "Alex", "age": 30, height: 170}
Run Code Online (Sandbox Code Playgroud)
这在Swift中可能吗?
我可以像字典一样访问类,例如可能使用:
test.value(forKey: "name");
Run Code Online (Sandbox Code Playgroud)
或类似的东西?
谢谢.
Leo*_*bus 36
您只需向您的计算属性添加struct
一个Dictionary
带有值的返回值即可.请注意,Swift本机字典类型没有任何调用方法value(forKey:)
.您需要将您投射Dictionary
到NSDictionary
:
struct Test {
let name: String
let age: Int
let height: Double
var dictionary: [String: Any] {
return ["name": name,
"age": age,
"height": height]
}
var nsDictionary: NSDictionary {
return dictionary as NSDictionary
}
}
Run Code Online (Sandbox Code Playgroud)
您还可以Encodable
按照@ColGraff发布的链接答案的建议扩展协议,使其适用于所有Encodable
结构:
struct JSON {
static let encoder = JSONEncoder()
}
extension Encodable {
subscript(key: String) -> Any? {
return dictionary[key]
}
var dictionary: [String: Any] {
return (try? JSONSerialization.jsonObject(with: JSON.encoder.encode(self))) as? [String: Any] ?? [:]
}
}
Run Code Online (Sandbox Code Playgroud)
struct Test: Codable {
let name: String
let age: Int
let height: Double
}
let test = Test(name: "Alex", age: 30, height: 170)
test["name"] // Alex
test["age"] // 30
test["height"] // 170
Run Code Online (Sandbox Code Playgroud)
您可以像这样使用Reflection和Mirror使其更具动态性,并确保您不会忘记属性。
struct Person {
var name:String
var position:Int
var good : Bool
var car : String
var asDictionary : [String:Any] {
let mirror = Mirror(reflecting: self)
let dict = Dictionary(uniqueKeysWithValues: mirror.children.lazy.map({ (label:String?,value:Any) -> (String,Any)? in
guard label != nil else { return nil }
return (label!,value)
}).compactMap{ $0 })
return dict
}
}
let p1 = Person(name: "Ryan", position: 2, good : true, car:"Ford")
print(p1.asDictionary)
Run Code Online (Sandbox Code Playgroud)
[“名称”:“ Ryan”,“位置”:2,“良好”:真实,“汽车”:“福特”]
聚会有点晚了,但我认为这对JSONEncoder
和来说是一个很好的机会JSONSerialization
。接受的答案确实涉及到这一点,这个解决方案让我们JSONSerialization
每次访问密钥时都可以调用,但同样的想法!
extension Encodable {
/// Encode into JSON and return `Data`
func jsonData() throws -> Data {
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
encoder.dateEncodingStrategy = .iso8601
return try encoder.encode(self)
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用JSONSerialization
创建一个Dictionary
ifEncodable
应该表示为 JSON 中的对象(例如 SwiftArray
将是一个 JSON 数组)。
这是一个例子:
struct Car: Encodable {
var name: String
var numberOfDoors: Int
var cost: Double
var isCompanyCar: Bool
var datePurchased: Date
var ownerName: String? // Optional
}
let car = Car(
name: "Mazda 2",
numberOfDoors: 5,
cost: 1234.56,
isCompanyCar: true,
datePurchased: Date(),
ownerName: nil
)
// Get the encoded JSON data
let jsonData = try car.jsonData()
// To get a dictionary from the JSON data
let json = try JSONSerialization.jsonObject(with: jsonData, options: [])
guard let dictionary = json as? [String : Any] else { return }
// Use dictionary...
// Print jsonString
guard let jsonString = String(data: jsonData, encoding: .utf8) else { return }
print(jsonString)
Run Code Online (Sandbox Code Playgroud)
输出:
{
"numberOfDoors" : 5,
"datePurchased" : "2020-03-04T16:04:13Z",
"name" : "Mazda 2",
"cost" : 1234.5599999999999,
"isCompanyCar" : true
}
Run Code Online (Sandbox Code Playgroud)