Version 1.4 adds Portable Journal v2 without redefining v1. Both versions use a standard ZIP container and the semantic format identifier com.thegiftjournal.portable-journal. Pure legacy/outgoing-only journals can still export as schemaVersion: 1; any Received Gift or Version 1.4 Relationship Memory that needs the new semantics exports as schemaVersion: 2.
Portable Journal Export exists so the meaningful contents of a journal can be inspected, archived or processed without requiring The Gift Journal or access to its private CloudKit implementation. There is no proprietary wrapper to decode and no special filename extension to rename first.
Opening the file
The export is a normal .zip archive. Save it somewhere convenient, then open or extract it with the ZIP support already built into macOS, iOS/iPadOS file providers, Windows, Linux or a third-party archive tool.
The simplest way to understand an export is to read README.txt first, then inspect manifest.json and journal.json. Developers can validate the JSON against the version-matched JSON Schema included in the same archive.
What is inside the ZIP
Portable Journal Export.zip
├── README.txt
├── manifest.json
├── journal.json
├── portable-journal-v1.schema.json or portable-journal-v2.schema.json
└── assets/
└── referenced image files, when present
The schema file matches the archive’s schemaVersion. External tools should read manifest.json first and use the schema file supplied by the archive rather than guessing.
How Version 1.4 chooses v1 or v2
- v1 — pure legacy/outgoing-only journal semantics that v1 can represent completely.
- v2 — any Received Gift or Version 1.4 Relationship Memory such as a Person Received Gift, partial/unknown received date, Person Practical Details (including current-value freshness or Previous values) or a non-empty Given-Gift Stored at value.
What Portable Journal v2 adds
Version 2 keeps the established record families but makes gift direction explicit. Readers should use the documented given/received direction instead of trying to infer direction from recipient fields.
- Given gifts: existing recipient/Occasion, status, planning and fulfilment meaning, plus optional private
storedAt. - Received gifts: Self or Person recipient semantics, zero-or-more giver Person IDs, exact/month/year/unknown received-date precision, optional occasion/reason and Wishlist → Received provenance.
- People:
practicalDetailsas stable labelledfactoravoidanceentries.
Protected Gifts, Hints and Wishlist items remain excluded by default. Deliberate authenticated inclusion preserves protection state, and excluded protected provenance is not leaked indirectly. Portable Journal remains an export for preservation, inspection and independent tooling; Full Backup remains the supported app-recovery contract and Portable Journal import is not implemented.
Contained file formats
| File | Format | What it is for |
|---|---|---|
README.txt | Plain text | The human starting point. It explains the portable format, the archive contents and how the versioned files relate to one another. |
manifest.json | JSON | A small package manifest for format/version metadata. Readers should use it to identify the semantic format and schema version before interpreting the journal data. |
journal.json | JSON | The user-meaningful journal data and relationships: People, Occasions, Gift Ideas/history, Hints, Context and Wishlist data, together with supported planning, budget and fulfilment meaning. |
| Version-matched JSON Schema | JSON Schema | The machine-readable definition of the selected v1 or v2 structure. It is the authoritative reference for exact property names, data types, required/optional fields and allowed values. |
assets/ | Referenced image files | Images are stored as ordinary files and referenced from the JSON rather than being embedded as large base64 strings. Preserve their relative paths and bytes when archiving or processing an export. |
How to read journal.json
The JSON is a semantic export, not a copy of the app's internal database. Stable identifiers preserve relationships between records, so a Gift remains one Gift even when it appears for more than one recipient or Occasion. Treat identifiers as opaque values and use the relationships described by the data rather than trying to reconstruct records from screen labels.
| Journal concept | Meaning represented in the portable data |
|---|---|
| People | Long-lived relationship records such as identity, birthday/relationship context, notes, preferences and supported photo references. |
| Occasions | Occasion identity and planning meaning, including dates/recurrence, Person relationships, supported budget/currency data and logical Occasion-plan relationships. |
| Gift Ideas / Gifts | One stable Gift identity with title/notes, URL/image/source information, price/currency, status, recipients, Occasion coverage, dates, provenance and supported fulfilment fields such as arrival, tracking/reference, order/reference and return-by information. |
| Hints | Lightweight clues associated with a Person and optionally an Occasion, including supported text, URL, image, tags and provenance relationships. |
| Context | Time-aware relationship context such as interests, life changes and other remembered details, with supported type/date/tag and archive/pinning meaning. |
| Wishlist | The user's private Wishlist records, including supported title, description, URL, image, price, priority and notes. |
Use the included JSON Schema for exact field names. The table above describes the meaning of the records; it is not a substitute for the schema. External tools should read the manifest/schema instead of assuming internal Swift model names or translated UI labels.
Rules for external readers
- Read
manifest.jsonfirst and check that the semantic format iscom.thegiftjournal.portable-journaland that your tool supports the declared schema version. - Validate
journal.jsonwith the JSON Schema included in that export before relying on particular fields or enum values. - Treat stable identifiers as opaque relationship keys. Do not create a second Gift simply because the same Gift is linked to several People.
- Use language-neutral stored meaning rather than translated labels shown in the app. Localisation is presentation; it does not redefine the portable semantics.
- Resolve image references to files inside
assets/. Do not expect images to be embedded insidejournal.json.
Privacy boundary
The portable ZIP is not a private CloudKit dump. It deliberately excludes implementation-only material such as CloudKit ancestry/revisions, pending sync queues, deletion tombstones, StoreKit/entitlement state, diagnostics, widget caches and similar app-internal state.
Protected Gifts, Hints and Wishlist items are excluded by default. An authenticated Include protected items export can deliberately include protected records; protected-Hint provenance remains privacy-sensitive so protected clue text is not leaked indirectly.
Portable export is not Full Backup
Full Backup is the app's lossless recovery format and may contain implementation-specific recovery information needed by The Gift Journal. Portable Journal Export contains durable, user-meaningful journal concepts intended to remain independently understandable. They are intentionally separate contracts.
Portable export is not Selective Sharing
Selective Sharing uses a smaller, deliberately curated projection. Sending a Wishlist, Occasion plan or Gift recommendation does not expose the sender's complete Portable Journal ZIP.
Versioning and compatibility
Both v1 and v2 use the same semantic format identifier and standard .zip container. The schemaVersion in manifest.json is the compatibility boundary: v1 stays frozen, while v2 explicitly represents the newer Received Gift and Version 1.4 Relationship Memory semantics. External readers should make compatibility decisions from the manifest and included schema, not from The Gift Journal's internal storage or filename conventions.
Import
Portable Journal Import is not supported by either the v1 or v2 Portable Journal contract. The public ZIP and schema are for export, inspection and interoperability; they do not mean arbitrary third-party JSON can be imported into the private journal.