Permalink
Browse files

Refactored the ubiquity transfer code, moving it to a new class calle…

…d TIUbiquityMonitor.

It was previously packed into the file manager app sync manager.
  • Loading branch information...
1 parent db0bc27 commit 10c0e714737a0505b21b8e7917cec106c8371269 @drewmccormack committed Feb 14, 2013
View
8 Examples/NotebookiCloud/Notebook.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 07DD945716CCED0D0047B456 /* TIUbiquityMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 07DD945616CCED0D0047B456 /* TIUbiquityMonitor.m */; };
1382B2701448B93200950A6F /* TICDSSynchronizationOperationManagedObjectContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 1382B26F1448B93200950A6F /* TICDSSynchronizationOperationManagedObjectContext.m */; };
1382B2741448B94000950A6F /* TICDSChangeIntegrityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1382B2731448B94000950A6F /* TICDSChangeIntegrityStoreManager.m */; };
383EB805138ACACF00FB580A /* TICDSListOfApplicationRegisteredClientsOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = 38A280C0138AA57000C81675 /* TICDSListOfApplicationRegisteredClientsOperation.m */; };
@@ -88,7 +89,9 @@
/* Begin PBXFileReference section */
07003D1415AECF2D004EF645 /* Notebook.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = Notebook.entitlements; sourceTree = "<group>"; };
- 07003EA915B00067004EF645 /* Notebook 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = file; path = "Notebook 2.xcdatamodel"; sourceTree = "<group>"; };
+ 07003EA915B00067004EF645 /* Notebook 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "Notebook 2.xcdatamodel"; sourceTree = "<group>"; };
+ 07DD945516CCED0D0047B456 /* TIUbiquityMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TIUbiquityMonitor.h; sourceTree = "<group>"; };
+ 07DD945616CCED0D0047B456 /* TIUbiquityMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TIUbiquityMonitor.m; sourceTree = "<group>"; };
1382B26E1448B93200950A6F /* TICDSSynchronizationOperationManagedObjectContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TICDSSynchronizationOperationManagedObjectContext.h; sourceTree = "<group>"; };
1382B26F1448B93200950A6F /* TICDSSynchronizationOperationManagedObjectContext.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TICDSSynchronizationOperationManagedObjectContext.m; sourceTree = "<group>"; };
1382B2721448B94000950A6F /* TICDSChangeIntegrityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TICDSChangeIntegrityStoreManager.h; sourceTree = "<group>"; };
@@ -547,6 +550,8 @@
389E1C3413856B7D00E9E7C1 /* 06 External Sources */ = {
isa = PBXGroup;
children = (
+ 07DD945516CCED0D0047B456 /* TIUbiquityMonitor.h */,
+ 07DD945616CCED0D0047B456 /* TIUbiquityMonitor.m */,
389E1C3513856B7D00E9E7C1 /* NSObject+TIDelegateCommunications.h */,
389E1C3613856B7D00E9E7C1 /* NSObject+TIDelegateCommunications.m */,
389E1C3713856B7D00E9E7C1 /* TICoreDataFactory.h */,
@@ -694,6 +699,7 @@
38AE077F13EC5E8C002F90A6 /* TICDSFileManagerBasedRemoveAllRemoteSyncDataOperation.m in Sources */,
1382B2701448B93200950A6F /* TICDSSynchronizationOperationManagedObjectContext.m in Sources */,
1382B2741448B94000950A6F /* TICDSChangeIntegrityStoreManager.m in Sources */,
+ 07DD945716CCED0D0047B456 /* TIUbiquityMonitor.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
10 Examples/iOSNotebook/iOSNotebook.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 07DD945A16CCED3B0047B456 /* TIUbiquityMonitor.m in Sources */ = {isa = PBXBuildFile; fileRef = 07DD945916CCED3B0047B456 /* TIUbiquityMonitor.m */; };
1382B2691448B8F800950A6F /* TICDSChangeIntegrityStoreManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1382B2681448B8F800950A6F /* TICDSChangeIntegrityStoreManager.m */; };
1382B26D1448B90800950A6F /* TICDSSynchronizationOperationManagedObjectContext.m in Sources */ = {isa = PBXBuildFile; fileRef = 1382B26C1448B90800950A6F /* TICDSSynchronizationOperationManagedObjectContext.m */; };
138EDADE1549C99000FA4432 /* DropboxSDK.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 138EDADD1549C99000FA4432 /* DropboxSDK.framework */; };
@@ -97,6 +98,8 @@
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
+ 07DD945816CCED3B0047B456 /* TIUbiquityMonitor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TIUbiquityMonitor.h; sourceTree = "<group>"; };
+ 07DD945916CCED3B0047B456 /* TIUbiquityMonitor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TIUbiquityMonitor.m; sourceTree = "<group>"; };
1382B2671448B8F800950A6F /* TICDSChangeIntegrityStoreManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TICDSChangeIntegrityStoreManager.h; sourceTree = "<group>"; };
1382B2681448B8F800950A6F /* TICDSChangeIntegrityStoreManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TICDSChangeIntegrityStoreManager.m; sourceTree = "<group>"; };
1382B26B1448B90800950A6F /* TICDSSynchronizationOperationManagedObjectContext.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TICDSSynchronizationOperationManagedObjectContext.h; sourceTree = "<group>"; };
@@ -581,6 +584,8 @@
3890AAAC1397ABBB00CC64B5 /* 06 External Sources */ = {
isa = PBXGroup;
children = (
+ 07DD945816CCED3B0047B456 /* TIUbiquityMonitor.h */,
+ 07DD945916CCED3B0047B456 /* TIUbiquityMonitor.m */,
3890AAAD1397ABBB00CC64B5 /* NSObject+TIDelegateCommunications.h */,
3890AAAE1397ABBB00CC64B5 /* NSObject+TIDelegateCommunications.m */,
3890AAAF1397ABBB00CC64B5 /* TICoreDataFactory.h */,
@@ -735,6 +740,7 @@
38AE078B13EC606B002F90A6 /* TICDSDropboxSDKBasedRemoveAllRemoteSyncDataOperation.m in Sources */,
1382B2691448B8F800950A6F /* TICDSChangeIntegrityStoreManager.m in Sources */,
1382B26D1448B90800950A6F /* TICDSSynchronizationOperationManagedObjectContext.m in Sources */,
+ 07DD945A16CCED3B0047B456 /* TIUbiquityMonitor.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -815,7 +821,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "iOSNotebook/iOSNotebook-Prefix.pch";
INFOPLIST_FILE = "iOSNotebook/iOSNotebook-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
@@ -833,7 +839,7 @@
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "iOSNotebook/iOSNotebook-Prefix.pch";
INFOPLIST_FILE = "iOSNotebook/iOSNotebook-Info.plist";
- IPHONEOS_DEPLOYMENT_TARGET = 3.1.3;
+ IPHONEOS_DEPLOYMENT_TARGET = 6.0;
PRODUCT_NAME = "$(TARGET_NAME)";
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = app;
View
3 TICoreDataSync/01 Headers and Constants/TICDSAllClassHeaders.h
@@ -90,4 +90,5 @@
#import "NSObject+TIDelegateCommunications.h"
#import "TICoreDataFactory.h"
#import "TIManagedObjectExtensions.h"
-#import "TIKQDirectoryWatcher.h"
+#import "TIKQDirectoryWatcher.h"
+#import "TIUbiquityMonitor.h"
View
14 .../02 Primary Classes/File Manager-Based Sync/TICDSFileManagerBasedApplicationSyncManager.h
@@ -23,27 +23,13 @@ extern NSString * const TICDSApplicationSyncManagerDidRefreshCloudTransferProgre
@private
NSURL *_applicationContainingDirectoryLocation;
NSMetadataQuery *_cloudMetadataQuery;
- NSMetadataQuery *_transferProgressMetadataQuery;
- NSMetadataQuery *_downloadMetadataQuery;
- NSMutableDictionary *_downloadingBytesRemainingByURL;
- void (^_downloadProgressBlock)(BOOL complete, long long remainingBytes, BOOL *stop);
}
-@property (readonly) long long cloudBytesToUpload, cloudBytesToDownload;
-
#pragma mark iCloud-Related Methods
/** Start a new metadata query to asynchronously download cloud files not yet local. */
- (void)refreshCloudMetadataQuery;
-/** Use a metadata query to download all data from the cloud. */
-- (void)downloadAllCloudData:(void(^)(BOOL complete, long long remainingBytes, BOOL *stop))block;
-
-/** Start a metadata query to scan iCloud files, and determine how much data still needs to be uploaded and downloaded.
- Access the results using the provided properties. Use the notification to determine when the asynchronous
- calculation is finished. */
-- (void)refreshCloudTransferProgress;
-
#pragma mark Dropbox-Related Methods
/** @name Dropbox-Related Methods */
View
140 .../02 Primary Classes/File Manager-Based Sync/TICDSFileManagerBasedApplicationSyncManager.m
@@ -13,7 +13,6 @@
@interface TICDSFileManagerBasedApplicationSyncManager ()
@property (nonatomic, retain) NSMetadataQuery *cloudMetadataQuery;
-@property (readwrite) long long cloudBytesToUpload, cloudBytesToDownload;
@end
@@ -176,79 +175,6 @@ - (void)initiateDownloadsForURLs:(NSArray *)urls
[fm release];
}
-#pragma mark Downloading All Cloud Data
-
-- (void)downloadAllCloudData:(void(^)(BOOL complete, long long remainingBytes, BOOL *stop))block
-{
- if ( _downloadMetadataQuery ) return;
- _downloadProgressBlock = [block copy];
- _cloudBytesToDownload = -1;
- _downloadingBytesRemainingByURL = [[NSMutableDictionary alloc] initWithCapacity:200];
- [self beginDownloadAllCloudDataQuery];
-}
-
-- (void)beginDownloadAllCloudDataQuery {
- _downloadMetadataQuery = [[NSMetadataQuery alloc] init];
- _downloadMetadataQuery.notificationBatchingInterval = 1.0;
- _downloadMetadataQuery.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDataScope];
- _downloadMetadataQuery.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemFSNameKey];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gatheredCloudDownloadURLs:) name:NSMetadataQueryDidFinishGatheringNotification object:_downloadMetadataQuery];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(gatheredCloudDownloadURLs:) name:NSMetadataQueryDidUpdateNotification object:_downloadMetadataQuery];
- [_downloadMetadataQuery startQuery];
-}
-
-- (void)gatheredCloudDownloadURLs:(NSNotification *)notif
-{
- [_downloadMetadataQuery disableUpdates];
-
- NSUInteger count = [_downloadMetadataQuery resultCount];
- NSMutableArray *newURLs = [[NSMutableArray alloc] initWithCapacity:count];
- for ( NSUInteger i = 0; i < count; i++ ) {
- NSURL *url = [_downloadMetadataQuery valueOfAttribute:NSMetadataItemURLKey forResultAtIndex:i];
- [newURLs addObject:url];
- }
-
- if ( _cloudBytesToDownload < 0 ) _cloudBytesToDownload = 0;
- for ( NSURL *url in newURLs ) {
- long long existingURLBytes = [_downloadingBytesRemainingByURL[url] longLongValue];
- _cloudBytesToDownload -= existingURLBytes;
-
- [_downloadingBytesRemainingByURL removeObjectForKey:url];
-
- NSNumber *fileSizeNumber = nil;
- NSNumber *percentDownloaded = nil;
- NSNumber *downloaded = nil;
-
- [url getResourceValue:&fileSizeNumber forKey:NSURLFileSizeKey error:NULL];
- [url getResourceValue:&percentDownloaded forKey:NSURLUbiquitousItemPercentDownloadedKey error:NULL];
- [url getResourceValue:&downloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:NULL];
-
- unsigned long long fileSize = fileSizeNumber.unsignedLongLongValue;
- if ( downloaded && !downloaded.boolValue ) {
- double percentage = percentDownloaded ? percentDownloaded.doubleValue : 100.0;
- long long fileDownloadSize = percentage / 100.0 * fileSize;
- _cloudBytesToDownload += fileDownloadSize;
- _downloadingBytesRemainingByURL[url] = @(fileDownloadSize);
- }
- }
- [newURLs release];
-
- BOOL cancelled = NO;
- if ( _downloadProgressBlock ) _downloadProgressBlock(_cloudBytesToDownload == 0, _cloudBytesToDownload, &cancelled);
-
- if ( _cloudBytesToDownload == 0 || cancelled ) {
- [_downloadingBytesRemainingByURL release], _downloadingBytesRemainingByURL = nil;
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:_downloadMetadataQuery];
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:_downloadMetadataQuery];
- [_downloadMetadataQuery stopQuery];
- [_downloadMetadataQuery release], _downloadMetadataQuery = nil;
- [_downloadProgressBlock release]; _downloadProgressBlock = nil;
- }
- else {
- [_downloadMetadataQuery enableUpdates];
- }
-}
-
- (void)checkUninitiatedUploadsForURLs:(NSArray *)urls
{
NSFileManager *fm = [[[NSFileManager alloc] init] autorelease];
@@ -333,63 +259,6 @@ - (void)cloudFilesDidChange:(NSNotification *)notif
});
}
-- (void)refreshCloudTransferProgress
-{
- if ( _transferProgressMetadataQuery ) return;
- _transferProgressMetadataQuery = [[NSMetadataQuery alloc] init];
- _transferProgressMetadataQuery.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDataScope];
- _transferProgressMetadataQuery.predicate = [NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemFSNameKey];
- [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(finishedGatheringCloudTransferProgress:) name:NSMetadataQueryDidFinishGatheringNotification object:_transferProgressMetadataQuery];
- [_transferProgressMetadataQuery startQuery];
-}
-
-- (void)finishedGatheringCloudTransferProgress:(NSNotification *)notif
-{
- [_transferProgressMetadataQuery disableUpdates];
-
- NSUInteger count = [_transferProgressMetadataQuery resultCount];
- NSMutableArray *urls = [NSMutableArray arrayWithCapacity:count];
- for ( NSUInteger i = 0; i < count; i++ ) {
- NSURL *url = [_transferProgressMetadataQuery valueOfAttribute:NSMetadataItemURLKey forResultAtIndex:i];
- [urls addObject:url];
- }
-
- dispatch_queue_t queue = dispatch_queue_create("sumtransfer", DISPATCH_QUEUE_SERIAL);
- dispatch_async(queue, ^{
- unsigned long long toDownload = 0, toUpload = 0;
- for ( NSURL *url in urls ) {
- NSNumber *fileSizeNumber = nil;
- NSNumber *percentDownloaded = nil, *percentUploaded = nil;
- NSNumber *uploaded = nil, *downloaded = nil;
-
- [url getResourceValue:&fileSizeNumber forKey:NSURLFileSizeKey error:NULL];
- [url getResourceValue:&percentDownloaded forKey:NSURLUbiquitousItemPercentDownloadedKey error:NULL];
- [url getResourceValue:&percentUploaded forKey:NSURLUbiquitousItemPercentUploadedKey error:NULL];
- [url getResourceValue:&uploaded forKey:NSURLUbiquitousItemIsUploadedKey error:NULL];
- [url getResourceValue:&downloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:NULL];
-
- unsigned long long fileSize = fileSizeNumber.unsignedLongLongValue;
- if ( uploaded && !uploaded.boolValue ) {
- double percentage = percentUploaded ? percentUploaded.doubleValue : 100.0;
- toUpload += percentage / 100.0 * fileSize;;
- }
- else if ( downloaded && !downloaded.boolValue ) {
- double percentage = percentDownloaded ? percentDownloaded.doubleValue : 100.0;
- toDownload += percentage / 100.0 * fileSize;
- }
- }
- dispatch_async(dispatch_get_main_queue(), ^{
- self.cloudBytesToDownload = toDownload;
- self.cloudBytesToUpload = toUpload;
- [[NSNotificationCenter defaultCenter] postNotificationName:TICDSApplicationSyncManagerDidRefreshCloudTransferProgressNotification object:self];
- });
- dispatch_release(queue);
- });
-
- [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:_transferProgressMetadataQuery];
- [_transferProgressMetadataQuery stopQuery];
- [_transferProgressMetadataQuery release], _transferProgressMetadataQuery = nil;
-}
#pragma mark -
#pragma mark Overridden Methods
@@ -508,14 +377,7 @@ - (void)dealloc
[_cloudMetadataQuery disableUpdates];
[_cloudMetadataQuery stopQuery];
[_cloudMetadataQuery release], _cloudMetadataQuery = nil;
- [_downloadMetadataQuery stopQuery];
- [_downloadMetadataQuery release], _downloadMetadataQuery = nil;
- [_downloadProgressBlock release]; _downloadProgressBlock = nil;
- [_transferProgressMetadataQuery stopQuery];
- [_transferProgressMetadataQuery release], _transferProgressMetadataQuery = nil;
-
- [_downloadingBytesRemainingByURL release], _downloadingBytesRemainingByURL = nil;
-
+
[super dealloc];
}
View
33 TICoreDataSync/06 External Sources/TIUbiquityMonitor.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2013 Drew McCormack
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import <Foundation/Foundation.h>
+
+@interface TIUbiquityMonitor : NSObject
+
+@property (readonly) long long ubiquitousBytesToUpload, ubiquitousBytesToDownload;
+@property (readonly) NSPredicate *predicate;
+
+- (id)initWithPredicate:(NSPredicate *)predicate;
+
+- (void)startMonitoringWithProgressBlock:(void(^)(long long bytesToDownload, long long bytesToUpload))progressBlock;
+- (void)stopMonitoring;
+
+@end
View
147 TICoreDataSync/06 External Sources/TIUbiquityMonitor.m
@@ -0,0 +1,147 @@
+// Copyright (c) 2013 Drew McCormack
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+#import "TIUbiquityMonitor.h"
+
+@implementation TIUbiquityMonitor {
+ NSMetadataQuery *metadataQuery;
+ NSMutableDictionary *downloadingBytesByURL, *uploadingBytesByURL;
+ void (^progressCallbackBlock)(long long toDownload, long long toUpload);
+ BOOL isMonitoring;
+}
+
+@synthesize ubiquitousBytesToDownload = ubiquitousBytesToDownload;
+@synthesize ubiquitousBytesToUpload = ubiquitousBytesToUpload;
+@synthesize predicate = predictate;
+
+#pragma mark Initialization and Deallocation
+
+- (id)initWithPredicate:(NSPredicate *)newPredicate
+{
+ self = [super init];
+ if ( self ) {
+ predictate = [newPredicate retain];
+ progressCallbackBlock = NULL;
+ isMonitoring = NO;
+ metadataQuery = nil;
+ downloadingBytesByURL = uploadingBytesByURL = nil;
+ ubiquitousBytesToUpload = ubiquitousBytesToDownload = 0;
+ }
+ return self;
+}
+
+- (id)init
+{
+ NSPredicate *newPredicate = [NSPredicate predicateWithFormat:@"%K like '*'", NSMetadataItemFSNameKey];
+ return [self initWithPredicate:newPredicate];
+}
+
+- (void)dealloc
+{
+ [self stopMonitoring];
+ [predictate release], predictate = nil;
+ [super dealloc];
+}
+
+#pragma mark Controlling Monitoring
+
+- (void)startMonitoringWithProgressBlock:(void(^)(long long toDownload, long long toUpload))block
+{
+ if ( isMonitoring ) @throw [NSException exceptionWithName:@"TIException" reason:@"Attempt to start monitoring in a TIUbiquityMonitor that is already monitoring" userInfo:nil];
+
+ isMonitoring = YES;
+
+ progressCallbackBlock = [block copy];
+ downloadingBytesByURL = [[NSMutableDictionary alloc] initWithCapacity:200];
+ uploadingBytesByURL = [[NSMutableDictionary alloc] initWithCapacity:200];
+
+ metadataQuery = [[NSMetadataQuery alloc] init];
+ metadataQuery.notificationBatchingInterval = 1.0;
+ metadataQuery.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDataScope];
+ metadataQuery.predicate = predictate;
+
+ NSNotificationCenter *notifationCenter = [NSNotificationCenter defaultCenter];
+ [notifationCenter addObserver:self selector:@selector(update:) name:NSMetadataQueryDidFinishGatheringNotification object:metadataQuery];
+ [notifationCenter addObserver:self selector:@selector(update:) name:NSMetadataQueryDidUpdateNotification object:metadataQuery];
+
+ [metadataQuery startQuery];
+}
+
+- (void)stopMonitoring
+{
+ [metadataQuery disableUpdates];
+
+ isMonitoring = NO;
+ [downloadingBytesByURL release], downloadingBytesByURL = nil;
+ [uploadingBytesByURL release], uploadingBytesByURL = nil;
+
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidFinishGatheringNotification object:metadataQuery];
+ [[NSNotificationCenter defaultCenter] removeObserver:self name:NSMetadataQueryDidUpdateNotification object:metadataQuery];
+
+ [metadataQuery stopQuery];
+ [metadataQuery release], metadataQuery = nil;
+
+ // Release callback last, because it could be retaining objects
+ [progressCallbackBlock autorelease], progressCallbackBlock = nil;
+}
+
+- (void)update:(NSNotification *)notif
+{
+ [metadataQuery disableUpdates];
+
+ NSUInteger count = [metadataQuery resultCount];
+ for ( NSUInteger i = 0; i < count; i++ ) {
+ NSURL *url = [metadataQuery valueOfAttribute:NSMetadataItemURLKey forResultAtIndex:i];
+
+ // Remove any existing contribution to the bytes counts from a previous update
+ ubiquitousBytesToDownload -= [downloadingBytesByURL[url] longLongValue];
+ ubiquitousBytesToUpload -= [uploadingBytesByURL[url] longLongValue];
+
+ [downloadingBytesByURL removeObjectForKey:url];
+ [uploadingBytesByURL removeObjectForKey:url];
+
+ NSNumber *percentDownloaded = [metadataQuery valueOfAttribute:NSMetadataUbiquitousItemPercentDownloadedKey forResultAtIndex:i];
+ NSNumber *percentUploaded = [metadataQuery valueOfAttribute:NSMetadataUbiquitousItemPercentUploadedKey forResultAtIndex:i];;
+ NSNumber *downloaded = [metadataQuery valueOfAttribute:NSMetadataUbiquitousItemIsDownloadedKey forResultAtIndex:i];
+ NSNumber *uploaded = [metadataQuery valueOfAttribute:NSMetadataUbiquitousItemIsUploadedKey forResultAtIndex:i];
+ NSNumber *fileSizeNumber = [metadataQuery valueOfAttribute:NSMetadataItemFSSizeKey forResultAtIndex:i];
+
+ unsigned long long fileSize = fileSizeNumber.unsignedLongLongValue;
+ if ( downloaded && !downloaded.boolValue ) {
+ double percentage = percentDownloaded ? percentDownloaded.doubleValue : 100.0;
+ long long fileDownloadSize = percentage / 100.0 * fileSize;
+ ubiquitousBytesToDownload += fileDownloadSize;
+ downloadingBytesByURL[url] = @(fileDownloadSize);
+ }
+ else if ( uploaded && !uploaded.boolValue ) {
+ double percentage = percentUploaded ? percentUploaded.doubleValue : 100.0;
+ long long fileDownloadSize = percentage / 100.0 * fileSize;
+ ubiquitousBytesToUpload += fileDownloadSize;
+ uploadingBytesByURL[url] = @(fileDownloadSize);
+ }
+ }
+
+ if ( progressCallbackBlock ) progressCallbackBlock(ubiquitousBytesToDownload, ubiquitousBytesToUpload);
+
+ [metadataQuery enableUpdates];
+}
+
+@end
+

0 comments on commit 10c0e71

Please sign in to comment.