PyObjC CoreData Framework

12.1 · active · verified Tue Apr 14

PyObjC-framework-CoreData provides Python wrappers for Apple's Core Data framework on macOS. Core Data is a powerful framework that offers generalized and automated solutions for object life-cycle management, object graph persistence, and change tracking. This package, currently at version 12.1, is part of the broader PyObjC project, which typically sees minor releases every few months and major version updates roughly annually to align with macOS SDK changes.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to programmatically define a Core Data model, set up an `NSPersistentContainer` with an in-memory store, create, save, and fetch `NSManagedObject` instances using PyObjC. It highlights the use of `NSPersistentContainer` for simplified stack management and the Python-Objective-C bridge mechanics, particularly for asynchronous operations like loading persistent stores.

import CoreData
import objc
import os

# 1. Define the Managed Object Model programmatically
model = CoreData.NSManagedObjectModel.alloc().init()
entity = CoreData.NSEntityDescription.alloc().init()
entity.name = "Event"
entity.managedObjectClassName = "Event"

attribute_name = CoreData.NSAttributeDescription.alloc().init()
attribute_name.name = "name"
attribute_name.attributeType = CoreData.NSStringAttributeType
attribute_name.optional = False

attribute_timestamp = CoreData.NSAttributeDescription.alloc().init()
attribute_timestamp.name = "timestamp"
attribute_timestamp.attributeType = CoreData.NSDateAttributeType
attribute_timestamp.optional = False

entity.properties = [attribute_name, attribute_timestamp]
model.entities = [entity]

# 2. Create a Persistent Container
# Use a unique in-memory store for a quick runnable example
container = CoreData.NSPersistentContainer.alloc().initWithName_managedObjectModel_(
    "MyCoreDataApp", model
)

# Configure an in-memory store for the quickstart
store_description = CoreData.NSPersistentStoreDescription.alloc().init()
store_description.URL = None # For in-memory store
store_description.type = CoreData.NSInMemoryStoreType
container.persistentStoreDescriptions = [store_description]

def load_stores(completion_handler):
    container.loadPersistentStoresWithCompletionHandler_(completion_handler)

# Convert Python function to an Objective-C block using objc.block
# This is necessary because loadPersistentStoresWithCompletionHandler_ expects an Objective-C block
@objc.block
def store_load_handler(store_description, error):
    if error:
        print(f"Failed to load persistent store: {error}")
    else:
        print(f"Successfully loaded store: {store_description.URL().path()}")
        # 3. Get the Managed Object Context
        context = container.viewContext

        # 4. Create and Save an NSManagedObject
        Event = context.persistentStoreCoordinator().managedObjectModel().entitiesByName().get("Event")
        new_event = CoreData.NSManagedObject.alloc().initWithEntity_insertIntoManagedObjectContext_(
            Event, context
        )
        new_event.setValue_forKey_("Python Demo Event", "name")
        new_event.setValue_forKey_(CoreData.NSDate.date(), "timestamp")
        
        # Save changes to the context (which saves to the store)
        try:
            context.save()
            print(f"Saved new event: {new_event.name()} at {new_event.timestamp()}")
        except Exception as e:
            print(f"Error saving context: {e}")

        # 5. Fetch NSManagedObjects
        fetch_request = CoreData.NSFetchRequest.fetchRequestWithEntityName_("Event")
        events = context.executeFetchRequest_error_(fetch_request, objc.NULL)

        if events:
            print("Fetched Events:")
            for event_obj in events:
                print(f" - Name: {event_obj.name()}, Timestamp: {event_obj.timestamp()}")
        else:
            print("No events found.")

load_stores(store_load_handler)

# To keep the application running for asynchronous operations (if not in a GUI app)
# For simple script, this might not be strictly needed as the completion handler finishes sync if in-memory.
# In a real app, you'd use NSApplication.run() or similar.

view raw JSON →