MeaK
MeaK

Reputation: 21

Using RestKit and CoreData with Swift

I try to use RestKit in Swift with the Bridging Header. I have a JSON file with the url "http://local:8888/api/0.1/jobs"

{"data":[{"id": "1", "name": "job1",..},{"id": "2", "name": "job2",...},...]}

The JSON file have 6 elements Job. I created the Job entity for CoreData and generate the Job class.

I set up the RestKit this way :

func setupRestKit() {
    var manager = RKObjectManager(baseURL: NSURL(string: "http://local:8888/api/0.1/"))

    RKObjectManager.setSharedManager(manager)

    var managedObjectModel = NSManagedObjectModel.mergedModelFromBundles(nil)
    var managedObjectStore = RKManagedObjectStore(managedObjectModel: managedObjectModel)
    manager.managedObjectStore = managedObjectStore

    RKManagedObjectStore.setDefaultStore(manager.managedObjectStore)

    var jobMapping = RKEntityMapping(forEntityForName: "Job", inManagedObjectStore: manager.managedObjectStore)

    jobMapping.identificationAttributes = ["id"]
    jobMapping.addAttributeMappingsFromDictionary([
        "id"     : "id",
        "name"      : "name"
    ])

    let responseDescriptor = RKResponseDescriptor(
        mapping: jobMapping,
        method: RKRequestMethod.GET,
        pathPattern: "/jobs",
        keyPath: "data",
        statusCodes: NSIndexSet(index: 200)
    )

    manager.addResponseDescriptor(responseDescriptor)

    managedObjectStore.createPersistentStoreCoordinator()

    let storePath = RKApplicationDataDirectory().stringByAppendingPathComponent("MyApp.sql")

    var persistentStore = managedObjectStore.addSQLitePersistentStoreAtPath(
        storePath,
        fromSeedDatabaseAtPath: nil,
        withConfiguration: nil,
        options: optionsForSqliteStore(),
        error: nil
    )

    managedObjectStore.createManagedObjectContexts()

    managedObjectStore.managedObjectCache = RKInMemoryManagedObjectCache(
        managedObjectContext: managedObjectStore.persistentStoreManagedObjectContext
    )
}

func optionsForSqliteStore() -> NSDictionary {
    return [
        NSInferMappingModelAutomaticallyOption: true,
        NSMigratePersistentStoresAutomaticallyOption: true
    ];
}

And in the ViewController :

override func viewDidLoad() {
    super.viewDidLoad()

    var fetchRequest = NSFetchRequest(entityName: "Job")

    fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]

    self.fetchedResultsController = NSFetchedResultsController(
        fetchRequest: fetchRequest,
        managedObjectContext: RKManagedObjectStore.defaultStore().mainQueueManagedObjectContext,
        sectionNameKeyPath: nil,
        cacheName: nil
    )

    self.fetchedResultsController?.delegate = self

    self.fetchedResultsController?.performFetch(nil)

    tableView.registerClass(UITableViewCell.self, forCellReuseIdentifier: "Cell")
}

func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    if let sections = fetchedResultsController?.sections {
        return sections.count
    } else {
        return 0
    }
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    if let sections = fetchedResultsController?.sections {
        var sectionInfo: AnyObject = sections[section]
        return sectionInfo.numberOfObjects
    } else {
        return 0
    }
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell") as UITableViewCell

    if let fetchedResults = fetchedResultsController {
        cell.textLabel?.text = fetchedResults.objectAtIndexPath(indexPath).name
    }

    return cell
}

The numberOfSectionsInTableView method return the value 0 and the tableView numberOfRowsInSection return the value 0 too.

I try many solutions by translating code from Objective-C because there isn't really much example of Swift using RestKit.

I'm able to access to the data from the JSON with the SwiftyJson framework and I also validate my configuration by store element by myself in the CoreData database.

I want to get the 6 jobs I have created with this simple RestApi and print it in a tableView.

I think I have do wrong something during the configuration but I don't know what it is.

Upvotes: 1

Views: 3028

Answers (1)

MeaK
MeaK

Reputation: 21

As David said I forgot to fetch from the server (Thanks).

// I just need to map correctly the path
var manager = RKObjectManager(baseURL: NSURL(string: "http://local:8888/api/0.1/jobs"))

[...]
var persistentStore = managedObjectStore.addSQLitePersistentStoreAtPath(
    storePath,
    fromSeedDatabaseAtPath: nil, // Set-up this
    withConfiguration: nil,
    options: optionsForSqliteStore(),
    error: nil
)

managedObjectStore.createManagedObjectContexts()

managedObjectStore.managedObjectCache = RKInMemoryManagedObjectCache(
    managedObjectContext: managedObjectStore.persistentStoreManagedObjectContext
)
manager.getObjectsAtPath(
    "", // Add path
    parameters: nil,
    success: nil,
    failure: nil
)

And I get the items in my view.

Upvotes: 1

Related Questions