< Previous PageNext Page > Hide TOC

Creating a Sync Schema

A sync schema consists of a property list, image files, and localization files contained in a bundle that you specify when registering a schema. If you are using Core Data, then it might contain one or more managed object models, too. You can create a schema to extend an existing schema or to define your own schema. The schema property list contains a description of the entities and properties used by the client as well as other attributes used by the sync engine.

See Cocoa Design Patterns in Cocoa Fundamentals Guide for a description of entity-relationship models and terminology. See “Registering Schemas” for how to register your own schemas.

Note: Core Data syncing and the managed object models schema property are available in Mac OS X v10.5 and later.

Contents:

Sync Schema Components
Creating a Sync Schema Bundle
Creating a Sync Schema Property List
Localizing Property Names
Creating a Schema Extension


Sync Schema Components

A sync schema is a property list stored in a .syncschema bundle along with other related files such as localization and image files. A property list is made up of primitive types such as arrays, dictionaries, and string values, not arbitrary types. Nevertheless, it’s helpful to view a property list as a pseudo object model.Figure 1 illustrates the components in a sync schema: the schema itself, entities, data classes, attributes, and relationships. The double arrowheads in the diagram imply a to-many relationship (implemented as an array in the property list) between components.


Figure 1  Sync schema components

Sync schema components

Creating a Sync Schema Bundle

You can create a schema bundle using Xcode. Just select New Project from the File menu and select the Sync Schema template from the Assistant. Then edit the Schema.plist file to define your entities and properties as described in “Creating a Sync Schema Property List.” You can also localize the names of entities and properties using the Schema.strings file as described in “Localizing Property Names.”

Creating a Sync Schema Property List

After you create a schema bundle, you edit the Schema.plist file to define your entities and properties. Unless otherwise stated, the following high-level sync schema properties are optional:

Property

Description

Comment

A string used to document the schema.

Available in Mac OS X v10.4 and later.

DataClasses

An array containing one or more dictionaries that describe a data class. The properties of a data class are described in “Data Class Properties.” If this is not a schema extension, this key is required.

Available in Mac OS X v10.4 and later.

Entities

An array of dictionaries describing new record types and record type extensions. The entity properties are described in “Entity Properties.”

Available in Mac OS X v10.4 and later.

ManagedObjectModels

An array of strings containing the paths to the Core Data managed object model files (files with a .mom suffix) associated with this schema.

Relative paths are relative to the location of the schema bundle. Use a relative path to load a model that lives outside the schema bundle—for example, use ../../../MyModel.mom to load a model located in the application's Resources directory.

Use this property if you want to sync Core Data managed objects. By default, all entities and properties defined in a managed object model are registered with the sync manager. Read “Syncing Core Data Applications” for how to designate a subset of entities and properties to sync and set other required sync information in a managed object model.

Available in Mac OS X v10.5 and later.

Name

A string providing a unique name for this schema. Typically, a reverse DNS-style name such as com.mycompany.SyncExamples. You should never change the schema name. Doing so orphans the old schema definition, which you then must remove. This key is required.

Available in Mac OS X v10.4 and later.

StrictParsing

Set to true if you want to use strict validation, false otherwise. If not specified, uses the validation corresponding to the binary registering the schema. If the binary was built on Mac OS X v10.5 and later, uses strict validation.

Available in Mac OS X v10.5 and later.

UIHelperClass

Set to the class that implements the ISyncUIHelper informal protocol. Use this key if you want to customize the presentation of your records and schema in the iSync user interface.

When the sync schema bundle is loaded, an instance of this class is created to handle presentation requests from the data change alert and conflict resolver user interfaces. Therefore, if this key is set, the class must be included in this schema bundle.

Available in Mac OS X v10.5 and later.

For example, the following property list fragment specifies the name of the sync schema as com.mycompany.SyncExamples. Typically, you use reverse DNS-style names for schemas, entities, and client identifiers. (Working applications using this example schema are located in /Developer/Examples/Sync Services/MediaExample.)

