Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Newer
Older
100644 248 lines (187 sloc) 9.962 kB
094e470 @MugunthKumar First commit
authored
1 //
2 // MKDocumentSync.m
3 // MKDocumentSync
4 //
5 // Created by Mugunth Kumar on 6/2/12.
2aad888 @MugunthKumar Removed documents
authored
6 // Copyright 2012 Steinlogic Consulting and Training Pte Ltd. All rights reserved.
094e470 @MugunthKumar First commit
authored
7 // File created using Singleton XCode Template by Mugunth Kumar (http://blog.mugunthkumar.com)
8 // More information about this template on the post http://mk.sg/89
9 // Permission granted to do anything, commercial/non-commercial with this file apart from removing the line/URL above
2aad888 @MugunthKumar Removed documents
authored
10 //
11 // Permission is hereby granted, free of charge, to any person obtaining a copy
12 // of this software and associated documentation files (the "Software"), to deal
13 // in the Software without restriction, including without limitation the rights
14 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 // copies of the Software, and to permit persons to whom the Software is
16 // furnished to do so, subject to the following conditions:
17 //
18 // The above copyright notice and this permission notice shall be included in
19 // all copies or substantial portions of the Software.
20 //
21 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 // THE SOFTWARE.
28
29 // As a side note, you might also consider
30 // 1) tweeting about this mentioning @mugunthkumar
31 // 2) A paypal donation to mugunth.kumar@gmail.com
094e470 @MugunthKumar First commit
authored
32 #import "MKDocumentSync.h"
33
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
34 @interface MKDocumentSync (/*Private Methods*/)
35 -(void) pullFromiCloud;
36 -(void) pushToiCloud;
b98de8f @MugunthKumar Added log statements
authored
37 -(NSString*) documentsDirectory;
47d4351 @MugunthKumar Syncing directories done
authored
38 @property (strong, nonatomic) NSMetadataQuery *metadataQuery;
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
39 @end
40
094e470 @MugunthKumar First commit
authored
41 @implementation MKDocumentSync
47d4351 @MugunthKumar Syncing directories done
authored
42 @synthesize metadataQuery = metadataQuery;
094e470 @MugunthKumar First commit
authored
43
44 #pragma mark -
45 #pragma mark Singleton Methods
46
47 + (MKDocumentSync*)sharedInstance {
48
49 static MKDocumentSync *_sharedInstance;
50 if(!_sharedInstance) {
51 static dispatch_once_t oncePredicate;
52 dispatch_once(&oncePredicate, ^{
53 _sharedInstance = [[super allocWithZone:nil] init];
54 });
55 }
56
57 return _sharedInstance;
58 }
59
60 + (id)allocWithZone:(NSZone *)zone {
61
62 return [self sharedInstance];
63 }
64
65
66 - (id)copyWithZone:(NSZone *)zone {
67 return self;
68 }
69
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
70 -(void) startSync {
71
72 if(NSClassFromString(@"NSUbiquitousKeyValueStore")) { // is iOS 5?
73
74 NSURL *iCloudFirstContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
75
76 if(iCloudFirstContainer) { // is iCloud enabled
77
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
78 [self pullFromiCloud];
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
79 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
47d4351 @MugunthKumar Syncing directories done
authored
80 [self pushToiCloud];
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
81 });
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
82
83 } else {
84 DLog(@"iCloud Document Sync not enabled");
85 }
86 }
87 else {
88 DLog(@"Not an iOS 5 device");
89 }
90 }
91
094e470 @MugunthKumar First commit
authored
92 #pragma mark -
93 #pragma mark Custom Methods
94
95 // Add your custom methods here
96
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
97 - (void)queryDidFinishGathering:(NSNotification *)notification {
98
f98c7b3 @MugunthKumar Cleanup
authored
99 for(NSMetadataItem *item in self.metadataQuery.results) {
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
100
101 NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
102 NSError *error = nil;
103 DLog(@"Downloading [%@] from iCloud", url);
0aae6c4 @MugunthKumar Downloads only when it's not already present
authored
104
105 NSNumber *isIniCloud = nil;
106 if ([url getResourceValue:&isIniCloud forKey:NSURLIsUbiquitousItemKey error:nil]) {
107
108 // If the item is in iCloud, see if it is downloaded.
109 if ([isIniCloud boolValue]) {
110 NSNumber* isDownloaded = nil;
111 error = nil;
112 // If the item is in iCloud, see if it is downloaded.
113 if ([url getResourceValue:&isDownloaded forKey:NSURLUbiquitousItemIsDownloadedKey error:&error]) {
114
b98de8f @MugunthKumar Added log statements
authored
115 if(error) DLog(@"Cannot check iCloud sync status of file [%@]", error);
0aae6c4 @MugunthKumar Downloads only when it's not already present
authored
116 if (![isDownloaded boolValue]) {
117
118 error = nil;
119 [[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error];
b98de8f @MugunthKumar Added log statements
authored
120 if(error) DLog(@"Cannot start downloading from iCloud [%@]", error);
0aae6c4 @MugunthKumar Downloads only when it's not already present
authored
121 }
122 }
123
124 error = nil;
125 NSNumber* isConflicted = nil;
126 if ([url getResourceValue:&isConflicted forKey:NSURLUbiquitousItemHasUnresolvedConflictsKey error:&error]) {
127
128 if ([isConflicted boolValue]) {
b98de8f @MugunthKumar Added log statements
authored
129
130 DLog(@"%@ is in conflict. Removing from iCloud", url);
131 NSString *fileName = [url lastPathComponent];
132 NSString *documentsDirectoryPath = [[self documentsDirectory] stringByAppendingPathComponent:fileName];
133 [[NSFileManager defaultManager] moveItemAtURL:url toURL:[NSURL fileURLWithPath:documentsDirectoryPath]
134 error:&error];
135 if(error) DLog(@"Moving conflicted file failed: [%@]", error);
136
137 error = nil;
138 [[NSFileManager defaultManager] evictUbiquitousItemAtURL:url error:&error];
139 if(error) DLog(@"Evicting conflicted file failed: [%@]", error);
0aae6c4 @MugunthKumar Downloads only when it's not already present
authored
140 }
141 }
142 }
143 }
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
144 }
145
f98c7b3 @MugunthKumar Cleanup
authored
146 [self.metadataQuery disableUpdates];
147 [self.metadataQuery stopQuery];
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
148 [[NSNotificationCenter defaultCenter] removeObserver:self
149 name:NSMetadataQueryDidFinishGatheringNotification
47d4351 @MugunthKumar Syncing directories done
authored
150 object:self.metadataQuery];
151 self.metadataQuery = nil; // we're done with it
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
152 }
153
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
154 -(void) pullFromiCloud {
155
47d4351 @MugunthKumar Syncing directories done
authored
156 self.metadataQuery = [[NSMetadataQuery alloc] init];
157 self.metadataQuery.searchScopes = [NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope];
158 self.metadataQuery.predicate = [NSPredicate predicateWithFormat:@"%K LIKE '*'", NSMetadataItemFSNameKey];
159
160 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:)
161 name:NSMetadataQueryDidFinishGatheringNotification
162 object:self.metadataQuery];
163 [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:)
164 name:NSMetadataQueryDidUpdateNotification
165 object:self.metadataQuery];
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
166
47d4351 @MugunthKumar Syncing directories done
authored
167 [self.metadataQuery startQuery];
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
168 }
169
170 -(void) pushToiCloud {
171
b98de8f @MugunthKumar Added log statements
authored
172 NSString *docsDirectory = [self documentsDirectory];
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
173 NSArray *listOfFiles = [self filesInDirectory:docsDirectory];
174 for(NSString *filePath in listOfFiles) {
175
f98c7b3 @MugunthKumar Cleanup
authored
176 NSURL *fileURL = [NSURL fileURLWithPath:filePath];
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
177 NSString *relativePath = [filePath stringByReplacingOccurrencesOfString:docsDirectory withString:@""];
47d4351 @MugunthKumar Syncing directories done
authored
178 relativePath = [relativePath substringFromIndex:1];
179
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
180 NSURL *iCloudFirstContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
7ac337f @MugunthKumar Added boiler plate code for pulling files
authored
181 NSURL *iCloudDestinationURL = [[iCloudFirstContainer URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:relativePath];
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
182
47d4351 @MugunthKumar Syncing directories done
authored
183 NSURL *directoryURL = [iCloudDestinationURL URLByDeletingLastPathComponent];
184
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
185 NSError *error = nil;
47d4351 @MugunthKumar Syncing directories done
authored
186 [[NSFileManager defaultManager] createDirectoryAtURL:directoryURL withIntermediateDirectories:YES attributes:nil error:&error];
b98de8f @MugunthKumar Added log statements
authored
187 if(error) DLog(@"Unable to create iCloud local directory [%@]", error);
47d4351 @MugunthKumar Syncing directories done
authored
188
189 error = nil;
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
190 [[NSFileManager defaultManager] setUbiquitous:YES
f98c7b3 @MugunthKumar Cleanup
authored
191 itemAtURL:fileURL
202646a @MugunthKumar Pushing to iCloud done
authored
192 destinationURL:iCloudDestinationURL
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
193 error:&error];
194
195 if(error) DLog(@"%@", error);
196
f98c7b3 @MugunthKumar Cleanup
authored
197 DLog(@"Moving [%@] to iCloud location at [%@]", fileURL, iCloudDestinationURL);
548c66c @MugunthKumar Copy to documents directory completed, sync started
authored
198 }
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
199 }
200
b98de8f @MugunthKumar Added log statements
authored
201 -(NSString*) documentsDirectory {
202
203 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
204 NSString *docsDirectory = [paths objectAtIndex:0];
205
206 return docsDirectory;
207 }
208
0aae6c4 @MugunthKumar Downloads only when it's not already present
authored
209 -(NSString*) iCloudLocalDocumentDirectory {
210
211 NSURL *iCloudFirstContainer = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
212 NSURL *iCloudDocsURL = [iCloudFirstContainer URLByAppendingPathComponent:@"Documents"];
213 return [iCloudDocsURL path];
214 }
215
216 -(NSMutableArray*) filesIniCloudDirectory {
217
218 return [self filesInDirectory:[self iCloudLocalDocumentDirectory]];
219 }
220
5a0efd5 @MugunthKumar Added documents from Van, implemented iCloud checking and enumerating…
authored
221 -(NSMutableArray*) filesInDirectory: (NSString*) directoryName
222 {
223 NSMutableArray *listOfFiles = [NSMutableArray array];
224
225 NSDirectoryEnumerator *sourceDirectoryFilePathEnumerator = [[NSFileManager defaultManager] enumeratorAtPath: directoryName];
226
227 NSString *fileName;
228 while ((fileName = [sourceDirectoryFilePathEnumerator nextObject])) {
229
230 NSDictionary* sourceDirectoryFileAttributes = [sourceDirectoryFilePathEnumerator fileAttributes];
231 NSString* sourceDirectoryFileType = [sourceDirectoryFileAttributes objectForKey:NSFileType];
232
233 if ([sourceDirectoryFileType isEqualToString:NSFileTypeRegular] == YES) {
234
235 NSString *absPath = [directoryName stringByAppendingPathComponent:fileName];
236 [listOfFiles addObject:absPath];
237 }
238
239 else if([sourceDirectoryFileType isEqualToString:NSFileTypeDirectory] == YES) {
240
241 [listOfFiles addObjectsFromArray:[self filesInDirectory:fileName]];
242 }
243 }
244
245 return listOfFiles;
246 }
094e470 @MugunthKumar First commit
authored
247 @end
Something went wrong with that request. Please try again.