1

I need to save JSON Object retrieved into Core Data using some mapper ( Object Mapper, for example). I'm using a rest api that retrieve this json:

[
{
    "event_id": "1",
    "event_name": "Lungo il tevere",
    "event_image_url": "https:\/\/www.dayroma.it\/wp-content\/uploads\/2016\/06\/event_fb-9400.jpg",
    "event_content": "<b>Lungo il Tevere Roma 2016, bancarelle sulle banchine del Tevere<\/b>\r\n\r\n&nbsp;\r\n\r\n&nbsp;",
    "event_start_date": "2016-07-29",
    "event_end_date": "2016-07-30",
    "event_start_time": "22:00:00",
    "event_end_time": "03:00:00",
    "location_name": "Lungotevere",
    "location_address": "Piazza Navona 2, Roma",
    "location_latitude": "41.897785",
    "location_longitude": "12.472971"
},
{
    "event_id": "8",
    "event_name": "test 7 - VIlla BOrghese",
    "event_image_url": "https:\/\/www.dayroma.it\/wp-content\/uploads\/2016\/06\/event_fb-9398.jpg",
    "event_content": "TEst villa borghese",
    "event_start_date": "2016-07-29",
    "event_end_date": "2016-07-30",
    "event_start_time": "22:00:00",
    "event_end_time": "02:00:00",
    "location_name": "Villa Borghese",
    "location_address": "Villa Borghese 4, Roma",
    "location_latitude": "41.912888",
    "location_longitude": "12.485208"
}

]

Nothing special, a simple JSON array. I need to parse it into Data Objects and store into Core Data. Actually, I have problem about mapping Object into Core Data Object, because only String value are retrieve, the others are nil.

Here my dataController

class DataController: NSObject {

var managedObjectContext: NSManagedObjectContext

override  init() {
    // This resource is the same name as your xcdatamodeld contained in your project.
    guard let modelURL = NSBundle.mainBundle().URLForResource("DataModel", withExtension:"momd") else {
        fatalError("Error loading model from bundle")
    }
    // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model.
    guard let mom = NSManagedObjectModel(contentsOfURL: modelURL) else {
        fatalError("Error initializing mom from: \(modelURL)")
    }
    let psc = NSPersistentStoreCoordinator(managedObjectModel: mom)
    self.managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
    self.managedObjectContext.persistentStoreCoordinator = psc

    let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
    let docURL = urls[urls.endIndex-1]
    /* The directory the application uses to store the Core Data store file.
     This code uses a file named "DataModel.sqlite" in the application's documents directory.
     */
    let storeURL = docURL.URLByAppendingPathComponent("DataModel.sqlite")
    do {
        try psc.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: storeURL, options: nil)
    } catch {
        fatalError("Error migrating store: \(error)")
    }

}

}

HERE my object core properties:

extension Event {

@NSManaged var eventId: Int
@NSManaged var eventName: String?
@NSManaged var eventImageUrl: String?
@NSManaged var eventContent: String?
@NSManaged var eventStartTime: NSDate?
@NSManaged var eventEndTime: NSDate?
@NSManaged var eventStartDate: NSDate?
@NSManaged var eventEndDate: NSDate?
@NSManaged var locationName: String?
@NSManaged var locationAddress: String?
@NSManaged var locationLatitude: NSNumber?
@NSManaged var locationLongitude: NSNumber?

}

And here my Core Data Object model that implements mappable:

class Event: NSManagedObject, Mappable {


override init(entity: NSEntityDescription, insertIntoManagedObjectContext context: NSManagedObjectContext?) {
    super.init(entity: entity, insertIntoManagedObjectContext: DataController().managedObjectContext)
}

required init?(_ map: Map) {
    let ctx = DataController().managedObjectContext
    let entity = NSEntityDescription.entityForName("Event", inManagedObjectContext: ctx)
    super.init(entity: entity!, insertIntoManagedObjectContext: ctx)

    mapping(map)
}

func mapping(map: Map) {

    eventId   <- map["event_id"]
    eventName   <- map["event_name"]
    eventImageUrl   <- map["event_image_url"]
    eventContent   <- map["event_content"]
    eventStartTime   <- map["event_start_time"]
    eventEndTime   <- map["event_end_time"]
    eventStartDate   <- map["event_start_date"]
    eventEndDate   <- map["event_end_date"]
    locationName   <- map["location_name"]
    locationAddress   <- map["location_address"]
    locationLatitude   <- map["location_latitude"]
    locationLongitude   <- map["location_longitude"]



}

}

Running this:

let URL = "##### MY API ######"
    Alamofire.request(.GET, URL).responseArray { (response: Response<[Event], NSError>) in

        let eventsArray = response.result.value

        for element in eventsArray! {
            print(element)
        }

    }

I retrieve this:

data: {
eventContent = "TEst villa borghese";
eventEndDate = nil;
eventEndTime = nil;
eventId = 0;
eventImageUrl = "https://www.dayroma.it/wp-content/uploads/2016/06/event_fb-9398.jpg";
eventName = nil;
eventStartDate = nil;
eventStartTime = nil;
locationAddress = "Villa Borghese 4, Roma";
locationLatitude = nil;
locationLongitude = nil;
locationName = "Villa Borghese";

}

Great part of fields are nil, can you help me to understand what is the problem?

Thank youy

3
  • Where is your code that converts from strings to dates? You have NSDate attributes on your model, but the JSON contains strings. Where do you convert to NSDate? Commented Jul 29, 2016 at 22:04
  • I don't know where convert every type form json.... This is the problem, object id is a int32, or int64, then I have latitude and longitude that are double and all the dates...where can I convert them? Commented Jul 29, 2016 at 22:11
  • When you assign values to those attributes. I guess maybe your mapping framework is supposed to do this? So maybe you should look at the framework code and see. The code is not hard to write yourself, though. Commented Jul 29, 2016 at 22:48

1 Answer 1

0

From you Json you only receive string even when you are waiting for NSNumber or NSDate.

To make this map works you should use custom transformation from ObjectMapper and set you mapping as is :

birthday    <- (map["birthday"], DateTransform())

or having a custom transformation such as :

private static let formatter: NSNumberFormatter = NSNumberFormatter()
private let transform = TransformOf<NSNumber, String>(fromJSON:
        { (value: String?) -> NSNumber? in
            // transform value from String? to Int?
            formatter.numberStyle = .DecimalStyle
            return formatter.numberFromString(value!)
    }, toJSON:
        { (value: NSNumber?) -> String? in
            // transform value from Int? to String?
            if let value = value
            {
                return String(value)
            }
            return nil
})

and use it :

people <- (map["people"], transform)

Hope this help.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.