Import a complex JSON #28

Closed
opened 2025-12-29 15:22:33 +01:00 by adam · 5 comments
Owner

Originally created by @brosnic on GitHub (Jan 14, 2016).

What's the suggested way to import a complex JSON?

Example:

JSON from Webservice:

{  
   "connections":[  
      {  
         "connectionSections":[  
            {  
               "departureTime":"16:12",
               "departureDate":"2016-01-14",
               "departureName":"CityA",
               "transportDescription":{  
                  "transportIcon":"",
                  "transportLabel":"S 44",
                  "transportText":"16456",
                  "transportDirection":"CityB",
               },
               "transportHint":null,
               "type":"TRANSPORT",
               "actionUrl":"v0/zuglauf/309287/2/95/008507000%2395/2016-01-12/16-12?von=Bern&nach=Thun",
               "arrivalTime":"16:51",
               "arrivalDate":"2016-01-14",
               "arrivalName":"CityB",
            }
         ],
         "departure":"CityA",
         "arrival":"CityB",
         "transfers":0,
         "duration":"0:39 h",
         "transportDescription":{  
            "transportIcon":"",
            "transportLabel":"S 44",
            "transportText":"16456",
            "transportDirection":"CityB",
         },
      }
    ],
   "departure":{  
      "displayName":"CityA",
      "externalId":"008507000#95",
      "type":"STATION",
      "longitude":6439122,
      "latitude":49948825
   },
   "arrival":{  
      "displayName":"CityB",
      "externalId":"008507100#95",
      "type":"STATION",
      "longitude":6629594,
      "latitude":49754856
   },
   "earlierUrl":"v0/connections/scroll/earlier/6l.02930220.1452611750%231",
   "laterUrl":"v0/connections/scroll/later/6l.02930220.1452611750%231"
}

CoreData Entities:

ConnectionInfo:

attributes:
  • earlierUrl
  • laterUrl
relationships:
  • one-to-many: connections (Entity: Connection)
  • one-to-one: departure (Entity: Station)
  • one-to-one: arrival (Entity: Station)

Connection:

attributes:
  • departure
  • arrival
  • transfers
  • duration
relationships:
  • one-to-many: connectionSections (Entity: ConnectionSection)
  • one-to-one: transportDescription (Entity: TransportDescription)

and so on.

Is there a way to still use transaction.importObjects(Into(ConnectionInfo), source: jsonDictionary)?

Originally created by @brosnic on GitHub (Jan 14, 2016). What's the suggested way to import a complex JSON? ## Example: ### JSON from Webservice: ``` { "connections":[ { "connectionSections":[ { "departureTime":"16:12", "departureDate":"2016-01-14", "departureName":"CityA", "transportDescription":{ "transportIcon":"", "transportLabel":"S 44", "transportText":"16456", "transportDirection":"CityB", }, "transportHint":null, "type":"TRANSPORT", "actionUrl":"v0/zuglauf/309287/2/95/008507000%2395/2016-01-12/16-12?von=Bern&nach=Thun", "arrivalTime":"16:51", "arrivalDate":"2016-01-14", "arrivalName":"CityB", } ], "departure":"CityA", "arrival":"CityB", "transfers":0, "duration":"0:39 h", "transportDescription":{ "transportIcon":"", "transportLabel":"S 44", "transportText":"16456", "transportDirection":"CityB", }, } ], "departure":{ "displayName":"CityA", "externalId":"008507000#95", "type":"STATION", "longitude":6439122, "latitude":49948825 }, "arrival":{ "displayName":"CityB", "externalId":"008507100#95", "type":"STATION", "longitude":6629594, "latitude":49754856 }, "earlierUrl":"v0/connections/scroll/earlier/6l.02930220.1452611750%231", "laterUrl":"v0/connections/scroll/later/6l.02930220.1452611750%231" } ``` ### CoreData Entities: #### ConnectionInfo: ##### attributes: - earlierUrl - laterUrl ##### relationships: - one-to-many: connections (Entity: Connection) - one-to-one: departure (Entity: Station) - one-to-one: arrival (Entity: Station) #### Connection: ##### attributes: - departure - arrival - transfers - duration ##### relationships: - one-to-many: connectionSections (Entity: ConnectionSection) - one-to-one: transportDescription (Entity: TransportDescription) and so on. Is there a way to still use transaction.importObjects(Into(ConnectionInfo), source: jsonDictionary)?
adam added the question label 2025-12-29 15:22:33 +01:00
adam closed this issue 2025-12-29 15:22:34 +01:00
Author
Owner

