使用 Swift 和 XCode 在 Core Data 中存储整数

Posted

技术标签:

【中文标题】使用 Swift 和 XCode 在 Core Data 中存储整数【英文标题】:Store Integers in Core Data using Swift and XCode 【发布时间】:2014-08-15 04:59:34 【问题描述】:

虽然字符串看起来不错,但我在将整数存储到核心数据中时遇到了一些问题。遵循教程并阅读那里的可用信息似乎对没有Objective-C背景的我没有帮助。 (Swift 似乎是一门直截了当的语言,就像我精通 php/OOPHP/javascript/VBScript/ 的语言一样……因此我开始使用它,到目前为止,我几乎可以做任何我想做的事情)

我现在要做的是,接收 JSON 数据并将其存储到 Core Data 中

这是我的核心数据

Entity name: Category

它的属性:

id Int16
title String
description String

我的 Swift 模型?文件:Category.swift

import CoreData

class Category: NSManagedObject 
    @NSManaged var id: Int //should I declare this as Int16?
    @NSManaged var title: String
    @NSManaged var description: String

我正在使用 SwiftyJASON 扩展?和 NSURLSession 协议?获取数据并解析如下:

import UIKit
import CoreData

class ViewController: UIViewController 

    let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext

    override func viewDidLoad() 
        super.viewDidLoad()
        fetchData()
    
        func fetchData() 
            var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category")
            var session = NSURLSession.sharedSession()
            session.dataTaskWithURL(url, completionHandler: (data, response, error) in
                // parse data into json
                let json = JSONValue(data)
                let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: self.managedObjectContext)
                let category = Category(entity: entityDescription, insertIntoManagedObjectContext: self.managedObjectContext)
                for item in json.array! 
                    category.id = item["id"].string!.toInt()! //goes KABOOM!
                    category.title = item["title"].string!
                    category.description = item["description"].string!
                    managedObjectContext?.save(nil)
                
                dispatch_async(dispatch_get_main_queue()) 
                    // do something
                
            ).resume()
        

假设 JASON 数据是:

["id":"1","title":"cat1","description":"blabala one","id":"2","title":"cat2","description":"blabala two"]

在上面写着category.id = item["id"].string!.toInt()! xCode 进入 KABOOM 的那一行,我在这里做错了什么?

笔记/更多问题:

我尝试将 Core Data 中的 id 类型更改为 Int32,然后将其声明为 Int 在模型(而不是 Int16 或 Int32)中减少了一些错误,但 xCode 仍然崩溃

我循环播放内容的方式可能不是最好的方式, 将数据数组存储到核心数据中的更好方法是什么 一次?

我看到的大多数教程都没有实体(表)的 id,我在这里遗漏了什么吗?

参考资料:

SiftyJSON: https://github.com/lingoer/SwiftyJSON 核心数据教程: http://rshankar.com/coredata-tutoiral-in-swift-using-nsfetchedresultcontroller/

编辑 > 工作代码:

Category.swift 模型文件,可以使用 File>New>File>ios>Core Data>NSManagedObject 子类自动生成[swift,不需要桥接头,但您需要手动添加@objc 行,如下所示]

import CoreData

@objc(Category) //Wouldn't work without this
class Category: NSManagedObject 
    @NSManaged var id: NSNumber //has to be NSNumber
    @NSManaged var title: String
    @NSManaged var mydescription: String //"description" is reserved so is "class"

ViewController.swift

import UIKit
import CoreData

class ViewController: UIViewController 

    override func viewDidLoad() 
        super.viewDidLoad()
        fetchData()
    
    func fetchData() 
        var url = NSURL.URLWithString("http://domain.com/index.php?r=appsync/read&id=category")
        var session = NSURLSession.sharedSession()
        session.dataTaskWithURL(url, completionHandler: (data, response, error) in
            let json = JSONValue(data)
            let managedObjectContext = (UIApplication.sharedApplication().delegate as AppDelegate).managedObjectContext //this line had to be moved here
            let entityDescription = NSEntityDescription.entityForName("Category", inManagedObjectContext: managedObjectContext)
            for item in json.array! 
                let category = Category(entity: entityDescription, insertIntoManagedObjectContext: managedObjectContext) //this line has to be in inside for loop
                category.id = item["id"].string!.toInt()!
                category.title = item["title"].string!
                category.mydescription = item["description"].string!
                managedObjectContext?.save(nil)
            
            dispatch_async(dispatch_get_main_queue()) 
                // do something
            
        ).resume()
    

样本提取数据代码:

func requestData() 
    let appDel:AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
    let context:NSManagedObjectContext = appDel.managedObjectContext!
    var request = NSFetchRequest(entityName: "Category")
    request.returnsObjectsAsFaults = false
    var results:NSArray = context.executeFetchRequest(request, error: nil)
    //println(results)
    for category in results 
        var cat = category as Category
        println("\(cat.id),\(cat.title),\(cat.mydescription)")
    

附:确保在更改模型后清理您的项目并从模拟器中删除应用程序

【问题讨论】:

应该是 NSNumber 吧?或者可能将其保留为 var id ? AS swift 会根据您放置的值推断它? 当我在同一行执行此操作时出现EXC_BAD_ACCESS 错误,我尝试将模型内的Int 更改为NSNumber 以及category.id = item["id"].string!.toInt()! as NSNumber! 和其他组合,结果相同。我不太明白你所说的 leave it as var id 是什么意思 不显式声明类型?我在 swift 方面做得不多。所以我不知道 EntityModel 是否可以在没有显式类型的情况下工作。所以改为:@NSManaged var id 你的 JSON 数据是什么类型的?它似乎是 Array> 类型,即 [[String: String]]... 对吗? 【参考方案1】:

核心数据中的标量类型(整数、浮点数、布尔值)在当前的 Swift beta (5) 中被破坏。使用 NSNumber 作为属性,并归档一个雷达。

object.intProperty = NSNumber(int:Int(item["id"] as String))

(在手机上输入,如果错了,很抱歉,而且我知道这是令人作呕的代码 - 因此,提交雷达!)

或者,在您的特定情况下,查看 JSON,使用字符串。无论如何,这些 ID 都是以字符串形式出现的。

【讨论】:

用工作代码更新了我的问题,我相信 xCode 正在发挥作用,因为我在没有清理我的项目的情况下更改了我的模型文件(我手动创建的)我收到了 BAD_ACCESS 错误 @(objc) 不是推荐的解决方案,请参阅***.com/questions/24926418/…【参考方案2】:

为 Swift 2 更新

如果您的 JSON 数据确实是 [[String:String]] 类型,您可以使用以下代码来设置 category.id

if let unwrappedString = item["id"], unwrappedInt = Int(unwrappedString) 
    category.id = unwrappedInt

【讨论】:

你的回答也正确我不得不在模型文件中使用 NSNumber

以上是关于使用 Swift 和 XCode 在 Core Data 中存储整数的主要内容,如果未能解决你的问题,请参考以下文章

使用 XCode 8 中 Core Data 生成的类创建对象数组

如何使用 swift 3 xcode 8 在核心数据中预加载数据库

向 Xcode 10 Core Data 生成的文件添加方法

Xcode Entity Core Data - NSDate 错误的年份? [复制]

带有 Segues、Core Data 和 Swift 的 UITableViewController 的问题

iOS swift应用程序中Core Data的奇怪行为