iOS Swift教程 Core Data (二)ManagedObject subclass 上

第二个实例是一个领结管理程序。在这个程序中,你可以切换不同颜色的领带,R代表红色,O代表橘黄色。点击任意颜色会加载对应颜色的领结并显示该领结的一些信息,包括:

  • 领结的名称
  • 你带过多少次这款领结
  • 最近一次带的时间
  • 你是否喜欢这款领结

转载请注明出处:http://blog.csdn.net/yamingwu/article/details/42235929

源代码地址:https://github.com/dnawym/StudySwift/tree/master/CoreData/Bow%20Ties

点击Wear按钮会增加该款领结的使用次数并更新最后一次带的时间。

点击Rate按钮可以修改你对该款领结的评分,评分是0-5的十进制数。


数据建模:

Core Data可以支持多种数据类型,除了第一节中使用的String,还可以支持Integer,Data,Double,Binary Data,Transformable等等。

其中,binary data用于存储如图片,pdf等可以序列化的数据。如果要存储的图片很大,将图片数据存入数据库则会降低Core Data的性能,因为每次访问一个entity都会将整个数据加载到内存中。这是就需要使用binary data的’Allow External Storage'选项,这样Core Data会自行判断应该将数据存入到数据库还是存储一个指向目标文件的URI。



存储非标准数据到Core Data中:

当我们要存储类似UIColor数据到Core Data中时,可以为UIColor定义Transformable类型的Core Data attribute,Core Data就可以帮我们对UIColor进行序列化和反序列化。只要符合NSCoding protocol的类,都可以使用这种方式。这样就不用在存储UIColor前手动进行序列化,在读取数据后,手动进行反序列化操作。


创建ManagedObject的子类

在第一个例子中我们使用了KVC方式来操作Core Data - Person,但是使用字符串方式编程很容易导致bug,因为字符串不像强类型,没有语法检查,很容易拼错。

创建BowTie类:


这就会创建如下的swift文件:

import Foundation
import CoreData

class Bowtie: NSManagedObject {

    @NSManaged var name: String
    @NSManaged var isFavorite: NSNumber
    @NSManaged var lastWorn: NSDate
    @NSManaged var rating: NSNumber
    @NSManaged var searchKey: String
    @NSManaged var timesWorn: NSNumber
    @NSManaged var photoData: NSData
    @NSManaged var tintColor: AnyObject

}

最后做如下修改就创建好了managed object的子类:


接下来我们测试一下我们创建的Core Data能否正常工作,在AppDelegate.swift中加入以下代码:

  func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

    // save test bow tie
    let entity = NSEntityDescription.entityForName("Bowtie", inManagedObjectContext: managedObjectContext!)
    
    let bowtie = Bowtie(entity: entity!, insertIntoManagedObjectContext: managedObjectContext)
    
    bowtie.name = "My bow tie"
    bowtie.lastWorn = NSDate()
    
    managedObjectContext?.save(nil)
    
    // retrieve test bow tie
    let request = NSFetchRequest(entityName: "Bowtie")
    let ties = managedObjectContext!.executeFetchRequest(request, error: nil) as [Bowtie]
    
    let sample = ties[0]
    println("Name: \(sample.name), Worn: \(sample.lastWorn)")
    
    return true
  }

这段代码在程序启动时创建一个名为‘my bow tie'的Bowtie对象,并设置lastWorn日期为今天,并插入到CoreData中。

然后,fetch所有的Bowtie实例并打印第一条领带的名字和最近一次佩戴时间。


在项目的其它文件中使用Managed Context:

在ViewController.swift中添加声明和定义

import CoreData

    var managedContext: NSManagedObjectContext!

修改AppDelegate,将managedObjectContext传递给ViewController,去掉appDelegate中的测试代码

    let viewController = self.window!.rootViewController as ViewController
    viewController.managedContext = self.managedObjectContext

接下来,我们读取plist中的数据来初始化Core Data数据库

函数insertSampleData查看CoreData中是否有领带的数据,如果有则返回,如果没有责将SampleData.plist中的数据插入到Core Data数据库中。

