美文网首页码农的世界程序员技术栈
唉,我去!撸手表的心得来了

唉,我去!撸手表的心得来了

作者: 何晓杰Dev | 来源:发表于2019-02-09 13:34 被阅读225次

这篇只是简单的总结,过年期间还天天写代码的,估计不多吧[捂脸]。不得不说,在 Apple Watch 的开发中,的确踩了很多坑,也有必要总结一下,防止以后再踩。

一、InterfaceController 的命名

原则上,在 Watch 上新建 InterfaceController 时,应当使用新建向导,而且建完类后的类名不能更改,否则 storyboard 内认不出这个类,也无法绑定。如果硬要改类名的情况,改后的类名必须以 InterfaceController 为结尾,否则 storyboard 也不认。

二、简易的 Table API

Watch 上的 API 都非常的简单,WKInterfaceTable 也是非常简单的,没有 dataSource 也没有 delegate。对于绑定数据,直接使用以下代码就可以轻松搞定:

table.setNumberOfRows(list.count, withRowType: "Cell")
for i in list.indices {
    let r = table.rowController(at: i) as! RowController
    r.label.setText(list[I])
}

由于 Watch 的性能问题,尽可能不要添加太多的 rows,否则你会发现绘制时变得很卡。

同样的,对于 table 内 row 的点击处理,也非常的简单,直接覆写 func table(_ table: WKInterfaceTable, didSelectRowAt rowIndex: Int) 这个方法就可以了。

三、push controller 传值

这一点与 iOS 的处理差异非常大,iOS 内可以依自己的需要在目标 Controller 内建立变量,并且直接赋值,而在 Watch 里,有固定的做法:

pushController(withName: "InterfaceController", context: obj)
override func awake(withContext context: Any?) {
    super.awake(withContext: context)
    // 此处的 context 就是 pushController 传来的值
}

所以通常不会传一些复杂的东西,对于要传递一大堆数据的情况,必须把那些数据拼装起来,当然我个人的喜好是拼成 json 串。

四、引用第三方库

首先有一点必须明确,就是 Watch 上的程序,必须开启 bitcode,否则将无法安装在真实设备上。这也就要求被引用的库也可以开启 bitcode。有一些上古时代的老库可能就没有办法折腾了。

对于可以开启 bitcode 的库,均可以直接添加 Watch 的 Target 以使得库可以在 Watch 上使用。在将一个 for iOS 的库变为 for Watch 时,需要注意的是,在 Build Phases 内必须重新添加要编译的目标文件,新建 Target 的时候并不会带入这些文件。

另外,由于我平时喜欢使用 CodeTyphon 来进行跨平台开发,也特地说明一下,到目前为止,CodeTyphon 还无法在 Watch 上工作,因为缺少 armv7k 架构的工具链,在网上找了一圈也没有相关的资料。

五、方法过期

在 Watch 中,对 API 版本有严格的要求,比如说 sendSynchronousRequest 这类方法,在 iOS 中标记为过期但是依然可用,然而在 Watch 中,是没有这样的方法的,这就要求我们把过期的东西全部去掉。

自己的代码容易修,而第三方的代码库就没那么好运了,在实际开发中,光是修过期代码就花费了不少时间。依然用网络请求来举例子,曾经的代码是:

func request(_ url: String) -> String { ... }
thread {
    let ret = request(url)
    ...
}

而现在就要改为:

func request(_ url: String, _ callback:(String) -> Void) { ... }
request(url) { ret in
    ... 
}

涉及到此的所有代码结构都得改一下了。

六、HTTP 请求和文件下载

众所周知的,苹果一直在建议 https 请求,在 Watch 的开发中依然遇到了这样的问题,发起一个 http 请求将被拒绝,此时需要修改 Info.plist,需要注意的是,只能对 Extension 下的 plist 进行修改,加入 App Transport Security Settings 配置,若是对 Watch Target 进行修改,则会报一个配置不被支持的错误。这个错误一开始也害我误以为在 Watch 上不允许 http 请求。

另外对于文件下载,Watch 上有一些很奇怪的限制,如以下代码:

(Data(contentsOf: URL(string: url)!) as NSData).write(toFile: path, atomically: true)

看起来没毛病 ,在模拟器上也能够正常运行,但是在真机上,怎么都下载不到文件,经过尝试,在真机上需要将代码改成这样:

let req = URLRequest(url: URL(string: url)!)
let task = URLSession.shared.dataTask(with: req) { data, resp, err in
    (data! as NSData).write(toFile: path, atomically: true)
}
task.resume()

七、Dictionary 的大坑

