问题
As the title states, I would like to iterate through a NSDictionary and save the single entries into an array of object type. I am currently struggling to read out the single entries of the NSDictionary, as I cannot simply call them with entry[index] and count upwards.
I've got a local JSON file named "Clients", which I get into swift. The file looks like this:
{
"clients": [
{
"id": 3895,
"phone": 0787623,
"age" : 23,
"customerSince" : 2008
},
{
"id": 9843,
"phone": 7263549,
"age" : 39,
"customerSince" : 2000
},
{
"id": 0994,
"phone": 1093609,
"age" : 42,
"customerSince" : 1997
}
]
}
What did I do? I created a class ClientObjects, which looks like this:
import Foundation
class ClientObjects{
var id : Int = 0;
var phone : Int = 0;
var age : Int = 0;
var customerSince : Int = 0;
}
Next I realized the JSON import into Swift, which works properly.
When I debug the session, the jsonResult variable contains the data of the JSON. But somehow I couldn't manage to process the data into the array of the object type ClientObjects.
// instantiate the ClientObjects as an Array
var clientsArray = [ClientObjects]();
func getData() {
if let path = NSBundle.mainBundle().pathForResource("Clients", ofType: "json")
{
if let jsonData = NSData(contentsOfFile:path)
{
do {
if let jsonResult = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableLeaves) as? NSDictionary
{
//print(jsonResult["clients"]);
// this print call returns the whole content of the JSON array
if let clients = jsonResult["clients"] as? [[String: AnyObject]] {
for client in clients {
clientsArray.append(client);
}
catch let error as NSError {
print("API error: \(error.debugDescription)")
}
}
}
}
}
The goal is, that I can print out single attributes of clients, like:
clientsArray[0].id;
Can somebody please give me some advice on my issue?
回答1:
First of all let's take a look at ClientObject.
- It should be a
struct - It should be simply named
Client - The properties should be constants without a default value
- It should have a failable initializer
- The
phoneshould be aString(please change your JSON accordingly)
Like this
struct Client {
let id: Int
let phone: String
let age: Int
let customerSince: Int
init?(json:[String:Any]) {
guard let
id = json["id"] as? Int,
phone = json["phone"] as? String,
age = json["age"] as? Int,
customerSince = json["customerSince"] as? Int else { return nil }
self.id = id
self.phone = phone
self.age = age
self.customerSince = customerSince
}
}
Now let's read the JSON
func getData() {
do {
guard let
path = NSBundle.mainBundle().pathForResource("Clients", ofType: "json"),
jsonData = NSData(contentsOfFile:path),
jsonResult = try NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableLeaves) as? NSDictionary,
jsonClients = jsonResult["clients"] as? [[String: Any]] else { return }
let clients = jsonClients.flatMap(Client.init) // <- now you have your array of Client
} catch let error as NSError {
print("API error: \(error.debugDescription)")
}
}
回答2:
You have to create ClientObjects objects and assign the values to the appropriate properties.
...
let jsonResult = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as! [String:AnyObject]
if let clients = jsonResult["clients"] as? [[String: Int]] {
for client in clients {
let newClient = ClientObjects()
newClient.id = client["id"]!
newClient.phone = client["phone"]!
newClient.age = client["age"]!
newClient.customerSince = client["customerSince"]!
clientsArray.append(newClient);
}
}
...
It's recommended to name classes with singular forms in this case ClientObject
And no if - let nor Foundation types like NSDictionary nor MutableLeaves options in the NSJSONSerialization line.
来源:https://stackoverflow.com/questions/35564194/iterate-through-nsdictionary-and-save-it-into-an-array-of-object-type