Telegram-iOS 源码分析:第三部分(Other Foundations)

版权声明
本文内容均为搬运,目的只为更方便的学习Telegram编码思维。

如需查阅原作者文章,附赠原文章机票

本章内容将继续介绍基础模块内容

日志记录(Logging)

该模块TelegramCore提供了一个简单的日志记录实现。

public final class Logger {
    private let queue = Queue(name: "org.telegram.Telegram.log", qos: .utility)
    // `false` in AppStore build
    public var logToFile: Bool
    // `false` in AppStore build
    public var logToConsole: Bool
    // `true` in AppStore build
    public var redactSensitiveData: Bool

    public static var shared: Logger

    public func log(_ tag: String, _ what: @autoclosure () -> String)
}

// for other modules
Logger.shared.log("Keychain", "couldn't get \(key) — not current")

如果开关打开,它支持在控制台打印和写入文件。用于文件写入的queue在非主线程进行。redactSensitiveData是另一个开关决定,是否在日志消息中包括敏感数据(例如具体的消息内容)。

if Logger.shared.redactSensitiveData {
    messageText = "[[redacted]]"
} else {
    messageText = message.text
}

在公开发布的版本中,仍然可以通过上面介绍的应用内调试控制器来更改设置。

对于不依赖TelegramCore的模块,项目将通过Network.swift当中设置桥函数registeredLoggingFunctions,重定向其他模块(MtProtoKitPostbox,和TelegramApi等)的记录/打印配置。

这不是一个甚至都不支持日志记录级别的理想框架。还有许多模块根本不进行日志记录,或仅通过Print/NSLog进行日志记录。在我看来,在未来或许会进一步清理。

崩溃报告

Telegram不使用第三方SDK以此来防止用户数据泄漏,这是合理的。令我感到惊讶的是,该项目没有任何内置的崩溃报告模块,甚至没有本地的崩溃报告模块。在查看提交历史之后,它确实集成了Hockey SDK,然后于今年1月通过提交bdc0bb2将其删除。工程师大概可以依赖AppStore的崩溃报告来检查稳定性问题。

Hockey SDK已被Microsoft淘汰,转而支持App Center。Telegram-iOS使用App Center API来检查更新。没有与SDK集成。

磁盘存储

为了支持main appwatch appintents app extension之间的数据共享,该项目将大多数数据存储在名为telegram-data组容器文件夹中。一些旧组件仍在使用Documents文件夹。以下是telegram-data典型的布局:

telegram-data/
|-- .tempkey  // the key for sqlcipher
|-- account-0123456789/ // data for account 0123456789
|   |-- network-stats/ // for `MTNetworkUsageManagerImpl`
|   |-- notificationsKey 
|   `-- postbox/ 
|       |-- db/
|       `-- media/ // media cache
|           |-- cache/
|           |-- short-cache/
|-- accounts-metadata/ // for `AccountManager`
|   |-- atomic-state/
|   |-- db/
|   |-- guard_db/
|   |-- media/
|   `-- spotlight/
|-- accounts-shared-data/
|-- lockState.json
|-- logs/  // log files
|-- notificationsPresentationData.json
|-- temp/
|   `-- app/
|-- widget-data/
`-- widgetPresentationData.json

除了直接读写文件外,该项目还主要SQLite用于结构化数据。启用了两个SQLite扩展:SQLCipher用于完全数据库加密;FTS5用于全文本搜索。这种方法在其他流行的即时通讯中也很流行,例如WeChatSignalApp

LMDB是基于BTree的事务键值存储,它提供了一些Objective-C组件:例如TGEmbedCoubPlayerViewcoub.com的嵌入式播放器),TGMediaEditingContext它负责在发送媒体消息时编辑照片和视频。

网络传输

消息传递和VoIP Call是需要网络传输的两个主要方案。可靠的连接性和实时更新是即时通讯的重要特征,这是一个令人着迷的挑战,因为全球网络环境相当复杂。为此发明了一些工程技巧,并在即时通讯中广泛应用,例如流量混淆,混合端点发现,域前沿等。

MTProtoTelegram的核心协议,旨在支持多种传输协议。当前版本的Telegram-iOS仅支持TCP传输。HTTP传输已于2018年删除。VoIP模块libtgvoip支持UDP和TCP传输。

Telegram-iOS还利用来自PushKitVoIP Notifications来通过Apple的网络接收数据。这是另一个广泛使用的技巧,使应用程序可以将数据封装在通知有效负载中并在后台处理数据,而无需用户进行交互。普通的APNS无法做到相同的行为。这对于某些核心功能至关重要,例如更新未读计数,在应用程序无法连接到后端时检索新端点,更新活动位置等。

由于任何滥用行为都可能导致严重的电池消耗问题,因此自iOS SDK 13以来,Apple在收到VoIP通知后开始要求应用程序必须调用CallKit。但是Telegram-iOS似乎可以从新规则中幸免,因为它获得了Apple的特别授权:com.apple.developer.pushkit.unrestricted-voip。在SignalApp中也可以找到相同的未记录权利。

UI框架

除了使用AsyncDisplayKit作为其核心UI呈现框架之外,Telegram-iOS进一步开发并重新实现了常见的UIKit控制器和视图。大多数UIKit的组件可以找到项目内的替代组件:NavigationControllerTabBarControllerAlertControllerActionSheetControllerNavigationBarItemListController(更换的UITableViewController的)等的方法是相当合理的。

题外话。有趣的是,大多数iOS工程师最终都会在UIKit上学到一些技巧。不知何故,重新实现UINavigationController之类的组件并不是一件容易的事,因为要破解原始组件。我最喜欢的细节之一是UINavigationController如何设法推送和弹出仅横向模式的控制器

关于UI属性动画,这POP是Objective-C中传统UI组件的一种,而swift模块大多在CADisplayLinkCoreAnimation上使用其自己的动画器实现。

应用程序内置了两个Lottie库rlottielottie-ios,以支持After Effects动画。rlottie主要是为动画贴纸tgs格式。Lottie-ios用于从Bundle资源加载动画文件。似乎实际上没有必要为同一件事使用两个库,lottie-ios可以用代替rlottie

单元测试

项目中基本上没有单元测试。

应用内调试

轻按10次设置可能会显示调试控制器,您可以在其中调整日志设置,收集日志,尝试实验性UI设置等。

part3-debug.jpeg

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容