#import <SyncServices/ISyncCommon.h>
#include <AppKit/NSResponder.h>
@class ISyncChange, ISyncClient, ISyncRecordSnapshot;



@interface ISyncSession : NSObject

/*beginSessionInBackgroundWithClient:entityNames:target:selector:

Creates a new sync session for the specified client. 

+ (void)beginSessionInBackgroundWithClient:(ISyncClient *)client entityNames:(NSArray *)entityNames target:(id)target selector:(SEL)selector
Discussion

Returns immediately and sends selector to target when a session was successfully or unsuccessfully created. The selector is passed two arguments: the first argument is the ISyncClient object and the second argument is the new ISyncSession object. If the sync engine is disabled and this method failed to create a session, selector is sent to target with nil as the ISyncSession object.

The entityNames argument specifies which entities the client wants to sync during this session. They can be a subset of the client's supported entities and may include entities which have been disabled. However, the sync engine does not allow the client to push changes to disabled entities nor does it provide changes to disabled entities while pulling changes. Typically, you use the array returned by sending enabledEntityNames to your ISyncClient object as the entityNames argument to this method.

Creating a session for client may trigger notifications to other clients observing syncs of this client type. This method differs from beginSessionWithClient:entityNames:beforeDate: by not blocking and sending selector to target when all dependent clients have joined the sync session. (Send setShouldSynchronize:withClientsOfType: to an ISyncClient object to setup these dependencies.) This method requires the client have a run loop running in the default mode.

Note: ISyncSession is not thread-safe. You can pass an ISyncSession object between threads but you should not use it concurrently. Asynchronous callbacks from ISyncSession are delivered to any client thread that used any of the SyncServices API. The client is responsible for directing the callback to an appropriate thread.

Availability
Available in Mac OS X v10.4 and later.
See Also
cancelPreviousBeginSessionWithClient: 
isEnabled (ISyncManager)*/

+ (void)beginSessionInBackgroundWithClient:(ISyncClient *)client entityNames:(NSArray *)entityNames target:(id)target selector:(SEL)selector;

/*shouldReplaceAllRecordsOnClientForEntityName:

Returns YES if the client should delete all the records for the entity, specified by entityName, and replace them with records pulled from the sync engine, NO otherwise.

- (BOOL)shouldReplaceAllRecordsOnClientForEntityName:(NSString *)entityName
Discussion

Send setShouldReplaceClientRecords:forEntityNames: to the client for this session to request a different behavior.

You can invoke this method at any time. However, you should not delete the local client data until the session enters the pulling state (after prepareToPullChangesForEntityNames:beforeDate: returns). Otherwise, if the session is canceled prematurely, the client may be left in an non synchronized state with no data.
Availability
Available in Mac OS X v10.4 and later.
See Also
shouldPullChangesForEntityName: 
clientDidResetEntityNames:*/

- (BOOL)shouldReplaceAllRecordsOnClientForEntityName:(NSString *)entityName;

/*prepareToPullChangesForEntityNames:beforeDate:

Returns NO if date expires before the sync engine is ready for the client to begin pulling changes, YES otherwise.

- (BOOL)prepareToPullChangesForEntityNames:(NSArray *)entityNames beforeDate:(NSDate *)date
Discussion

Moves the receiver to the mingling state and returns when the sync engine is ready for the client to begin pulling changes to the specified entities. Invoke this method after you have finished pushing changes to the sync engine and want to begin pulling changes. The entityNames array can contain a subset of the supported entity names. If this method returns NO, you can invoke it multiple times until it returns YES or the sync session is canceled or finished. 

Use this method during the pushing state to transition to the mingling state, otherwise an exception is raised. The mingling state ends when this method returns YES.
Availability
Available in Mac OS X v10.4 and later.
See Also
prepareToPullChangesInBackgroundForEntityNames:target:selector:*/
- (BOOL)prepareToPullChangesForEntityNames:(NSArray *)entityNames beforeDate:(NSDate *)date;

/*changeEnumeratorForEntityNames:

Returns the object enumerator for the ISyncChange objects which contain all the changes the client should apply to its local data.

- (NSEnumerator *)changeEnumeratorForEntityNames:(NSArray *)entityNames
Discussion

Use the returned object to iterate through the record changes during the pulling state. The entityNames argument can contain a subset of the supported entities. 

The sync engine applies client filters to the returned changes so that the client does not receive changes that were rejected. See Sync Services Programming Guide for more information on setting filters.

When the client applies a change described by an ISyncChange object, it must either accept or reject the change. You accept a change by sending clientAcceptedChangesForRecordWithIdentifier:formattedRecord:newRecordIdentifier: to the sync session, and reject a change by sending clientRefusedChangesForRecordWithIdentifier: to the sync session. After processing all changes (saving them on the device or locally) you send clientCommittedAcceptedChanges to the sync session to commit those changes. Any uncommitted accepted changes or rejected changes are sent again to the client during the next sync.

Use this method during the pulling state only, otherwise an exception is raised.
Availability
Available in Mac OS X v10.4 and later.
See Also
prepareToPullChangesForEntityNames:beforeDate:*/
- (NSEnumerator *)changeEnumeratorForEntityNames:(NSArray *)entityNames;

