- 版本:1.0.0
- GitHub: https://github.com/EddyVerbruggen/nativescript-homekit
- NPM: https://npmjs.net.cn/package/nativescript-homekit
- 下载
- 昨天: 0
- 上周: 0
- 上个月: 0
原生设备支持HomeKit插件
安装
从命令提示符转到您的应用根目录并执行
tns plugin add nativescript-homekit
示例应用
推荐!查看示例,了解您可以使用HomeKit做什么。
您可以通过在项目根目录中输入 npm run demo.ios
来运行示例应用。
一些背景信息
如此处所述,HomeKit是一个框架,用于与支持苹果HomeKit配件协议的智能家居配件进行通信和控制。HomeKit应用允许用户发现兼容的配件并对其进行配置。用户还可以创建动作来控制配件(如恒温器或灯具),将它们分组在一起,并使用Siri触发它们。
HomeKit对象存储在用户iOS设备上的数据库中,通过iCloud同步到其他iOS设备。HomeKit支持远程访问配件、多个用户设备和多个用户。HomeKit还为您处理安全和隐私。
住宅
在层次结构的顶部是“住宅”,例如您的家庭住宅和(永久性的)度假住宅。每个住宅可以包含多个房间。住宅中的配件可以分配到房间。最后,配件具有服务
区域
为了进一步结构化您的HomeKit布局并创建强大的场景,HomeKit可以将您的住宅划分为区域(“厨房”和“车库”房间可以聚集在“楼下”区域)
此插件的功能
此插件提供了一个简单直接的接口,用于管理HomeKit的SDK中的住宅、房间和区域,并将配件分配给这些住宅或房间。
除此之外还可以做更多的事情,但您需要直接与HomeKit SDK交互。不用担心,我们会解释如何操作,这比您想象的要简单。
您可能想知道为什么此插件没有暴露HomeKit的全部功能?主要是因为它非常庞大,而此插件之外的所有功能实际上都取决于您拥有的配件类型。这意味着我们会生成大量的未经测试的包装代码,而使用原始SDK本身并没有那么不同。
设置
在Xcode中打开您的项目,转到目标,然后启用HomeKit。除非您运行tns platforms remove ios
& tns platform add ios
,否则这只需要做一次。
下载HomeKit模拟器,它现在是硬件IO工具的一部分。这是测试您的HomeKit应用的一种非常方便的方式。
只需打开模拟器,并按图所示添加新的配件,您就可以在示例应用中玩转它了。
类型
HomeKit插件封装了原生iOS HomeKit SDK类,使您能够更方便地与之交互。以下API函数使用本节中列出的类型。
请注意,您可以跳过本节,直接查看此插件提供的TypeScript .ts.d
文件。如果您使用VSCode或Webstorm/Intellij等不错的IDE,您将基于这些定义获得自动完成等功能。
主页
| 属性 | 类型 | 描述 | --- | --- | --- | --- | name | string
| 这是由Siri使用的,因此是唯一的 | | primary | boolean
| 您创建的第一个家将是“主要”家 | | zones | Array
| 在此家中创建的所有区域 | | rooms | Array
| 在此家中创建的所有房间 | | accessories | Array
| 分配给此家的所有配件 | | ios | HMHome
| 您可以进一步探索的本地HomeKit SDK类 |
区域
| 属性 | 类型 | 描述 | --- | --- | --- | --- | name | string
| 这是由Siri使用的,因此对于家是唯一的 | | rooms | Array
| 区域可以包含多个房间,每个房间都有一个独特的名称 | | ios | HMZone
| 您可以进一步探索的本地HomeKit SDK类 |
房间
| 属性 | 类型 | 描述 | --- | --- | --- | --- | name | string
| 这是由Siri使用的,因此对于家是唯一的 | | accessories | Array
| 房间可以分配多个配件 | | ios | HMRoom
| 您可以进一步探索的本地HomeKit SDK类 |
配件
| 属性 | 类型 | 描述 | --- | --- | --- | --- | name | string
| 这是由Siri使用的,因此对于家是唯一的 | | bridged | boolean
| 此配件是否通过桥(也是一种配件)连接 | | room? | Room
| 配件可能或可能未分配给房间 | | ios | HMAccessory
| 您可以进一步探索的本地HomeKit SDK类 |
API
大部分示例将使用TypeScript,因为我认为这是目前用JavaScript构建任何东西的最好方式。如果您计划与HomeKit的配件和服务进行深度交互,您还需要安装tns-platform-declarations
模块,它提供了HomeKit SDK的类型声明。
听起来有点令人不知所措?只需查看示例应用即可,因为它已经配置了所有这些部分。这是一个由TypeScript和NativeScript驱动的非Angular应用,您可以从中复制代码片段。
请注意,所有这些API函数都使用Promises,因此它们的.then()
将接收resolve和reject参数。reject将始终包含一个错误原因的字符串。大多数时间,这些错误将来自HomeKit本身。例如,如果您向家中添加一个与现有房间同名的房间。或者如果房间名称以Siri不喜欢的字符结尾。
为了简洁,我将省略大部分示例中的reject。
可用
在iOS上,此方法始终返回true
,在Android上返回false
。因此,如果您已经有了其他方便的方法在两者之间分支代码,则无需调用此方法。
JavaScript
// require the plugin
var HomeKit = require("nativescript-homekit").HomeKit;
// instantiate the plugin
var homeKit = new HomeKit();
homeKit.available().then(
function(available) {
console.log(available ? "YES!" : "NO");
}
);
TypeScript
// require the plugin
import { HomeKit } from "nativescript-homekit";
// instantiate the plugin (assuming the code below is inside a Class)
private homeKit = new HomeKit();
public checkAvailability(): void {
this.homeKit.available().then(
avail => console.log(available ? "YES!" : "NO"),
err => console.log(err)
);
}
init
没有init
,就没有荣耀 - 哎,HomeKit交互。您需要传入一个函数,当HomeKit数据库中的任何内容发生变化时,该函数将接收更新,以便您的应用可以对这些更改做出响应。
this.homeKit.init((homes: Array<Home>) => {
// do anything with the Homes you received (look at the demo app!)
});
startSearchingForAccessories
配件可能会随时出现,但默认情况下,您的应用不会始终搜索它们。在您的应用UI中添加一个按钮以启动和停止搜索配件可能是一个好主意,因为用户将知道何时可以找到新的配件。
只能找到新的配件,而不能找到已分配给家或房间的配件。此外,当配件之前存储在本地HomeKit数据库中,现在已被删除(尝试一下,在HomeKit模拟器中删除一个)时,您也将收到通知。
为此,您可以传入2个不同的回调函数:第一个用于新发现的设备,第二个用于已删除的设备
this.homekit.startSearchingForAccessories(
(accessory: Accessory) => {
console.log("New accessory found: " + accessory.name);
// you can use this to further interact with the accessory:
console.log("Accessory native object: " + accessory.ios);
},
(accessory: Accessory) => {
console.log("Accessory removed: " + accessory.name);
}).then(
() => console.log("searching.."),
(err) => alert(err)
);
停止搜索配件
我不确定搜索配件会消耗多少电量,但允许用户停止搜索配件可能是个好主意。
此外,实现起来也很容易,所以赶快试试吧!
this.homekit.stopSearchingForAccessories().then(() => console.log("Searching stopped"));
管理家庭:addHome
、removeHome
、renameHome
您可以为用户提供配置家庭、区域和房间(如演示应用所做的那样)的功能。以下是管理家庭的方法
添加家庭
import { prompt, PromptResult } from "ui/dialogs";
// ask the user for a name and add it to HomeKit
prompt("Name the home").then((promptResult: PromptResult) => {
if (promptResult.result) {
that.homekit.addHome(promptResult.text).then((home: Home) => {
console.log(JSON.stringify(home));
that.homes.push(home);
}, err => alert(err));
}
});
删除家庭
this.homekit.removeHome(name).then((home: Home) => {
// the returned home is the one deleted
}, err => alert(err));
重命名家庭
// ask the user for a new name, prefill the old one
prompt(`Rename home '${currentName}' to..`, currentName).then((promptResult: PromptResult) => {
if (promptResult.result) {
// since the name is unique we're using 'currentName' as an identifier
that.homekit.renameHome(currentName, promptResult.text).then((home: Home) => {
// the returned home is already updated with the new name
console.log(`Renamed ${currentName} to ${home.name}`);
}, err => alert(err));
}
});
管理区域:addZone
、removeZone
、renameZone
与家庭管理类似,所以我们只在这里展示TypeScript定义,以免让您感到厌烦
addZone(name: string, toHome: string): Promise<Zone>;
removeZone(name: string, fromHome: string): Promise<Zone>;
renameZone(oldName: string, newName: string, inHome: string): Promise<Zone>;
管理房间:addRoomToHome
、addRoomToZone
、removeRoomFromZone
、removeRoomFromHome
、renameRoom
与其他操作非常相似。唯一的区别是您只能将房间添加到已添加到家庭的区域。这很有道理,对吧?没错。因此,在操作区域时,您还需要传递家庭名称。
addRoomToHome(name: string, toHome: string): Promise<Room>;
addRoomToZone(name: string, toZone: string, inHome: string): Promise<Zone>;
removeRoomFromZone(name: string, fromZone: string, inHome: string): Promise<Zone>;
removeRoomFromHome(name: string, fromHome: string): Promise<Room>;
renameRoom(oldName: string, newName: string, inHome: string): Promise<Room>;
管理配件:addAccessoryToHome
、removeAccessoryFromHome
、assignAccessoryToRoom
、renameAccessory
现在这应该已经很熟悉了。但也有一些需要注意的事项
- 区域不能分配配件,它们仅用于将房间分组。
- 在将配件分配给房间之前,您首先需要将配件分配给家庭。这就是为什么您需要在
assignAccessoryToRoom
中传递家庭名称的原因。 - 配件一次最多只能分配给一个家庭(和一个房间)。
- 如果您想将配件分配给不同的房间,只需使用
assignAccessoryToRoom
。
addAccessoryToHome(accessoryName: string, toHome: string): Promise<Home>;
removeAccessoryFromHome(accessoryName: string, fromHome: string): Promise<Home>;
assignAccessoryToRoom(accessoryName: string, roomName: string, homeName: string): Promise<Array<Room>>;
renameAccessory(oldName: string, newName: string): Promise<Accessory>;