这个问题不知是从哪里来的,经过分析感觉可能是 swift 的 bug,在解析 json 的过程中,使用以下代码:

let json = try JSONSerialization.jsonObject(with: data, options: JSONSerialization.ReadingOptions.mutableLeaves) as! Dictionary<String, Any>
let obj = json["data"] as! Dictionary<String, Any>
result.imageId = obj["imageid"] as! Int

坏就坏在最后一句代码,前面的 imageId 是 Int 类型,后面理所当然的要将 Any 转为 Int。但是这段代码在不同的情况下会产生不同的类型,经过测试有以下两种:

(lldb) po type(of: obj["imageid"])
__NSCFNumber
(lldb) po type(of: obj["imageid"])
NSTaggedPointerString

换言之,如果产生了下面那种类型,强转成 Int 就会报错。为了解决这个(不知道什么时候会发生的)问题,不得不写了一个扩展来解决:

extension Dictionary {
    
    func string(_ key: Key) -> String {
        let v = self[key]
        let ret = "\(v!)"
        return ret
    }
    
    func int(_ key: Key) -> Int {
        let v = self[key]
        let s = "\(v!)"
        var ret = 0
        if (s != "") {
            ret = Int(s)!
        }
        return ret
    }
}

然后把上面的代码改成:

result.imageId = obj.int("imageid")

八、连接真机

正常的流程是 Watch 和 iPhone 配对,然后 iPhone 插上 Mac(苹果硬件全家桶真贵!),然后手表上会提示是否信任该电脑,选择信任就可以了。

但是我当时手残了,不小心点了不信任,然后发现 xcode 怎么都没办法把 app 装到手表上,不论怎么重插都不再提示“是否信任”,这个情况需要按以下步骤进行:

1. 从 Mac 上拔下 iPhone
2. cd ~/Library/Developer/Xcode/watchOS DeviceSupport
3. rm -fr *
4.  重启手表
5. 将 iPhone 插到 Mac 上

此时在手表上就会重新出现是否信任的选项。


好了,就总结到这里吧,其实手表的开发还是挺简单的,毕竟屏幕小,那块 CPU 也不是十分强劲,做不了太多的事情,只能一切从简。

文中所述的代码均是从我的实际项目中分离而来,需要参看项目的请移步 Github,最终实现的效果就是这样啦:

watchapp.gif

相关文章

  • 唉,我去!撸手表的心得来了

    这篇只是简单的总结,过年期间还天天写代码的,估计不多吧[捂脸]。不得不说,在 Apple Watch 的开发中,的...

  • 16

    唉,感觉自己生物钟已经形成,到了点自然就很困了,早上时间差不多了,也就醒来了。我觉得这样挺好。我昨天买了一支手表,...

  • 人生不是只有体重

    “唉,唉,唉,你看,那边正在撸铁的帅哥帅不帅?” “哪个?” “穿黑色背心的那个。” “哦~看上去不错啊,身材真好...

  • 天使👼与恶魔👿

    “今天又是我值日。唉~”我满是抱怨道。当所有同学都走完后,我便“认命”般的去杂物间拿去扫把,撸起袖子就是干。忽然...

  • 小姨回来了

    今天,我的小姨回来了,爸爸去开车接我小姨,到了家之后,小姨给我了一个手表爸爸给我调那个手表,我给小姨倒水,等爸爸给...

  • 梦想的力量

    3年级时,我看上了小天才电话手表️。因此,我非让家长给我买电话手表,可无论我如何保证,父母都大摇其头。唉!只...

  • 唉,回来了

    呆子顶着一身寒气拖着破皮卷毛的灰耗子行李箱回来了。 看他那个不喜气的样子就知道他张嘴准没好事儿…… 果然,看见我的...

  • 如何学好英语口语?(手机篇)

    撸主不才,英语在学就来share经验,撸主目前在学冰岛语,英语,德语和法语。对于英语口语很有心得和经验。 我的几个...

  • 003.大家好,这里是戒客微学院,我是戒哥

    大家好,这里是戒客微学院,我是戒哥。今天和大家聊的话题是,我的戒色心得 再撸管报应就会来,报应来了那是躲也躲不掉的...

  • 流氓食荐:垂死病中惊坐起,吃喝玩乐又一年

    胖了,又胖了, 但是光吃草肯定是不行的, 最终还是把持不住去撸串了。 小金链大手表, 一天三顿全烧烤。 原始人从茹...

网友评论

    本文标题:唉,我去!撸手表的心得来了

    本文链接:https://www.haomeiwen.com/subject/gslasqtx.html