2017-07-23 | code

Swift 十日游

上周二接了个新活,写 iOS~ 虽然很久前就搞过黑苹果,看 oc 的书,不过都是折腾,以玩为主。这次的任务是个小应用,非常简单,准备用 swift 搞定。

需求

需求比较简单,一个登录页面,成功跳转制定 web 界面。值得一提的东西也就是一个 js 与native 之间调用,和接入第三方 objc 的车牌识别库。

大概功能如下:

  • 登录界面
  • 车牌识别
  • js 调用
  • objc lib 使用

开发

Swift

swift 和 kotlin 这两个语言还是有很多相似之处的,虽然一时不能掌握精髓,但是写出来个能跑得应用还是没问题的。有个网站可以简单看下 swift-is-like-kotlin.

写 swift 的大部分时间都在吐槽 xcode… 真是难用。快捷键不熟是一个原因,不过我认为 xcode 难用才是最主要的。下了个 AppCode 缓解下,然而苹果可视化操作又搞得太多了,基本不可能不用 xcode。写个功能搜 stackoverflow 不如直接搜 YouTube。

还有个东西比较烦人

1
2
3
4
var name: String!
...
print("my name is \(name)")
print("my name is \(name!)")

第一个输出会给 name 包装一层 Optional,不是很懂,我已经那么清楚的写了 name 不为空,为啥用的时候还要我再强调一次?怕异常吗?

网络请求

iOS 这边使用网络不用声明权限,但是默认限制使用非 https 接口,要自己手动把 http 加入可信列表,如果有条件一定要上 https 啊。

搜了一下,使用最多的请求库是 Alamofire。当时没找到使用广泛的类似 Retrofit 的框架(主要就三个接口,就没继续找),不过刚刚又搜了下好像有个叫 Moya 的东西,用到再看吧。

在写 token 过期重试的逻辑时又看到委托代理,最初接触这东西时真是一点概念都没有,回头再看只能感慨时光飞逝。好吧,只要实现 RequestAdapterRequestRetrier 即可,一个为所有请求添加 token , 一个控制失败重试。

js & native

这边和 Android 几乎一样,有两种方法可以实现。

  • 重写 shouldStartLoadWith 拦截 URL
  • 使用 JavaScriptCore 向 WebView 注入 js 对象

拦截 URL 就不说了,不喜欢,感觉很难用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// JsActionDelegate.swift
@objc protocol JsActionDelegate: JSExport {
func xxx()
func getXXX() -> String
}

// PlateScanJsBridge.swift
@objc class JsBridgeImpl: NSObject, JsActionDelegate {
func xxx() {
// do what you want to do
}

func getXXX() -> String {
return "what you want to return"
}
}

// ViewController
let model = JsBridgeImpl()
self.getJsContext().setObject(model, forKeyedSubscript: "ObjectNameForJS" as NSCopying & NSObjectProtocol)

private func getJsContext() -> JSContext {
return self.webview.value(forKeyPath:
"documentView.webView.mainFrame.javaScriptContext"
) as! JSContext
}

结论: @JsBridge 万岁!注解大法万岁!

objc library 调用

swift 与 objc 之间的调用我感觉已经很方便了,只要添加一个 Bridge.h 头文件即可,也可能和我的使用场景并不复杂有关。

写到这部分时遇到一个困扰了我一天的问题,EXC_BAD_ACCESS。随便搜一下大概是访问错误内存,常见于对象提前释放,偶现。我也是哭了,最后一次写 free()应该是大二学 C++ 时… 于是开始了漫长的调试。出问题的代码正是 swift 调用 oc 的位置,还包含好几个 oc 的类型强转在 swift 不能使用。因为不是非常了解这两个语言,起初怀疑是参数对象被提前释放,这个垃圾第三方库传了一堆参数,给的 demo 代码也乱的一比,浪费了好久。最后查出的结果是 oc 函数内部取图片像素时越界,我………

发布

申请证书ing,苹果爸爸限制真多

最后

好久没有这样玩过一个新的东西了,果然瞎折腾才是最好玩的。