Macos 苹果iCloud在Mac应用程序上的实现

Macos 苹果iCloud在Mac应用程序上的实现,macos,icloud,Macos,Icloud,我知道iOS有API将iCloud集成到应用程序中。 我也可以将iCloud集成到mac应用程序中吗? Mac应用程序集成iCloud的实施方式会有所不同吗? 如果是,是否有教程等或参考网站?是。iCloud在Mac上可用。 但是苹果关于这个主题的文档还不是很完整。我能找到的唯一官方资源是WWDC 2011和一些注释 当Lion&iCloud仍在保密协议下时,我将我的发现发布在苹果的devforums上。 这是以下内容的编辑版本: 我正在使用WWDC 2011会话107代码的修改版本。(摘自视频

我知道iOS有API将iCloud集成到应用程序中。 我也可以将iCloud集成到mac应用程序中吗? Mac应用程序集成iCloud的实施方式会有所不同吗?
如果是,是否有教程等或参考网站?

是。iCloud在Mac上可用。
但是苹果关于这个主题的文档还不是很完整。我能找到的唯一官方资源是WWDC 2011和一些注释

当Lion&iCloud仍在保密协议下时,我将我的发现发布在苹果的devforums上。
这是以下内容的编辑版本:

我正在使用WWDC 2011会话107代码的修改版本。(摘自视频) 我必须删除NSFileCoordinator的手动实例化以使示例正常工作(发言者提到协调员“将来可能不需要”):

上述iAction连接到一个NSMenuItem,该NSMenuItem检查文档是否已在iCloud中或是否需要上载:

- (BOOL)validateMenuItem:(NSMenuItem*)item 
{
     SEL action = [item action];
     if (action == @selector(moveToOrFromCloud:))
     {
          BOOL isUbiquitous = [[NSFileManager defaultManager] isUbiquitousItemAtURL:[[self document] fileURL]];
          [item setTitle:isUbiquitous ? @"Remove from Cloud": "Move to Cloud"];
          [item setTag:isUbiquitous?0:1];
          return [self.document fileURL] != nil;
     }    
     return YES;
}
使iCloud文档存储正常运行所需的非代码任务清单:

  • 检查开发者证书实用程序中是否激活了iCloud支持
  • 在开发者证书实用程序中创建ubiquity容器ID
  • Ubiquity容器ID以您的团队ID/个人ID开始(请参见成员中心的帐户选项卡)
  • 在Xcode中启用权限
  • 将您的ubiquity容器ID添加到授权文件(如此处“请求iCloud存储授权”所述)
  • 我的plist Bundle ID必须与ubiquity容器ID匹配(团队ID除外)
  • 我无法添加后缀(如上面文档中建议的“app.example.osx”、“app.example.ipad”…)
  • 创建配置文件
  • 确保配置文件已安装在您的开发人员计算机上,并显示在Xcode&System首选项中
  • 在应用程序生成设置中启用代码签名

苹果公司的一份文件在各个方面都非常详细

此处发布的代码的一个重要问题是,即使在检查表中提到了URLForUbiquityContainerIdentifier,它也没有团队的标识符,将其全部保留为零,以便从权利中自动填充似乎是最好的方法

就我个人而言,要让iCloud进入我的应用程序,我唯一需要做的改变是:

  • 检查开发者网站上的“使用iCloud”按钮以获取我的应用程序id
  • 下载该应用程序id的重新生成的配置
  • 选中xcode摘要中的“启用权限”
  • 仅此而已,这里有一个希望更清晰的示例代码(应该适用于iOS和OSX):


    集成后,它不会要求任何苹果ID或其他认证。因此,当用户切换到其他Mac时,用户仍然可以访问iCould文件等?iCloud API使用系统首选项的iCloud窗格中提供的凭据。不幸的是,Valexa的链接不再工作。目前是否有新的信息来源?(11/2012). 我想使用日志文件进行同步,而不是传输文档。我已经覆盖了所有的IOS端——只是IOS-OSX部分让我受阻。有人有什么消息吗?“那太好了!”大卫,你应该为这个问题单独发帖。但是,要在iOS和OS X应用程序之间同步iCloud,您只需要让它们共享iTunes Connect中的捆绑ID或某种iCloud组。一旦你在iTC中启用了该属性,我认为没有任何额外的代码可以使iOS和OS X应用程序同步。@RS,你是对的,但我的沮丧达到了顶峰,我放弃了一年的工作,试图让iCloud同步稳定下来。我转到Parse.com平台。至少他们告诉我是他们的东西还是我的东西坏了。谢天谢地,它通常是我的。
    - (BOOL)validateMenuItem:(NSMenuItem*)item 
    {
         SEL action = [item action];
         if (action == @selector(moveToOrFromCloud:))
         {
              BOOL isUbiquitous = [[NSFileManager defaultManager] isUbiquitousItemAtURL:[[self document] fileURL]];
              [item setTitle:isUbiquitous ? @"Remove from Cloud": "Move to Cloud"];
              [item setTag:isUbiquitous?0:1];
              return [self.document fileURL] != nil;
         }    
         return YES;
    }
    
    NSURL *url = [self getiCloudURLFor:@"foo.bar" containerID:nil]; //leaving nil so it is auto filled from entitlements
    if (url) {
        NSError *error;
        if (![[NSFileManager defaultManager] startDownloadingUbiquitousItemAtURL:url error:&error]) {
            NSLog(@"Error downloading/syncing %@ (%@)",[url path],[error description]);                
        }else{
            NSLog(@"Started downloading/syncing %@",[url path]);              
        }         
    }
    
    NSArray *conflicts = [NSFileVersion unresolvedConflictVersionsOfItemAtURL:url];
    for (NSFileVersion *conflict in conflicts) {
        NSLog(@"Conflicting %@ at %@ by %@ from %@",[url path],[conflict URL],[conflict localizedNameOfSavingComputer],[conflict modificationDate]);   
    }
    
    - (NSURL*)getiCloudURLFor:(NSString*)fileName containerID:(NSString*)containerID
    {   
        NSFileManager *fm = [NSFileManager defaultManager];  
    
        NSURL *rootURL = [fm URLForUbiquityContainerIdentifier:containerID];
        if (rootURL) {
            NSURL *directoryURL = [rootURL URLByAppendingPathComponent:@"Documents"];
            if (![fm fileExistsAtPath:[directoryURL path]]) [fm createDirectoryAtURL:directoryURL withIntermediateDirectories:NO attributes:nil error:NULL];
            NSURL *cloudURL = [directoryURL URLByAppendingPathComponent:fileName];
            if (![fm isUbiquitousItemAtURL:cloudURL]) [self makeUbiquitousItemAtURL:cloudURL];//this only runs once per filename when it is first added to iCloud
            return cloudURL;
        }else{
            return [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:fileName]; //no cloud
        }     
        return nil;
    }
    
    - (void)makeUbiquitousItemAtURL:(NSURL*)cloudURL
    {
        NSFileManager *fm = [NSFileManager defaultManager];
    
        NSURL *localURL = [[[fm URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] objectAtIndex:0] URLByAppendingPathComponent:[cloudURL lastPathComponent]]; 
        if (![fm fileExistsAtPath:[localURL path]]) [fm createFileAtPath:[localURL path] contents:nil attributes:nil];
        NSError *error;            
        if(![fm setUbiquitous:YES itemAtURL:localURL destinationURL:cloudURL error:&error])  {
            NSLog(@"Error making %@ ubiquituous at %@ (%@)",[localURL path],[cloudURL path],[error description]);
        }else{
            NSLog(@"Made %@ ubiquituous at %@",[localURL lastPathComponent],[cloudURL path]);               
        }      
    }