百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

Apple Watch应用开发经验谈:我遇到的那些坑

zhezhongyun 2025-07-23 19:23 32 浏览

【编者按】本文作者张忠良是滴答清单Apple Watch版应用的开发工程师,他用了一周的时间使用纯Objective-C语言完成了Apple Watch版滴答清单应用的开发工作。在这里,他从开发角度阐述了个人对于Apple Watch的理解,以及Apple Watch应用开发过程的经验心得,适合对iOS开发有一定了解的同学。

首先,开发Apple Watch应用必须掌握WatchKit Framework,这是Apple专门为Apple Watch开发而推出的一套新框架。这套框架中所有的类都是“WK”开头的,包括视图控制器类WKInterfaceController、
WKUserNotificationInterfaceController,其他UI元素类比如WKInterfaceGroup、WKInterfaceTable、WKInterfaceLabel、WKInterfaceButton等。具体用法就不在这里赘述了,想要系统地学习WatchKit可以阅读Chun Tips的《走进WatchKit Framework》。

不过,我个人还是强烈建议大家有时间最好还是仔细看一遍官方原版文档,在帮助你更好地理解API来进行开发的同时,还能从一定程度上降低产生bug的几率。

滴答清单Apple Watch版本的开发基本上还是比较顺利的,有设计师和产品经理洒下的血和泪,本人差不多搞了一周,目前应用已经完成上线。在此,具体的开发过程就不详述了,无非是UI搭建和逻辑处理。简单讲几个开发中需要注意的点,希望对大家有所帮助。

  • 从技术上讲,WatchKit App类似于之前iOS 8上新推出的App Extension(应用扩展),比如Today Extension(今天扩展)和Share Extension(分享扩展)。只要你对iOS开发有一定经验,UI的搭建相对是比较容易的。重点在于如何让iPhone和Apple Watch上的数据同步,这时候问题来了,how?

请看:

