我正在为我的文档管理应用程序开发开放模式的应用扩展程序。我已经实现了正常工作的导入模式。但在开放模式下,当第三方应用程序尝试从我的存储提供程序打开任何文档时,文件提供程序的以下方法正在执行多次,这是一种无限执行,从而导致内存警告异常。
- (instancetype)init
- (void)startProvidingItemAtURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler
同样供您参考完整的代码文件提供程序如下
- (NSFileCoordinator *)fileCoordinator {
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
[fileCoordinator setPurposeIdentifier:[self providerIdentifier]];
return fileCoordinator;
}
- (instancetype)init {
self = [super init];
if (self) {
[self.fileCoordinator coordinateWritingItemAtURL:[self documentStorageURL] options:0 error:nil byAccessor:^(NSURL *newURL) {
// ensure the documentStorageURL actually exists
NSError *error = nil;
[[NSFileManager defaultManager] createDirectoryAtURL:newURL withIntermediateDirectories:YES attributes:nil error:&error];
}];
}
return self;
}
- (void)providePlaceholderAtURL:(NSURL *)url completionHandler:(void (^)(NSError *error))completionHandler {
// Should call + writePlaceholderAtURL:withMetadata:error: with the placeholder URL, then call the completion handler with the error if applicable.
NSString* fileName = [url lastPathComponent];
NSURL *placeholderURL = [NSFileProviderExtension placeholderURLForURL:[self.documentStorageURL URLByAppendingPathComponent:fileName]];
NSUInteger fileSize = 0;
// TODO: get file size for file at <url> from model
[self.fileCoordinator coordinateWritingItemAtURL:placeholderURL options:0 error:NULL byAccessor:^(NSURL *newURL) {
NSDictionary* metadata = @{ NSURLFileSizeKey : @(fileSize)};
[NSFileProviderExtension writePlaceholderAtURL:placeholderURL withMetadata:metadata error:NULL];
}];
if (completionHandler) {
completionHandler(nil);
}
}
- (void)startProvidingItemAtURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler {
// Should ensure that the actual file is in the position returned by URLForItemWithIdentifier:, then call the completion handler
NSError* error = nil;
__block NSError* fileError = nil;
//getting the actual fiile from the shared container
NSURL *storeURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@"group.company.test.NBox"];
storeURL = [storeURL URLByAppendingPathComponent:[url.path lastPathComponent]];
NSData* fileData = [NSData dataWithContentsOfFile:[storeURL path]];
// TODO: get the contents of file at <url> from model
//Writing the file data to the documentStorage location
//[self.fileCoordinator coordinateWritingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
[fileData writeToURL:url options:0 error:&fileError];
//}];
if (error!=nil) {
completionHandler(error);
} else {
completionHandler(fileError);
}
}
- (void)itemChangedAtURL:(NSURL *)url {
// Called at some point after the file has changed; the provider may then trigger an upload
// TODO: mark file at <url> as needing an update in the model; kick off update process
NSLog(@"Item changed at URL %@", url);
}
- (void)stopProvidingItemAtURL:(NSURL *)url {
// Called after the last claim to the file has been released. At this point, it is safe for the file provider to remove the content file.
// Care should be taken that the corresponding placeholder file stays behind after the content file has been deleted.
[self.fileCoordinator coordinateWritingItemAtURL:url options:NSFileCoordinatorWritingForDeleting error:NULL byAccessor:^(NSURL *newURL) {
[[NSFileManager defaultManager] removeItemAtURL:newURL error:NULL];
}];
[self providePlaceholderAtURL:url completionHandler:NULL];
}
谢谢, VSH
答案 0 :(得分:1)
我也在尝试为开放模式开发应用扩展程序。我还没有成功,但我没有得到无限的执行。查看代码,storeURL
中的startProvidingItemAtURL:
可能指向容器内的某些内容。如果是这样,那么对fileData
的赋值将触发无限递归。
作为测试,请尝试使用以下测试消息设置fileData
:
NSString *message = [NSString stringWithFormat:@"This is a test."];
NSData *fileData = [NSKeyedArchiver archivedDataWithRootObject:message];
如果可以,那么storeURL
会出现问题,您必须找出一些不同的位置来获取数据。
(顺便提一下,我注意到你在startProvidingItemAtURL:
注释掉了文件协调员。我最后还是这样做是为了防止死锁,因为文档中有一条说明“不要使用文件协调”在这个方法中。“但它很混乱,因为文件提供者的模板代码将文件协调器放在该方法中!”