使用 CloudKit 作為跨平臺數據庫
原文 http://tips.producter.io/shi-yong-cloudkit-zuo-wei-kua-ping-tai-shu-ju-ku/
一直以來 CloudKit 在我心中是有點雞肋的,如果只是用在 Apple 的生態里還好,但是要面向 Web 和 Android 做 Public Database 就顯得捉襟見肘。
但是畢竟便宜!
這兩天在做Producter 的 App 時,用 CloudKit 來作為數據庫支持,發現還是很有潛力的。(只要蘋果改進下權限控制 & 支持云代碼)
WebService Access
Apple 在 CloudKit Web Services Reference 里晦澀的描述了如何使用 HTTP 來做 Request,不過用起來還是比較簡單的,下面以 Javascript 為例,首先需要下面幾個數據
- Apple 服務器地址
- iCloud Container
- 想要訪問的 CloudKit 數據庫環境
- 數據庫 (public or private)
- 操作(query,lookup)
- API Token (可以從 Dashboard 獲取)
var ServerPath = "https://api.apple-cloudkit.com/database/1/"; var CloudIdentifier = "iCloud.kevinzhow.Producter"; var Enviroment = "development" var DataBase = "public/records" var DataMethod = "query" var ckAPIToken= "xx"
隨后你需要定義查詢語句,例如我需要查詢的是 Article,那么最簡單的方法可以像這樣寫
var articleRequest = { query: { recordType: "article" } }
如果你的瀏覽器是 Chrome 那么可以用 fetch 來獲取數據試試了
var articleQuery = ServerPath+CloudIdentifier+"/"+Enviroment+"/"+DataBase+"/"+DataMethod+"?ckAPIToken="+ckAPIToken fetch(articleQuery, { method: 'POST', headers: { "Content-type": "application/json"}, body: JSON.stringify(articleRequest) }) .then(function(response) { status = response.status; console.log("Fetch article records " + status); return response.json(); }) .then(function(responseObject) { }).catch(function(err) { // An error occured parsing Json console.log("Fetch Error" + err); });
如果希望高端一點的查詢,可以嘗試增加 filterBy 的字段
var articleRequest = { query: { recordType: "article", filterBy: [{ comparator: "EQUALS", fieldName: "type", fieldValue:{ value: "article" }, sortBy: [{ fieldName: "article_id", ascending: false }] }] } }
CloudKitJS
寫入操作首先需要用戶驗證登錄,WebService API 目前沒有主動登錄的方式,而是會在你訪問需要用戶權限的 API 的時候返回一個 redirect url 給你,隨后你需要用瀏覽器打開這個 URL 進行認證。
于此相比,用 CloudKitJS 就要方便的多,首先在你的 HTML 里引入
<script src="https://cdn.apple-cloudkit.com/ck/1/cloudkit.js"></script>
進行一個基本的配置并獲取 Container 和 Database
CloudKit.configure({ containers: [{ containerIdentifier: CloudIdentifier, webTokenAuth: { webToken: ckAPIToken, persist: true }, environment: 'development' }] }); var container = CloudKit.getDefaultContainer(); var publicDatabase = container.publicCloudDatabase;
隨后你可以通過 setUpAuth() 方法來判斷用戶是否需要登錄
container.setUpAuth().then(function(userInfo) { if(userInfo) { // The user is authenticated } else { console.log("Need Login"); } });
而如何讓用戶登錄顯得有點 Magic,需要你在 HTML 里加入
<div id="apple-sign-in-button"></div> <div id="apple-sign-out-button"></div>
如果需要用戶登錄,Sign In 的按鈕會顯示(樣式 Apple 會默認幫你定義好),反之則會顯示 Sign Out。
用戶點擊按鈕會會被引導到一個登錄窗口,完成登錄后,你可以通過 whenUserSignsIn() 來監聽用戶登錄的情況。
container.whenUserSignsIn().then(function(userInfo) { // The user just signed in if(userInfo) { console.log("User Info " + userInfo); } else { console.log("Need Login"); } });
寫入數據
寫入數據可以如下構建 Model
var newArticle = { recordType: "Article", fields: { title: { value:"Title" }, author:{ value:"Kevin"} } }
執行寫入操作
publicDatabase.saveRecords(newArticle).then(function(response) { if (response.hasErrors) { // Insert error handling throw response.errors[0]; } else { // Insert successfully fetched record code } });
不妨開始使用 CloudKit 作為你的個人項目的數據庫,接下來的幾個月我就好好祈禱 CloudKit 在明年 WWDC 可以進化的更完善一些了。