gpt4 book ai didi

objective-c - 如何使用 iCloud 将 NSDocument 从 Mac osx 同步到 iPad/iPhone

转载 作者:可可西里 更新时间:2023-11-01 05:24:19 24 4
gpt4 key购买 nike

我看过 iOS 的 iCloud 文档示例代码,我用它来同步 往返于 iCloud,现在我正在尝试将 iCloud 与 同步在没有 UIDocument 的 Mac OSX 应用程序上。

我试图将 UIDocument 更改为 NSDocument 但所有与 同步的方法是不同的。除了来自 的文档外,我没有找到任何示例代码或教程。这是非常困惑的,写得不好。

例如,iOS 上的 UIDocument 中的以下方法在 OS X 上的 NSDocument 中不存在:

//doc is an instance of subclassed UIDocument
[doc openWithCompletionHandler:nil];

Apple 文档为 OS X 提供了以下代码:

- (void)checkIfCloudAvaliable {
NSURL *ubiquityContainerURL = [[[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil]
URLByAppendingPathComponent:@"Documents"];
if (ubiquityContainerURL == nil) {
NSDictionary *dict = [NSDictionary dictionaryWithObjectsAndKeys:
NSLocalizedString(@"iCloud does not appear to be configured.", @""),
NSLocalizedFailureReasonErrorKey, nil];
NSError *error = [NSError errorWithDomain:@"Application" code:404
userInfo:dict];
[self presentError:error modalForWindow:[self windowForSheet] delegate:nil
didPresentSelector:NULL contextInfo:NULL];
return;
}
dest = [ubiquityContainerURL URLByAppendingPathComponent:
[[self fileURL] lastPathComponent]];
}

- (void)moveToOrFromCloud {
dispatch_queue_t globalQueue =
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^(void) {
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSError *error = nil;
// Move the file.
BOOL success = [fileManager setUbiquitous:YES itemAtURL:[self fileURL]
destinationURL:dest error:&error];
dispatch_async(dispatch_get_main_queue(), ^(void) {
if (! success) {
[self presentError:error modalForWindow:[self windowForSheet]
delegate:nil didPresentSelector:NULL contextInfo:NULL];
}
});
});
[self setFileURL:dest];
[self setFileModificationDate:nil];
}

如何在 iOS 和 OS X 之间同步(因为 NSDocument 在 iOS 上不存在,UIDocument 在 OS X 上不存在)?有谁知道我在哪里可以找到 Mac OSX 的示例(NSDocument 同步)?

最佳答案

我设法让它工作了!这是我的子类 的代码OS X 上的文件:

头文件:

#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>

@interface subclassedNSDocument : NSDocument

@property (strong) NSData *myData;

@end

执行文件:

- (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError 
{
BOOL readSuccess = NO;
if (data)
{
readSuccess = YES;
[self setMyData:data];
}

[[NSNotificationCenter defaultCenter] postNotificationName:@"dataModified"
object:self];

return readSuccess;
}

- (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError
{
if (!myData && outError) {
*outError = [NSError errorWithDomain:NSCocoaErrorDomain
code:NSFileWriteUnknownError userInfo:nil];
}
return myData;
}

在 AppDelegate.m 文件中:

#define kFILENAME @"mydocument.dox"

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
NSURL *ubiq = [[NSFileManager defaultManager]
URLForUbiquityContainerIdentifier:nil];
if (ubiq) {
NSLog(@"iCloud access at %@", ubiq);
// TODO: Load document...
[self loadDocument];
}
else
{
NSLog(@"No iCloud access");
}

[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(dataReloaded:)
name:@"dataModified" object:nil];
}

- (void)update_iCloud
{
NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:kFILENAME];
self.doc.myData = [NSKeyedArchiver archivedDataWithRootObject:[@"Your Data Array or any data", nil]];
[self.doc saveToURL:ubiquitousPackage ofType:@"dox" forSaveOperation:NSSaveOperation error:nil];
}

- (void)loadData:(NSMetadataQuery *)query {

if ([query resultCount] == 1) {

NSMetadataItem *item = [query resultAtIndex:0];
NSURL *url = [item valueForAttribute:NSMetadataItemURLKey];
NSLog(@"url = %@",url);
subclassedNSDocument *doc = [[subclassedNSDocument alloc] initWithContentsOfURL:url ofType:@"dox" error:nil];
[doc setFileURL:url];
self.doc = doc;
}
else {

NSURL *ubiq = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSURL *ubiquitousPackage = [[ubiq URLByAppendingPathComponent:@"Documents"] URLByAppendingPathComponent:kFILENAME];

dataUrls *doc = [[dataUrls alloc] init];
[self.doc setFileURL:ubiquitousPackage];
self.doc = doc;
[self.doc saveToURL:ubiquitousPackage ofType:@"dox" forSaveOperation:NSSaveOperation error:nil];
}

}

- (void)queryDidFinishGathering:(NSNotification *)notification {

NSMetadataQuery *query = [notification object];
[query disableUpdates];
[query stopQuery];

[[NSNotificationCenter defaultCenter] removeObserver:self
name:NSMetadataQueryDidFinishGatheringNotification
object:query];

_query = nil;

[self loadData:query];

}

- (void)loadDocument {

NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
_query = query;
[query setSearchScopes:[NSArray arrayWithObject:NSMetadataQueryUbiquitousDocumentsScope]];
NSPredicate *pred = [NSPredicate predicateWithFormat: @"%K == %@", NSMetadataItemFSNameKey, kFILENAME];
[query setPredicate:pred];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(queryDidFinishGathering:) name:NSMetadataQueryDidFinishGatheringNotification object:query];

[query startQuery];

}

- (void)dataReloaded:(NSNotification *)notification
{
self.doc = notification.object;

NSArray *arrFromCloud = [NSKeyedUnarchiver unarchiveObjectWithData:self.doc.myData];

//Update you UI with new data
}

我唯一没有工作的是,如果我在 iPad 上更改文档的数据,Mac 应用程序不会调用 readFromData 方法从 iCloud 更新,有谁知道我错过了什么?

在 iOS 上,等效方法 loadFromContents 会在 iCloud 中的 UIDocument 每次更改时自动调用。在 OS X 上,readFromData 在加载时被调用一次,但再也不会被调用。

希望我的代码能有所帮助,对我来说它是从 Mac 到 iPad 的一种工作方式。

关于objective-c - 如何使用 iCloud 将 NSDocument 从 Mac osx 同步到 iPad/iPhone,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9032901/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com