/*clientAcceptedChangesForRecordWithIdentifier:formattedRecord:newRecordIdentifier:

Informs the sync engine that the client has accepted the changes to the record identified by recordIdentifier during the pulling state.

- (void)clientAcceptedChangesForRecordWithIdentifier:(NSString *)recordIdentifier formattedRecord:(NSDictionary *)formattedRecord newRecordIdentifier:(NSString *)newRecordIdentifier
Discussion

If your client or device can not store properties using the defined schema, then you can use the formattedRecord to specify an alternate format. By specifying an alternate format, you assist the sync engine in figuring out which records and properties are equal during the mingling state, so that the sync engine doesn’t generate false changes for records that were simply reformatted. The formattedRecord dictionary should contain the entire record—key-value pairs for the formatted and unformatted properties including the ISyncRecordEntityNameKey key identifying the record’s entity name. Otherwise, the formattedRecord argument should be nil.

For example, if you are syncing a device and the device truncates first and last names to 20 characters long, then you should specify a formattedRecord record for truncated values when invoking this method. The formattedRecord dictionary should contain key-value pairs for only the properties that have different formats (were truncated by the device). See Sync Services Programming Guide for more details on formatting records.

The sync engine creates a new identifier for added records using CFUUIDRef. However, if your client generates its own unique record identifiers, then you can use the newRecordIdentifier argument to request that your identifier be used in future communications with the sync engine. 

You can use this method to batch up changes by invoking it repeatedly. You can also use the clientRefusedChangesForRecordWithIdentifier: method to reject changes. However, after a sequence of accepting and rejecting changes, you need to invoke clientCommittedAcceptedChanges to end the transaction and actually commit them. 

Use this method during the pulling state only, otherwise an exception is raised.
Availability
Available in Mac OS X v10.4 and later.
See Also
clientChangedRecordIdentifiers: 
clientLostRecordWithIdentifier:shouldReplaceOnNextSync:*/

- (void)clientAcceptedChangesForRecordWithIdentifier:(NSString *)recordIdentifier formattedRecord:(NSDictionary *)formattedRecord newRecordIdentifier:(NSString *)newRecordIdentifier;

/*clientCommittedAcceptedChanges

Informs the sync engine that all accepted and rejected changes in the current transaction during the pulling state should be committed.

- (void)clientCommittedAcceptedChanges
Discussion

Invoke this method after you save the accepted changes locally or on the device you are syncing.

You accept a change by sending clientAcceptedChangesForRecordWithIdentifier:formattedRecord:newRecordIdentifier: to the sync session, and reject a change by sending clientRefusedChangesForRecordWithIdentifier: to the sync session. 

Invoking this method ends an open pull transaction that began by sending either prepareToPullChangesForEntityNames:beforeDate: or prepareToPullChangesInBackgroundForEntityNames:target:selector: to the receiver. Once a transaction ends the sync engine commits the changes to the truth database, and opens a new pull transaction.

Use this method during the pulling state only, otherwise an exception is raised.
Availability
Available in Mac OS X v10.4 and later.
See Also
cancelSyncing
finishSyncing*/
- (void)clientCommittedAcceptedChanges;

/*finishSyncing

Tells the sync engine that the client is done syncing. Invoking this method closes any open transactions in the pushing or pulling states.

- (void)finishSyncing
Discussion

You must invoke this method to cleanly terminate the session.

Use this method at any time but the receiver should be released soon afterwards since you can not continue using a finished session. 
Availability
Available in Mac OS X v10.4 and later.
See Also
cancelSyncing
isCancelled*/
- (void)finishSyncing;

@end

/*Notifications
ISyncAvailabilityChangedNotification

Posted by the distributed notification center when syncing is enabled or disabled. The notification object is an NSString equal to “YES” if enabled and “NO” if disabled. The receiver should still invoke isEnabled before beginning a sync session. This notification does not contain a userInfo dictionary.
Availability
Available in Mac OS X v10.4 and later.*/
APPKIT_EXPORT NSString *ISyncAvailabilityChangedNotification;

