A comprehensive Swift framework for the Gathr content platform API. Zero external dependencies — built entirely on Foundation and URLSession.
Manage audio, video, photos, text, events, store items, categories, users, authentication, and WordPress articles all from a single unified SDK.
- iOS: 14.0 or later
- macOS: 11 or later
- tvOS: 14.0 or later
- watchOS: 7.0 or later
- Xcode: 12.0 or later
- Swift: 5.3 or later
Add the package in Xcode via File > Add Package Dependencies, or in your Package.swift:
dependencies: [
.package(url: "https://github.com/WEBDMG/ios-gathrframework.git", from: "4.0.0")
]Then add "Gathr" as a dependency of your target.
Create a PlayMe.plist file in your app bundle with the following keys:
| Key | Description |
|---|---|
API_KEY |
Your Gathr API key |
BASE_URL |
Base URL for the Gathr API (default: https://api.gathr.me/v4/) |
TOKEN |
Your user token |
PLAYMEAPPTOKEN |
Your app token |
The framework reads this file automatically at launch via GathrConfiguration.sharedInstance.
import Gathr
// In application(_:didFinishLaunchingWithOptions:)
// GathrConfiguration reads PlayMe.plist automatically — no additional setup needed.GathrAudio().getAllSongs { tracks in
// tracks: [Audio]?
}
GathrAudio().getAllAudioByCategory(category: "jazz") { tracks in
// tracks: [Audio]?
}
GathrAudio().getAudioById(id: "123") { track in
// track: Audio?
}
GathrAudio().getLatestSongs { tracks in }
GathrAudio().getLatestPodcasts { tracks in }
GathrAudio().deleteAudio(params: ["id": "123"]) { success in }
GathrAudio().updateAudioTrack(params: [...]) { success in }
GathrAudio().activateAudio(params: ["id": "123"]) { success in }GathrVideo().getAllVideos { videos in
// videos: [Video]?
}
GathrVideo().getAllVideosByCategory(category: "drama") { videos in }
GathrVideo().getVideoById(id: "123") { video in }
GathrVideo().createVideo(params: [...]) { success in }
GathrVideo().updateVideo(params: [...]) { success in }
GathrVideo().activateVideo(params: [...]) { success in }
GathrVideo().deactivateVideo(params: [...]) { success in }GathrPhotos().getAllPhotos { photos in
// photos: [Photo]?
}
GathrPhotos().getAllPhotosByCategory(category: "nature") { photos in }
GathrPhotos().getPhotoById(id: "123") { photo in }
GathrPhotos().validatePhoto(params: [...]) { success in }
GathrPhotos().updatePhoto(params: [...]) { success in }
GathrPhotos().deletePhoto(params: [...]) { success in }GathrTexts().getAllTexts { texts in
// texts: [GathrText]?
}
GathrTexts().getAllTextByCategory(category: "quotes") { texts in }
GathrTexts().getTextById(id: "123") { text in }
GathrTexts().getTextList { texts in }
GathrTexts().createText(params: [...]) { success in }
GathrTexts().updateText(params: [...]) { success in }
GathrTexts().activateText(params: [...]) { success in }GathrEvent().getAllEvents { events in
// events: [Event]?
}
GathrEvent().getEventById(id: "123") { event in }
GathrEvent().getEventsByCategory(category: "music") { events in }
GathrEvent().createEvent(params: [...]) { success in }
GathrEvent().updateEvent(params: [...]) { success in }
GathrEvent().activateEvent(params: [...]) { success in }GathrItem().getAllItems { items in
// items: [Item]?
}
GathrItem().getItemById(id: "123") { item in }
GathrItem().getItemsByCategory(category: "merch") { items in }
GathrItem().createItem(params: [...]) { success in }
GathrItem().updateItem(params: [...]) { success in }
GathrItem().activateItem(params: [...]) { success in }GathrCategories().getAllCategory { categories in
// categories: [GathrCategory]?
}
// Returns unique, filtered categories (excludes "featured" and icon/flare suffixes)
GathrCategories().getAllCategoryType { types in }GathrUser().getUserByToken { user in
// user: NSDictionary?
}
GathrUser().getUserSettings { settings in }
GathrUser().saveUser(params: [...]) { success in }GathrLogin().login(params: ["email": "[email protected]", "password": "..."]) { user in
// user: NSDictionary?
}
GathrLogin().signinUserApp(params: [...]) { user in }
GathrLogin().getTokenByAppToken { app in }
GathrLogin().resetPassword(params: ["email": "[email protected]"]) { success in }
GathrLogin().getAudioCount { count in }
GathrLogin().getVideoCount { count in }
GathrLogin().getUserCount { count in }
GathrLogin().broadcast { data in }GathrApp().getApps { apps in
// apps: [NSDictionary]?
}
GathrApp().getAppInfo(id: "123") { info in }
GathrApp().getAppConfig { config in }
GathrApp().findCategoryByApp(category: "music") { categories in }GathrConfig().getConfigApi { config in
// config: Config1?
print(config?.blogurl)
print(config?.playmeappname)
}GathrArticles().getAllArticles("https://yourblog.com/wp-json/posts?filter[posts_per_page]=5") { articles in
// articles: [Articles]?
}The framework posts NotificationCenter notifications when data is loaded:
| Notification Name | Trigger |
|---|---|
GathrAudioLoaded |
Audio fetch completed |
GathrVideoLoaded |
Video fetch completed |
GathrPhotosLoaded |
Photos fetch completed |
GathrTextsLoaded |
Texts fetch completed |
GathrEventsLoaded |
Events fetch completed |
GathrItemsLoaded |
Items fetch completed |
GathrCategoriesLoaded |
Categories fetch completed |
GathrArticlesLoaded |
Articles fetch completed |
GathrNotifications().observeNotification(name: "GathrAudioLoaded") {
// reload your UI
}- Zero external dependencies — uses only Foundation / URLSession
GathrNetwork— internal networking layer with injectableURLSessionfor testabilityGathrConfiguration— readsPlayMe.plistfrom the app bundle; keys accessed viaGathrConfiguration.Keyconstants- All completion handlers are called on the main thread
Full API documentation is available via Xcode's built-in DocC support. The documentation includes:
- Getting Started Guide — Installation and configuration
- Configuration Guide — PlayMe.plist setup
- Service Guides — Detailed documentation for each service
- Model Documentation — Properties and usage examples
- Framework Notifications — Complete notification reference
- Extensions — String and UIColor utilities
Build the documentation:
xcodebuild docbuild -scheme Gathr- Audio: Songs, podcasts, episodes with rich metadata
- Video: YouTube integration and native video uploads
- Photos: Galleries from uploads and Instagram
- Text: Articles, quotes, and prose content
- Events: Venue information, ticketing, and scheduling
- Store: E-commerce items with inventory and pricing
- Categories: Organize content across all types
- WordPress Integration: Pull blog articles directly
- User login and authentication
- Profile management and settings
- Token-based access control
- User statistics and preferences
- App-specific user configurations
- Zero external dependencies
- Main-thread completion callbacks (safe for UI updates)
- NotificationCenter integration for data loading events
- Singleton pattern for easy access throughout your app
- Testable architecture with injectable URLSession
- Comprehensive error handling
The framework ships with a full unit test suite (197 tests) covering all services, models, and utilities.
xcodebuild test -scheme GathrTo test with custom network configuration:
import Gathr
// Override URLSession for testing
let mockConfig = URLSessionConfiguration.ephemeral
GathrNetwork.session = URLSession(configuration: mockConfig)
// Override configuration for testing
let testConfig: [String: Any] = [
"API_KEY": "test-key",
"BASE_URL": "https://test.example.com/v4/",
"TOKEN": "test-token",
"PLAYMEAPPTOKEN": "test-app-token"
]
GathrConfiguration.sharedInstance.configDictionary = testConfig as NSDictionary- Zero dependencies: Minimal binary size, no CocoaPods/SPM overhead
- Efficient networking: Native URLSession with JSON parsing via Foundation
- Lazy loading: Services only fetch data when accessed
- Main-thread dispatch: All completions use DispatchQueue.main for safe UI updates
- Weak references: Singletons use weak self in closures to prevent memory leaks
- Verify the file exists in your Xcode project
- Ensure it's added to your app target in Build Phases > Copy Bundle Resources
- Check that the filename is exactly
PlayMe.plist(case-sensitive)
- Verify all four keys are present in
PlayMe.plist - Check that your API key is valid
- Ensure network connectivity
- Verify the user token (if required) is valid
The framework handles network errors silently. To debug:
- Check your API key is correct
- Verify the base URL is reachable
- Ensure user tokens are valid if required
- Verify network permissions in your app's Info.plist
┌─────────────────────────────────┐
│ Your App │
└──────────┬──────────────────────┘
│
┌──────v──────────────────────────┐
│ Service Layer (Singletons) │
│ GathrAudio, GathrVideo, etc. │
└──────┬──────────────────────────┘
│
┌──────v──────────────────────────┐
│ GathrNetwork (HTTP) │
│ GET/POST with URLSession │
└──────┬──────────────────────────┘
│
┌──────v──────────────────────────┐
│ Gathr API (v4) │
│ https://api.gathr.me/v4/ │
└─────────────────────────────────┘
Contributions are welcome! Please maintain:
- Existing code style and patterns
- Unit tests for new functionality
- Documentation comments for public APIs
- Support for all platforms (iOS, macOS, tvOS, watchOS)
Copyright © 2016-2026 WEBDMG. All rights reserved.