🍎
iOS Penetration testing
WEBSITEGITHUBLINKEDININSTAGRAM
  • Let me Introduced Myself
  • 😍Jailbreaking iOS device.
  • 😎Installing tools on iOS device
  • πŸ₯³Installing and Obtaining IPA files on jailbroken iOS device
  • πŸ€“Static Testing of iOS application
  • πŸ˜‚Dynamic Testing of iOS application
  • πŸ˜€UserDefaults
  • 😜KeyChain
  • 😁Core Data
Powered by GitBook
On this page
  • Add Core Data to a New Xcode Project
  • Add a Core Data Model to an Existing Project
  • Data Modeling: Add Entities and Attributes
  • Generating Code
  • Creating the Core Data Manager
  • Create, Fetch and Delete Note in CoreData

Was this helpful?

Core Data

PreviousKeyChain

Last updated 1 year ago

Was this helpful?

Core Data is an object graph and persistence framework provided by Apple. It allows data to be organized in a relational entity–attribute model manner, so that it can be serialized into XML, binary, or SQLite stores.

You can use Core Data to save your application’s permanent data for offline use, to cache temporary data, and to add undo functionality to your app on a single device.

πŸ’‘ Remember that Core Data isn’t a database nor it consists of table of rows and columns. Core Data abstracts the details of mapping your objects to a store or database, making it easy to save data from Swift and Objective-C without administering a database directly.

The first step in working with Core Data is to create a data model file to define the structure of your app’s objects, including their object types, properties, and relationships. You can add a Core Data model file to your Xcode project when you create the project, or you can add it to an existing project. Let’s build a core data model for a notes app.

Add Core Data to a New Xcode Project

While creating a new project, select the Use Core Data checkbox. The resulting project includes an .xcdatamodeld file and the AppDelegate.swift file with Core Data Stack code.

Add a Core Data Model to an Existing Project

Choose File β†’New β†’File and select the iOS platform tab. Scroll down to the Core Data section, select Data Model, and click Next and save it to desired directory. Let’s save it in Models folder. Xcode adds an MyNotes.xcdatamodeld file in the Models directory.

Data Modeling: Add Entities and Attributes

The next step is to create a data-structure that will hold our notes. A Note class look like this:

class Note {
    let id = UUID()
    var text: String = ""
    var lastUpdated: Date = Date()
}

We will create a entity for this Note class. An entity describes an object, including its name, attributes, and relationships. Create an entity for each of your app's objects.

  1. Click Add Entity at the bottom of the editor area. A new entity with placeholder name Entity appears in the Entities list.

  2. In the Entities list, double-click the newly added entity and rename it as Note. This step updates both the entity name and class name visible in the Data Model inspector.

  3. After you create an entity, you can add attributes to that entity. An attribute describes a property of an entity. Add id,text,lastUpdated as attributes to Note entity.

Generating Code

Model, specify the classes that you’ll use to create instances of your entities. Core Data optionally generates two files to support your class: a class file and a properties file.

To select a code generation option:

  1. Select an entity from the Entities list.

  2. In the Data Model inspector, below Class, the Codegen pop-up menu offers three options: Manual/None, Class Definition, and Category/Extension.

  3. Choose Manual/None and from the Xcode menu bar, choose Editor -> create NSManagedObject Subclass -> select MyNotes as Data Model β†’ select Note as the entity to manage β†’ choose Models directory.

The Xcode will generate two files CoreDataClass and CoreDataProperties. CoreDataProperties file is sort of the representation of our data model(entity) which will have attributes and relationship property. CoreDataClass is a class that is available to us extend or add some properties to the Note class.

β€” While selecting Manual configuration, if we change any property to Note entity, we manually have to configure those changes in these two files.

β€” In Class Definition configuration, Xcode will automatically generate the required NSManagedObject subclass as part of the project’s derived data. If we have to change anything, Xcode automatically syncs these files with the corresponding entity. But, we will not have access to use class file and extend its properties.

β€” In Category/Extension configuration, Xcode will only automatically generate CoreDataProperties.swift for you and you will have to manage and maintain CoreDataClass.swift yourself. So, we can use this configuration without worrying about the entity properties.

Creating the Core Data Manager

While including a CoreData at project initialisation, you will see some extra code added there like persistent container in AppDelegates. Since, we added CoreData after our project initialisation and we don’t want to clutter the application delegate with the setup of the Core Data stack. we are going to create a separate class that is responsible for setting up and managing the Core Data stack.

  1. Create a new Swift file in the Models group and name the file CoreDataManager. This is the class that will be in charge of the Core Data stack of the application.

  2. We start by adding an import statement for the CoreData framework and define a singleton CoreDataManager class.

  3. Now lets dig in AppDelegate.swift file and discuss about code. The AppDelegate file contains application life cycle methods and code stubs related to core data.

  4. Initialize NSPersistentContainer class and thus core data stack objects (Managed object Model, PersistentStoreCoordinator, Managed Object Context).

  5. A method named save(). It saves managed object models in to store.

  6. Application life cycle method named applicationWillTerminate calls saveContext() also to save data in store when app is about to terminate.

