Skip to content
Back to Blog
informational

PLIST là gì? Định dạng Property List của Apple

2026-05-17 9 min read

Câu trả lời ngắn gọn: Một 'thùng chứa' có cấu trúc cho dữ liệu ứng dụng

Tệp PLIST—viết tắt của Property List—là định dạng mặc định của Apple để lưu trữ các cài đặt cấu hình, tùy chọn và dữ liệu tuần tự hóa trên toàn bộ hệ sinh thái của hãng: macOS, iOS, iPadOS, watchOS và tvOS. Nguồn gốc của nó kéo dài từ NeXTSTEP vào cuối những năm 1980, và nó vẫn là xương sống cho cách các ứng dụng của bạn ghi nhớ lựa chọn của bạn, cách các dịch vụ hệ thống tải cấu hình của chúng, và cách các dự án Xcode mô tả những gì cần xây dựng. Bạn có hàng trăm tệp PLIST trên máy Mac của mình ngay bây giờ, dù bạn có nhận ra hay không. Mở Terminal và chạy lệnh `ls ~/Library/Preferences/`. Bạn sẽ thấy một danh sách dài các tệp như `com.apple.finder.plist`, `com.apple.dock.plist`, và nhiều tệp khác nữa—hầu như mỗi ứng dụng bạn từng sử dụng đều có một tệp. Những tệp đơn giản này chính là thứ cho Finder biết độ rộng của thanh bên (sidebar) của bạn, cho Dock biết các biểu tượng của bạn nằm ở đâu, và nhắc Safari nhớ những tab nào đang mở khi bạn thoát lần cuối. Định dạng này hỗ trợ một tập hợp nhỏ, cố định các kiểu dữ liệu: chuỗi (strings), số nguyên (integers), số thực dấu phẩy động (floating-point numbers), boolean, ngày tháng (dates), dữ liệu nhị phân (Data), mảng (arrays) và từ điển (dictionaries). Đó là toàn bộ danh sách. Không có kiểu tùy chỉnh, không kế thừa và không có lược đồ. Đây không phải là một sự bỏ sót; đó là một lựa chọn thiết kế có chủ ý. Apple cần một định dạng mà hệ điều hành có thể đọc và ghi với chi phí tối thiểu, và đủ đơn giản để tồn tại một chỉnh sửa thủ công mà không làm hỏng ngay lập tức trạng thái của ứng dụng.

XML so với Binary so với JSON: Ba 'hương vị' của cùng một định dạng

Mặc dù chỉ có một định dạng PLIST, nhưng nó lại có ba kiểu mã hóa khác nhau. Nhầm lẫn giữa chúng là một nguyên nhân phổ biến gây bối rối. Đầu tiên là **XML PLIST**, phiên bản dễ đọc cho con người. Mở một tệp bằng trình soạn thảo văn bản và bạn sẽ thấy một khai báo DOCTYPE trỏ đến `http://www.apple.com/DTDs/PropertyList-1.0.dtd`, theo sau là một biển các thẻ lồng nhau: `<dict>`, `<key>`, `<string>`, `<integer>`, `<true/>`. Xcode sử dụng định dạng này cho các tệp dự án của nó (`project.pbxproj` là một biến thể), và đây là thứ bạn muốn khi xuất cài đặt để sao lưu hoặc kiểm tra. Nhược điểm rõ ràng là sự dài dòng. Một từ điển đơn giản với 20 khóa có thể dễ dàng trải dài trên 150 dòng. Để đạt hiệu suất, macOS hầu như luôn sử dụng **Binary PLIST** (bplist) khi ghi tệp vào đĩa. Khi một ứng dụng lưu tùy chọn của nó, nó thường ghi một tệp bắt đầu bằng các byte 'magic' `bplist00`. Định dạng này nhỏ gọn hơn đáng kể và phân tích cú pháp nhanh hơn nhiều so với phiên bản XML của nó. Tệp XML 150 dòng đó có thể thu gọn chỉ còn 400 byte ở dạng nhị phân. Đánh đổi là bạn không thể đọc các tệp PLIST nhị phân trong một trình soạn thảo văn bản tiêu chuẩn; chúng trông giống như các ký tự bị xáo trộn. Cuối cùng, có **JSON PLIST**, một tùy chọn mới hơn được hỗ trợ từ macOS 10.7. Nó sử dụng cú pháp JSON tiêu chuẩn, nhưng vẫn bị giới hạn trong các kiểu dữ liệu PLIST cốt lõi. Kiểu này hơi khác lạ. JSON không phân biệt tự nhiên số nguyên với số thực dấu phẩy động hoặc không có kiểu Date chuyên dụng, điều này tạo ra một số hạn chế tinh tế. Bạn sẽ hiếm khi thấy các công cụ của Apple tự tạo ra JSON PLIST; chúng chủ yếu xuất hiện khi các công cụ xây dựng của bên thứ ba hoặc các pipeline CI đang tạo tệp cấu hình. May mắn thay, bạn có thể dễ dàng chuyển đổi giữa cả ba định dạng này bằng công cụ dòng lệnh `plutil` tích hợp sẵn của Apple. Một lệnh như `plutil -convert xml1 com.apple.dock.plist -o dock_readable.plist` sẽ cung cấp cho bạn một bản sao dễ đọc của các tùy chọn Dock của bạn mà không làm thay đổi tệp nhị phân gốc.

