iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services

原文地址
这是一个系列文章,查看更多请移步目录页

苹果在WWDC 2015中介绍了 CloudKit JS,它允许开发者创建一个网页界面来连接已经使用了 CloudKit 的应用的相同的数据容器。 CloudKit 原来的一个显著的限制,就是数据只允许 iOS 和 OS X 应用来使用。希望取消了这个限制后,能够带来更多的开发者,在创建他们的应用时使用 CloudKit。

在这篇文章中,我们将通过创建一个简单的记事本应用,允许用户把重要的事情记录在云端数据库中,来演示 CloudKit JS 的特性。

CloudKit JS

CloudKit JS 支持以下浏览器

  • Safari
  • FirFox
  • Chrome
  • IE
  • Edge

有趣的是,它还支持 node, 意味着你可以通过自己中间层来获取请求,并展示结果给自己的API接口。

创建一个 CloudKit JS 应用

为了示范 CloudKit JS 的能力,我创建了一个简单的应用,允许你存储笔记到 CloudKit。

CloudNotes.png

让我们来演示一下这个应用是如何创建的。 当我们要创建一个 CloudKit 应用时,无论它是 iOS 的还是 JS 的,第一步是打开 iClound的 developer dashboard。在这里设置应用的细节,创建 record type, 建立安全规则,填写数据等等。你可以在这个页面了解更多关于 dashboard 的内容https://icloud.developer.apple.com/dashboard

创建一个叫做 CloudNotes的应用,把设置都默认。

创建了应用后,我们需要具体指明它的 record type. 这个应用仅存储简单的笔记,有一个标题和内容。选择左栏 Schema 下的 Record Types, 你可以看到,User 的记录类型已经存在了,这是默认生成的。

点击添加按钮“+” ,创建一个新的 record type,命名为 CloudNote. 这个 record 用来存储我们的数据。

cloudNote.png

现在需要给 record 添加字段了,添加 title 和 content 这两个字段,都设置为 String 类型。这是目前我们仅需要设置的数据结构。

接下来,我们添加一条记录,以便在网页上可以展示和检索到东西。在左栏的菜单中,选择 Public Data 下的 “Default Zone”。所有我们要在这个应用中使用的数据都是公共的。在真正的项目中,你可能希望把用户的数据存在单独的私有数据中,但为了简洁,这个示例中我们没有添加安全和授权方面的规则。

createNote2.png

点击添加按钮,会出现添加的页面,你填写完毕后点击保存按钮,数据就会保存在CloudKit 中了。

现在我们的CloudKit中已经有了一些数据,让我们写段JS代码展示一下他吧。

JS 应用的架构

我们这个应用仅有一个页面(index.html),包含了外链的 JavaScript 文件。用来请求和存储 CloudKit 数据。为了帮助展示数据,我们引入了Knockout JS。它可以用来简化数据的绑定和展示,确保当数据源变化是,UI可以自动被刷新。同时我们还引入了 bootstrap ,省去我们自己去写 css 样式。

下面是所有的外链引用。

<html>
<head>
  <title>iOS9 Day by Day - CloudKit Web Services Example</title>
  <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.3.0/knockout-min.js"></script>
  <script type="text/javascript" src="cloudNotes.js"></script>
  <script src="https://cdn.apple-cloudkit.com/ck/1/cloudkit.js" async></script>
</head>

让我们来看一下 CloudNotes.js,看他是如何从CloudKit获取数据的。

在请求数据之前,我们首先要等待CloudKit API的加载。我们添加下面的代码到window 的eventListener中。它可以监听到 cloudkitloaded事件。

