繁体   English   中英

Swift和CoreData /数据存储

[英]Swift and CoreData / Data Storage

我只是在学习Objective-C /可可接触和核心数据。 那么,用纯Swift编写的iOS App项目中实现数据存储的新可能性是什么? 我真的很喜欢这种语言,但是据我所知,所有核心数据方法都是用Objective-C编写的。 那么,核心数据类/方法会自动转换为Swift-Code吗?还是我们必须将用于核心数据的Objective-C代码与用于其他所有内容的Swift-Code混合使用?

这就是我实现核​​心数据的方式。

一些非常重要的注意事项:

  • 您必须将其添加到您的NSManagedObject类中:

    @objc(MyObject)

  • 您必须将实体名称添加到.xcdatamodel中的默认配置类中(包括图片)

xc数据模型

  • 您不能简单地制作一个NSManagedObject。

     var myObject : MyObject = MyObject() 

您必须这样做:

let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
let context: NSManagedObjectContext = appDelegate.managedObjectContext
let entityName: String = "MyObject"
let myEntityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)
var myObject = MyObject(entity: myEntityDescription, insertIntoManagedObjectContext: context)

这是我的NSManagedObject。 我包括了两种获取方法以及用于对象构造的类方法。 您可能会注意到,我正在利用新的枚举系统,以便可以轻松访问我的实体名称和实体属性

import UIKit
import CoreData

enum MyObjectPropertyList { 
    case name
    func description() -> String {
        switch self {
        case .name:
            return "name"
        }
    }
}

@objc(MyObject)
class MyObject: NSManagedObject {

    @NSManaged var name: String

    //
    //// CREATE CLASS OBJECT
    //

    class func createMyObject (propertyName:MyObjectPropertyList, value:String, context: NSManagedObjectContext) -> MyObject? {
        if !value.isEmpty {
            let propertyType = propertyName.description()

            let entityName = "MyObject"
            let request : NSFetchRequest = NSFetchRequest(entityName: entityName)
            request.returnsObjectsAsFaults = false
            request.predicate = NSPredicate(format: "\(propertyType) = %@", value)
            var error: NSError? = nil
            var matches: NSArray = context.executeFetchRequest(request, error: &error)

            if (matches.count > 1) {
                // handle error
                return matches[0] as? MyObject
            } else if matches.count ==  0 {
                let entityDescription = NSEntityDescription.entityForName(entityName, inManagedObjectContext: context)
                var myObject : MyObject = MyObject(entity: entityDescription, insertIntoManagedObjectContext: context)
                myObject.name = value
                return myObject
            }
            else {
                println(matches[0])
                return matches[0] as? MyObject
            }
        }
        return nil
    }
}

    //
    //// FETCH REQUESTS
    //

    func myGeneralFetchRequest (entity : CoreDataEntities,
                              property : MyObjectPropertyList,
                               context : NSManagedObjectContext) -> AnyObject[]?{

        let entityName = entity.description()
        let propertyName = property.description()

        let request :NSFetchRequest = NSFetchRequest(entityName: entityName)
        request.returnsObjectsAsFaults = false
        let sortDescriptor : NSSortDescriptor = NSSortDescriptor(key: propertyName, ascending: true)
        request.sortDescriptors = [sortDescriptor]
        var error: NSError? = nil
        var matches: NSArray = context.executeFetchRequest(request, error: &error)

        if matches.count > 0 {
            return matches
        }
        else {
            return nil
        }
    }

    func myNameFetchRequest (entity : CoreDataEntities,
                           property : MyObjectPropertyList,
                              value : String,
                            context : NSManagedObjectContext) -> AnyObject[]? {

        let entityName = entity.description()
        let propertyName = property.description()

        let request :NSFetchRequest = NSFetchRequest(entityName: entityName)
        request.returnsObjectsAsFaults = false
        request.predicate = NSPredicate(format: "\(propertyName) = %@", value)
        let sortDescriptor :NSSortDescriptor = NSSortDescriptor(key: propertyName, ascending: true)
        request.sortDescriptors = [sortDescriptor]
        var error: NSError? = nil
        var matches: NSArray = context.executeFetchRequest(request, error: &error)

        if matches.count > 0 {
            return matches
        }
        else {
            return nil
        }
    }

    //
    //// PRINT FETCH REQUEST
    //

    func printFetchedArrayList (myarray:AnyObject[]) {
        if myarray.count > 0 {
            println("Has \(myarray.count) object")
            for myobject : AnyObject in myarray {
                var anObject = myobject as MyObject
                var thename = anObject.name
                println(thename)
            }
        }
        else {
            println("empty fetch")
        }
    }