<plist version="1.0">
<dict>
    <key>Name</key>
    <string>com.mycompany.SyncExamples</string>
    <key>DataClasses</key>
    <array>
     ...
    </array>
    <key>Entities</key>
    <array>
     ...
    </array>
</dict>
</plist>

Data Class Properties

A data class is a logical grouping of related entities. Typically, it is a grouping that makes sense to a user—for example, a group of entities that a user might want to sync over .Mac such as contacts. You can add an entity to a data class by setting the entity’s DataClass attribute. Any data class you create should be added to the schema’s DataClasses property.

The properties of a data class are as follows:

Property

Description

ImagePath

Path to an image representing this data class. If it is a relative path, then it is assumed to be relative to the schema bundle. Typically, the image is an icon file that can be displayed at different resolutions. Otherwise, it should be at least 32 x 32 pixels. This key is required.

Available in Mac OS X v10.4 and later.

Name

A unique name for the data class. Typically, a reverse DNS-style name such as com.apple.Contacts. Can be localized using the Schema.strings file located in the schema bundle. This key is required.

Available in Mac OS X v10.4 and later.

For example, the following property list fragment specifies the data classes for an example application:

    <key>DataClasses</key>
    <array>
        <dict>
            <key>Name</key>
            <string>com.mycompany.SyncExamples</string>
            <key>ImagePath</key>
            <string>SyncExamples.icns</string>
        </dict>
    </array>

Entity Properties

The properties of an entity within a sync schema are described below and are optional unless explicitly stated otherwise:

Property

Description

Attributes

An array containing dictionaries describing the attributes in the entity or extension. Attribute properties are described in “Attribute Properties.”

Available in Mac OS X v10.4 and later.

DataClass

The name of the data class this entity belongs to. This key is required.

Available in Mac OS X v10.4 and later.

ExcludeFromDataChangeAlert

Set to true if you want to exclude changes to records of this entity type from the total count of changed records used in alert messages, false otherwise. The default value is false.

Available in Mac OS X v10.4 and later.

ExtensionName

A unique name for this extension, if you are adding attributes to an existing entity. The extension name is used to scope the attribute and relationship names to prevent collisions. Typically, a reverse DNS-style name such as com.apple.iCal.CalendarExtensions. If this is a schema extension, this key is required.

Available in Mac OS X v10.4 and later.

IdentityProperties

An array containing the names of the entity properties that are used to match a new record from a sync client with an existing record. If the target of a to-one relationship is used, the name of the relationship is specified.

Available in Mac OS X v10.4 and later.

Name

A unique name for the entity. Typically, a reverse DNS-style name such as com.apple.Contacts. Can be localized using the Schema.strings file located in the schema bundle. This key is required.

Available in Mac OS X v10.4 and later.

Parent

The name of the relationship that contains or encloses records belonging to this entity. Used to display a user friendly entity name when conflicts occur during syncing. For example, in the contacts schema, the target of the contact relationship is the parent of a Phone Number record.

Available in Mac OS X v10.4 and later.

PropertyDependencies

An array containing arrays of groups of properties that are dependent on each other. A dependent property is one which must be pushed to a client if any of its dependencies are changed. Each entry in this array is itself an array of strings, specifying the names of the codependent properties. Entries in these arrays may be an attribute name or a relationship name.

Available in Mac OS X v10.4 and later.

Relationships

An array containing dictionaries describing the relationships in the entity or extension. Relationship properties are described in “Relationship Properties.”

Available in Mac OS X v10.4 and later.

For example, the following property list fragment describes the properties of the com.mycompany.syncexamples.Media entity. Sample values for the Attributes and Relationships properties appear in “Attribute Properties” and “Relationship Properties.”

