RestKit, CoreData and Swift - I can't get the results back

I successfully configured the implementation of RestKit binding to CoreData in a new Swift-based application (currently Xcode 6 beta 3). I know that import mappings work from my RestKit JSON call, because I can check the sqlite database and see my data. However, I cannot get data from the data store in NSFetchRequest. What am I doing wrong?

I will take care of setting up and removing RestKit because it is pretty standard and seems to work just fine. So here is my AppDelegate request code, which does not seem to work:

var currentUser: User? { if !_currentUser { var error: NSError? = nil let request = NSFetchRequest(entityName: "User") let recordCount = self.managedObjectContext.countForFetchRequest(request, error:&error) NSLog("user records found: \(recordCount)") var result = self.managedObjectContext.executeFetchRequest(request, error:&error) for resultItem : AnyObject in result { _currentUser = resultItem as? User if _currentUser { NSLog("Fetched User for \(_currentUser!.firstname) \(_currentUser!.lastname)") } } } return _currentUser; } 

self.managedObjectContext references this from my AppDelegate to get the context from the shareObject RestKit:

 var managedObjectContext: NSManagedObjectContext { return RKObjectManager.sharedManager().managedObjectStore.mainQueueManagedObjectContext } 

The fetch request seems to be successful since a breakpoint in the for / in loop arises. However, when I check resultItem or _currentUser objects, they appear empty, and the NSX "if _currentUser" never fires.

Any ideas? Am I making the wrong assumptions about returning data to Swift?

EDIT 2:

The problem is related to my attempt to cast the resultItem object to Optional. If you declare _currentUser without an option and delete how? an optional query listing returns the correct user object:

  for resultItem : AnyObject in result { _currentUser = resultItem as User NSLog("Fetched User for \(_currentUser.firstname) \(_currentUser.lastname)") } 

EDIT: I added a record counter before the main query to fetch, and it correctly shows 1 record. So there is something wrong with the way I am trying to map the selection result to my custom object. Here is my user class:

 import Foundation import CoreData class User: NSManagedObject { @NSManaged var id: Int32 @NSManaged var createdAt: NSDate @NSManaged var udpatedAt: NSDate @NSManaged var username: String @NSManaged var email: String @NSManaged var firstname: String @NSManaged var lastname: String @NSManaged var organization: String @NSManaged var tokens: NSArray } 
+4
source share
1 answer

The answer is that, apparently, Swift does not like to distinguish the selection result as optional. I have to cast the result to a local variable, and then set an optional parameter:

 var currentUser: User? { if !_currentUser { var error: NSError? = nil let request = NSFetchRequest(entityName: "User") let recordCount = self.managedObjectContext.countForFetchRequest(request, error:&error) NSLog("user records found: \(recordCount)") var result = self.managedObjectContext.executeFetchRequest(request, error:&error) for resultItem : AnyObject in result { var currentUserItem = resultItem as User NSLog("Fetched User for \(currentUserItem.firstname) \(currentUserItem.lastname)") _currentUser = currentUserItem } } return _currentUser; } 

Here is my setting and disabling RestKit in Swift in case anyone (like niiamon) finds it useful:

From my RestApi.swift:

 var objectStore: RKManagedObjectStore = RKManagedObjectStore() init() { configureRestKit() } func configureRestKit() { let objectManager = RKObjectManager(baseURL: NSURL.URLWithString(baseUrl)) //objectManager.requestSerializationMIMEType = RKMIMETypeJSON; RKObjectManager.setSharedManager(objectManager) objectStore = RKManagedObjectStore(managedObjectModel: managedObjectModel()) let dataPath = "\(RKApplicationDataDirectory())/MyApp.sqlite" NSLog("Setting up store at \(dataPath)") objectStore.addSQLitePersistentStoreAtPath(dataPath, fromSeedDatabaseAtPath: nil, withConfiguration: nil, options: optionsForSqliteStore(), error: nil) objectStore.createManagedObjectContexts() objectStore.managedObjectCache = RKInMemoryManagedObjectCache(managedObjectContext: objectStore.persistentStoreManagedObjectContext) objectManager.managedObjectStore = objectStore // -- Declare routes -- // // Login Route objectManager.addResponseDescriptor(userLoginResponseDescriptor()) objectManager.addResponseDescriptor(eventLoginResponseDescriptor()) objectManager.router.routeSet.addRoute(RKRoute(name:kUserLoginRouteName, pathPattern: "/login", method: RKRequestMethod.POST)) } func tearDownRestKit() { // Cancel any network operations and clear the cache RKObjectManager.sharedManager().operationQueue.cancelAllOperations() NSURLCache.sharedURLCache().removeAllCachedResponses() // Cancel any object mapping in the response mapping queue RKObjectRequestOperation.responseMappingQueue().cancelAllOperations() // Ensure the existing defaultStore is shut down NSNotificationCenter.defaultCenter().removeObserver(RKManagedObjectStore.defaultStore()) RKObjectManager.setSharedManager(nil) RKManagedObjectStore.setDefaultStore(nil) } func userMapping() -> RKEntityMapping { let userMapping = RKEntityMapping(forEntityForName: "User", inManagedObjectStore: objectStore) var userDictionary = ["id": "id", "created_at": "createdAt", "updated_at": "updatedAt", "username": "username", "email": "email", "firstname": "firstname", "lastname": "lastname", "organization": "organization"] userMapping.addAttributeMappingsFromDictionary(userDictionary) let tokenMapping = RKEntityMapping(forEntityForName: "ApiToken", inManagedObjectStore: objectStore) tokenMapping.addAttributeMappingsFromArray(["token", "expiration"]) userMapping.addRelationshipMappingWithSourceKeyPath("tokens", mapping:tokenMapping) return userMapping } func userLoginResponseDescriptor() -> RKResponseDescriptor { let userResponseDescriptor = RKResponseDescriptor(mapping: userMapping(), method: RKRequestMethod.POST, pathPattern: "/login", keyPath: "user", statusCodes: NSIndexSet(index: 200)) return userResponseDescriptor } func managedObjectModel() -> NSManagedObjectModel { return NSManagedObjectModel.mergedModelFromBundles(nil) } func optionsForSqliteStore() -> NSDictionary { return [ NSInferMappingModelAutomaticallyOption: true, NSMigratePersistentStoresAutomaticallyOption: true ]; } 
+6
source

Source: https://habr.com/ru/post/1201641/


All Articles