Các tệp PLIST nằm ở đâu và chúng kiểm soát điều gì

Biết nơi tìm các tệp PLIST là một nửa cuộc chiến khi bạn đang khắc phục sự cố một ứng dụng gặp trục trặc hoặc di chuyển cài đặt sang một máy mới. Chúng nằm ở một vài vị trí dễ đoán. Các cài đặt ứng dụng cá nhân của bạn được lưu trữ trong `~/Library/Preferences/`. Đây là nơi bố cục Dock tùy chỉnh, giao diện màu sắc Terminal và các phím tắt Xcode của bạn cư trú, tất cả đều gắn liền với tài khoản người dùng cụ thể của bạn. Tên tệp tuân theo lược đồ đặt tên DNS ngược, như `com.apple.Terminal.plist` hoặc `com.googlecode.iterm2.plist`. Ngược lại, các cài đặt áp dụng cho mọi người dùng trên máy Mac được tìm thấy trong `/Library/Preferences/`. Những tệp này kiểm soát các hành vi trên toàn hệ thống như cấu hình mạng và múi giờ, và chúng thường yêu cầu quyền quản trị để sửa đổi. PLIST không chỉ lưu trữ các tùy chọn; chúng còn điều khiển hệ thống tự động hóa của macOS. Các tệp trong `/Library/LaunchAgents/`, `/Library/LaunchDaemons/` và các phiên bản `~/Library/` dành riêng cho người dùng là những gì định nghĩa các dịch vụ nền và các tác vụ theo lịch trình. Một LaunchDaemon PLIST cho dịch vụ `launchctl` biết tệp thực thi nào cần chạy, đối số nào cần truyền, có nên khởi động lại khi gặp sự cố hay không và lịch trình của nó. Có lẽ quan trọng nhất trong số đó là tệp `Info.plist` nằm gọn bên trong mỗi gói `.app`. Nhấp chuột phải vào bất kỳ ứng dụng nào trong Finder, chọn Show Package Contents, và điều hướng đến `Contents/Info.plist` để xem nó. Tệp này là thẻ căn cước chính thức của ứng dụng, khai báo định danh gói (bundle identifier), phiên bản hệ điều hành tối thiểu, khả năng phần cứng yêu cầu, lược đồ URL và các quyền mà nó cần (như truy cập camera hoặc microphone). Trên iOS, `Info.plist` là thứ mà App Store và bản thân hệ điều hành sử dụng để quyết định xem ứng dụng của bạn có thể chạy trên một thiết bị cụ thể hay không. Một lời cảnh báo quan trọng: nếu bạn định chỉnh sửa một tệp trong `~/Library/Preferences/`, hãy luôn thoát ứng dụng tương ứng trước. Đọc một tệp khi ứng dụng đang chạy thì không sao, nhưng nếu bạn ghi các thay đổi, ứng dụng có thể sẽ ghi đè chúng vào lần tiếp theo nó lưu trạng thái. Thoát ứng dụng, thực hiện chỉnh sửa của bạn, sau đó khởi chạy lại.

Đọc và chỉnh sửa tệp PLIST: Các lựa chọn thực tế của bạn

