作为 iOS 开发者的你,肯定是知道 Promo codes 这个东西的,也就是我们常说的兑换码。(当然,作为 iOS 用户兴许你也对此不陌生)
这次,我们就来看看,这个看似无穷无尽的兑换码,到底有哪些限制。
有效期
苹果后台生成的兑换码有效期一直是一个谜,虽然官方的说法的 4 周,也就是 28 天,但实际上如果这期间你的 app 更新了,那么兑换码很可能就会失效[1]。
&nbs[……]
作为 iOS 开发者的你,肯定是知道 Promo codes 这个东西的,也就是我们常说的兑换码。(当然,作为 iOS 用户兴许你也对此不陌生)
这次,我们就来看看,这个看似无穷无尽的兑换码,到底有哪些限制。
苹果后台生成的兑换码有效期一直是一个谜,虽然官方的说法的 4 周,也就是 28 天,但实际上如果这期间你的 app 更新了,那么兑换码很可能就会失效[1]。
&nbs[……]
在使用 Swift 进行开发落格输入法时,我遇到了一个很有意思的问题——去重。
众所周知,输入法的候选在计算出来后总会有可能是重复的选项(比如码表和词库中都有某个词,也许他们编码不同,但字是一样的之类),这时候就需要去重,但又要保持候选的先后顺序不变。
如果你去网上找,那么你可能找到的是这样的:
1 2 3 4 5 |
extension Array where Element : Hashable { var unique: [Element] { return Array(Set(self)) } } |
来源:[……]
办公软件这东西,文字处理、表格编辑、还有著名的“ppt”幻灯片,毕业后我几乎就没再碰过微软系了,偶尔需要文字编辑用的也是苹果的 iWork 系列(当然写论文什么的就别想了),总之,这次我要软一次,推一下 Office 365.
其实就是微软的办公套件,各位可能还在用盗版——这次是绝佳的机会把它洗白——价格足够便宜。
我的 落格输入法 macOS 2 的中国区[……]
在两年前,我曾写过一篇名为《ios 为视障用户支持 VoiceOver》的文章,里边主要介绍了 iOS 端该如何为 VoiceOver 进行必要的支持,后来我又开发了 macOS 端的落格输入法,但很遗憾由于 macOS 自身系统 bug,第三方输入法根本无法获得 VoiceOver 焦点(主要是 10.13 及以下版本),所以我也就没有过多关注——甚至直到这款输入法整个生命周期结束也没能实现 V[……]
用 Linux 的朋友可能会对这个命令比较熟悉,它可以在脚本里快速和批量地对文本文档进行操作,比如改动某一行或者替换具体内容……
macOS 自然也是有这个命令的,但有一点不太一样,如果你执行 sed -i ,那么多半你会得到一个奇怪的报错 sed: 1: “…”: invalid command code 。
[……]
2018年11月02日 更新,切换到 DoT 一天后,所有 stubby 内置服务器运行异常缓慢,直到日常使用都难……只好放弃。
2018年11月01日 更新,使用了 5 天 DoH 后,由于目前提供此服务的服务器只有 1.1.1.1,这个地址在我这里被运营商屏蔽了。
1 2 3 4 5 6 |
PING 1.1.1.1 (1.1.1.1): 56 data bytes Request timeout for icmp_seq 0 Request timeout for icmp_seq 1 ^C --- 1.1.1.1 ping statistics --- 3 packets transmitted, 0 packets received, 100.0% packet loss |
三年前[……]
废话不多说,直接上代码。
GET:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
// 创建一个会话,这个会话可以复用 let session = URLSession(configuration: .default) // 设置URL let url = "http://127.0.0.1/api/" var UrlRequest = URLRequest(url: URL(string: url)!) // 创建一个网络任务 let task = session.dataTask(with: UrlRequest) {(data, response, error) in do { // 返回的是一个json,将返回的json转成字典r let r = try JSONSerialization.jsonObject(with: data!, options: []) as! NSDictionary print(r) } catch { // 如果连接失败就... print("无法连接到服务器") return } } // 运行此任务 task.resume() |
POST:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
// 这个session可以使用刚才创建的。 let session = URLSession(configuration: .default) // 设置URL let url = "http://127.0.0.1/api/" var request = URLRequest(url: URL(string: url)!) request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" // 设置要post的内容,字典格式 let postData = ["email":"user@xxx.com","password":"123456"] let postString = postData.compactMap({ (key, value) -> String in return "\(key)=\(value)" }).joined(separator: "&") request.httpBody = postString.data(using: .utf8) // 后面不解释了,和GET的注释一样 let task = session.dataTask(with: request) {(data, response, error) in do { let r = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers) as! NSDictionary print(r) } catch { print("无法连接到服务器") return } } task.resume() |
[……]
今天学员群里有人提了这么一个问题,为什么把特性的字典类型作为泛型类型约束的时候,就必然报错?
1 |
inheritance from non-protocol, non-class type 'Dictionary<String, Any>' |
显然,说的很明确了,“你不能从一个非协议、非类的类型继承”。显然,字典是个泛型结构体……
那么解决思路也很明确了,创建一个类来装饰个字典或许是个不错的选择但太麻烦,那么就从协议上下手。
我们可以给字典[……]