The below code creates a NSPersistentContainer object. An instance of NSPersistentContainer includes all objects needed to represent a functioning Core Data stack. NSPersistentContainer is a container that encapsulates the Core Data stack (Heart of the core data) in your application. NSPersistentContainer simplifies the creation/initialization and management of the Core Data stack by handling the creation of below objects:- βŠ› managed object model (NSManagedObjectModel), βŠ› persistent store coordinator (NSPersistentStoreCoordinator), βŠ› and the managed object context (NSManagedObjectContext).

 //  CoreDataManager.swift

import Foundation
import CoreData

class CoreDataManager {
    static var shared = CoreDataManager(modelName: "MyNotes")
    let persistentContainer: NSPersistentContainer
    
    private init(modelName: String){
        persistentContainer = NSPersistentContainer(name: modelName)
    }
    
    // Core Data stack
    var viewContext: NSManagedObjectContext {
        return persistentContainer.viewContext
    }
        
    func load(completion : (() -> Void)? = nil) {
        persistentContainer.loadPersistentStores { (description, error) in
            guard error == nil else {
                fatalError("Unresolved error \(error?.localizedDescription)")
            }
            completion?()
        }
    }
    
    func save() {
        if viewContext.hasChanges {
            do {
                try viewContext.save()
            }
            catch {
                print("An error occured while saving \(error.localizedDescription)")
            }
        }
    }
}

Now add the following code in didFinishLaunchingWithOptions in AppDelegate to load our data store.

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {        
    ...
    CoreDataManager.shared.load()
    ...
}

In the above code, persistentContainer = NSPersistentContainer(name: modelName) Initializes a persistent container with the given name "MyNotes". Where parameters (name :"MyNotes") is the name of the NSPersistentContainer object and return a persistent container initialized with the given name.

When persistent container have been initialized, we need to execute load to instruct the container to load the persistent stores and complete the creation of the Core Data stack. Once the completion handler has fired, the stack is fully initialized and is ready for use.

storeDescription β†’ As the name of the class suggests, NSPersistentStoreDescription class encapsulates the information and configuration to add a persistent store to the persistent store coordinator. In other words, it describes a persistent store.

var viewContext: NSManagedObjectContext {
    return persistentContainer.viewContext
}

In above code we are calling persistent container’s view context object. This view context is name of property of type ManagedObjectContext class. Function save looks for the changes made on managed object model. If there is any change we call viewContext.save() method of context object to finally save our data.

Create, Fetch and Delete Note in CoreData

extension CoreDataManager {
    func createNote() -> Note {
        let note = Note(context: viewContext)
        note.id = UUID()
        note.lastUpdated = Date()
        note.text = ""
        save()
        return note
    }
}

Let’s create a method createNote() that will initialize a Note object. We can’t just simply initialize a new note as let note = Note(), we need to initialize it with a context. And after initialization, we call save() function to save the changes in our viewContext.

func fetchNotes(filter: String? = nil) -> [Note] {
    let request: NSFetchRequest<Note> = Note.fetchRequest()
    if let filter = filter {
        let predicate = NSPredicate(format: "text contains[cd] %@", filter)
        request.predicate = predicate
    }
    let sortDescriptor = NSSortDescriptor(keyPath: \Note.lastUpdated, ascending: false)
    request.sortDescriptors = [sortDescriptor]
    return (try? viewContext.fetch(request)) ?? []
}

Method fetchNotes() will return an array of Notes. First, we create a request of type NSFetchRequest and assigning equal to Note.fetchRequest() which is a class method in Properties file.

To filter the contents of the Notes, we will use NSPredicate Predicates are simple tests, which are used to filter out the data which you need in our resultant array of data. The test will be applied to every object in your Core Data entity. Next thing we want to do is sort which one will be most recently updated notes. We create a sortDescriptor of type NSSortDescriptor and add it to the request and in last return viewContext.fetch

func deleteNote(note: Note){
    viewContext.delete(note)
    save()
}

Method deleteNote(), we will pass a note object to viewContext.delete() We can call these methods for CRUD operations according to our needs.

πŸ’‘ Core Data provides on-disk persistence, which means your data will be accessible even after terminating your app or shutting down your device. This is different from in-memory persistence, which will only save your data as long as your app is in memory, either in the foreground or in the background.

😁