Objective c 是否支持在外部编辑器中进行文档更改?
我有一个NSC文档,其中包含一些简单的代码:Objective c 是否支持在外部编辑器中进行文档更改?,objective-c,macos,cocoa,nsdocument,Objective C,Macos,Cocoa,Nsdocument,我有一个NSC文档,其中包含一些简单的代码: - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { self.string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; return YES; } 如果我在外部编辑器中更改文件,如何得到通知以便处理它?我想这里面有
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
self.string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
return YES;
}
如果我在外部编辑器中更改文件,如何得到通知以便处理它?我想这里面有东西,但我找不到
我正在寻找NSC文档中内置的内容。我知道FSEvent,但它的级别似乎太低,无法对大多数基于文档的应用程序执行非常常见的操作。您想注册到。从10.7开始,您可以观看任意文件
可能重复的。NSMetadataQuery似乎是无需轮询且cpu开销低的情况下监视文件和文件夹更改的最佳方法 一些用于监视文件夹的基本代码,您只需要将filePattern设置为文件名,而不是通配符*
NSString* filePattern = [NSString stringWithFormat:@"*"];
NSString *watchedFolder = @"not/fake/path";
NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
[query setSearchScopes:@[watchedFolder]];
NSString *itemName = (NSString*)kMDItemFSName;
[query setPredicate:[NSPredicate predicateWithFormat:@"%K LIKE %@", NSMetadataItemDisplayNameKey, filePattern]];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(queryFoundStuff:) name:NSMetadataQueryDidFinishGatheringNotification object:query];
[nc addObserver:self selector:@selector(queryFoundStuff:) name:NSMetadataQueryDidUpdateNotification object:query];
[query setNotificationBatchingInterval:0.5];
[query startQuery];
- (void)queryFoundStuff:(NSNotification *)notification {
[query disableUpdates];
NSLog(@"Notification: %@", notification.name);
NSMutableArray *results = [NSMutableArray arrayWithCapacity:query.resultCount];
for (NSUInteger i=0; i<query.resultCount; i++) {
[results addObject:[[query resultAtIndex:i] valueForAttribute:NSMetadataItemPathKey]];
}
// file has updated, do something
[query enableUpdates];
}
NSString*filePattern=[NSString stringWithFormat:@“*”];
NSString*watchedFolder=@“not/fake/path”;
NSMetadataQuery*query=[[NSMetadataQuery alloc]init];
[查询集搜索范围:@[watchedFolder]];
NSString*itemName=(NSString*)kMDItemFSName;
[query setPredicate:[NSPredicate predicateWithFormat:@“%K LIKE%@”,NSMetadataItemDisplayNameKey,filePattern];
NSNotificationCenter*nc=[NSNotificationCenter defaultCenter];
[nc addObserver:自选择器:@selector(queryFoundStuff:)名称:NSMetadataQueryDifinishGatheringNotification对象:查询];
[nc addObserver:自选择器:@selector(queryFoundStuff:)名称:NSMetadataQueryIDUpdateNotification对象:查询];
[查询设置NotificationBatchingInterval:0.5];
[查询开始查询];
-(无效)queryFoundStuff:(NSNotification*)通知{
[查询禁用更新];
NSLog(@“Notification:%@”,Notification.name);
NSMutableArray*results=[NSMutableArray阵列容量:query.resultCount];
对于(i=0;i当我在基于文档的应用程序中打开文档,在另一个应用程序中编辑,然后切换回我的应用程序时,使用新数据调用您提到的相同方法(readFromData:ofType:error:
)
然后,您可以添加一个布尔实例变量来检查是否由于外部更新而调用它(在我的例子中,我检查我的一个iboutlet是否已初始化:如果未初始化,则第一次加载文档)。您可能希望将使用字符串
实例变量的代码移动到某个方法中,如果文档已初始化,则可以调用该方法,如下所示:
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
self.string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (self.isLoaded)
[self documentChanged];
return YES;
}
- (void)windowControllerDidLoadNib:(FCWindowController *)windowController {
self.isLoaded = YES;
[self documentChanged];
}
- (void)documentChanged {
// use self.string as you like
]
class MyDocument: NSDocument {
// ...
var canonicalModificationDate: Date!
override func presentedItemDidChange() {
guard fileContentsDidChange() else { return }
guard isDocumentEdited else {
DispatchQueue.main.async { self.reloadFromFile() }
return
}
DispatchQueue.main.async { self.showReloadDialog() }
}
fileprivate func showReloadDialog() {
// present alert "do you want to replace your stuff?"
}
/// - returns: `true` if the contents did change, not just the metadata.
fileprivate func fileContentsDidChange() -> Bool {
guard let fileModificationDate = fileModificationDateOnDisk()
else { return false }
return fileModificationDate > canonicalModificationDate
}
fileprivate func fileModificationDateOnDisk() -> Date? {
guard let fileURL = self.fileURL else { return nil }
let fileManager = FileManager.default
return fileManager.fileModificationDate(fileURL: fileURL)
}
}
由于OS X v10.7,NSDocument
提供了一种简单得多的机制,您可以在子类中重写:-presentedItemDidChange
处理-presentedItemDidChange
,忽略元数据更改
不过,当元数据发生变化时,仅仅依靠这个回调就可能产生误报。例如,对于存储在Dropbox中的文件,这很快让我感到不安
我在Swift中处理这一问题的方法大致如下:
- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError {
self.string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
if (self.isLoaded)
[self documentChanged];
return YES;
}
- (void)windowControllerDidLoadNib:(FCWindowController *)windowController {
self.isLoaded = YES;
[self documentChanged];
}
- (void)documentChanged {
// use self.string as you like
]
class MyDocument: NSDocument {
// ...
var canonicalModificationDate: Date!
override func presentedItemDidChange() {
guard fileContentsDidChange() else { return }
guard isDocumentEdited else {
DispatchQueue.main.async { self.reloadFromFile() }
return
}
DispatchQueue.main.async { self.showReloadDialog() }
}
fileprivate func showReloadDialog() {
// present alert "do you want to replace your stuff?"
}
/// - returns: `true` if the contents did change, not just the metadata.
fileprivate func fileContentsDidChange() -> Bool {
guard let fileModificationDate = fileModificationDateOnDisk()
else { return false }
return fileModificationDate > canonicalModificationDate
}
fileprivate func fileModificationDateOnDisk() -> Date? {
guard let fileURL = self.fileURL else { return nil }
let fileManager = FileManager.default
return fileManager.fileModificationDate(fileURL: fileURL)
}
}
现在,您还必须更新子类中的canonicalModificationDate
:
- 在“是否要替换内容?”警报的回调中,我将其称为
-ignoreLatestFileChanges
,这样您就不会对用户的广告内容唠叨
- 在
-readFromURL:ofType:error:
中,或者以读取初始值的内容为结束
- 在
-dataOfType:error:
中,或者以任何方式生成要写入磁盘的内容
FSEvents
会起作用吗?寻找NSDocument中内置内容的可能重复。有人在NSFilePresenter中提到了presentedItemDidChange
(哪个NSDocument符合)。查看是否有显示UI的内容,以询问用户做什么。根据文档,-查看文档中的-(NSDate*)fileModificationDate
@TonyArnold需要轮询,这对我来说似乎不是一个解决方案。谢谢!这与另一个问题有点不同。我只对文档内容的更改感兴趣。我希望NSDocument中内置一些内容。