作为 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>' |
显然,说的很明确了,“你不能从一个非协议、非类的类型继承”。显然,字典是个泛型结构体……
那么解决思路也很明确了,创建一个类来装饰个字典或许是个不错的选择但太麻烦,那么就从协议上下手。
我们可以给字典[……]
在开发落格输入法的过程中,我就一直被一个问题所困扰,那就是当用户点击在屏幕左侧边缘时, UIButton 的 touchDown event 几乎变成了 touchUpInside 。也就是说,这两个同时发生,而当你仅按下的时候,[……]
在开发落格输入法 macOS 的过程当中,我一直被一个奇怪的问题所困扰——文本模糊。
无论我怎样调试,落格输入法的候选文字都无法达到原生文字的那样清晰和锐利。在请教了大神之后,得到的活久见经验是——上游次像素渲染 bug。
在很多平台都有类似问题,macOS 底层渲染也有这样的错误,一旦你的布局出现了小数点或者不是整数,就会导致文本渲染模糊。
那[……]
隐私是个很奇妙的东西,当你一个人的时候,它就不存在。
TenSteps
如今的互联网普遍对隐私焦虑,常常有人喊“要保护隐私”……但紧跟着就有人会说“我没什么好隐藏的”。面对这样的丧气的回复,保护隐私的倡导者们除了内心深深的无力感,还有就是迷茫了。
隐私这个东西,实际上在互联网之前就已经存在,比如法律规定不允许私自拆读他人信件——这就是对你个人隐私的保护。
在互联网之前,隐私传播需要[……]
文章原标题《如果这个输入法再无法让我维持生计,我就回家卖红薯》
人家说一个 App 想要卖的好,总得配一个动人的故事,去年一篇专访如果下个月没人买我的 App,我就得 GG扎了很多人的心——一不小心说了大实话,不少人难以接受这个现实。——人是动到了,就是角度似乎有点问题hhh
我也不想接受这个现实——但现实就是如此,双拼用户市场比我预计的还要小那么一点点,仅仅两年,落格输入法的下载量就已经[……]
cocoapods 无法更新,可能是由于本地数据库损坏造成的,我们可以直接进入 CocoaPods 本地目录里手动更新它:
|
1 2 3 |
~/.cocoapods/repos/master git pull git checkout master |
执行后再回到项目中即可正常 pod update .[……]
在 iOS 开发中,我们经常会用到 Timer 这个类,用来进行一些重复或者延迟调用。
不过,在实际的使用中,如果你是用来周期地更新 UI,则会发现 Timer 的调用经常会被其他操作阻挡导致无法正常更新 UI。
比如说在我的 HourlyMeow 项目中,自定义时钟[……]
1995.10.09 – 2018.06.03[……]