RestKit、CoreData 和 Swift - 我似乎无法取回结果

2024-01-08

我已经在一个新的基于 Swift 的应用程序(当前是 XCode 6 beta 3)中成功设置了 RestKit 到 CoreData 的映射实现。我知道导入映射正在通过我的 RestKit JSON 调用进行工作,因为我可以检查 sqlite 数据库并查看我的数据。但是,我无法从 NSFetchRequest 中的数据存储中取回数据。我究竟做错了什么?

我将省略所有 RestKit 设置和拆卸,因为它非常标准并且看起来运行良好。所以这是我的 AppDelegate 查询代码,它似乎不起作用:

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 从我的 AppDelegate 引用它,以从 RestKit shareObject 获取上下文:

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

看起来 fetch 请求成功,因为 for/in 循环中出现了断点。然而,当我检查 resultItem 或 _currentUser 对象时,它们显示为空,并且“if _currentUser”NSLog 永远不会触发。

有任何想法吗?我是否对 Swift 中获取数据做出了错误的假设?

EDIT 2:

问题源于我尝试将 resultItem 放入可选值中。如果声明 _currentUser 时不带可选参数并删除 as?可选强制转换查询返回正确的 User 对象:

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

编辑: 我在主提取请求之前添加了记录计数,它正确显示了 1 条记录。因此,我尝试将获取结果映射到我的用户对象的方式出现了问题。这是我的用户类别:

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
}

答案是显然 Swift 不喜欢将获取结果转换为可选。我必须将结果放入局部变量中,然后设置可选:

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;
}

这是我在 Swift 中对 RestKit 的设置和拆卸,以防任何人(如 niiamon)发现它有帮助:

来自我的 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
    ];
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RestKit、CoreData 和 Swift - 我似乎无法取回结果 的相关文章

随机推荐

  • 个人版本控制器

    我想知道是否有个人源代码控制器 我想在我的机器上有一个存储库 而无需设置服务器 而且我使用 TeX 文件而不是任何特定语言 我希望有像子版本一样备份我的文件 如果你安装乌龟SVN http tortoisesvn net 您的 Window
  • 为什么 C++ 模运算符对于 -1 % str.size() 返回 0?

    我很困惑为什么以下代码会产生此输出 include
  • 命令在 shell 中有效,但在脚本中无效 [重复]

    这个问题在这里已经有答案了 我正在使用命令ls files text txt xt 获取以任何模式结尾的所有文件 当我在 shell 中运行它时 我得到这个结果 ls files text txt xt files f1 text file
  • 如何在 tidyr 中使用 Gather_ 和变量

    我将 tidyr 与闪亮一起使用 因此需要在 tidyr 操作中利用动态值 然而 我在使用 Gather 时遇到了麻烦 我认为它是为这种情况设计的 下面的最小示例 library tidyr df lt data frame name le
  • CI运行时执行失败:执行失败:无法启动容器进程:打开/dev/pts/0:不允许操作:未知

    当我运行以下命令时 docker compose exec web bash 这是我遇到的错误 OCI 运行时执行失败 执行失败 无法启动容器进程 打开 dev pts 0 不允许操作 未知 这也发生在我身上 但我不小心停止了容器 重新启动
  • 确定夏令时是否有效? SQL服务器

    我有一个包含用户 UTC 时间偏移以及他们是否遵守夏令时的表 是否有内置方法可以获取正确的用户时间 这并非在所有情况下都有效 但对于美国 DST 定义为 3 月第 2 个星期日到 11 月第 1 个星期日之间的用户来说 这是一个快速解决方案
  • Pandas DataFrame.to_csv 引发 IOError:没有这样的文件或目录

    你好 我正在尝试使用Pandas DataFrame to csv方法来保存dataframe to a csv file filename dir name csv df to csv filename 但是我收到错误 IOError E
  • iTextSharp - XFA 填充日期/时间字段

    工作流程是这样的 我们下载一个模板表单 预填充静态值 导出 XML 模板 使用 NET 表单应用程序解析 XML 添加动态值 生成的 XML 需要重新导入到 PDF 模板中 在 iTextSharp 上使用 MergeXfaData 方法一
  • xlwings - 删除一系列行

    我似乎找不到一种方法来删除从第 x 行开始到工作表底部的一系列行 例如在VBA代码中我会这样做 Rows CStr currRow 65536 Select Selection Delete Shift xlUp 其中 currRow 可以
  • 降低 Vuetify 下拉菜单的高度

    我无法降低 Vuetify 下拉组件的高度v select 我尝试使用道具dense但它只会降低要选择的选项的高度 并且不会对关闭的下拉列表产生任何影响 我尝试了以下模板代码
  • Android O:通知通道本地化

    我创建了一个这样的通知通道 NotificationChannel channel new NotificationChannel CHANNEL ID FOOBAR getContext getString R string notifi
  • 利用 BackGroundWorker 在 Winforms 控件上跨线程调用 GUI 操作?

    受到我自己使用多线程 Winforms 应用程序的经验以及诸如此类的问题的启发 避免跨线程 WinForm 事件处理中 Invoke BeginInvoke 的麻烦 https stackoverflow com questions 136
  • 如何使用鼠标拖动来画线?

    我需要使用光标在delphi中画一条线 我已经创建了线代码 但我不知道下一步该做什么 如何才能做到这一点 我按下鼠标 当线条需要开始并拖动鼠标时 或者简单地释放鼠标按钮并绘制线条 procedure TForm1 Button1Click
  • 如何查明在我的 servlet 中按下了哪个 HTML 按钮?

    我正在创建一个包含两个提交按钮的注册表单 我需要知道在我的 servlet 代码中单击了表单中的哪个按钮 阅读以下问题的答案这个问题 https stackoverflow com questions 5222 accessing post
  • 获取有关 LLDB 中错误内存地址的信息

    我正在尝试在我的 iPhone 应用程序中调试 EXC BAD ACCESS 它在方法调用时崩溃 并且该方法的行是EXC BAD ACCESS code 1 address xxx 以前 我只会使用gdb info malloc histo
  • 一堂课可以延长两堂课吗?

    我的班级应该同时扩展两个班级 public class Preferences extends AbstractBillingActivity public class Preferences extends PreferenceActiv
  • R中根据字符分割字符串

    我的数据集中有一列 其中有一个我想要拆分的字符串 df data frame col c BrBkRY BBkRBr YBRG RBBk 这是我想用来有条件分割的向量 sep c Br Bk R Y B G 这就是最终的样子 我是用手做的
  • 如何将 Maven 嵌入到我的应用程序中?

    我想将 Maven 或能够发挥所有作用的库嵌入到我的 Java 应用程序中 要点 这是我想要执行的两项任务 1 在本地存储库中发布 jar2 在私有企业存储库 Nexus 中发布jar 所有必需的 jar 必须位于公共 Maven 存储库中
  • 烧瓶蓝图模板文件夹

    我的烧瓶应用程序布局是 myapp run py admin init py views py pages index html main init py views py pages index html init py 文件为空 管理
  • RestKit、CoreData 和 Swift - 我似乎无法取回结果

    我已经在一个新的基于 Swift 的应用程序 当前是 XCode 6 beta 3 中成功设置了 RestKit 到 CoreData 的映射实现 我知道导入映射正在通过我的 RestKit JSON 调用进行工作 因为我可以检查 sqli