Contents

mattt/ontology

A Swift library for working with structured data.

Requirements

  • Swift 6.0+ / Xcode 16+
  • macOS 14.0+ (Sonoma)
  • iOS 17.0+

Installation

Swift Package Manager

Add the following to your Package.swift file:

dependencies: [
    .package(url: "https://github.com/mattt/Ontology.git", from: "0.11.0")
]

Supported Types

Schema.org Vocabulary

Supported Schema.org types and their Apple framework equivalents:

| Schema.org Type | Apple Framework Type | Description | |----------------|----------------------|-------------| | ContactPoint | CNInstantMessageAddress | Represents a method of contact like instant messaging | | DateTime | Date | Represents a date and time with ISO 8601 formatting | | Event | EKEvent | Represents an event with start/end dates, location, etc. | | Schedule | EKRecurrenceRule | Represents a repeating time period for an event, such as a weekly class | | GeoCoordinates | CLLocation | Represents geographic coordinates with latitude, longitude, and optional elevation | | Organization | CNContact | Represents an organization with properties like name and contact info | | Person | CNContact | Represents a person with properties like name, contact info, and relationships | | Place | MKPlacemark, MKMapItem | Represents a geographical location, specific address, or point of interest | | ItemList | EKCalendar | Represents a list of items with properties like name, identifier, and item count | | PlanAction | EKReminder | Represents a planned action or task with properties like name, description, due date, and completion status | | PostalAddress | CNPostalAddress | Represents a physical address with street, city, region, etc. | | QuantitativeValue | Measurement | Represents measurements with standardized units using UN/CEFACT Common Codes | | Trip | MKDirections.Response, MKDirections.ETAResponse | Represents an itinerary of visits to one or more places with optional arrival/departure times |

Apple WeatherKit Vocabulary

Additional types supporting [Apple WeatherKit][weatherkit]:

| Type | WeatherKit Type | Description | |------|----------------|-------------| | WeatherForecast | DayWeather, HourWeather, MinuteWeather | Detailed weather forecast including temperature, precipitation, wind, sun/moon data | | WeatherConditions | CurrentWeather, HourWeather | Current or hourly weather conditions including temperature, wind, and humidity |

A WeatherForecast or WeatherConditions value encoded as the root of a document includes the attribution that WeatherKit requires. A value encoded in another value, such as an array of forecasts, omits it, so that the attribution isn't repeated for each value. In that case, include the attribution once in the containing value.

Usage

Creating objects and encoding as JSON-LD

import Ontology

// Create a Person
var person = Person()
person.givenName = "John"
person.familyName = "Doe"
person.email = ["john.doe@example.com"]

// Create an organization
var organization = Organization()
organization.name = "Example Corp"

// Associate person with organization
person.worksFor = organization

// Encode to JSON-LD
let encoder = JSONEncoder()
let jsonData = try encoder.encode(person)
print(String(data: jsonData, encoding: .utf8)!)

// Output:
// {
//   "@context": "https://schema.org",
//   "@type": "Person",
//   "givenName": "John",
//   "familyName": "Doe"
// }

Initializing from Apple framework types

import Ontology
import Contacts

// Convert from Apple's CNContact to Schema.org Person
let contact = CNMutableContact()
contact.givenName = "Jane"
contact.familyName = "Smith"
contact.emailAddresses = [
    CNLabeledValue(label: CNLabelHome,
                   value: "jane.smith@example.com" as NSString)
]

// Convert to Schema.org Person
let person = Person(contact)

Configuring DateTime representations

By default, DateTime objects are encoded with their specified time zone, or GMT/UTC if none is specified. You can override the time zone used during encoding by providing a specific TimeZone in the JSONEncoder's userInfo dictionary:

import Ontology

// Create a DateTime object
let dateTime = DateTime(Date())

// Create an encoder that will use the local timezone
let encoder = JSONEncoder()
encoder.userInfo[DateTime.timeZoneOverrideKey] = TimeZone.current

// Or specify a particular timezone
// encoder.userInfo[DateTime.timeZoneOverrideKey] = TimeZone(identifier: "America/New_York")

// Encode using the specified timezone
let jsonData = try encoder.encode(dateTime)

This feature is particularly useful when:

  • Working with date-only values that should be interpreted in the user's local timezone
  • Ensuring consistent timezone representation across different data sources
  • Presenting dates to users in their local timezone regardless of how they were originally stored

So to recap, the date encoding priority is:

  1. TimeZone from encoder's userInfo (if provided)
  2. TimeZone from the DateTime object (if specified)
  3. GMT/UTC (default fallback)

Omitting nested types

By default, every encoded value includes its @type, including values nested in another value. To make the output shorter, such as when it goes into a language model's context, set JSONLD.omitsNestedTypesKey to true. The root value keeps its @context and @type:

var person = Person(name: "Jane Doe")
person.worksFor = Organization(name: "Example Corp")

let encoder = JSONEncoder()
encoder.userInfo[JSONLD.omitsNestedTypesKey] = true
let jsonData = try encoder.encode(person)

// Output:
// {
//   "@context": "https://schema.org",
//   "@type": "Person",
//   "givenName": "Jane",
//   "familyName": "Doe",
//   "worksFor": {
//     "name": "Example Corp"
//   }
// }

Values in a top-level array aren't at the root, so they omit @type too. JSON-LD processors can't infer the type of a nested value, so don't set this key for output that other software reads as linked data. Decoding accepts values with or without @type.

License

This project is available under the MIT license. See the LICENSE file for more info.

Package Metadata

Repository: mattt/ontology

Default branch: main

README: README.md