在 iCloud 中收到有关文件更改的通知
Get notified on file changes in iCloud
我在两台不同的设备上创建了一个名为 File - 1.jpg
的文件,并将其放入 iCloud 容器中。
我不使用 UIDocument
,即使我尝试使用它,也不会产生冲突。相反,我看到的是 iCloud 自动重命名和移动文档。
所以上传一个文件或另一个文件后变成File - 2.jpg
。所有这一切都很好,但现在我没有对文件的引用,所以我不知道哪个是哪个...
有什么方法可以在应用程序端通知 iCloud 中的文件 renamed/moved/deleted?
使用CK订阅:
初始化 CKSubscription 时,您可以指定通知选项:
- CKSubscriptionOptionsFiresOnRecord创建
- CKSubscriptionOptionsFiresOnRecord删除
- CKSubscriptionOptionsFiresOnRecord更新
- CKSubscriptionOptionsFires一次
这些看起来对你也很有用:
http://www.raywenderlich.com/83116/beginning-cloudkit-tutorial
最终,我不得不创建一个实现 NSFilePresenter
的 class 并将其指向 iCloud 容器文件夹。
来自 iCloud 的实时更新可能会很晚并且仅在 iCloud 提取元数据时发生。
此外,我必须将每个创建的文件与每个设备和 iCloud 帐户关联起来,并保存这些数据,在我的例子中是在 CoreData 中。这就是 ubiquityIdentityToken
有用的地方。
iCloud 容器中的所有文件操作当然应该使用 NSFileCoordinator
。
对于 add/remove 事件最好使用 NSMetadataQuery
,NSFileCoordinator
根本不报告这些事件,但对于检测文件何时移动仍然有用,这就是元数据查询报告为更新。
这是一个非常基本的样板文件,可以用作起点:
@interface iCloudFileCoordinator () <NSFilePresenter>
@property (nonatomic) NSString *containerID;
@property (nonatomic) NSURL *containerURL;
@property (nonatomic) NSOperationQueue *operationQueue;
@end
@implementation iCloudFileCoordinator
- (instancetype)initWithContainerID:(NSString *)containerID {
self = [super init];
if(!self) {
return nil;
}
self.containerID = containerID;
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.qualityOfService = NSQualityOfServiceBackground;
[self addFilePresenter];
return self;
}
- (void)dealloc {
[self removeFilePresenter];
}
- (void)addFilePresenter {
[NSFileCoordinator addFilePresenter:self];
}
- (void)removeFilePresenter {
[NSFileCoordinator removeFilePresenter:self];
}
#pragma mark - NSFilePresenter
#pragma mark -
- (NSURL *)presentedItemURL {
NSURL *containerURL = self.containerURL;
if(containerURL) {
return containerURL;
}
NSFileManager *fileManager = [[NSFileManager alloc] init];
containerURL = [fileManager URLForUbiquityContainerIdentifier:self.containerID];
self.containerURL = containerURL;
return containerURL;
}
- (NSOperationQueue *)presentedItemOperationQueue {
return self.operationQueue;
}
- (void)presentedSubitemAtURL:(NSURL *)oldURL didMoveToURL:(NSURL *)newURL {
NSLog(@"Moved file from %@ to %@", oldURL, newURL);
}
/*
... and other bunch of methods that report on sub item changes ...
*/
@end
我在两台不同的设备上创建了一个名为 File - 1.jpg
的文件,并将其放入 iCloud 容器中。
我不使用 UIDocument
,即使我尝试使用它,也不会产生冲突。相反,我看到的是 iCloud 自动重命名和移动文档。
所以上传一个文件或另一个文件后变成File - 2.jpg
。所有这一切都很好,但现在我没有对文件的引用,所以我不知道哪个是哪个...
有什么方法可以在应用程序端通知 iCloud 中的文件 renamed/moved/deleted?
使用CK订阅:
初始化 CKSubscription 时,您可以指定通知选项:
- CKSubscriptionOptionsFiresOnRecord创建
- CKSubscriptionOptionsFiresOnRecord删除
- CKSubscriptionOptionsFiresOnRecord更新
- CKSubscriptionOptionsFires一次
这些看起来对你也很有用:
http://www.raywenderlich.com/83116/beginning-cloudkit-tutorial
最终,我不得不创建一个实现 NSFilePresenter
的 class 并将其指向 iCloud 容器文件夹。
来自 iCloud 的实时更新可能会很晚并且仅在 iCloud 提取元数据时发生。
此外,我必须将每个创建的文件与每个设备和 iCloud 帐户关联起来,并保存这些数据,在我的例子中是在 CoreData 中。这就是 ubiquityIdentityToken
有用的地方。
iCloud 容器中的所有文件操作当然应该使用 NSFileCoordinator
。
对于 add/remove 事件最好使用 NSMetadataQuery
,NSFileCoordinator
根本不报告这些事件,但对于检测文件何时移动仍然有用,这就是元数据查询报告为更新。
这是一个非常基本的样板文件,可以用作起点:
@interface iCloudFileCoordinator () <NSFilePresenter>
@property (nonatomic) NSString *containerID;
@property (nonatomic) NSURL *containerURL;
@property (nonatomic) NSOperationQueue *operationQueue;
@end
@implementation iCloudFileCoordinator
- (instancetype)initWithContainerID:(NSString *)containerID {
self = [super init];
if(!self) {
return nil;
}
self.containerID = containerID;
self.operationQueue = [[NSOperationQueue alloc] init];
self.operationQueue.qualityOfService = NSQualityOfServiceBackground;
[self addFilePresenter];
return self;
}
- (void)dealloc {
[self removeFilePresenter];
}
- (void)addFilePresenter {
[NSFileCoordinator addFilePresenter:self];
}
- (void)removeFilePresenter {
[NSFileCoordinator removeFilePresenter:self];
}
#pragma mark - NSFilePresenter
#pragma mark -
- (NSURL *)presentedItemURL {
NSURL *containerURL = self.containerURL;
if(containerURL) {
return containerURL;
}
NSFileManager *fileManager = [[NSFileManager alloc] init];
containerURL = [fileManager URLForUbiquityContainerIdentifier:self.containerID];
self.containerURL = containerURL;
return containerURL;
}
- (NSOperationQueue *)presentedItemOperationQueue {
return self.operationQueue;
}
- (void)presentedSubitemAtURL:(NSURL *)oldURL didMoveToURL:(NSURL *)newURL {
NSLog(@"Moved file from %@ to %@", oldURL, newURL);
}
/*
... and other bunch of methods that report on sub item changes ...
*/
@end