Retired Document
Important:
The information in this document is deprecated in Mac OS X v10.7; don't use it for new development. Instead use the iCloud extensions to the NSFileManager
class to share file-based data and use the NSUbiquitousKeyValueStore
class to share preferences. Use the Address Book framework to access shared contact data and use the Calendar Store framework to access shared calendar data.
Filtering Records
You can use the ISyncFiltering
protocol and the setFilters:
method of ISyncClient
to filter the types of records your application syncs. Your filter can contain any custom logic you like as long as the sync engine can archive the filter and compare it with another filter. This article describes how to implement a filter using an example—extending the MediaExample application.
Creating a Filter Class
To implement a filter, you create a filter class that conforms to the NSCoding
and ISyncFiltering
protocols. The class needs to conform to NSCoding
so that it can be archived. The ISyncFiltering
protocol defines the methods that the sync engine will invoke to perform the actual filtering operation. The filter class also needs to override isEqual:
so that the sync engine can compare two filters.
For example, suppose you want to add to the MediaExample schema an entity called Calendar, which maintains a collection of events. 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. Figure 1 illustrates the modified schema.
You can modify the Events application to group events by calendar—when you import events, you add Event records to a Calendar record. You can then use a filter to sync only those events that belong to your Calendar records—when the filter is set, no other events will be pushed or pulled. This section describes how to create a filter.
Follow these steps to create a filter that rejects all Event records that do not belong to a specified Calendar:
In this example, the filter class is called CalendarFilter and defines one instance variable, the record identifier of the Calendar record:
@interface CalendarFilter : NSObject <NSCoding, ISyncFiltering> {
NSString *calendarIdentifier;
}
- (NSString *)calendarIdentifier;
- (void)setCalendarIdentifier:(NSString *)value;
@end
Next add implementations of the NSCoding protocol methods,
initWithCoder:
andencodeWithCoder:
, toCalendarFilter.m
:- (id)initWithCoder:(NSCoder *)coder
{
if ( [coder allowsKeyedCoding] ) {
calendarIdentifier = [[coder decodeObjectForKey:@"calendarIdentifier"] retain];
} else {
calendarIdentifier = [[coder decodeObject] retain];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)coder
{
if ([coder allowsKeyedCoding]) {
[coder encodeObject:calendarIdentifier forKey:@"calendarIdentifier"];
} else {
[coder encodeObject:calendarIdentifier];
}
return;
}
Then add implementations for the
ISyncFiltering
methods,supportedEntityNames
andshouldApplyRecord:withRecordIdentifier:
, toCalendarFilter.m
. ThesupportedEntityNames
method simply returns the names of the entities that you are filtering.- (NSArray *)supportedEntityNames
{
return [NSArray arrayWithObject:@"com.mycompany.syncexamples.Event"];
}
The
shouldApplyRecord:withRecordIdentifier:
method performs the actual filter operation. In this example, the filter rejects all Event records that do not belong to the Calendar record specified bycalendarIdentifier
.- (BOOL)shouldApplyRecord:(NSDictionary *)record withRecordIdentifier:(NSString *)recordIdentifier
{
NSArray *relationship = [record valueForKey:@"calendar"];
if ((relationship != nil) && ([relationship count] > 0) &&
[[relationship objectAtIndex:0] isEqual:[self calendarIdentifier]])
return YES;
else
return NO;
}
Setting Filters
You can set multiple filters. For example, you can create multiple instances of CalendarFilter—one for each Calendar instance in your application—or create an entirely different filter for other entities.
You create an instance of a filter and activate it by sending setFilters:
to your sync client. The setFilters:
method takes an array of filters as the argument. The sync engine compares the filters with existing filters (using isEqual:
) and replaces only those filters that are different.
id filter = [[CalendarFilter alloc] init]; |
[filter setCalendarIdentifier:calendarIdentifier]; |
[mySyncClient setFilters:[NSArray arrayWithObject:filter]]; |
Using Filters
If you set a filter and push records that do not match that filter, the sync engine will issue deletes for those pushed records on the subsequent pull phase. This is because filters are applied to the pulled records only, not the pushed records. If this behavior is not desired, clients should implement their own filters when pushing records (for example, don’t push records that you don’t want to pull), or modify their filters to accept all pushed records.
You can also use the ISyncFilter
class to create a combination of filters—that is, create a filter that is a logical AND
or OR
of multiple filters.
Filtering Using the Client Description
You can also filter the entities and properties your client syncs using the client description property list. The client description property list specifies the entities and properties you support and can be a subset of the entities and properties defined in your schemas. See Registering Clients for more details on the format of client description property lists.
For example, if you want to use the existing iCal Calendars schema but only want to sync Calendar and Event entities, and a minimal set of their properties, then you could edit the client description property list as follows:
<?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>DisplayName</key> |
<string>FooApp</string> |
<key>ImagePath</key> |
<string>FooApp.icns</string> |
<key>Entities</key> |
<dict> |
<key>com.apple.calendars.Calendar</key> |
<array> |
<string>title</string> |
<string>notes</string> |
<string>events</string> |
</array> |
<key>com.apple.calendars.Event</key> |
<array> |
<string>summary</string> |
<string>start date</string> |
<string>calendar</string> |
</array> |
</dict> |
</dict> |
</plist> |
Although the Calendar entity defines many more properties, when your client syncs this entity, it will only push and pull the title
, notes
and events
properties. (The events
property is an inverse to-many relationship to Event.) Similarly, it will only push and pull the start date
, summary
and calendar
properties of Event records.
See Apple Applications Schema Reference for a complete description of the iCal Calendars schema.
Copyright © 2004, 2011 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2011-07-06