<dict>
    <key>Name</key>
    <string>com.mycompany.syncexamples.Media</string>
    <key>DataClass</key>
    <string>com.mycompany.SyncExamples</string>
    <key>Attributes</key>
    ...
    <key>Relationships</key>
    ...
    <key>IdentityProperties</key>
    ...
</dict>

Attribute Properties

The properties of an attribute belonging to an entity are as follows:

Property

Description

ExcludeFromDataChangeAlert

Set to true if you want to exclude changes to this attribute from the total count of changed attributes used in alert messages, false otherwise.

Available in Mac OS X v10.4 and later.

Name

The name of the attribute. Can be localized using the Schema.strings file located in the schema bundle. The localization key is $entity/$attribute_name. For example, the localization key for the title attribute of the com.mycompany.syncexamples.Media entity would be com.mycompany.syncexamples.Media/title. This key is required.

Available in Mac OS X v10.4 and later.

Required

Set to true if required, false otherwise. The sync engine will reject a record that doesn’t have a required attribute set. The default value is false.

Available in Mac OS X v10.4 and later.

Type

The type of the attribute. This key is required.

Available in Mac OS X v10.4 and later.

Sync Services supports the following types of attributes. Note that the types are case-sensitive and expected to appear in lowercase.

Attribute type

Objective-C class

array

NSArray

boolean

NSNumber

calendar date

NSCalendarDate

color

NSColor

data

NSData

date

NSDate

dictionary

NSDictionary

enum

NSString

number

NSNumber

string

NSString

url

NSURL

For example, the following property list fragment describes the attributes of the com.mycompany.syncexamples.Media entity. Each dictionary below contains the name and type of each attribute. For example, the date attribute is specified as a calendar date type. Therefore, when pushing or pulling a com.mycompany.syncexamples.Media record, the value for the date key will be an instance of NSCalendarDate.

<key>Attributes</key>
<array>
    <dict>
        <key>Name</key>
        <string>date</string>
        <key>Type</key>
        <string>calendar date</string>
    </dict>
    <dict>
        <key>Name</key>
        <string>imageURL</string>
        <key>Type</key>
        <string>url</string>
    </dict>
    <dict>
        <key>Name</key>
        <string>title</string>
        <key>Type</key>
        <string>string</string>
    </dict>
</array>

If you use an array type, you can further limit the contents of the array to instances of a class and its subclasses using the Subtype key. For example, the following property list fragment describes a dates attribute as an array containing NSCalendarDate objects. The Subtype key is optional but if used, is enforced by the sync engine.

<key>Attributes</key>
<array>
    <dict>
        <key>Name</key>
        <string>dates</string>
        <key>Type</key>
        <string>array</string>
        <key>Subtype</key>
        <string>calendar date</string>
    </dict>
</array>

If you use an enum type, you must also specify the possible enum values using the EnumValues key. In this example, the display order attribute is an enum that can be either firstNameFirst or lastNameFirst:

<dict>
    <key>EnumValues</key>
    <array>
    <string>firstNameFirst</string>
    <string>lastNameFirst</string>
    </array>
    <key>Name</key>
    <string>display order</string>
    <key>Type</key>
    <string>enum</string>
</dict>

Relationship Properties

Relationships from one entity to another are allowed only if the entities belong to the same data class. If you attempt to define a relationship to an entity in another data class, validation fails at runtime and an exception is raised. Schema validation may fail as well.

The properties of a relationship belonging to an entity are:

Property

Description

ExcludeFromDataChangeAlert

Set to true if you want to exclude changes to this relationship from the total count of changed relationships used in alert messages, false otherwise.

Available in Mac OS X v10.4 and later.

DeleteRule

A value of cascade or nullify. If set to cascade, then when the source record of the relationship is deleted, all the target records are deleted. If set to nullify, then when the target record is deleted, the reference from the source’s relationship is removed. If it is a to-one relationship, the relationship is set to null. If it is a to-many relationship, then it is removed from that relationship.

Available in Mac OS X v10.4 and later.

InverseRelationships

