Daisy R.
Daisy R.

Reputation: 633

Save json dictionary to core data Swift 3

I am able to get the last guest dictionary value in the json array saved into core data as a dictionary using the transformable key value however the other guest dictionary values are not saving. Guest is also it's on entity for now but I was hoping to save the guest as a dictionary since this task doesn't require complex relationships. I'm sure I'm looking through the json, the value type for reservation.guest = [AnyHashable: Any]?Any suggestions would be helpful here is my json response https://pastebin.com/J28myW66, thanks

Note: using Alamofire for the HTTP Request. Also haven't included my entire class here as this is the main part of it. Reservation and Guest are both NSManagedObject classes

    let managedObjectContext = CoreDataManager.shared.persistentContainer.viewContext

    let reservationEntityDescription = NSEntityDescription.entity(forEntityName: "Reservation", in: managedObjectContext)
    let guestEntityDescription = NSEntityDescription.entity(forEntityName: "Guest", in: managedObjectContext)

    let reservation = Reservation(entity: reservationEntityDescription!, insertInto: managedObjectContext)
    let guest = Guest(entity: guestEntityDescription!, insertInto: managedObjectContext)


    let url = "\(serverEndpoint)\(path)"

    manager?.request(
        url
        ).responseJSON { responseData in

            if(responseData.result.error != nil) {

                print(responseData.response)
            }
            else if responseData.result.value != nil{


                let json = JSON(responseData.result.value!)

               let content = json["data"]

                    var reservationArray: [String] = []
                    if let dates = content.array {
                        for item in dates {
                            if let str = item["date_time"].string {
                                reservationArray.append(str)
                                print(reservationArray)
                            }
                        }

                    }

                    for (key,obj) in content {

                        let guestData = obj["guest"]
                        let guestDict = guestData.dictionaryObject!

                        reservation.guest = guestDict
                        reservation.id = obj["id"].stringValue
                        reservation.dateTime = obj["date_time"].date
                        reservation.startTime = obj["start_time"].time 
                        reservation.numOfPeople = obj["number_of_people"].intValue as NSNumber?
                        reservation.status = obj["status"].stringValue
                        reservation.tables = obj["tables"].arrayObject as! [NSString]?
                        reservation.reservationCollections = reservationArray as [NSString]?

                        guest.id = guestData["id"].stringValue
                        guest.email = guestData["email"].stringValue
                        guest.name = guestData["full_name"].stringValue
                        guest.phone = guestData["phone"].stringValue
                        guest.notes = guestData["notes"].stringValue

                    }
                     print("Reservation to be saved\(reservation)")
                     print("Guest to be saved: \(guest)")
             }
       }

               do {
                    try reservation.managedObjectContext?.save()

                    } catch let error as NSError {

                        fatalError(error.localizedDescription)

                    }

                do {
                    try guest.managedObjectContext?.save()

                } catch let error as NSError {

                    fatalError(error.localizedDescription)

                }

Upvotes: 0

Views: 6373

Answers (2)

Tom Harrington
Tom Harrington

Reputation: 70946

When your code starts, you create one instance of Guest and one instance of Reservation:

let reservation = Reservation(entity: reservationEntityDescription!, insertInto: managedObjectContext)
let guest = Guest(entity: guestEntityDescription!, insertInto: managedObjectContext)

After that you never create any other instances. In your loop you assign values to this instance:

reservation.guest = guestDict
reservation.id = obj["id"].stringValue
...

guest.id = guestData["id"].stringValue
guest.email = guestData["email"].stringValue
...

But since there's only one instance, only the last pass through the loop gets saved. The first time through the loop you assign values to guest and reservation. Every other time, you overwrite the previous values with new ones.

If you want to save a new instance for every pass through the loop, you need to create new instances every time. Move the let guest = ... and let reservation = ... lines inside the loop.

Upvotes: 2

Abhishek Thapliyal
Abhishek Thapliyal

Reputation: 3708

Firstly you need to make design flow bit generic i.e The HTTP request/response, DataBase Part, Model Part and UI part.

Now create a generic model class for your response, so that the values will bind in single object. In you core data sub class your table i.e custom NSManagedObject Class.

First convert the dictionary objects [objects in content.array] into respective model class objects.

In that SBPlayer is a model class

Favourite+CoreDataProperties.swift & Favourite+CoreDataClass.swift are custom NSManagedObject class (auto-generated).

Now with every object, you have mapping respective properties in database table and in custom NSManagedObject class.

Map the values and Save it DataBase.

For example: https://github.com/Abhishek9634/ScoreBoard/blob/master/ScoreBoard/ScoreBoard/SBDBManager.swift

Reference : https://github.com/Abhishek9634/ScoreBoard

Upvotes: 0

Related Questions