Files
Sportstime/SportsTime/Export/Sharing/ShareService.swift
Trey t 61c4e39807 feat: update bundle ID config, CloudKit container, and add landing page
- Update CloudKit container ID to iCloud.com.88oakapps.SportsTime across all services
- Update IAP product IDs to match new bundle ID (com.88oakapps.SportsTime)
- Add app landing page with light, welcoming design matching app aesthetic
- Update entitlements and project configuration

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-01 22:47:55 -06:00

122 lines
3.6 KiB
Swift

//
// ShareService.swift
// SportsTime
//
// Handles Instagram direct share and fallback to system share sheet.
//
import SwiftUI
import UIKit
@MainActor
final class ShareService {
static let shared = ShareService()
private init() {}
// MARK: - Share to Instagram
func shareToInstagram(image: UIImage) -> Bool {
guard let imageData = image.pngData() else { return false }
// Check if Instagram is installed
guard let instagramURL = URL(string: "instagram-stories://share"),
UIApplication.shared.canOpenURL(instagramURL) else {
return false
}
// Set up pasteboard with image
let pasteboardItems: [String: Any] = [
"com.instagram.sharedSticker.backgroundImage": imageData
]
UIPasteboard.general.setItems(
[pasteboardItems],
options: [.expirationDate: Date().addingTimeInterval(300)]
)
// Open Instagram Stories
let urlString = "instagram-stories://share?source_application=com.88oakapps.SportsTime"
if let url = URL(string: urlString) {
UIApplication.shared.open(url)
return true
}
return false
}
// MARK: - Copy to Clipboard
func copyToClipboard(image: UIImage) {
UIPasteboard.general.image = image
}
// MARK: - System Share Sheet
func presentShareSheet(image: UIImage, from viewController: UIViewController) {
let activityVC = UIActivityViewController(
activityItems: [image],
applicationActivities: nil
)
// iPad support
if let popover = activityVC.popoverPresentationController {
popover.sourceView = viewController.view
popover.sourceRect = CGRect(
x: viewController.view.bounds.midX,
y: viewController.view.bounds.midY,
width: 0,
height: 0
)
}
viewController.present(activityVC, animated: true)
}
}
// MARK: - Theme Persistence
enum ShareThemePreferences {
private static let tripKey = "shareTheme.trip"
private static let achievementKey = "shareTheme.achievement"
private static let progressKey = "shareTheme.progress"
static var tripTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: tripKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: tripKey) }
}
static var achievementTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: achievementKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: achievementKey) }
}
static var progressTheme: ShareTheme {
get { ShareTheme.theme(byId: UserDefaults.standard.string(forKey: progressKey) ?? "dark") }
set { UserDefaults.standard.set(newValue.id, forKey: progressKey) }
}
static func theme(for cardType: ShareCardType) -> ShareTheme {
switch cardType {
case .tripSummary:
return tripTheme
case .achievementSpotlight, .achievementCollection, .achievementMilestone, .achievementContext:
return achievementTheme
case .stadiumProgress:
return progressTheme
}
}
static func setTheme(_ theme: ShareTheme, for cardType: ShareCardType) {
switch cardType {
case .tripSummary:
tripTheme = theme
case .achievementSpotlight, .achievementCollection, .achievementMilestone, .achievementContext:
achievementTheme = theme
case .stadiumProgress:
progressTheme = theme
}
}
}