Apple cung cấp một bộ công cụ đầy đủ để đọc và sửa đổi các tệp PLIST, từ các giao diện đồ họa bóng bẩy đến các tiện ích dòng lệnh mạnh mẽ. Đối với hầu hết các nhà phát triển, **trình chỉnh sửa PLIST tích hợp của Xcode** là nơi tốt nhất để bắt đầu. Nó mở bất kỳ tệp PLIST nào trong chế độ xem cây có cấu trúc với khả năng chỉnh sửa nhận biết kiểu dữ liệu: bạn có các ô chọn cho boolean, bộ chọn ngày cho giá trị Date và các mảng, từ điển có thể mở rộng gọn gàng. Bạn có thể thêm, xóa và sắp xếp lại các khóa mà không cần chạm vào XML thô. Đây là quy trình làm việc tiêu chuẩn, được chấp thuận để chỉnh sửa các tệp `Info.plist` và entitlement. Đối với script và tự động hóa, **công cụ dòng lệnh `plutil`** là không thể thiếu. Nó đi kèm với macOS và là một công cụ mạnh mẽ để xác thực, chuyển đổi và chỉnh sửa cấp độ khóa. Lệnh `plutil -lint myfile.plist` nhanh chóng kiểm tra lỗi cú pháp, trong khi một lệnh như `plutil -replace NSHighResolutionCapable -bool YES MyApp.app/Contents/Info.plist` có thể đặt một khóa duy nhất mà không cần mở trình chỉnh sửa. Đây là công cụ bắt buộc phải có cho các script shell và pipeline CI/CD. Khi bạn muốn thay đổi tùy chọn người dùng, **lệnh `defaults`** là công cụ phù hợp cho công việc. Bạn có thể đọc một cài đặt hiện tại bằng `defaults read com.apple.finder ShowPathbar` hoặc thay đổi nó bằng `defaults write com.apple.finder ShowPathbar -bool TRUE`. Đây chính xác là lý do tại sao rất nhiều tùy chỉnh dành cho 'người dùng nâng cao' của macOS được chia sẻ dưới dạng các lệnh `defaults write` một dòng đơn giản. Đôi khi bạn cần nhiều sức mạnh hơn. **Các trình chỉnh sửa của bên thứ ba** như PlistEdit Pro (khoảng $12 trên Mac App Store tính đến năm 2025) bổ sung các tính năng mà Xcode thiếu, chẳng hạn như so sánh song song, chỉnh sửa trực tiếp PLIST nhị phân mà không cần chuyển đổi và các thao tác hàng loạt. Nếu bạn thấy mình phải vật lộn với PLIST hàng ngày, một công cụ chuyên dụng là một khoản đầu tư thông minh. Còn về một **trình soạn thảo văn bản** đơn giản thì sao? Nó hoạt động hoàn hảo cho XML PLIST, nhưng sẽ làm hỏng các tệp nhị phân. Nếu bạn mở một tệp nhị phân trong VS Code hoặc BBEdit, bạn phải chuyển đổi nó sang XML trước bằng `plutil -convert xml1`. Sau khi chỉnh sửa, hãy chuyển đổi nó trở lại dạng nhị phân bằng `plutil -convert binary1` trước khi hệ thống có thể sử dụng nó.

Chuyển đổi tệp PLIST: Những gì CocoConvert có thể và không thể làm

