【发布时间】: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]]... 对吗?