An array of dictionaries specifying this relationship’s inverse relationships. The keys in an inverse relationship dictionary are described in “Inverse Relationship Properties.”

Available in Mac OS X v10.4 and later.

Name

The name of the relationship. Can be localized using the Schema.strings file located in the schema bundle. The localization key is $entity/$relationship_name. For example, the localization key for the event relationship of the com.mycompany.syncexamples.Media entity would be com.mycompany.syncexamples.Media/event. This key is required.

Available in Mac OS X v10.4 and later.

Ordinality

Indicates a to-one or to-many relationship, value of one or many. The default value is one.

Available in Mac OS X v10.4 and later.

Ordering

Value of none, weak or strong. If the value is none, then no order is maintained. If the value is strong, then the order is maintained and alert panels appear when conflicts occur. If the value is weak, then the order is maintained but alert panels do not appear when conflicts occur—the sync engine merges ordering conflicts. The default value is none.

Available in Mac OS X v10.4 and later.

Required

Set to true if required, false otherwise. The sync engine will reject a record that doesn’t have a required relationship set. The default value is false.

Available in Mac OS X v10.4 and later.

Target

An array containing the names of the target entities belonging to the same data class. Generally, a relationship has a single target. However, you can specify multiple entities as the target if the target can be a number of different types. This key is required.

Available in Mac OS X v10.4 and later.

For example, the following property list fragment describes the relationships of the com.mycompany.syncexamples.Media entity. The fragment defines a to-one relationship, called event, from com.mycompany.syncexamples.Media to com.mycompany.syncexamples.Event.

<key>Relationships</key>
<array>
    <dict>
        <key>Name</key>
        <string>event</string>
        <key>Ordinality</key>
        <string>one</string>
        <key>Target</key>
        <array>
            <string>com.mycompany.syncexamples.Event</string>
        </array>
    </dict>
</array>

Inverse Relationship Properties

The properties of an inverse relationship belonging to a relationship are as follows:

Property

Description

EntityName

The name of the entity belonging to the same data class. This key is required.

Available in Mac OS X v10.4 and later.

RelationshipName

The name of the entity that has the inverse relationship. This key is required.

Available in Mac OS X v10.4 and later.

For example, the following property list fragment describes the inverse relationship between the event relationship of the com.mycompany.syncexamples.Media entity and the media relationship of the com.mycompany.syncexamples.Event entity. The media relationship is a to-many relationship from com.mycompany.syncexamples.Event to com.mycompany.syncexamples.Media.

<key>InverseRelationships</key>
<array>
    <dict>
        <key>EntityName</key>
        <string>com.mycompany.syncexamples.Event</string>
        <key>RelationshipName</key>
        <string>media</string>
    </dict>
</array>

Identity Properties

The value of the IdentityProperties key is an array containing the names of the properties that are used to identify a record of this entity type if there is a conflict. For example, the identity properties for a com.mycompany.syncexamples.Media entity are specified as the date and title properties below. The com.mycompany.syncexamples.Media entity may have other properties, such as imageURL, which are not in this array.

<key>IdentityProperties</key>
<array>
    <string>date</string>
    <string>title</string>
</array>
!

Warning: You should always push the identity properties for a record. Otherwise, you might create duplicate records during the first sync or a refresh sync.

Property Dependencies

In some cases, if one property changes, you might want to push another related property, even if its value didn’t change. For example, suppose you change a calendar event to an all day event in iCal and using your phone you change the start time of the same event. Even though each client changed a different property, the changes conflict and need to be resolved. You can inform the sync engine about dependent properties within your entities so that these types of conflicts are recognized when syncing.

The value of the PropertyDependencies key is an array of arrays containing the dependent properties. Each array contains the set of properties that are dependent on each other. For example, you might declare that the startDate, endDate and allDayEvent properties are dependent as follows:

<key>PropertyDependencies</key>
<array>
    <array>
        <string>startDate</string>
        <string>endDate</string>
        <string>allDayEvent</string>
    </array>
