Create note in official Notes app

20 May: Updated with iCloud synchronization support

Notice: This method is undocumented and only for tweaks or apps that will not be submitted to AppStore.

Lately, as I was developing Tap to Note, I had to find a way to add notes in official Notes app without directly updating notes database file (SQLite).

Eventually, I used the private framework (Notes.framework) to perform update. Here only covers the way to insert a new note.

The Notes framework uses Core Data to perform all changes to the note database file. For those who don’t know what Core Data is, check out the documentation here and example here.

The first step is to initialize a new note context (NoteContext) ourselves (not sure if this is the most correct way).

NoteContext *noteContext = [[NSClassFromString(@"NoteContext") alloc] init];

UPDATE: To support iCloud synchronization, add the following line.

[noteContext enableChangeLogging:YES];

Then get the NSManagedObjectContext (for Core Data) from the context instance.

NSManagedObjectContext *context = [noteContext managedObjectContext];

And the default note store object (NoteStoreObject) as well.

NoteStoreObject *store = [noteContext defaultStoreForNewNote];

Actually you may want to insert notes to other stores (e.g. local or iCloud). You can get the desired note store using other similar methods in NoteContext (e.g. allStoreslocalStore).

After that, we are going to create a note object as follows.

NoteObject *note = [NSClassFromString(@"NSEntityDescription") insertNewObjectForEntityForName:@"Note" inManagedObjectContext:context];
NoteBodyObject *body = [NSClassFromString(@"NSEntityDescription") insertNewObjectForEntityForName:@"NoteBody" inManagedObjectContext:context];

// set body parameters
body.content = @"note content";
body.owner = note; // reference to NoteObject

// set note parameters
note.store = store; // reference to NoteStoreObject
note.integerId = [noteContext nextIndex];
note.title = @"title here";
note.summary = @"summary here";
note.body = body; // reference to NoteBodyObject
note.creationDate = [NSData date];
note.modificationDate = [NSData date];

Note content is the full content with HTML code as the official app uses HTML tags to wrap lines (i.e. <div>, <br />). Consecutive spaces need to be replaced with “&nbsp;”. Everything will just be shown in a web view.

Title and summary are normally extracted from the first and second line of content respectively while summary can be nil or empty if there’s only one line of content.

The last step is, of course, to save the note and release the initialized note context instance.

NSError *error;

BOOL success = [noteContext saveOutsideApp:&error];
[noteContext release];

You could retrieve the error message from the error variable and get the insertion result (success or not) from the return value of the method saveOutsideApp:.