-(NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier;

iOS 8之后,NSFileManager中有了这么个方法,假设你的应用已经支持了App Group(稍后会介绍),那么你肯定也有了groupIdentifier,调用这个方法会返回一个本地文件目录的URL。简单讲它就是一个共享文件夹,任何应用或者扩展,只要支持App group并拥有相同的Group ID,都对它有读写权限,这样一来数据同步就不是问题了。想详细学习这个的可以阅读《iOS 8 Extensions》,我只能说看了这个你不懂也难!不过,还是推荐大家阅读Apple官方文档,一样的道理,原版的才是最好的。

虽然数据是能够同步了,但是我如何在Apple Watch上知道iPhone上刚刚创建了一条新任务呢?不用想了,造轮子的成本又高且容易出问题,这里推荐MMWormhole,它是一个比较成熟稳定的第三方开源库,用在App Group内的通信,非常方便好用。原理就不讲了,有需要的同学可以去下载研究一下。

  • 搭建UI的时候你会发现Apple Watch并不支持AutoLayout(如果你还在手动布局,不要挣扎了孩子,好好学习AutoLayout),那么该怎么办?难道只能纯代码布局了么?

Apple当然不会这么土,WatchKit里有个类叫做WKInterfaceGroup,乍一看像是UIView,但是这货其实是用来布局的。从Storyboard中拉一个WKInterfaceGroup出来,在属性检查器(Attributes Inspector)中有个Layout属性,通过设置成Horizontal或Vertical,就可以让这个group下所有的子视图水平排列或竖直排列。再结合AutoLayout的知识,就可以轻松满足设计师大人的任何非人类要求啦。

  • WatchKit中的WKInterfaceTable不同于UITableView,没有dataSource和delegate,只能通过主动方式填充并展现数据。对应每一种不同类型的cell,都需要为它构造一个rowController(继承自NSObject),这个rowController负责往这种类型的row中填充需要展现的内容。

方法如下:

-(id)rowControllerAtIndex:(NSInteger)index;

通过调用这个方法得到指定行的rowController,再调用这个rowController的自定义方法来进行渲染。例如:

- (void)configureRowWithDataModel:(id)dataModel;

另外,如果要插入行和删除行,则要在上述操作之前先调用:

-(void)insertRowsAtIndexes:(NSIndexSet *)rows withRowType:(NSString *)rowType;
-(void)deleteRowsAtIndexes:(NSIndexSet *)rows;

到这里一切顺利,但不要太开心,Apple在这里挖了个大坑,请大家千万要踩进去!

我们在iOS开发中如果要刷新UITableView,只要更新数据源后再调用reloadData方法就可以。但是就像之前说的,WKInterfaceTable并没有主动刷新数据的方法,只能通过调用 [table setRowTypes:nil] 方法先清除所有数据,再用新数据源重新填充一遍。仅仅是这样就算了,还有更凶残的。

假设你现在视图控制器A中,然后被push到了视图控制器B,那么如果你在B中刷新A中的WKInterfaceTable是没有用的。但是不是完全没用,经过多次测试,我发现,数据源确实是被更新了,但是界面上的内容并没有刷新。也就是说,数据源和界面没有保持一致。翻遍官方文档和各大技术论坛,都没有找到解决方案,好不容易在开发者论坛发现这似乎是Apple的一个bug。

暂时的解决方法是,在需要刷新的时候记录一个标记位,然后在willActivate的时候根据这个标记位进行延时刷新。一个很明显的副作用就是刷新时会产生跳动,相信之后的版本Apple应该会修复这个问题。

再谈几点个人体会:

个人觉得不管是对Apple Watch持有乐观期望或是悲观态度,都只是针对智能手表这个新生平台而非产品本身。我相信任何一个挑剔的人都没办法从这个艺术品里挑出什么刺来。Apple在预售开始当天就不得不延迟了发货时间就很好的说明了它的魅力。

也许你们会说这是因为人们普遍会对新鲜事物产生好奇并积极关注它,并不完全是因为它很优秀,但是我们不得不承认,Apple Watch正在冲击智能手表平台甚至整个生态圈。健康监测、远程控制、移动支付,像这些操作成本小、周期短、时效性高的任务如果全都能托付给它,那我们的生活是不是会变得更加简单?

就拿滴答清单来说,一开始开发Apple Watch版本想到的就是加强提醒。手机放在兜里或者放在一边的时候,正好有一条任务来了,很可能没接到(我自己就经常遇这种情况),等想起来去查看手机的时候已经晚了。和手机不一样,Apple Watch戴在手上几乎不会出现人机分离,任务提醒也不容易被miss掉。

所以我们比较看重的是它在移动场景中表现出来的优势:解放双手,随时随地。手机也很方便,但也不会有人总是拿着手机吧,一旦手机不在手上的时候,很多事情就没法处理。虽然Apple Watch屏幕比较小,但某些场景下进行操作的时候会简便很多。

未来规划的话,也会主要从Apple Watch本身的优势出发,结合我们产品的一些特性。当前我们开发的Apple Watch应用,就像精简版的手机应用,只是加强了辅助功能。以后可能会尝试做一些跟手机应用不一样的东西,Apple Watch本身有一些强大的功能,比如监测用户的心率等数据,我们可能会根据这些数据做一些实时的智能提醒,当然都还只是些想法,有待检验。

CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面,如果您有想分享的技术、观点,可通过电子邮件(tangxy#csdn.net,请把#改成@)投稿。

第一时间掌握最新移动开发相关信息和技术,请关注mobilehub公众微信号(ID: mobilehub)。

相关推荐

Python入门学习记录之一:变量_python怎么用变量

写这个,主要是对自己学习python知识的一个总结,也是加深自己的印象。变量(英文:variable),也叫标识符。在python中,变量的命名规则有以下三点:>变量名只能包含字母、数字和下划线...

python变量命名规则——来自小白的总结

python是一个动态编译类编程语言,所以程序在运行前不需要如C语言的先行编译动作,因此也只有在程序运行过程中才能发现程序的问题。基于此,python的变量就有一定的命名规范。python作为当前热门...

Python入门学习教程:第 2 章 变量与数据类型

2.1什么是变量?在编程中,变量就像一个存放数据的容器,它可以存储各种信息,并且这些信息可以被读取和修改。想象一下,变量就如同我们生活中的盒子,你可以把东西放进去,也可以随时拿出来看看,甚至可以换成...

绘制学术论文中的“三线表”具体指导

在科研过程中,大家用到最多的可能就是“三线表”。“三线表”,一般主要由三条横线构成,当然在变量名栏里也可以拆分单元格,出现更多的线。更重要的是,“三线表”也是一种数据记录规范,以“三线表”形式记录的数...

Python基础语法知识--变量和数据类型

学习Python中的变量和数据类型至关重要,因为它们构成了Python编程的基石。以下是帮助您了解Python中的变量和数据类型的分步指南:1.变量:变量在Python中用于存储数据值。它们充...

一文搞懂 Python 中的所有标点符号

反引号`无任何作用。传说Python3中它被移除是因为和单引号字符'太相似。波浪号~(按位取反符号)~被称为取反或补码运算符。它放在我们想要取反的对象前面。如果放在一个整数n...

Python变量类型和运算符_python中变量的含义

别再被小名词坑哭了:Python新手常犯的那些隐蔽错误,我用同事的真实bug拆给你看我记得有一次和同事张姐一起追查一个看似随机崩溃的脚本,最后发现罪魁祸首竟然是她把变量命名成了list。说实话...

从零开始:深入剖析 Spring Boot3 中配置文件的加载顺序

在当今的互联网软件开发领域,SpringBoot无疑是最为热门和广泛应用的框架之一。它以其强大的功能、便捷的开发体验,极大地提升了开发效率,成为众多开发者构建Web应用程序的首选。而在Spr...

Python中下划线 ‘_’ 的用法,你知道几种

Python中下划线()是一个有特殊含义和用途的符号,它可以用来表示以下几种情况:1在解释器中,下划线(_)表示上一个表达式的值,可以用来进行快速计算或测试。例如:>>>2+...

解锁Shell编程:变量_shell $变量

引言:开启Shell编程大门Shell作为用户与Linux内核之间的桥梁,为我们提供了强大的命令行交互方式。它不仅能执行简单的文件操作、进程管理,还能通过编写脚本实现复杂的自动化任务。无论是...

一文学会Python的变量命名规则!_python的变量命名有哪些要求

目录1.变量的命名原则3.内置函数尽量不要做变量4.删除变量和垃圾回收机制5.结语1.变量的命名原则①由英文字母、_(下划线)、或中文开头②变量名称只能由英文字母、数字、下画线或中文字所组成。③英文字...

更可靠的Rust-语法篇-区分语句/表达式,略览if/loop/while/for

src/main.rs://函数定义fnadd(a:i32,b:i32)->i32{a+b//末尾表达式}fnmain(){leta:i3...

C++第五课:变量的命名规则_c++中变量的命名规则

变量的命名不是想怎么起就怎么起的,而是有一套固定的规则的。具体规则:1.名字要合法:变量名必须是由字母、数字或下划线组成。例如:a,a1,a_1。2.开头不能是数字。例如:可以a1,但不能起1a。3....

Rust编程-核心篇-不安全编程_rust安全性

Unsafe的必要性Rust的所有权系统和类型系统为我们提供了强大的安全保障,但在某些情况下,我们需要突破这些限制来:与C代码交互实现底层系统编程优化性能关键代码实现某些编译器无法验证的安全操作Rus...

探秘 Python 内存管理:背后的神奇机制

在编程的世界里,内存管理就如同幕后的精密操控者,确保程序的高效运行。Python作为一种广泛使用的编程语言,其内存管理机制既巧妙又复杂,为开发者们提供了便利的同时,也展现了强大的底层控制能力。一、P...