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。

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第1张图片
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 用来存储我们的数据。

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第2张图片
cloudNote.png

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

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

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第3张图片
createNote2.png

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

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

JS 应用的架构

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

下面是所有的外链引用。



  iOS9 Day by Day - CloudKit Web Services Example
  
  
  
  

让我们来看一下 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取一个名字,然后把对应的值复制到上面的代码中。

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第4张图片
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 检测。意味着会根据数据来重新渲染页面。这样查询到的笔记结果,就会显示在页面当中。

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

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第5张图片
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 客户端的应用。

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第6张图片
iosApp1.png

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

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

设置如下图。

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第7张图片
xcodeSetup.png

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

iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services_第8张图片
iosApp2.png

总结

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

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

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

延伸阅读

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

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

你可能感兴趣的:(iOS9 Day-by-Day :: Day 13 :: CloudKit Web Services)