2016-11-15 59 views
2

我無法理解一些CloudKit共享概念,而WWDC 2016「CloudKit中的新增功能」視頻並未解釋允許用戶共享和訪問共享記錄所需的所有內容。CloudKit共享

我已成功創建了一個應用程序,允許用戶在他們的私人數據庫中創建和編輯記錄。 我也可以使用提供的共享UIController創建共享記錄並共享此記錄。這可以被參與者用戶成功接收和接受,但我無法弄清楚如何查詢和顯示這個共享記錄。

該應用程序在用戶私人數據庫中創建一個「MainZone」,然後在此「MainZone」中創建一個CKRecord。然後我創建並保存CKShare記錄並使用它顯示UICloudSharingController。

如何查詢sharedDatabase以訪問此記錄?我已經使用了相同的查詢試圖作爲privateDatabase使用,但得到以下錯誤:

"ShareDB can't be used to access local zone" 

編輯

我發現了問題 - 我需要處理在AppDelegate中接受的記錄。現在它們出現在CloudKit儀表板中,但我仍然無法查詢它們。看來我可能需要獲取sharedDatabase「MainZone」才能查詢它們。

回答

1

老兄,我明白了:首先,您需要獲得該共享記錄的CKRecordZone。您可通過執行以下操作步驟:

let sharedData = CKContainer.default().sharedCloudDatabase 
    sharedData.fetchAllRecordZones { (recordZone, error) in 
     if error != nil { 
      print(error?.localizedDescription) 
     } 
     if let recordZones = recordZone { 
      // Here you'll have an array of CKRecordZone that is in your SharedDB! 
     } 
    } 

現在,隨着在手該數組,所有你需要做的是正常抓取:

func showData(id: CKRecordZoneID) { 

    ctUsers = [CKRecord]() 

    let sharedData = CKContainer.default().sharedCloudDatabase 
    let predicate = NSPredicate(format: "TRUEPREDICATE") 
    let query = CKQuery(recordType: "Elder", predicate: predicate) 

    sharedData.perform(query, inZoneWith: id) { results, error in 
     if let error = error { 
      DispatchQueue.main.async { 
       print("Cloud Query Error - Fetch Establishments: \(error)") 
      } 
      return 
     } 
     if let users = results { 
      print(results) 
      self.ctUsers = users 
      print("\nHow many shares in cloud: \(self.ctUsers.count)\n") 
      if self.ctUsers.count != 0 { 
       // Here you'll your Shared CKRecords! 
      } 
      else { 
       print("No shares in SharedDB\n") 
      } 
     } 
    } 
} 
+0

我不會推薦這種方法,如果有數百萬用戶分享內容會發生什麼?將有數百萬個記錄區域,因此這個查詢可能非常大。我認爲正確的做法似乎是將本地引用存儲到與用戶共享的內容中,並使用它們來查詢更改。我認爲這個想法也是儘量減少查詢,然後註冊更改,然後處理更改 - 但是我擔心在某些情況下可能會導致推送流量太大。 –

+0

嗯 - 實際上你可能是對的,因爲用戶只能看到與他們共享的記錄中的區域! –

0

我不太明白你想獲得這些信息。我遇到同樣的問題,但我只能通過點擊URL來獲取共享數據...要做到這一點,您需要兩個功能。第一個在的AppDelegate

func application(_ application: UIApplication, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) { 

    let acceptSharesOperation = CKAcceptSharesOperation(shareMetadatas: [cloudKitShareMetadata]) 
    acceptSharesOperation.perShareCompletionBlock = { 
     metadata, share, error in 
     if error != nil { 
      print(error?.localizedDescription) 
     } else { 
      let viewController: ViewController = self.window?.rootViewController as! ViewController 
      viewController.fetchShare(cloudKitShareMetadata) 
     } 
    } 
    CKContainer(identifier: cloudKitShareMetadata.containerIdentifier).add(acceptSharesOperation) 
} 

ViewConroller你有將獲取元數據功能:

func fetchShare(_ metadata: CKShareMetadata) { 
    let operation = CKFetchRecordsOperation(recordIDs: [metadata.rootRecordID]) 
    operation.perRecordCompletionBlock = { record, _, error in 
     if error != nil { 
      print(error?.localizedDescription) 
     } 
     if record != nil { 
      DispatchQueue.main.async() { 
       self.currentRecord = record 
       //now you have your Shared Record 
      } 
     } 
    } 
    operation.fetchRecordsCompletionBlock = { _, error in 
     if error != nil { 
      print(error?.localizedDescription) 
     } 
    } 
    CKContainer.default().sharedCloudDatabase.add(operation) 
} 

正如我以前說過,我現在想不來獲取ShareDB訪問URL。一旦我已經接受分享,我不想依賴鏈接。希望這可以幫助你!

+0

由於這是有道理的,但我會如何查詢所有共享來自數據庫的記錄還是應用程序希望保留自己的這些共享記錄的副本(本地或在私人數據庫中)?我不想在本地存儲數據,我只想查詢共享記錄,但似乎沒有辦法做到這一點,除非查詢每個共享區域。 –

+0

不幸的是,我和你在同一個地方,試圖弄清楚這一點。共享內容不會保留在您的privateDB中,它保留在sharedDB中。我試圖做的是查詢像一個正常的CKRecord,畢竟,CKShare是CKRecord的參考!但是,一旦我用* ZoneID *執行查詢,我得到了與「ShareDB不能用於訪問本地區域」相同的消息「 –

+0

我檢查記錄zoneID並在zoneID中查詢工作正常。所以我保留私人數據庫zoneID並與記錄zoneID進行比較,如果它們不匹配,那麼我知道它必須是sharedDatabase查詢,然後在查詢中需要zoneID。現在,我將在privateDatabase中存儲所有Shared zoneID的副本,以便輕鬆知道要在sharedDatabase中查詢哪些區域。 –