window.addEventListener('cloudkitloaded', function() {

当CloudKit对象加载成功后,你需要设置他的identifier,environment 和 API token。

CloudKit.configure({
    containers: [{
        containerIdentifier: 'iCloud.com.shinobicontrols.CloudNotes',
        apiToken: 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
        environment: 'development'
    }]
});

现在我们会到 CloudKit的 Dashboard 来生成一个 API token。在左栏选择Admin下的 API Tokens,然后点击添加,给API token取一个名字,然后把对应的值复制到上面的代码中。

apiTokenSetup.png

在我的代码中,我引用了 Knockout JS 来绑定 model 到 HTML 上。 我创建了一个 CloudNotesViewModel,负责管理页面。它包括一个数组,里面包含了所有的笔记数据。同时包括了保存新笔记,查询笔记,以及在有无权限的情况下的两种展示效果。

在视图模型能够调用这些方法之前,首先我们需要创建CloudKit的权限验证。

container.setUpAuth().then(function(userInfo) {
  // Either a sign-in or a sign-out button will be added to the DOM here.
  if(userInfo) {
      self.gotoAuthenticatedState(userInfo);
  } else {
      self.gotoUnauthenticatedState();
  }
  self.fetchRecords(); // Records are public so we can fetch them regardless.
});

当验证解决后,它依据用户是否登录的状态,在Dom中添加一个登录或退出的按钮。你需要在页面中创建一个id为 "apple-sign-in-button"的div。这个container.setUpAuth 方法可以在登录以后,自动修改 div。

查询记录

下面是在 CloudKit 中查询 “ColudNote” 的代码。

self.fetchRecords = function() {
      var query = { recordType: 'CloudNote' };

  // Execute the query.
  return publicDB.performQuery(query).then(function (response) {
      if(response.hasErrors) {
          console.error(response.errors[0]);
          return;
      }
      var records = response.records;
      var numberOfRecords = records.length;
      if (numberOfRecords === 0) {
          console.error('No matching items');
          return;
      }

      self.notes(records);
  });
};

你可以看到我们根据recordtype建立了一个简单的查询,然后在公用数据库中进行了遍历查询。当然,你也可以在私有数据库中进行查询,只是在本例子中,我们只使用了公用数据库。

当我们查询到笔记的结果后,我们把它存储在slef.notes中,它受 knockout 检测。意味着会根据数据来重新渲染页面。这样查询到的笔记结果,就会显示在页面当中。

<div data-bind="foreach: notes">
<div class="panel panel-default">
    <div class="panel-body">
        <h4><span data-bind="text: fields.title.value"></span></h4>
        <p><span data-bind="text: fields.content.value"></span></p>
    </div>
</div>

</div>

模版会遍历所有的 notes 对象,打印 title 和 content 到 panel 上。

renderedNote.png

当用户登录后,在 panel 上看到 “Add New Note”。 所以 saveNewNote 方法需要实现把数据存储到 CloudKit 的功能。

if (self.newNoteTitle().length > 0 && self.newNoteContent().length > 0) {
self.saveButtonEnabled(false);

var record = {
    recordType: "CloudNote",
    fields: {
        title: {
            value: self.newNoteTitle()
        },
        content: {
            value: self.newNoteContent()
        }
    }
};

在方法的前半段,我们首先做基本的数据验证工作。并且依据表单的内容新建一个记录。

创建了新的记录后,我们把它存入 CloudKit。

publicDB.saveRecord(record).then(
function(response) {
    if (response.hasErrors) {
        console.error(response.errors[0]);
        self.saveButtonEnabled(true);
        return;
    }
    var createdRecord = response.records[0];
    self.notes.push(createdRecord);

    self.newNoteTitle("");
    self.newNoteContent("");
    self.saveButtonEnabled(true);
}
);

publicDB.saveRecord(record) 会把新创建的记录保存到公共数据库中,同时返回一个响应结果。然后记录会放入之前我们创建好的数组,无须再去查询一遍,同时表单会被清空,保存按钮也再次变为可点击状态。

iOS 应用

我们的示例是为了演示数据通过 CloudKit 如何在 iOS 和 web 应用之间共享,所以,还需要一个 iOS 客户端的应用。

iosApp1.png

创建这个应用,我们选择 Xcode 的默认模版 master detail application.

为了能够让 iCloud 工作,我们需要在设置中打开 capablities. 开启 iCloud 服务, Xcode 会自动的链接开发者中心,并为你准备好需要的权限项。

设置如下图。

xcodeSetup.png

现在已经准备好了,可以在应用中使用 CloudKit了。这里我们不详细介绍如何组织界面了,编写代码了,感兴趣的可以去看 comprehensive explanation of how to use CloudKit on iOS in iOS8-day-by-day。下面是应用的样子,标题限制在 viewController 的 title 上,内容显示在屏幕中央。

iosApp2.png

总结

希望本文能够让你对 CloudKit JS 的 API 有所了解,看它是如何的简单易用。我非常高兴苹果公司推出这样的基于 web 的 api。但我仍持部分保留意见,我想,我个人不会在项目中使用它的。

我很多第三方的云服务,比苹果的原生SDK,拥有更好的文档,更多的特性。而且,我始终无法在模拟器中使用 CloudKit,如果这个 bug 不及时解决,会对开发者带来很大困扰。

使用 CloudKit 的需求,是确定存在的,我推荐开发者都去尝试一下。想想,如果你的数据需要在另一个平台共享的场景。

延伸阅读

想要了解更多关于 CloudKit JS 和 web 服务的内容,请查看WWDC 2015的 session 710 CloudKit JS and Web Services. 另外,你可以在 Github 中,查看本文的示例代码

这是一个系列文章,查看更多请移步目录页

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 207,113评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,644评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 153,340评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,449评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,445评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,166评论 1 284
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,442评论 3 401
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,105评论 0 261
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,601评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,066评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,161评论 1 334
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,792评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,351评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,352评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,584评论 1 261
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,618评论 2 355
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,916评论 2 344

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,601评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,748评论 6 342
  • 转载请注明,原文地址:滚蛋吧!服务器 · Begining CloudKit[http://rockerhx.gi...
    Andy矢倉阅读 4,693评论 18 20
  • 现在我嘴上正吟唱着一首老歌。喜欢唱歌,尤其爱唱老歌。唱歌是因为想抓住快乐,唱老歌是因为怀旧情结,唱起一首首经典老歌...
    天涯孤旅背包客阅读 361评论 1 6
  • 晚上在操场上跑跑步,我接到了家里的电话。和爸妈聊些琐碎的事情,很平常,感觉很温暖。 有时候真觉得家人真是上天最好的...
    橘子和她的一世长安阅读 259评论 0 0