Hướng dẫn mã nguồn Telegram IOS phần 3: Các nền tảng sử dụng trong ứng dụng

226

Bài viết được sự cho phép của tác giả Lê Xuân Quỳnh

Tiếp theo bài số 2, hôm nay hãy để tôi giới thiệu các nền tảng khác được sử dụng trong Telegram.

  Stateless là gì? Stateful là gì?
  5 bài học quí giá về việc phát triển ứng dụng iOS

Tuyển ios lương cao up to 2000 USD

Logging

Logging là phần ghi lại các hoạt động của app. Module TelegramCore cung cấp giải pháp logging đơn giản:

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")

Nó hỗ trợ logging vào console và file hệ thống nếu như cờ log đang được bật. Một queue dùng để ghi lại không thuộc main-thread. redactSensitiveData có đưa dữ liệu nhạy cảm vào message log hay không.

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

Đối với các modules không phụ thuộc vào TelegramCore, dự án thiết lập bridge function ở hàm registeredLoggingFunctions tại file  Network.swift. Nó sẽ chuyển hưởng logging tới các modules khác như MtProtoKitPostbox, và TelegramApi.

Nó không phải là framework hỗ trợ logging nhiều level. Có nhiều modules đơn giản chỉ là in ra qua lệnh NSLog và print. Ví dụ khi mở 1 url nó in ra qua lệnh print, điều này có vẻ như không phải là 1 ý tưởng hay.

Crash Reporting

Có một điều hợp lý đó là Telegram không muốn sử dụng thư viện bên thứ 3 để tránh rò rỉ dữ liệu người dùng. Tôi rất ngạc nhiên khi không có 1 module nào ghi lại lịch sử crash, thậm chí là 1 module cây nhà lá vườn. Đầu tiên là họ đã thêm Hockey nhưng sau đó đã xóa bỏ nó bởi commit bdc0bb2. Có lẽ các kỹ sư đã dựa vào báo cáo của AppStore để kiểm tra về sự ổn định.

Hockey SDK bị Microsoft cho ngưng hỗ trợ App Center. Telegram sử dụng  App Center API để kiểm tra cập nhật. Không có tích hợp nào với SDK.

Disk Storage

Để hỗ trợ chia sẻ dữ liệu giữa main app, app extensions, watch app, ứng dụng lưu trữ dữ liệu tại group container folder, tên là telegram-data. Một số thành phần kế thừa vẫn sử dụng Document folder. Dưới đây là layout cây thư mục của 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

Bên cạnh việc đọc ghi trực tiếp, dự án sử dụng SQLite để lưu trữ data. 2 phần SQLite mở rộng được bật: SQLCipher để mã hóa cơ sử dữ liệu đầy đủ và FTS5 cho tìm kiếm text. Cách tiếp cận này cũng được sử dụng ở các ứng dụng khác, ví dụ  WeChat và  SignalApp.

LMDB – cây lưu trữ Btree cung cấp cho các Objective-C components: giống như  TGEmbedCoubPlayerView (trình phát nhúng bởi  coub.com), và TGMediaEditingContext chịu trách nhiệm chỉnh sửa ảnh và video trong quá trình gửi tin nhắn đa phương tiện.

Network Transport

Nhắn tin và cuộc gọi VoIP là 2 kịch bản chính cần network transport. Kết nối đáng tin cậy và cập nhật thời gian thực là những đặc điểm quan trọng của một ứng dụng nhắn tin, đó là một thách thức vì môi trường mạng global khá phức tạp. Một số thủ thuật đã được tạo ra và được áp dụng rộng rãi trong các ứng dụng nhắn tin: hybrid endpoint discovery, domain fronting… Tôi sẽ cố gắng viết nhiều hơn về chủ đề này trong các bài viết khác.

MTProto – một core protocol của Telegram, được thiết kế để hỗ trợ  multiple transport protocols. Version hiện tại của Telegram-iOS chỉ support TCP transport. Phương thức HTTP transport đã bị xóa năm 2018. Module VoIP –  libtgvoip hỗ trợ cả UDP và TCP transports.

Telegram-iOS cũng tận dụng VoIP notifications from PushKit để nhận dữ liệu qua mạng của Apple. Đó là một thủ thuật được sử dụng rộng rãi khác cho phép ứng dụng đóng gói dữ liệu trong phần tải thông báo và xử lý trong background mà không cần người dùng tương tác. Điều này là cần thiết cho các tính năng cốt lõi, giống như cập nhật tin nhắn chưa đọc, retrieving new endpoints nếu ứng dụng không thể kết nối tới backend, cập nhật location trực tuyến, etc.

Vì bất kỳ sự lạm dụng nào có thể gây ra sự cố tiêu hao pin đáng kể, Apple bắt đầu yêu cầu các ứng dụng invoke CallKit sau khi nhận được thông báo VoIP kể từ iOS SDK 13. Nhưng Telegram-iOS dường như vẫn tồn tại khỏi quy tắc mới vì nó đã nhận được quyền đặc biệt từ Apple: com.apple.developer.pushkit.unrestricted-voip. Quyền lợi tương tự cũng được tìm thấy ở ứng dụng  SignalApp.

UI Framework

Bên cạnh việc sử dụng thư viện AsyncDisplayKit để hiển thị giao diện, Telegram-iOS còn tiến xa hơn khi hoàn thiện các UIKit controllers và views. Hầu hết các thành phần của UIKit có thể tìm thấy trong dự án: NavigationControllerTabBarControllerAlertControllerActionSheetControllerNavigationBarItemListController (thay thế cho UITableViewController) vv… Cách tiếp cận này khá là hợp lý, khi bạn không nhận được sự nhất quán trong hành vi giữa các hệ điều hành IOS.

Thật buồn cười khi hầu hết các kỹ sư iOS cuối cùng sẽ học một số thủ thuật thay đổi trên UIKit. Bằng cách nào đó, việc thực hiện lại các thành phần như UINavigationController để nó hoạt động không giống như nguyên mẫu. Một trong những phần yêu thích của tôi là cách làm cho UINavigationController có thể di chuyển ngang.

Về các hiệu ứng animation của UI,  POP  là một  legacy UI components kế thừa trong Objective-C, trong khi các modules swift thường được sử dụng là CADisplayLink or CoreAnimation.

Hai thư viện Lottie, rlottie và lottie-ios, được xây dựng để hỗ trợ After Effect animations. rlottie để hỗ trợ  animated stickers định dạng thetgs của họ. Lottie-ios hỗ trợ ảnh động từ bundled resources. Có vẻ như không cần thiết sử dụng 2 thư viện này một lúc,  lottie-ios có thể thay thế bằng rlottie.

Unit Test

Ứng dụng này không có unit test.

In-App Debugging

Nhấn vào tab cài đặt 10 lần có thể hiển thị debug controller, trong đó bạn có thể thay đổi  log settings, collect logs, experimental UI settings

DebugController

Kết luận

Vậy là chúng ta đã nắm qua những thành phần chính của ứng dụng Telegram-iOS. Trong các bài tiếp theo, chúng ta sẽ nghiên cứu về MTProto Connections. Hãy theo dõi blog này và chia sẻ với nhiều người nhé. Thank for reading.

Bài viết tiếng Anh đọc ở đây: https://hubo.dev/2020-05-15-source-code-walkthrough-of-telegram-ios-part-3/

Bài viết gốc được đăng tải tại codetoanbug.com

Có thể bạn quan tâm:

Xem thêm Việc làm IT hấp dẫn trên TopDev