这是我的视图控制器

import UIKit
import CoreData

enum CoreDataEntities {
    case MyObject
    func description() -> String {
        switch self {
        case .MyObject:
            return "MyObject"
        }
    }
}

class ViewController: UIViewController {

    //
    //// MOC
    //

    var managedObjectContext : NSManagedObjectContext = NSManagedObjectContext()

    //
    //// Text Field
    //

    @IBOutlet var myTextField : UITextField

    //
    //// BUTTONS
    //

    @IBAction func saveButtonPress(sender : UIButton) {
        makeEntityAction()
    }

    @IBAction func fetchButtonPress(sender : UIButton) {
        fetchObjectAction()
    }

    //
    //// ACTIONS
    //

    func makeEntityAction () {
        println("-- Make action --")

        let value:String = self.myTextField.text
        var myObject : MyObject = MyObject.createMyObject(MyObjectPropertyList.name, value : value, context: self.managedObjectContext)!
        saveContext(self.managedObjectContext)
    }

    func fetchObjectAction () {
        println("-- Fetch action --")

        if let myTotalarray = myGeneralFetchRequest(CoreDataEntities.MyObject, MyObjectPropertyList.name, self.managedObjectContext) {
            printFetchedArrayList(myTotalarray)
        }
        if let mySinglearray: AnyObject[] = myNameFetchRequest(CoreDataEntities.MyObject, MyObjectPropertyList.name, "Bill", self.managedObjectContext) {
            println("(--  --)")
            printFetchedArrayList(mySinglearray)
        }

    }

    //
    //// LOAD & SAVE
    //

    func loadContext () {
        let appDelegate: AppDelegate = UIApplication.sharedApplication().delegate as AppDelegate
        let context: NSManagedObjectContext = appDelegate.managedObjectContext
        self.managedObjectContext = context
    }

    func saveContext (context: NSManagedObjectContext) {
        var error: NSError? = nil
        context.save(&error)
    }

    //
    //// LOAD
    //

    func myLoad () {
        loadContext ()
        println("Loaded Context")
    }

    //
    //// Life Cycle
    //

    override func viewDidLoad() {
        super.viewDidLoad()
        myLoad ()
    }

}

所有的Objective-C框架都可以立即使用。 Swift友好的标头是自动生成的(按需显示),并且您可以从ObjC中访问Swift中的任何内容。

我已经测试过使用swift访问coredata,请访问演示代码: https : //github.com/iascchen/SwiftCoreDataSimpleDemo

如果您想体验Swift和CoreData,我已经编写了一个框架,该框架是CoreData的Active Record风格助手。

SuperRecord Swift框架

(注意:不是无耻的插件:)我实际上以为这对用户有用。

XCode 6 Beta 4现在允许您从数据模型生成NSManagedObject子类时选择Objective C或Swift。

这是将CoreData添加到Swift应用程序的另一种方法。 这种方法对应用程序的其余部分隐藏了CoreData实现细节。 在应用程序中,您可以使用以下查询/更新:

Query("Order").sort("date").fetch()

要么:

let newClient = Query("Client").create() as? Client

参见要点: https : //gist.github.com/gk11/438c3f2883c5d7c0b0d8

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM