import UIKit import CoreData @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { // Override point for customization after application launch. return true } }
import UIKit import Foundation import CoreData let kCSErrorDomain = "ru.novilab-mobile.cstest" let kCSErrorLocalStorageCode = -1000 @objc(CSDataManager) class CSDataManager:NSObject { //Managed Model var _managedModel: NSManagedObjectModel? var managedModel: NSManagedObjectModel{ if !_managedModel{ _managedModel = NSManagedObjectModel.mergedModelFromBundles(nil) } return _managedModel! } //Store coordinator var _storeCoordinator: NSPersistentStoreCoordinator? var storeCoordinator: NSPersistentStoreCoordinator{ if !_storeCoordinator{ let _storeURL = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CSDataStorage.sqlite") _storeCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedModel) func addStore() -> NSError?{ var result: NSError? = nil if _storeCoordinator!.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: _storeURL, options: nil, error: &result) == nil{ println("Create persistent store error occurred: \(result?.userInfo)") } return result } var error = addStore() if error != nil{ println("Store scheme error. Will remove store and try again. TODO: add scheme migration.") NSFileManager.defaultManager().removeItemAtURL(_storeURL, error: nil) error = addStore() if error{ println("Unresolved critical error with persistent store: \(error?.userInfo)") abort() } } } return _storeCoordinator! } //Managed Context var _managedContext: NSManagedObjectContext? = nil var managedContext: NSManagedObjectContext { if !_managedContext { let coordinator = self.storeCoordinator if coordinator != nil { _managedContext = NSManagedObjectContext() _managedContext!.persistentStoreCoordinator = coordinator } } return _managedContext! } //Init init() { super.init() NSNotificationCenter.defaultCenter().addObserver(self, selector: "appDidEnterBackground", name: UIApplicationDidEnterBackgroundNotification, object: nil) } @objc(appDidEnterBackground) func appDidEnterBackground(){ var (result:Bool, error:NSError?) = self.saveContext() if error != nil{ println("Application did not save data with reason: \(error?.userInfo)") } } // Returns the URL to the application's Documents directory. var applicationDocumentsDirectory: NSURL { let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) return urls[urls.endIndex-1] as NSURL } //Save context func saveContext() -> (Bool, NSError?){ println("Will save") var error: NSError? = nil var result: Bool = false let context = self.managedContext if context != nil{ if context.hasChanges && !context.save(&error){ println("Save context error occurred: \(error?.userInfo)") }else{ result = true } }else{ let errorCode = kCSErrorLocalStorageCode let userInfo = [NSLocalizedDescriptionKey : "Managed context is nil"] error = NSError.errorWithDomain(kCSErrorDomain, code: errorCode, userInfo: userInfo) } return (result, error) } //Singleton Instance class func sharedInstance() -> CSDataManager{ struct wrapper{ static var shared_instance: CSDataManager? = nil static var token: dispatch_once_t = 0 } dispatch_once(&wrapper.token, {wrapper.shared_instance = CSDataManager()}) return wrapper.shared_instance! } }
@objc()
to the class name and the methods we need - for example, this is the part: @objc(CSDataManager) class CSDataManager:NSObject { ... @objc(appDidEnterBackground) func appDidEnterBackground(){ ...
void
method call. In principle, everything is zen here - no, it is not. But in the head such things when designing your product, it is worth bearing in mind. import Foundation import CoreData import UIKit class CSDepartment : NSManagedObject{ @NSManaged var title: NSString @NSManaged var internalID: NSNumber @NSManaged var phone: NSString? }
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { //Get manager let manager = CSDataManager.sharedInstance() //Create new department let newDepartment : AnyObject! = NSEntityDescription.insertNewObjectForEntityForName("CSDepartment", inManagedObjectContext: manager.managedContext) //Save context manager.saveContext() //Get and print all departments let request = NSFetchRequest(entityName: "CSDepartment") let departments = manager.managedContext.executeFetchRequest(request, error: nil) println("Departments: \(departments)") return true }
[<NSManagedObject: 0xb264030> (entity: CSDepartment; id: 0xb264090 <x-coredata:///CSDepartment/t3403D9E7-F910-4E2D-989E-95D9C984C1762> ; data: {employees = (); internalID = nil;phone = nil;title = nil;})]
let newDepartment : CSDepartment = NSEntityDescription.insertNewObjectForEntityForName("CSDepartment", inManagedObjectContext: manager.managedContext) as CSDepartment
@objc()
import Foundation import CoreData import UIKit @objc(CSDepartment) class CSDepartment : NSManagedObject{ @NSManaged var title: NSString @NSManaged var internalID: NSNumber @NSManaged var phone: NSString? override func awakeFromInsert() { self.title = "New department" self.internalID = 0 } func description() -> NSString{ return "Department: className=\(self.dynamicType.description()), title=\(self.title), id=[\(self.internalID)] and phone=\(self.phone)" } }
CSEmployee
. There is only one thing left to do - to make our system work correctly with entities - to be able to add and delete links. The relationship between the department and the staff is one-to-many. Here, the new language and Xcode behaved in two ways. import Foundation import CoreData let st_fNames = ["John", "David", "Michael", "Bob"] let st_lNames = ["Lim", "Jobs", "Kyler"] @objc(CSEmployee) class CSEmployee:NSManagedObject{ @NSManaged var firstName: NSString @NSManaged var lastName: NSString @NSManaged var age: NSNumber? @NSManaged var department: CSDepartment override func awakeFromInsert() { super.awakeFromInsert() self.firstName = st_fNames[Int(arc4random_uniform(UInt32(st_fNames.count)))] self.lastName = st_lNames[Int(arc4random_uniform(UInt32(st_lNames.count)))] } func description() -> NSString{ return "Employee: name= \(self.firstName) \(self.lastName), age=\(self.age) years" } }
import Foundation import CoreData @objc(CSDepartment) class CSDepartment : NSManagedObject{ @NSManaged var title: NSString @NSManaged var internalID: NSNumber @NSManaged var phone: NSString? @NSManaged var employees: NSSet override func awakeFromInsert() { self.title = "New department" self.internalID = 0 } func description() -> NSString{ let employeesDescription = self.employees.allObjects.map({employee in employee.description()}) return "Department: title=\(self.title), id=[\(self.internalID)], phone=\(self.phone) and employees = \(employeesDescription)" } //Working with Employees func addEmployeesObject(employee: CSEmployee?){ let set:NSSet = NSSet(object: employee) self.addEmployees(set) } func removeEmployeesObject(employee: CSEmployee?){ let set:NSSet = NSSet(object: employee) self.removeEmployees(set) } func addEmployees(employees: NSSet?){ self.willChangeValueForKey("employees", withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: employees) self.primitiveValueForKey("employees").unionSet(employees) self.didChangeValueForKey("employees", withSetMutation: NSKeyValueSetMutationKind.UnionSetMutation, usingObjects: employees) } func removeEmployees(employees: NSSet?){ self.willChangeValueForKey("employess", withSetMutation: NSKeyValueSetMutationKind.MinusSetMutation, usingObjects: employees) self.primitiveValueForKey("employees").minusSet(employees) self.didChangeValueForKey("employees", withSetMutation: NSKeyValueSetMutationKind.MinusSetMutation, usingObjects: employees) } }
import UIKit import CoreData @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { //Get manager let manager = CSDataManager.sharedInstance() //Testing insert new objects let newDepartment : CSDepartment = NSEntityDescription.insertNewObjectForEntityForName("CSDepartment", inManagedObjectContext: manager.managedContext) as CSDepartment let newEmployee: CSEmployee = NSEntityDescription.insertNewObjectForEntityForName("CSEmployee", inManagedObjectContext: manager.managedContext) as CSEmployee let newEmployee2: CSEmployee = NSEntityDescription.insertNewObjectForEntityForName("CSEmployee", inManagedObjectContext: manager.managedContext) as CSEmployee newEmployee.department = newDepartment newDepartment.addEmployeesObject(newEmployee2) manager.saveContext() //Get and print all departments println("Have add oen department and two employees") println("Departments: \(manager.departments())") println("Employees: \(manager.employees())") //Testing remove child object newDepartment.removeEmployeesObject(newEmployee2) manager.saveContext() println("Have delete one employee") println("Departments: \(manager.departments())") //Testing cascade remove manager.managedContext.deleteObject(newDepartment) manager.saveContext() println("\nHave delete department") println("Departments: \(manager.departments())") println("Employees: \(manager.employees())") //Uncomment to remove all records // let departments = manager.departments() // for i in 0..departments.count{ // let dep = departments[i] as CSDepartment // manager.managedContext.deleteObject(dep) // } // let employees = manager.employees() // for i in 0..employees.count{ // let emp = employees[i] as CSEmployee // manager.managedContext.deleteObject(emp) // } // manager.saveContext() // println("\nHave delete all data") // println("Departments: \(manager.departments())") // println("Employees: \(manager.employees())") return true } }
removeEmployeesObject removeEmployees
on the child objects, you do not reset the department pointers and, accordingly, the objects are still validly stolen by the system in the storage.Source: https://habr.com/ru/post/225727/
All Articles