</array>

Localizing Property Names

You can define user-friendly names for data classes, entities, and properties by editing the Schema.strings schema bundle localization file. Localized names are used by Sync Services applications that present records to users.

For example, an alert message might appear using a data class name in a message—for example, a panel might appear asking the user if it’s okay to syncronize with other applications. If no localization is provided, the DNS-style data class name is used in the alert message which might be confusing to the user. You should modify your Schema.strings file to provide both plural and singular forms of data class names.

Specifically, you can define a localized string for the DataClass, Entity, Relationship, and Attribute components illustrated in Figure 1. The key for the DataClass and Entity localized string is simply the Name attribute of the DataClass component. The key for an Attribute or Relationship component is of the form:

$entity/$property

For example, the Schema.strings file for the MediaExample application located in /Developer/Examples/Sync Services is:

/* Data Class: The data class for the Sync Services examples.*/
"com.mycompany.SyncExamples" = "Media Example Data";
 
/* Singular Data Class Name: Used for any UI that needs a singular name.*/
"Singular:com.mycompany.SyncExamples" = "Media Example Data";
 
/* Entity: A media item such as a photo taken at an event. */
"com.mycompany.syncexamples.Media" = "Media";
 
/* Attribute: The date a photo was taken. */
"com.mycompany.syncexamples.Media/date" = "Creation Date";
 
/* Attribute: The file URL for the image. */
"com.mycompany.syncexamples.Media/imageURL" = "Image URL";
 
/* Attribute: A user-friendly title of the photo. */
"com.mycompany.syncexamples.Media/title" = "Image Title";
 
/* Relationship: The event where the photo was taken. */
"com.mycompany.syncexamples.Media/event" = "Event";
...

Creating a Schema Extension

Sync Services also allows you to extend an existing schema without changing it directly—for example, when you don’t have permission to change it directly or you want to encapsulate your extensions from other applications. Sync Services ensures that only those applications that use the extension see the entities and properties defined by them. You can even extend existing Apple Applications schemas without adversely affecting other desktop applications. Read Apple Applications Schema Reference for details on these schemas.

Schema extensions reside in a bundle structure that is identical to sync schema bundles. The only difference is that the Schema.plist and Schema.strings files pertain only to entity and property extensions.

For example, suppose you want to add an entity called Calendar to the MediaExample schema, which maintains a collection of Event records. That way, when you import an iCal file, you can group the events together. You can do this by creating a Calendar entity with an identity attribute, such as a name or title, and an inverse to-many relationship to Event.

