Skip to main content
← Portfolio

Afterdark

SwiftUI · SwiftData · Foundation Models

Afterdark is an iOS app for finding the haunted places around you. Browse over ten thousand haunted locations across the United States, get a notification when you drive past one, plan a road trip through the spookiest stops nearby, and hear each location's story told back to you by an on-device AI.

Haunted locations on the map
Haunted locations on the map
Read the story behind each haunt
Read the story behind each haunt
Explore nearby and new locations
Explore nearby and new locations
Get notified near a haunted location
Get notified near a haunted location
Plan haunted road trips
Plan haunted road trips
Climb the community leaderboards
Climb the community leaderboards

Features

  • Haunted Map

    Every haunted location on one map, with photo pins that cluster and shrink as you zoom out.

  • Haunted Notifications

    A heads-up when you come within a mile of a haunted location, even with the app closed.

  • Haunted Road Trips

    Pick up to ten stops and Afterdark orders them into the shortest drive, with driving directions between each.

  • Echoes

    A short horror story inspired by a location's lore, written on device in one of four voices: Explorer, Campfire, Lost Journal or Case File.

  • Visits

    Check in when you're actually at a location to build your visit history.

  • Leaderboards

    Compete with the community on most visits and most locations added.

  • Community Stories

    Comment with your own experiences, and see what's trending across the app.

  • Add Locations

    Submit a haunted location with a photo, and it joins the map once it's reviewed.

  • Saved Locations

    Bookmark the places you want to visit next.

  • Afterdark+

    A monthly, yearly or lifetime upgrade that unlocks every location, notifications, road trips and Echoes.

Location Data

Locations live in a remote backend and are mirrored on device with SwiftData, so search, Near You and the map all read from a local store and keep working offline. The first launch pages through the whole table by id, and every launch after that only fetches rows edited or deleted since the last sync. The sync watermark is taken from the newest row actually read rather than the device clock, so clock skew can never skip a change.

Haunted Notifications

iOS only lets an app watch twenty regions at a time, so Afterdark uses CLMonitor to geofence the twenty closest locations the user hasn't been notified about, and re-picks them as the user moves. When the user crosses into one, iOS relaunches the app in the background to send the notification. Each location only notifies once, with a cooldown between alerts, and the notified list syncs with the remote backend so a reinstall doesn't repeat them.

Road Trips

Stops are ordered without any network requests: a nearest neighbor pass builds a route from straight-line distances, then 2-opt reverses any stretch where the route doubles back on itself. Driving directions for each leg are then requested from MapKit together, and a leg that fails falls back to a straight line so the rest of the trip still shows.

Echoes

Echoes use Apple's Foundation Models framework to write stories entirely on device, with no server and no cost per story. The model generates into a @Generable type with guided fields for the title and story, and the text streams in as it's written. Each narrative voice has its own instructions, so the same location reads differently as a campfire tale or a case file.