更新:Xcode 9.3修复了它.
在中创建UIDocument文件时 UIDocumentBrowserViewController
[默认] [错误]无法解析书签.错误:错误域= NSFileProviderInternalErrorDomain代码= 1"不允许读者访问该URL." UserInfo = {NSLocalizedDescription =不允许读者访问该URL.}
[DocumentManager]无法从bookmarkableString创建URL(错误域= NSFileProviderInternalErrorDomain Code = 1"不允许读者访问URL."UserInfo = {NSLocalizedDescription =不允许读者访问URL.})
代码在Xcode 9.1中运行良好,但在Xcode 9.2中失败.与wwdc 2017几乎相同的代码.
func documentBrowser(_ controller: UIDocumentBrowserViewController, didRequestDocumentCreationWithHandler importHandler: @escaping (URL?, UIDocumentBrowserViewController.ImportMode) -> Void) {
let newDocumentURL: URL? = R.file.templateDocument()
// Set the URL for the new document here. Optionally, you can present a template chooser before calling the importHandler.
// Make sure the importHandler is always called, even if the user cancels the creation request.
if newDocumentURL …Run Code Online (Sandbox Code Playgroud) 我有一个UIDocument基于应用程序,使用NSFileWrappers来存储数据.'master'文件包装器包含许多其他目录文件包装器,每个包装器代表文档的不同页面.
保存仅修改了一页的一小部分的大型文档UIDocument时,在后台花费很长时间写入更改(in writeContents:andAttributes:safelyToURL:forSaveOperation:error:).当然它应该只写出这个文件包装器的一个小改动......什么花了这么长时间?
我的contentsForType:error:覆盖返回一个新的目录文件包装器,其中包含主文件包装器的内容(例如,WWDC 2012会话218 - 使用带有UIDocument的iCloud):
- (id)contentsForType:(NSString *)typeName error:(NSError *__autoreleasing *)outError
{
if (!_fileWrapper) {
[self setupEmptyDocument];
}
return [[NSFileWrapper alloc] initDirectoryWithFileWrappers:[_fileWrapper fileWrappers]];
}
Run Code Online (Sandbox Code Playgroud)
这里是Time Profiler的堆栈跟踪的可爱图片:

顺便提一下,它表示要保存的工作线程约为1.6s - 在实际运行时间内,这相当于大约8秒.
编辑:
有什么方法可以检查文件包装器是否需要写入磁盘?正因为如此,我可以确认我做某些奇怪的事情,比如当我做一个小改动时更新每个子文件包装器(尽管我确定我不是......).
编辑:
我进一步使用了CloudNotes示例应用程序,看起来NSFileWrapper 确实实现了增量保存,至少在这种情况下!我通过初始化一个包含100个音符的文档来测试它,每个音符包含大约5MB的数据.我在这里和那里做了一个小编辑(文本视图的单个字符更改将文档标记为需要保存),并大致记录每次保存所花费的时间.测试相对粗糙(并在模拟器上运行),但结果是这样的:
显然有很多因素会影响它所花费的时间,特别是因为它在后台线程中使用文件协调来节省,但总的来说趋势似乎总是这种指数衰减,直到所有写入变得非常快.
但我仍然想弄清楚为什么这不会发生在我的应用程序中.对于大型多页文档(大型,但仍然比我上面执行的CloudNotes测试的文档小很多倍),用户可以等待很多秒才能关闭文档.我不想把旋转器放在一个应该是瞬间的东西上.
我们最近将代码转换为使用UIDocument而不是直接操作文件系统上的文件,因此我们遇到了一些性能问题.我们想知道我们是否正在使用这个类,如果其他人有这些问题,以及解决它们的常用方法是什么.
我们有一个"鞋盒应用程序"来管理一堆文档,每个文档由多个图像文件组成,这些文件可能非常重,一个小的元数据文件和一个小的预览图像.用户可能在她的设备上有许多文档(1000多个文档).每个文档的文件都分组在一个目录中,我们使用NSFileWrapper来读取和写入它们.
当我们的应用程序启动时,它需要所有文档的元数据才能显示文档索引和预览图像的子集.用户滚动时会加载更多预览图像.
为了获取该信息,我们打开所有文档,阅读其元数据并预览图像(如果需要),关闭它们,然后根据需要再次打开.
打开所有文档并阅读其元数据需要花费大量时间.我认为有几个因素导致了这个问题: - 每个文档打开动作相对较慢 - 打开文档块和完成块在同一队列上执行,这使得操作的延迟非常糟糕(我的文档是打开的,但是完成块必须等待X打开文档块才能运行)
我们考虑使用单独的索引文件来解决这个问题,但是这种方法的缺点是我们需要在两个地方管理元数据,并且我们需要保持它与文件系统同步,以防iCloud更改文件.
每个打开的文档都创建自己的"文件访问线程".当我们同时打开许多文档时,开销会破坏应用程序.
我们通过使用信号量同步打开操作来解决此问题.这种方法的缺点是它可以进一步减慢负载.
谢谢!
我有一个relativley简单的应用程序,它将数据保存到位于文档文件夹中的plist文件中.数据在启动时加载到UITableView中.然后,用户可以编辑,删除或添加记录,任何更改都会保存回plist文件.
现在我想使用iCloud跨设备共享此数据(plist文件).我查看了文档,我的理解是我需要创建一个UIDocument来"管理"plist文件.
我查看了几个iCloud教程,但是它们都在UIDocument类的属性中存储了一个简单的字符串,而不是整个文件(如plist).
如何使用UIDocument对象将我的plist文件(或任何其他文件)与iCloud共享?
我会将plist文件内容转换为NSData,然后将其保存在UIDocument中的属性中吗?我应该使用NsFileWrapper吗?
我似乎很难绕着UIDocument/iCloud安排我的脑袋.我可能会让它变得更加复杂.
我有一个iOS应用程序,它使用一个简单的UIDocument模型和一个内容字段用于iCloud存储.我检索文档列表以使用NSMetadataQuery填充UITableView.我希望在此表的顶部显示新文档,但默认排序似乎是旧的 - >新的.
我知道如果我在文档中有自定义日期字段,我可以在该字段上使用NSSortDescriptor对查询进行排序,但我的问题是是否可以按照通过UIDocument iCloud存储创建的文件的内在修改日期进行排序?或者还有另一种首选方法吗?
我想知道如何正确地执行以下操作:我有一个返回NSData对象的方法.它NSData从a 获取对象UIDocument.该NSData对象可以得到很大,所以我想,以确保反应开始之前它完全加载.因此,我想从块本身返回方法的值.所以像这样:
- (NSData*)getMyData {
MyUIDocument *doc = [[MyUIDocument alloc] initWithFileURL:fileURL];
[doc openWithCompletionHandler:^(BOOL success) {
if (success) {
return doc.myResponseData; // this is to be the return for the method not the block
}
}];
}
Run Code Online (Sandbox Code Playgroud)
这会导致一个错误,因为return显然指block的return.
如何在不必使线程阻塞等待/循环的情况下完成此操作?
谢谢.
我有一个对象,其属性可能为零.我应该如何在encodeWithCoder(和decodeWithCoder)中实现它?
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:_duration forKey:kDuration]; //_duration could be nil
}
Run Code Online (Sandbox Code Playgroud) 我正在研究使用UIDocumenten NSFileWrapper来存储包含大量视频文件和一些小文本文件的"项目".我遇到了一些问题,我开始怀疑UIDocument是否仍然是正确的策略.
性能
据我所知,NSFileWrapper将所有内容加载到内存中.使用大型视频文件时,这可能是一个问题.我认为可以通过使用放弃标准的自定义保存和加载方法来解决这个问题NSFileWrapper.
元数据
我想显示所有文档的列表以及一些元数据.这可以例如包括预览图像,记录的场景的数量,视频的长度等.现在获取该数据的唯一方法是打开每个文档并检索它.可能很慢,特别是对于大型文档.
解决方案?
我现在看到两个解决方案:完全抛弃UIDocument并转向自定义架构,或者使用某种集中式元数据文件.后者的缺点是我必须在两个不同的地方管理元数据,我需要手动保持它们同步.
UIDocument仍然是去这里的方式,如果是这样的话:什么可以解决这些问题?
有没有办法检查 UIDocument(正在与 iCloud 同步)是否已使用 iCloud 在其他地方打开 - 除了等待发生冲突?
uidocument ×10
ios ×9
icloud ×3
performance ×2
block ×1
core-data ×1
instagram ×1
metadata ×1
nscoding ×1
objective-c ×1
persistence ×1
plist ×1
save ×1
xcode ×1