简体   繁体   English

Swift和CoreData /数据存储

[英]Swift and CoreData / Data Storage

I'm just learning Objective-C / Cocoa Touch and Core Data. 我只是在学习Objective-C /可可接触和核心数据。 So, what are the new possibilities to implement data storage in iOS App Projects that are written in pure Swift? 那么,用纯Swift编写的iOS App项目中实现数据存储的新可能性是什么? I really like the language, but as far as I know all core data methods are written in Objective-C. 我真的很喜欢这种语言,但是据我所知,所有核心数据方法都是用Objective-C编写的。 So will the core data classes/methods converted to Swift-Code automatically or will we have to mix up Objective-C Code for Core data and Swift-Code for everything else? 那么,核心数据类/方法会自动转换为Swift-Code吗?还是我们必须将用于核心数据的Objective-C代码与用于其他所有内容的Swift-Code混合使用?

This is how I implemented core data. 这就是我实现核​​心数据的方式。

A couple of really important notes: 一些非常重要的注意事项:

  • You have to add this to your NSManagedObject class: 您必须将其添加到您的NSManagedObject类中:

    @objc(MyObject) @objc(MyObject)

  • You have to add the entity name to your default configuration class in the .xcdatamodel (picture included) 您必须将实体名称添加到.xcdatamodel中的默认配置类中(包括图片)

xc数据模型

  • You can't simply make an NSManagedObject. 您不能简单地制作一个NSManagedObject。

     var myObject : MyObject = MyObject() 

You have to do this: 您必须这样做:

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)

Here is my NSManagedObject. 这是我的NSManagedObject。 I included two fetch methods as well as a class method for object construction. 我包括了两种获取方法以及用于对象构造的类方法。 You may notice that I am taking advantage of the new enum system so that I can easily access my entity names and entity attributes 您可能会注意到,我正在利用新的枚举系统,以便可以轻松访问我的实体名称和实体属性

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")
        }
    }

Here is my view controller 这是我的视图控制器

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 ()
    }

}

All Objective-C frameworks are swift-ready. 所有的Objective-C框架都可以立即使用。 Swift-friendly headers are automatically generated (on-demand, it appears), and you can access anything from Swift that you can from ObjC. Swift友好的标头是自动生成的(按需显示),并且您可以从ObjC中访问Swift中的任何内容。

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

If you wanna have a play around with Swift and CoreData, I've written a framework thats an Active Record style assistant to CoreData. 如果您想体验Swift和CoreData,我已经编写了一个框架,该框架是CoreData的Active Record风格助手。

SuperRecord Swift Framework SuperRecord Swift框架

(note: not a shameless plug :) i actually thought this would be useful for the user). (注意:不是无耻的插件:)我实际上以为这对用户有用。

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

Here is another approach to adding CoreData to your Swift app. 这是将CoreData添加到Swift应用程序的另一种方法。 This approach hides the CoreData implementation details from the rest of the app. 这种方法对应用程序的其余部分隐藏了CoreData实现细节。 In the app, you use queries/updates like these: 在应用程序中,您可以使用以下查询/更新:

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

or: 要么:

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

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

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

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