- Ứng dụng macOS có các thành phần phức tạp hơn chương trình dòng lệnh, và quản lý riêng các tài nguyên giao diện như cửa sổ và menu trong một cấu trúc tách biệt
- Trong Classic Mac OS, mã thực thi và tài nguyên được lưu trong resource fork của tệp, nhưng từ Mac OS X trở đi đã chuyển sang cấu trúc bundle
- App bundle được tổ chức xoay quanh thư mục Contents, gồm các thư mục con như MacOS·Resources·Frameworks và các tệp cốt lõi như Info.plist
- Về sau, các yếu tố như code signing·biên lai App Store·notarization được bổ sung, giúp cấu trúc này tăng cường bảo mật và tính toàn vẹn
- Cấu trúc tự chứa (app bundle) này trở thành nền tảng cốt lõi giúp đơn giản hóa việc cài đặt·cập nhật·gỡ bỏ, đồng thời nâng cao độ an toàn và hiệu quả bảo trì
Cấu trúc ứng dụng của Classic Mac OS
- Trong Mac OS thời kỳ đầu, các tài nguyên UI như cửa sổ và menu được tách khỏi tệp thực thi và lưu trong resource fork
- Ví dụ, tài nguyên của QuarkXPress 4.11 được hiển thị trong ResEdit
- Mã thực thi nằm trong tài nguyên CODE, đồng thời thông tin type và creator của tệp cũng được lưu để Finder có thể nhận diện
Cấu trúc bundle của Mac OS X
- Mac OS X đã giới thiệu cấu trúc bundle có nguồn gốc từ NeXTSTEP
- Ứng dụng có dạng một thư mục với phần mở rộng
.app, bên trong chứa thư mục Contents
- Thư mục MacOS chứa tệp thực thi của ứng dụng GUI và các công cụ dòng lệnh
- Thư mục Resources lưu các tệp tài nguyên như biểu tượng ứng dụng và thành phần GUI
- Một số ứng dụng bao gồm thư mục Frameworks để nhúng dylib (thư viện động)
- Tệp Info.plist là bắt buộc, định nghĩa tên tệp thực thi, biểu tượng, phiên bản macOS tối thiểu, loại tài liệu, số phiên bản, v.v.
- Tệp PkgInfo duy trì thông tin type·creator của Classic Mac OS nhưng không bắt buộc
- Khi ứng dụng chạy, launchd khởi động mã thực thi, còn LaunchServices và RunningBoard thực hiện quy trình khởi tạo dựa trên thông tin trong Info.plist
Bảo mật và mở rộng trên macOS
- Từ Mac OS X 10.5 Leopard (2007), Code Signature được đưa vào và thư mục
_CodeSignature được bổ sung
- Tệp CodeResources chứa code directory hash (CDHash) để xác minh tính toàn vẹn của ứng dụng
- Ứng dụng phân phối qua App Store bao gồm biên lai cửa hàng trong thư mục
_MASReceipt
- Từ năm 2018 trở đi, notarization được áp dụng, cho phép “staple” ticket do Apple cấp vào bundle thông qua tệp CodeResources
- App bundle hiện đại tự chứa các thành phần trước đây từng được cài vào thư mục hệ thống
- Thư mục Library: LaunchDaemons, LoginItems, v.v.
- Thư mục XPCServices: các dịch vụ thực thi riêng mà ứng dụng sử dụng
- Thư mục Plugins / Extensions: chức năng mở rộng của ứng dụng và App Intents
- Một số ứng dụng cũng có tệp version.plist
Lợi ích của app bundle
- Việc tích hợp mọi thành phần vào bên trong bundle giúp việc cài đặt·cập nhật·gỡ bỏ trở nên dễ dàng
- Giảm khả năng thiếu thành phần, đồng thời tăng cường bảo mật nhờ bảo vệ bằng chữ ký và notarization
- Ứng dụng App Store còn bao gồm thêm biên lai và ticket notarization để bảo đảm độ tin cậy
- Không có khác biệt về cấu trúc giữa kiến trúc Intel và Arm; tệp thực thi Mach-O được lưu dưới dạng binary universal (fat) chứa mã cho cả hai nền tảng
- Trong cùng một tệp cũng tồn tại signature tương ứng cho từng kiến trúc
Tổng quan trực quan về cấu trúc ứng dụng
- Trong sơ đồ, màu vàng nhạt biểu thị các thành phần bắt buộc hoặc có mặt trong gần như mọi ứng dụng
- Màu xanh lá là các mục chỉ có ở ứng dụng phân phối qua App Store, còn màu xanh dương biểu thị ticket notarization tùy chọn
- Ngoài ra còn có thể bao gồm các yếu tố bổ sung như workflow Automator, script, v.v.
- Nhìn chung, ứng dụng macOS đã phát triển theo hướng cấu trúc tự chứa, lấy bảo mật làm trung tâm
1 bình luận
Ý kiến Hacker News
Phần được đánh dấu màu xanh là notarisation ticket (vé công chứng), nhưng trên thực tế gần như không phải là tùy chọn
Ứng dụng không được công chứng gây quá nhiều bất tiện cho người dùng, nên rốt cuộc vẫn phải trả phí đăng ký nhà phát triển Apple $99/năm
Nếu chỉ build và chạy cho mục đích cá nhân thì không sao, nhưng nếu để phân phối thì macOS sẽ hiện cảnh báo khiến ứng dụng trông như bị hỏng
Trước đây còn có thể chạy bằng cách nhấp chuột phải, nhưng giờ phải vào cả cài đặt hệ thống mới có thể cho phép
Có thể xem ảnh chụp màn hình liên quan trong tài liệu hỗ trợ của Apple và tin tức nhà phát triển
Tôi thích triết lý bảo mật của Apple, nhưng cho rằng cơ chế công chứng cho ứng dụng ngoài App Store là bất lợi cho tất cả các bên
Tôi chưa tìm được trường hợp thực tế nào mà công chứng đã ngăn chặn được vấn đề bảo mật
Tôi từng nghĩ công chứng trên macOS đã đủ phiền, nhưng sau khi thử phân phối trên Windows thì thấy còn tệ hơn
Muốn có được sự tin cậy từ Windows Defender thì phải mua chứng chỉ, và cả công ty lẫn cá nhân đều phải trải qua xác minh danh tính chuyên sâu
Còn phải ký bằng hardware token nên chỉ một người mới có thể phát hành bản release
Thêm nữa, cơ quan cấp chứng chỉ có thể khóa khóa bất kỳ lúc nào, nên nếu bị chặn đúng lúc cần phát hành bản vá bảo mật thì sẽ rất khủng khiếp
Xét ở điểm này thì tôi thấy hệ sinh thái macOS tốt hơn nhiều
Tôi đang phát triển một ngôn ngữ lập trình có thể biên dịch sang nhiều nền tảng, và việc ký cùng công chứng hoàn toàn không phù hợp với quy trình này
Những cơ chế ký như vậy chỉ là công cụ kiểm soát, và có nguy cơ bị lạm dụng như trường hợp Epic
Nếu không thể chạy binary chưa được ký một cách hợp lý thì tôi xem nền tảng đó là đóng và sẽ không hỗ trợ
Những nền tảng đóng như iOS hay Android có thể được thay thế phần nào bằng PWA
Tuy vậy, tôi ngày càng ít tin rằng Google sẽ tiếp tục cho phép chạy ứng dụng tự ký
Tôi chỉ biết hai trường hợp Apple đã thu hồi chứng chỉ của ứng dụng ngoài App Store
Một là Research App của Facebook, hai là Screenwise Meter của Google
Cả hai đều là ứng dụng mang tính chất spyware nhắm vào thanh thiếu niên, và việc thu hồi chứng chỉ đã làm tê liệt cả các công cụ nội bộ
Sau đó có vẻ Screenwise Meter đã được đưa trở lại App Store
Bài liên quan: Wired, EFF
Khoảng một nửa số ứng dụng trong thư mục ứng dụng của tôi không được công chứng, nhưng thực tế không có vấn đề gì lớn
Sau khi công chứng, stapled ticket (vé đính kèm) là tùy chọn
Nếu không đính kèm vé thì người dùng phải kiểm tra trạng thái công chứng qua kết nối Internet
Khi phát triển AppBundler.jl, tôi có rất nhiều bất mãn với cấu trúc ứng dụng macOS
Việc ép buộc cấu trúc thư mục Frameworks nhìn thì gọn gàng, nhưng trên thực tế khiến việc bundle trở nên phiền phức, nên tôi đang lách bằng thư mục Libraries
Vấn đề lớn nhất là ký mã — phải gắn chữ ký vào mọi binary khiến tôi cảm thấy rất lãng phí
Khó mà hiểu nổi tại sao lại phải làm phức tạp như vậy trong khi chỉ cần gom hash của các tệp rồi ký một lần là đủ
Ngoài ra, việc entitlements chỉ được gắn vào binary launcher cũng kém hiệu quả
Vì tiêu chuẩn công chứng ngày càng bị siết chặt theo thời gian, nên về sau ứng dụng có thể đột nhiên không còn vượt qua được nữa
Tôi đã tham gia Apple Developer Program để ký và công chứng ứng dụng Tauri, nhưng đã thất bại suốt 3 tuần
Vì không có máy Mac nên tôi thử bằng GitHub Actions, nhưng người ta nói lần công chứng đầu tiên thường mất rất lâu
Chỉ riêng chi phí GitHub đã gần $100 mà vẫn chưa công chứng xong
Bộ phận hỗ trợ của Apple từ chối giúp vì tôi không có máy Mac và lại dùng Tauri
Quy trình xác thực API công chứng cũng đúng là ác mộng — phải tạo JWT bằng PKCS8 nhưng tài liệu gần như không có, nên tôi phải tự viết chương trình Node
Đây là trải nghiệm nhà phát triển (DX) tệ nhất mà tôi từng gặp
Họ nói cố giải quyết chuyện này mà không có phần cứng Apple đúng là lãng phí thời gian
Nhìn ảnh chụp màn hình OS đầu tiên mà tôi thấy lạnh sống lưng
Ngày xưa UI thực dụng và gọn gàng, còn giờ thì chỉ toàn góc bo tròn và biểu tượng như bong bóng, phí phạm không gian
Dù vậy, chất lượng phần cứng Mac vẫn quá tốt nên tôi chưa chuyển sang ThinkPad được
Góc bo tròn thực ra lại là một tính năng có lợi cho thị giác con người
Có nghiên cứu cho thấy các góc vuông gây mỏi mắt
Bài liên quan: Round Rects Are Everywhere
Tôi cũng không thích macOS hiện đại, nhưng ảnh chụp đó cũng không hoàn hảo
Có quá nhiều đường nét và thiếu màu sắc nên làm phân tán ánh nhìn
Cá nhân tôi thấy Aqua UI thời Leopard có sự cân bằng tốt giữa mật độ thông tin và chiều sâu thị giác
Nếu xét theo tỷ lệ pixel thì UI cũ thực ra còn chiếm nhiều không gian hơn
Với độ phân giải 5K thì MacBook Pro hiện đại hiệu quả hơn
Mac cổ điển cũng đã có các góc bo tròn nhẹ từ trước rồi
Tham khảo: Infinite Mac
Máy tính không chỉ là công cụ làm việc mà còn là công cụ mang lại niềm vui
Chỉ là UI ngày nay có cảm giác đã đi quá xa khỏi tính thực dụng
Phần lớn màn hình là những thông tin kiểu 101101 vô dụng nên khó mà gọi là thực dụng
Nói rằng launchd là bên thực thi khi chạy công cụ dòng lệnh trên macOS là sai
Trên thực tế, giống như các hệ UNIX khác, nó được thực thi bằng fork/spawn từ shell
Hệ thống bundle của NeXTSTEP đã truyền cảm hứng cho thiết kế tệp JAR của Java
Ứng dụng Power Mac trên Mac OS cổ điển lưu mã PPC trong data fork
Binary CFM-68K cũng vậy, còn thứ dùng CODE resource chỉ là mã 68K đời cũ
Tôi nhớ quãng thời gian vui vẻ khi chỉnh sửa ứng dụng bằng ResEdit ngày xưa
Việc bùng nổ quan liêu như trong sơ đồ cuối cùng không phải là tín hiệu tốt
Càng ít lý do hơn để “nâng cấp” lên macOS 26
Cấu trúc hiện tại đúng là “tiêu chuẩn” của macOS, nhưng không phải là cách duy nhất
Nếu thiết lập RPATH hợp lý thì vẫn có thể đặt thư viện trong các thư mục con tùy ý mà vẫn vượt qua công chứng
Ví dụ đường dẫn AppName.App/Contents/Libraries cũng hoạt động
Tuy vậy, lợi ích thực tế của cách này gần như không có, và trong khoảng 100 ứng dụng trên hệ thống của tôi thì không có cái nào dùng thư mục /Libraries
Thay vì .dylib thì bắt buộc phải dùng định dạng .framework, và đây là quy tắc không được tài liệu hóa
Khi gửi lên có thể bị hệ thống tự động phát hiện và từ chối