JSON to Plist Converter
Convert JSON to Apple Property List (plist) XML format instantly in your browser. Supports all plist data types including dict, array, string, integer, real, boolean, date, and data.
About
Apple Property List (plist) files are the standard configuration format across macOS, iOS, watchOS, and tvOS. They store serialized objects as XML conforming to Apple's DTD at https://www.apple.com/DTDs/PropertyList-1.0.dtd. Misconfigured plist files cause silent failures in Xcode builds, broken app preferences, and rejected App Store submissions. This converter performs a recursive type-mapped translation from JSON to plist XML 1.0, handling all 8 plist data types: dict, array, string, integer, real, boolean, date (ISO 8601), and data (Base64). It detects circular references and validates input before conversion.
The tool approximates type inference since JSON lacks plist's type granularity. Integers vs. reals are distinguished by the absence or presence of a decimal component. ISO 8601 strings matching the pattern YYYY-MM-DDTHH:mm:ssZ are auto-detected as date types. Base64-encoded strings are not auto-detected as data to avoid false positives. Pro Tip: if your JSON contains keys with periods (e.g., com.apple.security), they are preserved verbatim in the plist output since dots are valid in plist dictionary keys.
Formulas
The converter applies a recursive type-mapping function T that transforms each JSON node into its plist XML equivalent:
The ISO 8601 date detection uses the pattern: ^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2} followed by an optional timezone designator. XML special characters are escaped via the mapping: & → &, < → <, > → >, " → ", ' → '.
Where T = type mapping function, node = current JSON value being processed, isISO8601 = regex-based date string detector, isObject = plain object check excluding arrays and null.
Reference Data
| JSON Type | Plist Type | Plist XML Tag | Example JSON | Example Plist Output | Notes |
|---|---|---|---|---|---|
| String | string | <string> | "hello" | <string>hello</string> | XML entities escaped |
| Integer Number | integer | <integer> | 42 | <integer>42</integer> | No decimal point |
| Float Number | real | <real> | 3.14 | <real>3.14</real> | Has decimal component |
| Boolean true | true | <true/> | true | <true/> | Self-closing tag |
| Boolean false | false | <false/> | false | <false/> | Self-closing tag |
| null | string (empty) | <string/> | null | <string/> | No native null in plist |
| Object | dict | <dict> | {"a":1} | <dict><key>a</key><integer>1</integer></dict> | Keys become <key> tags |
| Array | array | <array> | [1,2] | <array><integer>1</integer><integer>2</integer></array> | Ordered collection |
| ISO 8601 String | date | <date> | "2024-01-15T08:30:00Z" | <date>2024-01-15T08:30:00Z</date> | Auto-detected pattern |
| Nested Object | Nested dict | <dict> | {"a":{"b":1}} | Recursive conversion | Unlimited depth |
| Mixed Array | Mixed array | <array> | [1,"a",true] | Each element typed individually | Heterogeneous support |
| Empty Object | Empty dict | <dict/> | {} | <dict/> | Self-closing |
| Empty Array | Empty array | <array/> | [] | <array/> | Self-closing |
| Large Integer | integer | <integer> | 9007199254740991 | <integer>9007199254740991</integer> | Max safe integer |
| Negative Number | integer/real | <integer> or <real> | −7 | <integer>-7</integer> | Sign preserved |
| Scientific Notation | real | <real> | 1.5e10 | <real>15000000000</real> | Expanded to decimal |