@JohnEstropia commented on GitHub (Jan 14, 2016):

@brosnic Sure it should work. If you check methods for the ImportableObject and ImportableUniqueObject protocols, the transaction is always passed:

func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws

This lets you do nested imports inside your implementation. Something like this:

class ConnectionInfo: NSManagedObject, ImportableObject {
    // ...
    func didInsertFromImportSource(source: [NSString: AnyObject], inTransaction transaction: BaseDataTransaction) throws {
        self.earlierUrl = source["earlierUrl"] as? String
        self.laterUrl = source["laterUrl"] as? String
        // Here's how you can set relationships:
        self.connections = transaction.importObjects(Into(Connection), sourceArray: source["connections"] as? [[NSString: AnyObject]]) // one-to-many
        self.departure = transaction.importObject(Into(Station), source: source["departure"] as? [NSString: AnyObject]) // one-to-one
         //... etc
    }
@JohnEstropia commented on GitHub (Jan 14, 2016): @brosnic Sure it should work. If you check methods for the `ImportableObject` and `ImportableUniqueObject` protocols, the transaction is always passed: ``` swift func didInsertFromImportSource(source: ImportSource, inTransaction transaction: BaseDataTransaction) throws ``` This lets you do nested imports inside your implementation. Something like this: ``` swift class ConnectionInfo: NSManagedObject, ImportableObject { // ... func didInsertFromImportSource(source: [NSString: AnyObject], inTransaction transaction: BaseDataTransaction) throws { self.earlierUrl = source["earlierUrl"] as? String self.laterUrl = source["laterUrl"] as? String // Here's how you can set relationships: self.connections = transaction.importObjects(Into(Connection), sourceArray: source["connections"] as? [[NSString: AnyObject]]) // one-to-many self.departure = transaction.importObject(Into(Station), source: source["departure"] as? [NSString: AnyObject]) // one-to-one //... etc } ```
Author
Owner

@brosnic commented on GitHub (Jan 14, 2016):

Thank you!

@brosnic commented on GitHub (Jan 14, 2016): Thank you!
Author
Owner

@ro22e0 commented on GitHub (Mar 21, 2017):

Hello,

I want to set relationship but I don't know how to deal with NSSet and importUniqueObjects

Thanks in advance,

@ro22e0 commented on GitHub (Mar 21, 2017): Hello, I want to set relationship but I don't know how to deal with NSSet and importUniqueObjects Thanks in advance,
Author
Owner

@JohnEstropia commented on GitHub (Mar 22, 2017):

@ro22e0 Hi, I'm not sure which one is your use-case, but here are examples.

CoreStore.beginAsynchronous { (transaction) in
    // ...
    do {
        let friends: [Person] = transaction.importUniqueObjects(
            Into(Person.self),
            sourceArray: json // Array of your ImportSource
        )
        
        // Case 1: If you need to reset the whole NSSet
        person.friends = NSSet(array: friends)
        
        // Case 2: If you need to append
        //     Method 1: Use KVC
        person
            .mutableSetValue(forKey: #keyPath(Person.friends))
            .addObjects(from: friends)

        //    Method 2: Copy and mutate
        var friendsCopy = Array(person.friends)
        friendsCopy.append(contentsOf: friends)
        person.friends = NSSet(array: friendsCopy)
    }
    catch {
        // handle error
    }
    transaction.commit  { (result) in
        // ...
    }
}
@JohnEstropia commented on GitHub (Mar 22, 2017): @ro22e0 Hi, I'm not sure which one is your use-case, but here are examples. ```swift CoreStore.beginAsynchronous { (transaction) in // ... do { let friends: [Person] = transaction.importUniqueObjects( Into(Person.self), sourceArray: json // Array of your ImportSource ) // Case 1: If you need to reset the whole NSSet person.friends = NSSet(array: friends) // Case 2: If you need to append // Method 1: Use KVC person .mutableSetValue(forKey: #keyPath(Person.friends)) .addObjects(from: friends) // Method 2: Copy and mutate var friendsCopy = Array(person.friends) friendsCopy.append(contentsOf: friends) person.friends = NSSet(array: friendsCopy) } catch { // handle error } transaction.commit { (result) in // ... } } ```
Author
Owner

@ro22e0 commented on GitHub (Mar 23, 2017):

Thanks a lot !

@ro22e0 commented on GitHub (Mar 23, 2017): Thanks a lot !
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/CoreStore#28