Di bawah ini kelas
class User: NSManagedObject {
@NSManaged var id: Int
@NSManaged var name: String
}
Perlu dikonversi ke
{
"id" : 98,
"name" : "Jon Doe"
}
Saya mencoba secara manual lewat objek untuk fungsi yang menetapkan variabel-variabel ke dalam sebuah kamus dan pengembalian kamus. Tapi aku akan ingin cara yang lebih baik untuk mencapai hal ini.
Di Swift 4, anda dapat mewarisi dari Codable
jenis.
struct Dog: Codable {
var name: String
var owner: String
}
// Encode
let dog = Dog(name: "Rex", owner: "Etgar")
let jsonEncoder = JSONEncoder()
let jsonData = try jsonEncoder.encode(dog)
let json = String(data: jsonData, encoding: String.Encoding.utf16)
// Decode
let jsonDecoder = JSONDecoder()
let dog = try jsonDecoder.decode(Dog.self, from: jsonData)
Selain Swift 4 (Foundation) sekarang itu adalah native didukung di kedua cara, JSON string ke objek - objek JSON string. Silahkan lihat Apple's dokumentasi di sini JSONDecoder() dan di sini JSONEncoder()
String JSON ke Object
let jsonData = jsonString.data(using: .utf8)!
let decoder = JSONDecoder()
let myStruct = try! decoder.decode(myStruct.self, from: jsonData)
Swift Objek untuk JSONString
let encoder = JSONEncoder()
encoder.outputFormatting = .prettyPrinted
let data = try! encoder.encode(myStruct)
print(String(data: data, encoding: .utf8)!)
Anda dapat menemukan semua rincian dan contoh-contoh berikut ini Panduan Ultimate untuk Parsing JSON Dengan Cepat 4
UPDATE: Codable
protokol diperkenalkan di Swift 4 harus cukup untuk sebagian besar JSON
parsing kasus. Di bawah ini jawabannya adalah untuk orang-orang yang terjebak di versi sebelumnya dari Swift dan untuk alasan warisan
NSDictionary
, majic jungle software
, Dicetak
, Hashable
dan Equatable
Contoh:
class User: EVObject { # extend EVObject method for the class
var id: Int = 0
var name: String = ""
var friends: [User]? = []
}
# use like below
let json:String = "{\"id\": 24, \"name\": \"Bob Jefferson\", \"friends\": [{\"id\": 29, \"name\": \"Jen Jackson\"}]}"
let user = User(json: json)
Contoh:
class User: Mappable { # extend Mappable method for the class
var id: Int?
var name: String?
required init?(_ map: Map) {
}
func mapping(map: Map) { # write mapping code
name <- map["name"]
id <- map["id"]
}
}
# use like below
let json:String = "{\"id\": 24, \"name\": \"Bob Jefferson\", \"friends\": [{\"id\": 29, \"name\": \"Jen Jackson\"}]}"
let user = Mapper<User>().map(json)
Saya bekerja sedikit lebih kecil solusi yang doesn't membutuhkan warisan. Tapi itu belum't telah diuji banyak. It's cukup jelek atm.
https://github.com/peheje/JsonSerializerSwift
Anda dapat lulus ke sebuah taman bermain untuk menguji itu. E. g. berikut struktur kelas:
//Test nonsense data
class Nutrient {
var name = "VitaminD"
var amountUg = 4.2
var intArray = [1, 5, 9]
var stringArray = ["nutrients", "are", "important"]
}
class Fruit {
var name: String = "Apple"
var color: String? = nil
var weight: Double = 2.1
var diameter: Float = 4.3
var radius: Double? = nil
var isDelicious: Bool = true
var isRound: Bool? = nil
var nullString: String? = nil
var date = NSDate()
var optionalIntArray: Array<Int?> = [1, 5, 3, 4, nil, 6]
var doubleArray: Array<Double?> = [nil, 2.2, 3.3, 4.4]
var stringArray: Array<String> = ["one", "two", "three", "four"]
var optionalArray: Array<Int> = [2, 4, 1]
var nutrient = Nutrient()
}
var fruit = Fruit()
var json = JSONSerializer.toJson(fruit)
print(json)
cetakan
{"name": "Apple", "color": null, "weight": 2.1, "diameter": 4.3, "radius": null, "isDelicious": true, "isRound": null, "nullString": null, "date": "2015-06-19 22:39:20 +0000", "optionalIntArray": [1, 5, 3, 4, null, 6], "doubleArray": [null, 2.2, 3.3, 4.4], "stringArray": ["one", "two", "three", "four"], "optionalArray": [2, 4, 1], "nutrient": {"name": "VitaminD", "amountUg": 4.2, "intArray": [1, 5, 9], "stringArray": ["nutrients", "are", "important"]}}
Ini bukan pilihan/solusi otomatis tapi saya percaya ini adalah idiomatic dan asli cara untuk melakukan hal tersebut. Dengan cara ini anda don't perlu setiap perpustakaan atau seperti.
Membuat sebuah protokol seperti:
/// A generic protocol for creating objects which can be converted to JSON
protocol JSONSerializable {
private var dict: [String: Any] { get }
}
extension JSONSerializable {
/// Converts a JSONSerializable conforming class to a JSON object.
func json() rethrows -> Data {
try JSONSerialization.data(withJSONObject: self.dict, options: nil)
}
}
Kemudian menerapkannya di kelas anda seperti:
class User: JSONSerializable {
var id: Int
var name: String
var dict { return ["id": self.id, "name": self.name] }
}
Sekarang:
let user = User(...)
let json = user.json()
Catatan: jika anda ingin json
sebagai string, hal ini sangat sederhana untuk mengkonversi string: String(data: json, encoding .utf8)
Beberapa hal di atas jawaban yang benar-benar baik-baik saja, tapi aku menambahkan ekstensi di sini, hanya untuk membuatnya lebih mudah dibaca dan digunakan.
extension Encodable {
var convertToString: String? {
let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = .prettyPrinted
do {
let jsonData = try jsonEncoder.encode(self)
return String(data: jsonData, encoding: .utf8)
} catch {
return nil
}
}
}
struct User: Codable {
var id: Int
var name: String
}
let user = User(id: 1, name: "name")
print(user.convertToString!)
//Cetak ini akan seperti berikut:
{
"id" : 1,
"name" : "name"
}
Tidak yakin jika lib/framework yang ada, tapi jika anda ingin melakukannya secara otomatis dan anda akan ingin menghindari tenaga kerja manual :-) tetap dengan MirrorType
...
class U {
var id: Int
var name: String
init(id: Int, name: String) {
self.id = id
self.name = name
}
}
extension U {
func JSONDictionary() -> Dictionary<String, Any> {
var dict = Dictionary<String, Any>()
let mirror = reflect(self)
var i: Int
for i = 0 ; i < mirror.count ; i++ {
let (childName, childMirror) = mirror[i]
// Just an example how to check type
if childMirror.valueType is String.Type {
dict[childName] = childMirror.value
} else if childMirror.valueType is Int.Type {
// Convert to NSNumber for example
dict[childName] = childMirror.value
}
}
return dict
}
}
Menganggapnya sebagai kasar contoh, kurang tepat konversi dukungan, kekurangan rekursi, ... Itu's hanya MirrorType
demonstrasi ...
P. S. Berikut ini's dilakukan di U
, tapi anda're akan meningkatkan NSManagedObject
dan kemudian anda'akan dapat mengkonversi semua NSManagedObject
subclass. Tidak perlu untuk menerapkan ini dalam semua subclass/dikelola benda-benda.
struct User:Codable{
var id:String?
var name:String?
init(_ id:String,_ name:String){
self.id = id
self.name = name
}
}
Sekarang hanya membuat objek anda seperti ini
biarkan user = user("1","pawan")
do{
let userJson = data: try JSONEncoder().encode(parentMessage), encoding:.utf8)
}catch{
fatalError("Unable To Convert in Json")
}
Kemudian reconvert dari json ke Object
let jsonDecoder = JSONDecoder()
do{
let convertedUser = try jsonDecoder.decode(User.self, from: userJson.data(using: .utf8)!)
}catch{
}