CocoConvert được xây dựng để xử lý các tình huống chuyển đổi PLIST phổ biến nhất mà mọi người gặp phải trên web: chuyển đổi XML PLIST sang JSON, biến JSON thành XML PLIST và giải mã các tệp PLIST nhị phân thành XML dễ đọc mà không cần công cụ dành cho nhà phát triển. Đối với chuyển đổi XML sang JSON, CocoConvert ánh xạ các kiểu dữ liệu PLIST sang các kiểu tương đương trong JSON. Chuỗi, số nguyên, mảng và từ điển chuyển đổi sạch sẽ. Boolean trở thành `true` và `false` trong JSON. Ngày tháng được tuần tự hóa thành chuỗi ISO 8601 tiêu chuẩn (ví dụ: `2024-11-03T14:22:00Z`). Bất kỳ dữ liệu nhị phân nào từ các phần tử `<data>` đều được mã hóa base64 trong đầu ra, điều này bảo toàn nội dung hoàn hảo nhưng có nghĩa là các trường cụ thể đó trong JSON sẽ không dễ đọc đối với con người. Tính năng chuyển đổi nhị phân sang XML đặc biệt hữu ích. Nếu bạn đã từng xuất một bản sao lưu tùy chọn từ iPhone bằng một công cụ của bên thứ ba, CocoConvert có thể phân tích tệp `bplist` thu được và tạo ra một XML PLIST dễ đọc, cho phép bạn kiểm tra nội dung của nó mà không cần cài đặt Xcode trên máy của mình. Chúng tôi cũng cần nói rõ về những gì CocoConvert không thể làm: nó không thể chuyển đổi các tệp PLIST trở lại định dạng nhị phân. Việc tạo ra một PLIST nhị phân yêu cầu xây dựng các bảng bù đắp cấp độ byte chính xác, một nhiệm vụ đơn giản đối với các thư viện gốc của Apple nhưng rất khó để triển khai chính xác trong một dịch vụ web. Nếu bạn cần ghi một PLIST nhị phân đã sửa đổi trở lại thiết bị—ví dụ, để khôi phục các tùy chọn iPhone đã chỉnh sửa—bạn phải sử dụng `plutil` trên máy Mac hoặc một trình chỉnh sửa gốc như PlistEdit Pro. Mặc dù macOS thường có thể đọc một tệp XML ở nơi dự kiến có tệp nhị phân, một số ứng dụng rất nghiêm ngặt và sẽ từ chối hoặc bỏ qua phiên bản XML. CocoConvert cũng xác thực cấu trúc, không phải ngữ nghĩa. Một PLIST có định danh gói (bundle identifier) bị lỗi hoặc phiên bản hệ điều hành không hợp lệ vẫn sẽ chuyển đổi tốt, bởi vì từ góc độ định dạng tệp, nó hợp lệ. Đó là những vấn đề ở cấp độ ứng dụng mà một công cụ chuyển đổi định dạng không thể chẩn đoán.

Các vấn đề PLIST thường gặp và cách chẩn đoán chúng

Hỏng PLIST hiếm khi xảy ra, nhưng đó là một tình huống khắc phục sự cố macOS cực kỳ khó chịu. Các triệu chứng—một ứng dụng không khởi chạy, tùy chọn bị đặt lại mỗi khi khởi động lại, một dịch vụ hệ thống âm thầm thất bại—hiếm khi chỉ thẳng đến một tệp cụ thể. Nguyên nhân thường xuyên nhất là **hỏng do ghi không đúng cách**. Nếu macOS gặp sự cố hoặc mất điện khi một ứng dụng đang lưu cài đặt của nó, tệp PLIST trên đĩa có thể bị cắt ngắn hoặc bị xáo trộn. Bước chẩn đoán đầu tiên của bạn nên là `plutil -lint ~/Library/Preferences/com.example.app.plist`. Một tệp lành mạnh sẽ trả về `OK`; một tệp bị hỏng sẽ báo lỗi phân tích cú pháp, thường kèm theo số dòng hoặc bù đắp byte hữu ích. **Các vấn đề về quyền (Permission)** đứng thứ hai. Một tệp PLIST trong thư mục `~/Library/Preferences/` của người dùng mà bằng cách nào đó thuộc sở hữu của `root` sẽ khiến một ứng dụng âm thầm quay về cài đặt mặc định của nó mỗi lần khởi chạy. Kiểm tra quyền sở hữu bằng `ls -l ~/Library/Preferences/com.example.app.plist`—chủ sở hữu phải là tên người dùng của bạn, không phải `root`. Bạn có thể khắc phục bằng `sudo chown $(whoami) ~/Library/Preferences/com.example.app.plist`. Một vấn đề tinh tế hơn nữa là **tùy chọn được bộ nhớ đệm (cached preferences)**. Để nhanh hơn, macOS sử dụng một daemon nền, `cfprefsd`, để lưu các giá trị tùy chọn vào bộ nhớ đệm. Điều này có nghĩa là ngay cả khi bạn trực tiếp chỉnh sửa một tệp PLIST trên đĩa, ứng dụng đang chạy vẫn có thể tiếp tục đọc phiên bản cũ, đã được lưu vào bộ nhớ đệm. Nếu các thay đổi `defaults write` của bạn không có hiệu lực, đây gần như chắc chắn là lý do. Buộc xóa bộ nhớ đệm bằng `killall cfprefsd` (nó tự động khởi động lại) hoặc đơn giản là đăng xuất và đăng nhập lại. Lỗi xây dựng Xcode thường bắt nguồn từ một tệp `Info.plist` bị định dạng sai. Quá trình xây dựng sẽ thất bại với một lỗi mơ hồ như "Dữ liệu không thể đọc được vì nó không ở định dạng chính xác," đó chỉ là cách Xcode nói rằng tệp không thể phân tích cú pháp. Trước khi làm bất cứ điều gì khác, hãy kiểm tra các dấu hiệu xung đột hợp nhất (merge conflict markers) như `<<<<<<<` trong XML, hoặc chỉ cần chạy `plutil -lint` trên tệp đó. Đối với bất kỳ tệp PLIST nào mà bạn không tự tạo—một tệp từ bản sao lưu thiết bị, một kho lưu trữ GitHub hoặc từ đồng nghiệp—hãy chạy `plutil -lint` trên đó trước. Chỉ mất ba giây và giúp bạn tránh được rất nhiều bối rối.