而colorFromDict用于将plist中存放的颜色对应的3原色转换为UIColor。

这里需要注意:

  • 存储image到core data时,我们先从文件系统中读取图片构造UIImage,然后通过UIImagePNGRepresentation转换UIImage为NSData,最后将转换后的数据存入imageData中
  • 存储color时,由于color被存储在transformable属性中,我们不需要做其它特殊操作就能够将颜色存入tintColor中。

    // Insert sample data
    func insertSampleData() {
        let fetchRequest = NSFetchRequest(entityName: "Bowtie")
        fetchRequest.predicate = NSPredicate(format: "searchKey != nil")
        let count = managedContext.countForFetchRequest(fetchRequest, error: nil)
        
        if count > 0 {
            return
        }
        
        let path = NSBundle.mainBundle().pathForResource("SampleData", ofType: "plist")
        
        let dataArray = NSArray(contentsOfFile: path!)
        
        for dict : AnyObject in dataArray! {
            let entity = NSEntityDescription.entityForName("Bowtie", inManagedObjectContext: managedContext)
            
            let bowtie = Bowtie(entity: entity!, insertIntoManagedObjectContext: managedContext)
            
            let btDict = dict as NSDictionary
            
            bowtie.name = btDict["name"] as NSString
            bowtie.searchKey = btDict["searchKey"] as NSString
            bowtie.rating = btDict["rating"] as NSNumber
            let tintColorDict = btDict["tintColor"] as NSDictionary
            bowtie.tintColor = colorFromDict(tintColorDict)
            
            let imageName = btDict["imageName"] as NSString
            let image = UIImage(named: imageName)
            let photoData = UIImagePNGRepresentation(image)
            bowtie.photoData = photoData
            
            bowtie.lastWorn = btDict["lastWorn"] as NSDate
            bowtie.timesWorn = btDict["timesWorn"] as NSNumber
            bowtie.isFavorite = btDict["isFavorite"] as NSNumber
        }
        
        var error: NSError?
        if !managedContext.save(&error) {
            println("Could not save \(error), \(error!.userInfo)")
        }
    }
    
    func colorFromDict(dict: NSDictionary) -> UIColor {
        let red = dict["red"] as NSNumber
        let green = dict["green"] as NSNumber
        let blue = dict["blue"] as NSNumber
        
        let color = UIColor(red: CGFloat(red)/255.0, green: CGFloat(green)/255.0, blue: CGFloat(blue)/255.0, alpha: 1)
        
        return color
    }

在我们将领结数据存入CoreData后,通过viewDidLoad来读取数据

    override func viewDidLoad() {
        super.viewDidLoad()

        insertSampleData()
        
        let request = NSFetchRequest(entityName: "Bowtie")
        let firstTitle = segmentedControl.titleForSegmentAtIndex(0)
        
        request.predicate = NSPredicate(format: "searchKey == %@", firstTitle!)
        
        var error: NSError? = nil
        
        var results = managedContext.executeFetchRequest(request, error: &error) as [Bowtie]?
        
        if let bowties = results {
            populate(bowties[0])
        } else {
            println("Could not fetch \(error), \(error!.userInfo)")
        }
    }
    
    func populate(bowtie: Bowtie) {
        imageView.image = UIImage(data: bowtie.photoData)
        nameLabel.text = bowtie.name
        ratingLabel.text = "Rating: \(bowtie.rating.doubleValue)/5"
        timesWornLabel.text = "# times worn: \(bowtie.timesWorn.integerValue)"
        
        let dateFormatter = NSDateFormatter()
        dateFormatter.dateStyle = .ShortStyle
        dateFormatter.timeStyle = .NoStyle
        
        lastWornLabel.text = "Last worn: " + dateFormatter.stringFromDate(bowtie.lastWorn)
        
        favoriteLabel.hidden = !bowtie.isFavorite.boolValue
        view.tintColor = bowtie.tintColor as UIColor

    }
这样我们就完成了读取数据并显示的工作

下一节,我们将继续完善这个程序,实现在领结间的切换,完成wear和rate按钮事件的处理,以及验证数据的有效性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值