Follow these steps to create a schema extension that adds a Calendar entity to SyncExamples.syncschema:

  1. Define a unique name for the schema extension in Schema.plist:

    <key>Name</key>
    <string>SyncExamplesExtension</string>
  2. Add new properties to existing entities in Schema.plist. Specifically, add an inverse to-one relationship from Event to Calendar:

    <dict>
        <key>ExtensionName</key>
        <string>com.mycompany.syncexamples.EventExtensions</string>
        <key>Name</key>
        <string>com.mycompany.syncexamples.Event</string>
        <key>Relationships</key>
        <array>
            <dict>
                <key>InverseRelationships</key>
                <array>
                    <dict>
                        <key>EntityName</key>
                        <string>com.mycompany.syncexamples.Calendar</string>
                        <key>RelationshipName</key>
                        <string>events</string>
                    </dict>
                </array>
                <key>Name</key>
                <string>calendar</string>
                <key>Ordinality</key>
                <string>one</string>
                <key>Target</key>
                <array>
                    <string>com.mycompany.syncexamples.Calendar</string>
                </array>
            </dict>
        </array>
    </dict>
  3. Add new entity definitions to Schema.plist: Specifically, add a Calendar entity and to-many inverse relationship from Calendar to Event. You can use the same data class, com.mycompany.SyncExamples, defined in SyncExamples.syncschema:

    <dict>
        <key>Attributes</key>
        <array>
            <dict>
                <key>Name</key>
                <string>title</string>
                <key>Type</key>
                <string>string</string>
            </dict>
        </array>
        <key>DataClass</key>
        <string>com.mycompany.SyncExamples</string>
        <key>IdentityProperties</key>
        <array>
            <string>title</string>
        </array>
        <key>Name</key>
        <string>com.mycompany.syncexamples.Calendar</string>
        <key>Relationships</key>
        <array>
            <dict>
                <key>InverseRelationships</key>
                <array>
                    <dict>
                        <key>EntityName</key>
                        <string>com.mycompany.syncexamples.Event</string>
                        <key>RelationshipName</key>
                        <string>calendar</string>
                    </dict>
                </array>
                <key>Name</key>
                <string>events</string>
                <key>Ordinality</key>
                <string>many</string>
                <key>Target</key>
                <array>
                    <string>com.mycompany.syncexamples.Event</string>
                </array>
            </dict>
        </array>
    </dict>
  4. Finally, add localization strings for new entities and properties to Schema.strings:

    /* Relationship: The calendar associated with an event. */
    "com.mycompany.syncexamples.Event/calendar" = "Calendar";
     
    /* Entity: A calendar, group of events.*/
    "com.mycompany.syncexamples.Calendar" = "Calendar";
     
    /* Attribute: The calendar title. */
    "com.mycompany.syncexamples.Calendar/title" = "Title";
     
    /* Relationship: The events associated with a calendar. */
    "com.mycompany.syncexamples.Calendar/events" = "Events";

Note: Make sure that the original schema is registered with the sync engine before registering a schema extension.

The schema extensions file should look similar to the file in Listing 1.

Listing 1  Schema Extensions Example

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>Entities</key>
    <array>
        <dict>
            <key>ExtensionName</key>
            <string>com.mycompany.syncexamples.EventExtensions</string>
            <key>Name</key>
            <string>com.mycompany.syncexamples.Event</string>
            <key>Relationships</key>
            <array>
                <dict>
                    <key>InverseRelationships</key>
                    <array>
                        <dict>
                            <key>EntityName</key>
                            <string>com.mycompany.syncexamples.Calendar</string>
                            <key>RelationshipName</key>
                            <string>events</string>
                        </dict>
                    </array>
                    <key>Name</key>
                    <string>calendar</string>
                    <key>Ordinality</key>
                    <string>one</string>
                    <key>Target</key>
                    <array>
                        <string>com.mycompany.syncexamples.Calendar</string>
                    </array>
                </dict>
            </array>
        </dict>
        <dict>
            <key>Attributes</key>
            <array>
                <dict>
                    <key>Name</key>
                    <string>title</string>
                    <key>Type</key>
                    <string>string</string>
                </dict>
            </array>
            <key>DataClass</key>
            <string>com.mycompany.SyncExamples</string>
            <key>IdentityProperties</key>
            <array>
                <string>title</string>
            </array>
            <key>Name</key>
            <string>com.mycompany.syncexamples.Calendar</string>
            <key>Relationships</key>
            <array>
                <dict>
                    <key>InverseRelationships</key>
                    <array>
                        <dict>
                            <key>EntityName</key>
                            <string>com.mycompany.syncexamples.Event</string>
                            <key>RelationshipName</key>
                            <string>calendar</string>
                        </dict>
                    </array>
                    <key>Name</key>
                    <string>events</string>
                    <key>Ordinality</key>
                    <string>many</string>
                    <key>Target</key>
                    <array>
                        <string>com.mycompany.syncexamples.Event</string>
                    </array>
                </dict>
            </array>
        </dict>
    </array>
    <key>Name</key>
    <string>SyncExamplesExtension</string>
</dict>
</plist>


< Previous PageNext Page > Hide TOC


© 2004, 2007 Apple Inc. All Rights Reserved. (Last updated: 2007-10-31)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.