检查用户是否已登录iCloud?Swift/iOS

检查用户是否已登录iCloud?Swift/iOS,ios,swift,icloud,cloudkit,Ios,Swift,Icloud,Cloudkit,有没有办法让我在用户打开应用程序时检查并查看他们是否登录了iCloud?如果他们没有登录,并且如果他们登录iCloud并且以前使用过应用程序,我希望能够将他们引导到设置页面-我想跳过登录页面 我查阅了苹果的iCloud和Cloudkits文档,但找不到任何有帮助的东西!这可能吗?给你——希望是不言自明的。有关更多信息,请参阅以下NSFileManager功能的Apple文档 func isICloudContainerAvailable()->Bool { if let c

有没有办法让我在用户打开应用程序时检查并查看他们是否登录了iCloud?如果他们没有登录,并且如果他们登录iCloud并且以前使用过应用程序,我希望能够将他们引导到设置页面-我想跳过登录页面


我查阅了苹果的iCloud和Cloudkits文档,但找不到任何有帮助的东西!这可能吗?

给你——希望是不言自明的。有关更多信息,请参阅以下NSFileManager功能的Apple文档

func isICloudContainerAvailable()->Bool {
        if let currentToken = NSFileManager.defaultManager().ubiquityIdentityToken {
            return true
        }
        else {
            return false
        }
    }
见下文摘录: 表示当前用户iCloud身份的不透明令牌(只读)
当iCloud当前可用时,此属性包含表示当前用户身份的不透明对象。如果iCloud因任何原因不可用或没有登录用户,则此属性的值为零

我认为最好使用这种异步方法,这样在检查时就不会阻塞

        CKContainer.defaultContainer().accountStatusWithCompletionHandler { (accountStat, error) in
          if (accountStat == .Available) {
              print("iCloud is available")
          }
          else {
              print("iCloud is not available")
          }
        }

如果您只想知道用户是否登录到iCloud,可以使用同步方法:

if FileManager.default.ubiquityIdentityToken != nil {
    print("iCloud Available")
} else {
    print("iCloud Unavailable")
}
如果
ubiquityIdentityToken
nil
并且您想知道iCloud不可用的原因,您可以使用异步方法:

CKContainer.default().accountStatus { (accountStatus, error) in
    switch accountStatus {
    case .available:
        print("iCloud Available")
    case .noAccount:
        print("No iCloud account")
    case .restricted:
        print("iCloud restricted")
    case .couldNotDetermine:
        print("Unable to determine iCloud status")
    }
}
请注意,这需要使用CloudKit,这需要CloudKit权限:

<key>com.apple.developer.icloud-services</key>
<array>
    <string>CloudKit</string>
</array>

检查iCloud功能有两种方法,它们是为两种不同的需求提供的

  • 检查iCloudDrive的可用性
  • 检查iCloud CKContainer的可用性
  • 检查iCloudDrive的可用性 来自苹果公司的文档:

    FileManager.default.ubiquityIdentityToken->表示当前用户iCloud驱动器文档身份的不透明标记

    在iCloud驱动器文档中,当iCloud可用时,此属性包含表示当前用户身份的不透明对象。如果iCloud不可用或没有登录用户,则此属性的值为零

    要检查此iCloud功能,我们可以检索该令牌并检查nil

    为确保收到通知,如果iCloudDrive的可用性在应用程序运行期间发生变化,请->向通知中心注册以获取NSUbiquityIdentityDidChange通知

    检查iCloud容器的可用性 要检查用户iCloud帐户是否可用于访问CKContainer(及其私有数据库),我们可以在默认容器上使用异步请求

    // Check iCloud account status (access to the apps private database)
    CKContainer.default().accountStatus { (accountStatus, error) in
    
      if accountStatus == .available {
          print("iCloud app container and private database is available")
      } else {
          print("iCloud not available \(String(describing: error?.localizedDescription))")
      }   
    }
    

    要在应用程序运行时获得有关更改的通知,您可以使用CKAccountChanged通知。

    这让我觉得没有解决方案。是否可以从我自己的应用程序调用iCloud登录?例如,如果
    isICloudContainerAvailable
    返回false,则打开登录名。对我不起作用。我使用了一个iCloud帐户和两个不同的设备。本应为两台设备获得1个相同的密钥,但获得2个不同的密钥。2017年更新:看起来像。从现在起,我必须使用(下面)中的异步方法。事实上,苹果现在说,您不应该使用令牌来标识登录/注销状态。来自文档:“CloudKit客户端不应使用此令牌来标识iCloud帐户是否已登录。相反,请使用accountStatus(completionHandler:)或fetchUserRecordID(completionHandler:)。”我有一个运行12.4.8的iOS测试设备,可以确认
    ubiquityIdentityToken
    nil
    ,即使是1。登录到iCloud2。iCloud drive已打开,并且3。我的应用程序已在iCloud中打开。它在100%的时间内是可重复的。在同一台设备上测试
    CKContainer.default().accountStatus
    会产生
    .available
    。我猜这意味着我们必须实现CloudKit来检查iCloud的状态。默认情况下不是异步的吗。。?我想是的。@Duranzo公认的答案是sync。这个答案是异步的。来自Apple docs for ubiquityIdentityToken:“访问此属性的值相对较快,因此您可以在启动时从应用程序的主线程检查该值。”@joseph duffy您的编辑偏离了帖子的原始内容,我取消了它。如果您想添加新信息或演示新版本语言的用法,请随意发布您自己的答案。谢谢。@EricAya根据问题,当前的答案是错误的;如果
    accountStat
    变量为
    couldnotdeterminate
    Restricted
    ,则将执行
    打印(“iCloud可用”)
    ,即使iCloud不可用。我确实用Swift 3写了答案,我很高兴将其转换为2.2。我还应该发布一个新的答案吗?我不觉得再发一篇文章会增加问题的难度。
    // Request iCloud token
    let token = FileManager.default.ubiquityIdentityToken
    if token == nil {
        print("iCloud (Drive) is not available")
    } else {
        print("iCloud (Drive) is available")
    }
    
    // Check iCloud account status (access to the apps private database)
    CKContainer.default().accountStatus { (accountStatus, error) in
    
      if accountStatus == .available {
          print("iCloud app container and private database is available")
      } else {
          print("iCloud not available \(String(describing: error?.localizedDescription))")
      }   
    }