AppleWatch 开发的一些知识总结
最近忙了一阵子Apple Watch 的开发。虽然Apple Watch 4马上就要发布了,但详细的中文开发资料还不是很多。我这里就不按照步骤走了,总结一下非常规的知识点以及个人理解。
静态布局
所有静态UI控件都在 Storyboard 上完成,彻底抛弃frame的概念。WatchKit 布局方式很像CSS,包括绝对布局和相对布局,支持横向排列和纵向排列,UI之间无法重叠。但可以使用 Group 处理。 比如我们去拖一个 左图片 右文字 的 Button,该如何操作呢?
1、拖一个button, 设置其 Content 为 Group 类型(默认为 Text)。
2、在该 Group 上再拖一个 Group2 ,用来容纳图片和文字,只要让该 Group2 居中,那么图片和文字就可以居中啦。
3、设置 Group2 的 Layout 为 Horizontal ,在 Group2 上拖进来一个 WKInterfaceImage 和一个 WKInterfaceLabel 即可。
具体层级关系如下图:
动态绘制
WatchKit 上的 UI 控件不多,和 UIKit 有些类似。但由于不支持frame的概念,所以很难处理根据网络数据的不同,frame 不同的问题。比如这种曲线图。
WatchKit 上没有提供 CALayer 相关的 类。但可以采用 UIBezierPath 和 CGContextRef 相结合的方法去动态绘制。绘制完成后,将画布合成为 UIImage, 然后就可以放到 WKInterfaceImage 上显示了。
需要注意的是,画布的大小要设置为屏幕尺寸的二倍(或者直接乘以 screenScale ),不然绘制出来的很模糊。
这里只摘要一小段代码示例(根据不同体重绘制不同位置的白点)
- (void)drawGraph{CGFloat graphWidth = CGRectGetWidth([WKInterfaceDevice currentDevice].screenBounds);CGFloat graphHeight = CGRectGetWidth([WKInterfaceDevice currentDevice].screenBounds);float scaleFactor = [WKInterfaceDevice currentDevice].screenScale;CGSize size = CGSizeMake(graphWidth*scaleFactor, graphHeight*scaleFactor);NSArray *positionsArray = [self transPointToValue:self.dataArray];UIGraphicsBeginImageContext(size);CGContextRef context = UIGraphicsGetCurrentContext();//绘制体重的小白点[self drawWhiteDotPath:positionsArray];/*这里你可以绘制任何东西*/UIImage *image = [UIImage imageWithCGImage:CGBitmapContextCreateImage(context)];UIGraphicsEndImageContext();[self.weightCurveImage setImage:image]; }
- (void)drawWhiteDotPath:(NSArray *)pointArray{for (NSValue *pointValue in pointArray) {UIBezierPath *dotPath = [UIBezierPath bezierPath];[[UIColor whiteColor] setStroke];[[UIColor whiteColor] setFill];[dotPath addArcWithCenter:pointValue.CGPointValue radius:5 startAngle:0 endAngle:2*M_PI clockwise:YES];dotPath.lineWidth = 1;[dotPath fill];[dotPath stroke];} }
数据交互(未激活虚拟SIM卡的情况,激活之后是否一样还待测试)
首先知道一点,在 watchOS 2.0之前,只能通过蓝牙进行数据传输。Watch上的网络请求也是交给 iPhone 去发起,然后把结果传递回来。而之后,Apple Watch 支持连接WIFI,利用 NSURLSession 可以自主发起网络请求。
1、与手机处于同一 WiFi 下,手机会把该 WiFi 共享给 Watch。
2、iPhone 和 Watch 正常连接,如果 iPhone 断开网络,Watch 也无法使用自己的WiFi。
3、iPhone 和 Watch 断开连接(iPhone关闭蓝牙),等半分钟左右,Watch 会使用自主的WiFi。
WCSession
正常连接的时候可以通过 WCSession 进行网络通信。 Watch 通过 WCSession 给 iPhone上的app 发送消息,会静默启动app。但反过来却不会。
sendMessage
为异步操作,所以涉及到更新UI的情况,注意要在主线程中进行。[session sendMessage:@{@"xxx":@"xxx"} replyHandler:^(NSDictionary<NSString *,id> * _Nonnull replyMessage) { NSDictionary *messageDict = (NSDictionary *)replyMessage; dispatch_async(dispatch_get_main_queue(), ^{//更新UI }); } errorHandler:^(NSError * _Nonnull error) {}];
官方文档说 session 的激活再要尽量早的地方,一般在 app 的
didFinishLaunchingWithOptions
进行激活,可以为此专门建一个类,作为 session 的 delegate ,这样可以避免在 AppDelegate 写太多代码,保持简洁。而 Watch 方面 Session 的激活,可以在 InterfaceController 类的awakeWithContext
方法里进行。另外,为了保持Session的稳定性,要在断开连接的时候做一下激活Session的处理。
iPhone方面:
- (void)sessionDidDeactivate:(WCSession *)session __IOS_AVAILABLE(9.3) __WATCHOS_UNAVAILABLE{//重新启动 Sessionif ([WCSession isSupported]) {WCSession *session = [WCSession defaultSession];session.delegate = self;[session activateSession];} }
Apple Watch 方面:
- (void)sessionReachabilityDidChange:(WCSession *)session{ //重新启动 Sessionif (!session.reachable) {WCSession *session = [WCSession defaultSession];session.delegate = self;[session activateSession];} }
NSURLSession
如上文提到的,当 Watch 与iPhone 断开连接,可以自主发起网络请求:
NSString *urlString = [your.host stringByAppendingString:urlString];NSMutableDictionary *headers = [NSMutableDictionary dictionary];[headers setValue:@"application/json; charset=utf-8" forKey:@"Content-Type"];[headers setValue:@"application/json" forKey:@"Accept"];NSURL *url = [NSURL URLWithString:urlString];NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];[request setHTTPMethod:your.methordType?:@"GET"];//设置 headerfor (NSString *keyString in headers.allKeys) {[request addValue:headers[keyString] forHTTPHeaderField:keyString];}//设置请求参数NSMutableDictionary *tempDcit = [[NSMutableDictionary alloc] initWithDictionary:parameters];[tempDcit setValue:@"xxxx" forKey:@"xxxx"];[request setHTTPBody:[[tempDcit dictionaryToJsonString] dataUsingEncoding:NSUTF8StringEncoding]];NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];if (@available(watchOS 4.0, *)) {configuration.waitsForConnectivity = YES;}NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:requestcompletionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {//请求结果处理}];[dataTask resume];
既然 Apple Watch 也有了网络请求,那么在开发过程中如何选择,是利用 NSURLSession自主请求还是利用 WCSession 把请求任务给手机,让手机传递请求结果呢?个人觉得最好的方案是两个都要兼容。建议对请求做一层封装过滤,如果
session.reachable
为YES,把请求交给 iPhone,否则,就由 Watch 发起请求。
Some Tips
WKCrownDelegate
通过准守 WKCrownDelegate 协议,我们可以监听表冠的旋转,实现自己的需求,比如调整数字。
参考资料:传送门
- (void)willActivate {[super willActivate];self.crownSequencer.delegate = self;[self.crownSequencer focus]; }
#pragma mark - WKCrownDelegateCGFloat crownAccumulator = 0.0; - (void)crownDidRotate:(nullable WKCrownSequencer *)crownSequencer rotationalDelta:(double)rotationalDelta API_AVAILABLE(watchos(3.0)){crownAccumulator += rotationalDelta;if (crownAccumulator > 0.1) {//让你的数字+0.1crownAccumulator = 0.0;} else if (crownAccumulator < -0.1) {//让你的数字-0.1crownAccumulator = 0.0;} }
PS:通过改变参考值 0.1 来调整表冠的灵敏度。
打包:
对于iOS,bitcode是可选的;对于watchOS,bitcode是必须的;因此,Archive 的时候要把 WatchExtension 的 bitcode 设置为 YES; 版本号和构建号要和 app 保持一致。
=======完结
AppleWatch 开发的一些知识总结相关推荐
- AppleWatch开发教程之调试程序使用帮助文档
AppleWatch开发教程之调试程序使用帮助文档 AppleWatch开发教程之调试程序 调试又被称为排错,是发现和减少程序错误的一个过程.在Xcode中进行调试的需要实现以下几个步骤: 1.添加断 ...
- AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码
AppleWatch开发教程之Watch应用对象新增内容介绍以及编写运行代码 添加Watch应用对象时新增内容介绍 Watch应用对象添加到创建的项目中后,会包含两个部分:Watch App 和 Wa ...
- Android开发必看知识,不看后悔
Android开发必看知识,不看后悔 打包为大家奉上最实用最给力的资源,不看你绝对后悔. 最强大的UI特效 奇艺高清UI界面源代码 http://www.eoeandroid.com/thread-1 ...
- 前端开发的浏览器知识
前端开发的浏览器知识 1.1 在浏览器中输入url 用户输入url,例如http://www.feng.com.其中http为协议,www.feng.com为网络地址,及指出需要的资源在哪台计算机上. ...
- java webstock 在线直播_在线教育直播开发的这些知识你知道吗?
线下教育在当代已经趋于落后了,随之而来的是大批的在线教育直播系统,许多大的互联网公司也想来分一杯羹,毕竟在线教育与线下教育相比,优势还是比较明显的,那么在线教育直播开发的相关知识您都知道多少呢? 1. ...
- OpenFOAM程序开发的基本知识(基本术语)
OpenFOAM程序开发的基本知识(基本术语) OpenFOAM程序开发的基本知识 openFOAM的基本术语 重要的环境变量: $WM_PROJECT_USER_DIR ―― OpenFOAM的用户 ...
- 尝试:Script Lab,开发模式之知识储备//SL02
前期00:深度:从 Office 365 新图标来看微软背后的设计新理念 前期01:尝试:Script Lab,快速 Office 365 开发工具 //SL01 本期02:尝试:Script Lab ...
- 前端开发之基础知识-HTML(一)
1.1 html概述和基本结构 html概述 HTML是 HyperText Mark-up Language 的首字母简写,意思是超文本标记语言,超文本指的是超链接,标记指的是标签,是一种用来制作网 ...
- Android camera(4)---Android Camera开发之基础知识篇
Android Camera开发之基础知识篇 转自:https://blog.csdn.net/feiduclear_up/article/details/51968975#jump5 概述 Andr ...
最新文章
- C# 调用WinRar解压压缩包
- python计算直角三角形顶点坐标
- 居民信息管理系统java_基于jsp的社区住户信息管理系统-JavaEE实现社区住户信息管理系统 - java项目源码...
- 一个小型的网页抓取系统的架构设计
- spring aop使用
- 前端面试题和setTimeout异步
- oracle分同步事务和异步事务,oracle的事务隔离
- matlab mysvd代码解释,关于使用SVD进行PCA主成分提取的代码问题!也是必须涉及到原理的!...
- Python并发机制的实现(一)——多进程
- linux 查看文件开头几行、末尾几行、中间几行
- Dubbo 服务 IP 注册错误踩坑经历
- spring异常+自定义以及使用
- jquery实现新浪微博的表情插件
- UltraEdit v17.00.0注册机
- 解决cmd中tomcat中文乱码问题
- 稳压二极管的原理和伏安特性
- 计算机管理里面和打印机相关的,打印机设备
- 2021技术人的百宝黑皮书
- 无线充电动牙刷PCBA单片机方案牙刷无线充底座IC芯片
- linux 脚本 expected,使用expect实现shell中scp自动输入密码
热门文章
- 将html转换为word文档的几种方式
- 根据经纬度计算指定范围内或者附近的人(java)
- xctf攻防世界 MISC高手进阶区 saleae
- 打开计算机网络自动连接,电脑网络怎么自动连接
- 【苹果家庭推送iMessage】软件安装应用程序访问HealthKit HomeKit
- 多功能网络侦查OSINT工具,FinalRecon
- IE和Outlook Express的翻译插件设计
- html img素材,html使用img标签和背景图片之间的区别
- 9月20日.周日 第一场正式的比赛:2020年CCPC网络赛
- ITS Mobile Template interpretation failed. Template does not exist