/geotoolbox
GeoToolbox PlaceDescriptor patterns with MapKit integration for location representation, geocoding, and multi-service place identifiers. Use when working with place descriptors, geocoding, or cross-service location data.
$ npx -y skills add rshankras/claude-code-apple-skills --skill geotoolbox --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/geotoolbox
Context preview
The summary Claude sees to decide when to auto-load this skill.
GeoToolbox PlaceDescriptor patterns with MapKit integration for location representation, geocoding, and multi-service place identifiers. Use when working with place descriptors, geocoding, or cross-service location data.
SKILL.md
geotoolbox.SKILL.mdname: geotoolbox
description: GeoToolbox PlaceDescriptor patterns with MapKit integration for location representation, geocoding, and multi-service place identifiers. Use when working with place descriptors, geocoding, or cross-service location data.
allowed-tools: [Read, Glob, Grep]
last_verified: 2026-07-16
review_by: 2027-06-22
GeoToolbox and PlaceDescriptor Patterns
Portable location representation using `PlaceDescriptor` from the GeoToolbox framework. Covers place construction from coordinates, addresses, and MapKit items; forward and reverse geocoding with the new async APIs; and multi-service place identifiers for cross-platform interop.
When This Skill Activates
Use this skill when the user:
- Asks about **GeoToolbox** or **PlaceDescriptor**
- Wants to represent a place with coordinates, address, or common name
- Needs to convert between **MKMapItem** and **PlaceDescriptor**
- Asks about **forward geocoding** (address to coordinates) or **reverse geocoding** (coordinates to address)
- Wants to store or transmit **multi-service place identifiers** (Apple Maps, Google Maps, etc.)
- Mentions **PlaceRepresentation**, **SupportingPlaceRepresentation**, or **MKGeocodingRequest**
- Asks about portable or interoperable location data structures
Decision Tree
What do you need?
|
+-- Represent a place with coordinates and/or address
| +-- From a known coordinate
| | +-- PlaceRepresentation.coordinate(CLLocationCoordinate2D)
| +-- From a known address string
| | +-- PlaceRepresentation.address(String)
| +-- Both coordinate and address
| | +-- Pass multiple representations to PlaceDescriptor
| +-- From an existing MKMapItem
| +-- PlaceDescriptor(item: MKMapItem)
|
+-- Geocode an address to coordinates
| +-- MKGeocodingRequest(addressString:)
| +-- try await request.mapItems
|
+-- Reverse geocode coordinates to an address
| +-- MKReverseGeocodingRequest(location:)
| +-- try await request.mapItems
|
+-- Attach service identifiers (Apple Maps, Google, etc.)
| +-- SupportingPlaceRepresentation.serviceIdentifiers([String: String])
|
+-- Read place properties
+-- descriptor.coordinate, descriptor.address, descriptor.commonName
+-- descriptor.serviceIdentifier(for: "com.apple.maps")API Availability
| API | Minimum OS | Import | |-----|-----------|--------| | `PlaceDescriptor` | iOS 26 / macOS 26 | `GeoToolbox` | | `PlaceRepresentation` | iOS 26 / macOS 26 | `GeoToolbox` | | `SupportingPlaceRepresentation` | iOS 26 / macOS 26 | `GeoToolbox` | | `MKGeocodingRequest` | iOS 26 / macOS 26 | `MapKit` | | `MKReverseGeocodingRequest` | iOS 26 / macOS 26 | `MapKit` | | `PlaceDescriptor(item:)` | iOS 26 / macOS 26 | `GeoToolbox` + `MapKit` | | `MKMapItem` | iOS 6 / macOS 10.9 | `MapKit` | | `CLLocationCoordinate2D` | iOS 2 / macOS 10.6 | `CoreLocation` |
Quick Start
Create a PlaceDescriptor from Coordinates
import GeoToolbox
import CoreLocation
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let descriptor = PlaceDescriptor(
representations: [.coordinate(coordinate)],
commonName: "Apple Park"
)
// Read back
if let coord = descriptor.coordinate {
print("Lat: \(coord.latitude), Lon: \(coord.longitude)")
}
print(descriptor.commonName ?? "No name")Create a PlaceDescriptor from an Address
import GeoToolbox
let descriptor = PlaceDescriptor(
representations: [.address("One Apple Park Way, Cupertino, CA 95014")],
commonName: "Apple Park"
)
if let address = descriptor.address {
print("Address: \(address)")
}Multiple Representations and Service Identifiers
import GeoToolbox
import CoreLocation
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let descriptor = PlaceDescriptor(
representations: [
.coordinate(coordinate),
.address("One Apple Park Way, Cupertino, CA 95014")
],
commonName: "Apple Park",
supportingRepresentations: [
.serviceIdentifiers([
"com.apple.maps": "apple-maps-id-12345",
"com.google.maps": "ChIJ-bfVTh8_j4ARDMPaL2Njo3I"
])
]
)
// Access a specific service identifier
if let appleId = descriptor.serviceIdentifier(for: "com.apple.maps") {
print("Apple Maps ID: \(appleId)")
}Convert from MKMapItem
import GeoToolbox
import MapKit
func descriptorFromMapItem(_ mapItem: MKMapItem) -> PlaceDescriptor {
PlaceDescriptor(item: mapItem)
}Forward Geocoding (Address to Coordinates)
import MapKit
func geocodeAddress(_ addressString: String) async throws -> [MKMapItem] {
let request = MKGeocodingRequest(addressString: addressString)
let mapItems = try await request.mapItems
return mapItems
}
// Usage
let items = try await geocodeAddress("One Apple Park Way, Cupertino, CA")
if let first = items.first {
let coord = first.placemark.coordinate
print("Found: \(coord.latitude), \(coord.longitude)")
}Reverse Geocoding (Coordinates to Address)
import MapKit
import CoreLocation
func reverseGeocode(_ coordinate: CLLocationCoordinate2D) async throws -> [MKMapItem] {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
let request = MKReverseGeocodingRequest(location: location)
let mapItems = try await request.mapItems
return mapItems
}
// Usage
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let items = try await reverseGeocode(coordinate)
if let first = items.first {
print("Address: \(first.placemark.title ?? "Unknown")")
}Full Integration Example
Geocode an address, convert the result to a PlaceDescriptor with service identifiers, and read back all properties:
import GeoToolbox
import MapKit
import CoreLocation
func buildPlaceDescriptor(from addressString: String) async throws -> PlaceDescriptor? {
// Forward geocodeRead more
name: geotoolbox description: GeoToolbox PlaceDescriptor patterns with MapKit integration for location representation, geocoding, and multi-service place identifiers. Use when working with place descriptors, geocoding, or cross-service location data. allowed-tools: [Read, Glob, Grep] last_verified: 2026-07-16 review_by: 2027-06-22
GeoToolbox and PlaceDescriptor Patterns
Portable location representation using `PlaceDescriptor` from the GeoToolbox framework. Covers place construction from coordinates, addresses, and MapKit items; forward and reverse geocoding with the new async APIs; and multi-service place identifiers for cross-platform interop.
When This Skill Activates
Use this skill when the user:
- Asks about **GeoToolbox** or **PlaceDescriptor**
- Wants to represent a place with coordinates, address, or common name
- Needs to convert between **MKMapItem** and **PlaceDescriptor**
- Asks about **forward geocoding** (address to coordinates) or **reverse geocoding** (coordinates to address)
- Wants to store or transmit **multi-service place identifiers** (Apple Maps, Google Maps, etc.)
- Mentions **PlaceRepresentation**, **SupportingPlaceRepresentation**, or **MKGeocodingRequest**
- Asks about portable or interoperable location data structures
Decision Tree
What do you need?
|
+-- Represent a place with coordinates and/or address
| +-- From a known coordinate
| | +-- PlaceRepresentation.coordinate(CLLocationCoordinate2D)
| +-- From a known address string
| | +-- PlaceRepresentation.address(String)
| +-- Both coordinate and address
| | +-- Pass multiple representations to PlaceDescriptor
| +-- From an existing MKMapItem
| +-- PlaceDescriptor(item: MKMapItem)
|
+-- Geocode an address to coordinates
| +-- MKGeocodingRequest(addressString:)
| +-- try await request.mapItems
|
+-- Reverse geocode coordinates to an address
| +-- MKReverseGeocodingRequest(location:)
| +-- try await request.mapItems
|
+-- Attach service identifiers (Apple Maps, Google, etc.)
| +-- SupportingPlaceRepresentation.serviceIdentifiers([String: String])
|
+-- Read place properties
+-- descriptor.coordinate, descriptor.address, descriptor.commonName
+-- descriptor.serviceIdentifier(for: "com.apple.maps")API Availability
| API | Minimum OS | Import | |-----|-----------|--------| | `PlaceDescriptor` | iOS 26 / macOS 26 | `GeoToolbox` | | `PlaceRepresentation` | iOS 26 / macOS 26 | `GeoToolbox` | | `SupportingPlaceRepresentation` | iOS 26 / macOS 26 | `GeoToolbox` | | `MKGeocodingRequest` | iOS 26 / macOS 26 | `MapKit` | | `MKReverseGeocodingRequest` | iOS 26 / macOS 26 | `MapKit` | | `PlaceDescriptor(item:)` | iOS 26 / macOS 26 | `GeoToolbox` + `MapKit` | | `MKMapItem` | iOS 6 / macOS 10.9 | `MapKit` | | `CLLocationCoordinate2D` | iOS 2 / macOS 10.6 | `CoreLocation` |
Quick Start
Create a PlaceDescriptor from Coordinates
import GeoToolbox
import CoreLocation
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let descriptor = PlaceDescriptor(
representations: [.coordinate(coordinate)],
commonName: "Apple Park"
)
// Read back
if let coord = descriptor.coordinate {
print("Lat: \(coord.latitude), Lon: \(coord.longitude)")
}
print(descriptor.commonName ?? "No name")Create a PlaceDescriptor from an Address
import GeoToolbox
let descriptor = PlaceDescriptor(
representations: [.address("One Apple Park Way, Cupertino, CA 95014")],
commonName: "Apple Park"
)
if let address = descriptor.address {
print("Address: \(address)")
}Multiple Representations and Service Identifiers
import GeoToolbox
import CoreLocation
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let descriptor = PlaceDescriptor(
representations: [
.coordinate(coordinate),
.address("One Apple Park Way, Cupertino, CA 95014")
],
commonName: "Apple Park",
supportingRepresentations: [
.serviceIdentifiers([
"com.apple.maps": "apple-maps-id-12345",
"com.google.maps": "ChIJ-bfVTh8_j4ARDMPaL2Njo3I"
])
]
)
// Access a specific service identifier
if let appleId = descriptor.serviceIdentifier(for: "com.apple.maps") {
print("Apple Maps ID: \(appleId)")
}Convert from MKMapItem
import GeoToolbox
import MapKit
func descriptorFromMapItem(_ mapItem: MKMapItem) -> PlaceDescriptor {
PlaceDescriptor(item: mapItem)
}Forward Geocoding (Address to Coordinates)
import MapKit
func geocodeAddress(_ addressString: String) async throws -> [MKMapItem] {
let request = MKGeocodingRequest(addressString: addressString)
let mapItems = try await request.mapItems
return mapItems
}
// Usage
let items = try await geocodeAddress("One Apple Park Way, Cupertino, CA")
if let first = items.first {
let coord = first.placemark.coordinate
print("Found: \(coord.latitude), \(coord.longitude)")
}Reverse Geocoding (Coordinates to Address)
import MapKit
import CoreLocation
func reverseGeocode(_ coordinate: CLLocationCoordinate2D) async throws -> [MKMapItem] {
let location = CLLocation(latitude: coordinate.latitude, longitude: coordinate.longitude)
let request = MKReverseGeocodingRequest(location: location)
let mapItems = try await request.mapItems
return mapItems
}
// Usage
let coordinate = CLLocationCoordinate2D(latitude: 37.3349, longitude: -122.0090)
let items = try await reverseGeocode(coordinate)
if let first = items.first {
print("Address: \(first.placemark.title ?? "Unknown")")
}Full Integration Example
Geocode an address, convert the result to a PlaceDescriptor with service identifiers, and read back all properties:
import GeoToolbox
import MapKit
import CoreLocation
func buildPlaceDescriptor(from addressString: String) async throws -> PlaceDescriptor? {
// Forward geocodeA collection of Claude Code skills for iOS, macOS, watchOS, visionOS, and Apple platform development. These skills help you plan and build apps, maintain code quality, ensure HIG compliance, and guide you from idea to App Store.
Repo: rshankras/claude-code-apple-skills
Other skills on rshankras-apple-skills.
- /app-store
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user needs help with App Store presence, ASO, marketing, or customer communication.
Open skill - /ad-attribution
Privacy-preserving ad measurement with AdAttributionKit (SKAdNetwork's successor) — install and re-engagement attribution, conversion-value strategy under crowd anonymity, and end-to-end postback testing. Use when running paid acquisition beyond Apple Ads, measuring
Open skill - /app-description-writer
Generate compelling App Store descriptions that convert browsers into users. Use when writing initial descriptions, improving existing copy, or drafting promotional text and What's New for a major update.
Open skill - /apple-search-ads
Apple Search Ads campaign strategy for indie developers — paid acquisition, keyword bidding, budget planning, and ROAS optimization. Use when user asks about running ads, paid user acquisition, or Apple Search Ads campaigns.
Open skill - /iap-finalizer
Take a one-time in-app purchase from MISSING_METADATA to READY_TO_SUBMIT in App Store Connect — set its price schedule and localized display name/description (and optional review screenshot) via the ASC REST API. Use at Phase 6 (Pre-Release), after the IAP is built in-app (Phase
Open skill - /keyword-optimizer
Optimize app title, subtitle, and keywords for maximum App Store discoverability. Use when launching a new app, improving search rankings, entering new markets/languages, or safely optimizing ASO for an app with existing traffic.
Open skill

