viewhack

Plist viewer: open a binary or XML .plist, or a .mobileprovision

Drop an Info.plist, a macOS preferences file, an iTunes library, an NSKeyedArchiver archive or an iOS provisioning profile. A binary plist, which a text editor shows as garbage starting with bplist00, opens as a tree of keys and values with their types. Search it, copy any key's path, and save it as JSON or as a readable XML plist. A profile also shows its app ID, team, expiry, entitlements, devices and certificates.

The file is read on your device. It is never uploaded.

What it shows

Provisioning profiles (.mobileprovision)

A profile is an XML plist wrapped in a CMS (PKCS#7) signature from Apple. The page unwraps it and shows the answers developers usually dig for with security cms -D -i:

Profile typeHow the page decides
Developmenta device list, and get-task-allow is true, so a debugger can attach
Ad Hoca device list, and get-task-allow is false
App Storeno device list (App Store and TestFlight builds are re-signed by Apple)
Enterprise (in-house)ProvisionsAllDevices is true

Where to find them: inside an app, at Payload/Name.app/embedded.mobileprovision in the .ipa (an .ipa is a ZIP file). On a Mac, profiles installed by Xcode 16 and later are in ~/Library/Developer/Xcode/UserData/Provisioning Profiles/, and by earlier versions in ~/Library/MobileDevice/Provisioning Profiles/. Each is named by its UUID.

Files it opens

FileWhat is insideHow it is recognised
.plist (binary)most macOS preferences in ~/Library/Preferences, the Info.plist inside a built app, Xcode and Simulator statebplist00 in the first 8 bytes
.plist (XML)an Info.plist in source code, launchd jobs, iTunes Library.xml, .entitlements filesa <plist> root element, or <!DOCTYPE plist
.mobileprovision, .provisionprofilean iOS, tvOS, watchOS, visionOS or macOS provisioning profileCMS signed data (OID 1.2.840.113549.1.7.2) whose content is an XML plist
.mobileconfig (signed)a device configuration profile (Wi-Fi, VPN, MDM enrolment)the same CMS envelope around a plist; an unsigned one is plain XML
.webarchive, .webloc, .stringsa page saved by Safari, a Finder web link, an app's compiled translationsbinary or XML plist, as above

A worked example: an iTunes library

The file iTunes-small.bplist from the node-bplist-parser project's tests is a 24,433-byte binary plist from iTunes 9.0.3. Its offset table lists 1,138 objects. The writer stores a repeated value once and points to it from each place it is used, so these unfold into 1,322 values in the tree. The root dict has 9 keys. :Tracks holds 42 tracks and :Playlists 13 playlists.

A search for castle finds :Tracks:100:Name, “Spanish Castle Magic” by Jimi Hendrix, and :Tracks:112:Name, “Castles Made Of Sand”, along with their file paths. Track 100 has two play dates. Play Date UTC is a real plist date, 2010-02-22 23:36:18 UTC. Play Date is a plain integer, 3349701378, that only makes sense as seconds since 1 January 1904 (the classic Mac OS epoch) in the computer's local time: 2010-02-22 16:36:18, seven hours behind UTC.

One playlist name, :Playlists:6:Name “90’s Music”, is marked as an ASCII string but holds the UTF-8 bytes of a curly apostrophe. Python's plistlib refuses the whole file because of it (“Invalid file”). This page reads it as UTF-8 and says so.

The same jobs on the command line

On a Mac: plutil -p file.plist prints any plist, and plutil -convert xml1 file.plist rewrites a binary one as XML, in place. plutil -convert json stops with “invalid object in plist for destination format” when the file holds a date or data. security cms -D -i profile.mobileprovision prints a profile's plist, and /usr/libexec/PlistBuddy -c "Print :Entitlements" file prints one entry, using the path this page copies. On Windows and Linux there is no plutil unless you install one; this page does the same reading in any browser.

What this cannot do