【问题标题】:How to Sync an NSDocument from iPad/iPhone to Mac osx with iCloud如何使用 iCloud 将 NSDocument 从 iPad/iPhone 同步到 Mac osx
【发布时间】:2014-01-25 21:30:19
【问题描述】:

如何使用/同步到Mac osx

我设法让它工作了!从 Mac osx 到 iPhone/iPad 但不是从 iPad/iPhone 到 Mac osx

这是我在 上的子类 文件中的代码:

头文件:

#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 上,每次更改 iCloud 中的 UIDocument 时都会自动调用等效方法 loadFromContents。在 OS X 上,readFromData 在加载时被调用一次,但不再被调用。

希望我的代码可以提供帮助,对我来说,它是从 Mac 到 iPad 的一种方式。

【问题讨论】:

  • 嗨,你解决了吗?我面临同样的问题。我可以从调试器中看到 iCloud 正在下载一些数据,但观察者从未触发过。我也试过添加NSMetadataQueryDidUpdateNotification观察者,还是不行。

标签: nsdocument ipad iphone icloud nsdocument osx macos sync icloud nsdocument uidocument


【解决方案1】:

自己修好了。

显然,这只是一个实现不佳且过于复杂的示例代码。

applicationDidFinishLaunching: 我们只需要

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

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

并添加以下方法:

- (void)queryUpdated:(NSNotification *)notification {
    NSLog(@"queryUpdated called...");
    NSMetadataQuery *query = [notification object];
    [query disableUpdates];

    if ([query resultCount] == 1) {
        // update views, etc. here
    }

    [query enableUpdates];
}

然后从原始样本中删除所有未调用的方法。

【讨论】:

    猜你喜欢
    • 2012-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-30
    • 2011-12-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多