PLIST trong quy trình phát triển rộng hơn của Apple

Vượt xa việc chỉ lưu trữ các tùy chọn, các tệp PLIST là cơ sở hạ tầng chịu tải trong chuỗi công cụ phát triển của Apple, thường theo những cách mà chỉ trở nên rõ ràng khi có điều gì đó hỏng hóc. Việc ký mã (code signing) của một ứng dụng phụ thuộc vào một PLIST entitlements. Đây là tệp khai báo chính xác những khả năng đặc biệt nào mà một ứng dụng được phép sử dụng: iCloud, thông báo đẩy (push notifications), App Groups, chia sẻ Keychain, v.v. Tệp này được nhúng trực tiếp vào chữ ký mã của ứng dụng trong quá trình xây dựng. Nếu PLIST entitlements không khớp với hồ sơ cấp phép (provisioning profile), ứng dụng đơn giản sẽ không cài đặt được trên thiết bị. Công cụ `codesign` của Apple đọc và xác thực tệp này trực tiếp. Hệ thống xây dựng của Xcode cũng phụ thuộc rất nhiều vào PLIST. Các tệp `*.xcscheme` được tìm thấy bên trong `.xcodeproj/xcshareddata/xcschemes/` là các PLIST mô tả những mục tiêu nào cần xây dựng, đối số nào cần truyền khi khởi chạy và biến môi trường nào cần đặt. Vì chúng chỉ là XML có cấu trúc, chúng an toàn để đưa vào kiểm soát phiên bản và dễ dàng so sánh (diff) giữa các nhánh. Ngay cả siêu dữ liệu gửi lên App Store cũng được quản lý bởi một PLIST. Tệp khai báo quyền riêng tư (privacy manifest) (`PrivacyInfo.xcprivacy`), được giới thiệu trong Xcode 15 và bắt buộc đối với hầu hết các lượt gửi ứng dụng sau tháng 5 năm 2024, là một tệp PLIST. Nó khai báo những API nào ứng dụng của bạn sử dụng có thể được dùng để nhận dạng (fingerprinting) và lý do tại sao. Sai tệp này không gây ra lỗi xây dựng; nó gây ra việc từ chối xem xét App Store, điều này khó chịu hơn nhiều khi gỡ lỗi. Đối với bất kỳ ai xây dựng các công cụ đa nền tảng tương tác với hệ sinh thái của Apple—hệ thống CI, giải pháp MDM hoặc tiện ích sao lưu—việc hiểu sâu về định dạng PLIST là điều không thể tránh khỏi. Thông số kỹ thuật của định dạng được ghi lại trong tài liệu tham khảo `CFPropertyList` của Apple, nhưng định dạng nhị phân cũng đã được đảo ngược kỹ lưỡng. Các trình phân tích cú pháp mã nguồn mở xuất sắc tồn tại cho Python, Ruby, Go và Rust. Mô-đun `plistlib` trong thư viện chuẩn của Python (từ phiên bản 3.4) đặc biệt đáng tin cậy cho các script sản xuất cần xử lý các bản sao lưu thiết bị hoặc tệp dự án Xcode.