如何在 iOS 中准确地追踪【远程推送已接收】事件?

| Swift , iOS

在发送营销内容前,市场部的工作人员都会设计衡量营销效果的方案。移动互联网时代,推送消息是大多数企业常用的营销手段。 那么,如何衡量推送消息的转化率呢? 大致的计算方式: 消息接收率 = 成功接收消息的设备数量 / 消息发送量 消息查看率 = 查看消息的设备数量 / 成功接收消息的设备数量 可以看出,成功接收消息的设备数量 是必不可少的参数。所以,要衡量推送消息的转化率,必须要能够准确地追踪【推送消息已接收】事件。

如何用 Xcode 来调试 App Extension?

| iOS , Xcode , 测试

App Extensions 可以有效地扩展应用的使用场景,让用户更便捷地享用我们提供的服务。 某些 App Extensions 相对来说会比较常见,如:Home 页面的小插件(Widget)、分享、富文本推送通知等等。 越来越多的应用开始支持 App Extensions,调试 App Extension 自然必不可少。如何调试并且高效地调试就变成了一个我们需要解决的问题。 可能有朋友会说,在 Scheme 处选中 App Extension,然后直接运行就可以了。 抱歉,这样做是不行的呢!如果您也这样认为,那么 Ficow 建议您去回顾官方文档对 App Extension 的讲解。实际上,App Extension 是不可以作为可执行程序独立运行的,它只能被动地被系统启动。 现在,和 Ficow 来了解一下相关的内容吧~

App 执行后台任务(UIBackgroundTask)时崩溃,错误信息:BUG IN CLIENT OF LIBDISPATCH: Unbalanced call to dispatch_group_leave()

| iOS

应用在执行后台任务时,莫名其妙地就崩溃了。登录 Firebase 查看 Crashlytics 控制台,在 crash_info_entry_0 这个 Key 对应的 Value 处看到一个令人困惑的错误:BUG IN CLIENT OF LIBDISPATCH: Unbalanced call to dispatch_group_leave()。 查看了相关的代码,并没有调用 dispatch_group 或相关的方法。好吧,先请强大的 Google 帮帮我~ Google 的搜索结果里面有一条记录是苹果官方的开发者论坛:crash iOS 14 - Unbalanced call to dispatch_group_leave() 其中,GaelPB 的推测观点 是比较接近最终答案的(不过,不正确)。 在此,Ficow 先说明问题的成因: App 在 iOS 14 中执行后台任务时,completionHandler 被多次调用,就会导致崩溃。 这是如何调查出来的呢?问题如何解决呢?希望后文中 Ficow 的 debug 思路能够对您有帮助~

WWDC 2021 - 为你的 App 减少网络延迟

| iOS , WWDC

如今,很多App都会在加载数据的时候显示一个加载指示器(旋转菊花?)。然而,有些App经常会处于加载状态,而且加载的时间很长。如果您遇到这种App,您会选择怎么解决这种问题呢? 1. 换一个更快的网络? 2. 反馈问题,期待App团队进行改进? 3. 找到这个App的替代品,卸载这个App? 我猜,大多数人都会选择最后一个选项。如何避免咱们的App因为网络延迟太久而被用户抛弃,无疑是我们这些App开发人员要面对的一个问题。 别怕,苹果工程师给大家带来了灵丹妙药!来,和 Ficow 一起瞧瞧吧~

UIScrollView 如何自适应子视图的高度?

| Swift , iOS

如今,在开发 iOS 应用的过程中,我们经常会采用 AutoLayout 来配置页面布局。然而,UIScrollView 这个家伙好像不好驾驭。别担心,Ficow 来陪你一起驯服这只倔驴子! 只要吃透本文中的几个重要概念,我相信您以后可以游刃有余地使用 AutoLayout 来配置 UIScrollView 的布局。 如果您未曾听说或者使用过 UILayoutGuide 以及 UIScrollView 的 frameLayoutGuide 和 contentLayoutGuide 属性,理解并掌握这些内容对您也会大有裨益。

Swift 进阶 —— 泛型

| Swift , iOS

什么是泛型?《Swift 进阶》中给出的定义是:泛型编程是一种可以保持类型安全性的代码重用技术。 泛型也被成为 参数化多态。 实际上,就是让编译器帮我们生成结构重复的代码。 比如,我们要实现最大值函数用于获取两个整数、两个浮点数、两个字符串中较大的值。 如果不借助泛型,我们需要为每一种数据结构单独定义一个 max 函数: func max(_ a: Int, _ b: Int) -> Int { return a > b ? a : b } func max(_ a: Float, _ b: Float) -> Float { return a > b ? a : b } func max(_ a: String, _ b: String) -> String { return a > b ? a : b } 如果借助泛型,我们只需要定义一个 max 泛型函数,然后让每种数据结构遵循 Comparable 协议即可: func max<T>(_ x: T, _ y: T) -> T where T : Comparable { return x > y ? x : y } 泛型通常都会和协议成对出现,因为 Swift 要通过协议明确约束泛型参数的行为。上面的 max 泛型函数就是一个很好的例子,泛型 T 需要遵守 Comparable 协议。 Swift 中的泛型也非常强大,快来深入了解一下吧~

Swift 中的并发之 async/await —— WWDC 2021

| Swift , iOS , WWDC

这一次 WWDC 2021,让我们很多苹果开发者眼前一亮的是 Swift 中的并发特性:async/await,虽然这个概念并不新。 您可能会有以下疑问: 为什么 Swift 5 会被加入并发机制,我们不是有 GCD 这些任务调度框架了吗? async/await 做了什么? 新的并发特性 async/await 该怎么上手? 为什么 Swift 5 中会决定采用 async/await 并发机制? 请别急,现在来和 Ficow 一起揭晓答案吧~

Ficow 陪你看 WWDC 2021

| Swift , iOS , WWDC

苹果每年都会举行主要面向开发者的 WWDC,2021年也不例外。 然而,今年的WWDC不像以前的,更多的更新都是软件层面的,硬件层面基本没有更新。而且,软件层面有非常多的重大更新!!! 对于我们苹果开发者来说,硬件层面的更新不用那么紧张,反倒是软件层面的变动会更多地影响到我们的日常开发工作。 话不多说,我们一起来扫描一下,今年到底有些什么软件层面的更新吧! 文章内附有 WWDC 2021 完整视频列表,一起来看看吧~

命令行操作,从0到1 —— Git 常用命令

| 实用工具 , Git/Github

类似 SourceTree 这样的带有图形界面的 Git 管理工具固然好用,有时候我们还是需要使用命令行来执行一些操作。对于后端开发运维工程师来说,在命令行中管理 Git 可能更为常见。Ficow 也比较习惯了在命令行中管理 Git,所以在此梳理一份常用命令清单。如有必要,我也会持续更新这篇文章。

命令行操作,从0到1 —— 提高操作效率

| 实用工具

在 【命令行操作,从0到1 —— 基础知识】 一文中,您已经学会了一些最基本的命令行知识。 程序员是一个比较注重效率的群体,所以 Ficow 希望通过本文来帮助您提高命令行操作的效率。 本文的主要内容为:高效的键盘操作、高效的指令、高效的工具。