diff --git a/Apps/KiedyBus/Assets.xcassets/Colors/AccentColor.colorset/Contents.json b/Apps/KiedyBus/Assets.xcassets/Colors/AccentColor.colorset/Contents.json new file mode 100644 index 000000000..b8b3110d1 --- /dev/null +++ b/Apps/KiedyBus/Assets.xcassets/Colors/AccentColor.colorset/Contents.json @@ -0,0 +1,38 @@ +{ + "colors" : [ + { + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEC", + "green" : "0x96", + "red" : "0x45" + } + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "color-space" : "srgb", + "components" : { + "alpha" : "1.000", + "blue" : "0xEC", + "green" : "0x96", + "red" : "0x45" + } + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Apps/KiedyBus/Assets.xcassets/Colors/Contents.json b/Apps/KiedyBus/Assets.xcassets/Colors/Contents.json index da4a164c9..73c00596a 100644 --- a/Apps/KiedyBus/Assets.xcassets/Colors/Contents.json +++ b/Apps/KiedyBus/Assets.xcassets/Colors/Contents.json @@ -1,6 +1,6 @@ { "info" : { - "version" : 1, - "author" : "xcode" + "author" : "xcode", + "version" : 1 } -} \ No newline at end of file +} diff --git a/Apps/OneBusAway/project.yml b/Apps/OneBusAway/project.yml index 91caff0c1..d60eb16da 100644 --- a/Apps/OneBusAway/project.yml +++ b/Apps/OneBusAway/project.yml @@ -11,17 +11,9 @@ targets: - path: Apps/OneBusAway name: App group: OneBusAway - - path: Apps/Shared/Analytics - name: Analytics - group: OneBusAway - path: Apps/Shared/CommonClient name: Common group: OneBusAway - - path: Apps/Shared/OneSignal - name: OneSignal - group: OneBusAway - dependencies: - - package: OneSignal entitlements: path: Apps/OneBusAway/OneBusAway.entitlements properties: @@ -107,6 +99,7 @@ include: - path: Apps/Shared/app_shared.yml - path: Apps/Shared/analytics_fx_config.yml - path: Apps/Shared/push_config.yml + - path: Apps/Shared/donations_config.yml - path: OBAKitCore/project.yml - path: OBAKit/project.yml - path: OBAKitTests/project.yml diff --git a/Apps/Shared/analytics_fx_config.yml b/Apps/Shared/analytics_fx_config.yml index 3e94e6b2e..2232cc58a 100644 --- a/Apps/Shared/analytics_fx_config.yml +++ b/Apps/Shared/analytics_fx_config.yml @@ -10,3 +10,7 @@ targets: product: FirebaseAnalytics - package: Firebase product: FirebaseCrashlytics + sources: + - path: ./Analytics + name: Analytics + group: Features \ No newline at end of file diff --git a/Apps/Shared/app_shared.yml b/Apps/Shared/app_shared.yml index 0f267e92b..196cba75a 100644 --- a/Apps/Shared/app_shared.yml +++ b/Apps/Shared/app_shared.yml @@ -99,12 +99,6 @@ packages: MarqueeLabel: url: https://github.com/cbpowell/MarqueeLabel.git exactVersion: 4.3.0 - OneSignal: - url: https://github.com/OneSignal/OneSignal-iOS-SDK.git - minorVersion: 3.11.2 - stripe-ios-spm: - url: https://github.com/stripe/stripe-ios-spm.git - minorVersion: 23.18.2 SwiftProtobuf: url: https://github.com/apple/swift-protobuf.git minorVersion: 1.19.1 diff --git a/Apps/Shared/donations_config.yml b/Apps/Shared/donations_config.yml new file mode 100644 index 000000000..f5933c24c --- /dev/null +++ b/Apps/Shared/donations_config.yml @@ -0,0 +1,19 @@ +targets: + App: + info: + path: Apps/OneBusAway/Info.plist + properties: + NSCameraUsageDescription: This app uses Stripe to process credit cards. You can use Stripe to scan your credit card number with your camera. + OBAKit: + dependencies: + - package: stripe-ios-spm + product: Stripe + - package: stripe-ios-spm + product: StripeApplePay + - package: stripe-ios-spm + product: StripePaymentSheet + +packages: + stripe-ios-spm: + url: https://github.com/stripe/stripe-ios-spm.git + minorVersion: 23.18.2 \ No newline at end of file diff --git a/Apps/Shared/push_config.yml b/Apps/Shared/push_config.yml index 012fafe41..43b1dea1c 100644 --- a/Apps/Shared/push_config.yml +++ b/Apps/Shared/push_config.yml @@ -4,10 +4,21 @@ targets: SystemCapabilities: com.apple.Push: enabled: 1 + dependencies: + - package: OneSignal entitlements: properties: aps-environment: development info: properties: UIBackgroundModes: - - remote-notification \ No newline at end of file + - remote-notification + sources: + - path: ./OneSignal + name: OneSignal + group: Features + +packages: + OneSignal: + url: https://github.com/OneSignal/OneSignal-iOS-SDK.git + minorVersion: 3.11.2 \ No newline at end of file diff --git a/OBAKit/Donations/DonationLearnMoreView.swift b/OBAKit/Donations/DonationLearnMoreView.swift index b4883ef76..f66522300 100644 --- a/OBAKit/Donations/DonationLearnMoreView.swift +++ b/OBAKit/Donations/DonationLearnMoreView.swift @@ -9,6 +9,8 @@ import SwiftUI import UIKit import OBAKitCore +#if canImport(Stripe) + enum DonationRecurrence: String, CaseIterable, Identifiable { case oneTime case recurring @@ -241,3 +243,5 @@ struct DonationLearnMoreView: View { // abxoxo - needs environment object added. // DonationLearnMoreView() // } + +#endif diff --git a/OBAKit/Donations/DonationModel.swift b/OBAKit/Donations/DonationModel.swift index 3e08dad2a..3df5b496e 100644 --- a/OBAKit/Donations/DonationModel.swift +++ b/OBAKit/Donations/DonationModel.swift @@ -5,24 +5,12 @@ // Created by Aaron Brethorst on 11/11/23. // +#if canImport(Stripe) import StripePaymentSheet import SwiftUI import OBAKitCore import PassKit -extension PaymentSheetResult: Equatable { - public static func == (lhs: PaymentSheetResult, rhs: PaymentSheetResult) -> Bool { - switch (lhs, rhs) { - case (.completed, .completed), (.canceled, .canceled): - return true - case (.failed(let lhsError), .failed(let rhsError)): - return lhsError.localizedDescription == rhsError.localizedDescription - default: - return false - } - } -} - /// `DonationModel` is an `ObservableObject` for use in SwiftUI that manages the donation process. /// /// It manages the donation data, communicates with the server, and provides updates to the UI. @@ -239,3 +227,8 @@ class DonationModel: ObservableObject { } } } + +#else +class DonationModel: ObservableObject { +} +#endif diff --git a/OBAKit/Donations/DonationsManager.swift b/OBAKit/Donations/DonationsManager.swift index 02a97f12d..c86d08463 100644 --- a/OBAKit/Donations/DonationsManager.swift +++ b/OBAKit/Donations/DonationsManager.swift @@ -7,9 +7,15 @@ import Foundation import OBAKitCore -import StripeApplePay import SwiftUI +public enum DonationsUserDefaultsKeys: String, RawRepresentable { + case forceStripeTestModeDefaultsKey = "forceStripeTestMode" +} + +#if canImport(Stripe) +import StripeApplePay + /// Manages the visibility of donation requests. public class DonationsManager { @@ -29,7 +35,7 @@ public class DonationsManager { self.analytics = analytics self.userDefaults.register( - defaults: [DonationsManager.forceStripeTestModeDefaultsKey: false] + defaults: [DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue: false] ) } @@ -44,7 +50,6 @@ public class DonationsManager { private let userDefaults: UserDefaults private static let donationRequestDismissedDateKey = "donationRequestDismissedDateKey" private static let donationRequestReminderDateKey = "donationRequestReminderDateKey" - public static let forceStripeTestModeDefaultsKey = "forceStripeTestMode" // MARK: - Dismiss Donations Request @@ -103,7 +108,7 @@ public class DonationsManager { #if DEBUG return true #else - return userDefaults.bool(forKey: DonationsManager.forceStripeTestModeDefaultsKey) + return userDefaults.bool(forKey: DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue) #endif } @@ -161,3 +166,27 @@ public class DonationsManager { .environmentObject(AnalyticsModel(analytics)) } } +#else +public class DonationsManager { + public init( + bundle: Bundle, + userDefaults: UserDefaults, + obacoService: ObacoAPIService?, + analytics: Analytics? + ) {} + + public var donationsEnabled: Bool { + false + } + + public var shouldRequestDonations: Bool { + false + } + + public func dismissDonationsRequests() {} + + public func remindUserLater() {} + + public func refreshStripePublishableKey() {} +} +#endif diff --git a/OBAKit/Donations/StripeExtensions.swift b/OBAKit/Donations/StripeExtensions.swift new file mode 100644 index 000000000..94dcb0e04 --- /dev/null +++ b/OBAKit/Donations/StripeExtensions.swift @@ -0,0 +1,23 @@ +// +// StripeExtensions.swift +// OBAKit +// +// Created by Aaron Brethorst on 1/16/24. +// + +#if canImport(Stripe) +import StripePaymentSheet + +extension PaymentSheetResult: Equatable { + public static func == (lhs: PaymentSheetResult, rhs: PaymentSheetResult) -> Bool { + switch (lhs, rhs) { + case (.completed, .completed), (.canceled, .canceled): + return true + case (.failed(let lhsError), .failed(let rhsError)): + return lhsError.localizedDescription == rhsError.localizedDescription + default: + return false + } + } +} +#endif diff --git a/OBAKit/Orchestration/Application.swift b/OBAKit/Orchestration/Application.swift index 949b287bd..8ab7c2113 100644 --- a/OBAKit/Orchestration/Application.swift +++ b/OBAKit/Orchestration/Application.swift @@ -15,7 +15,9 @@ import OBAKitCore import SafariServices import MapKit import SwiftUI +#if canImport(Stripe) import StripeApplePay +#endif // MARK: - Protocols @@ -289,10 +291,12 @@ public class Application: CoreApplication, PushServiceDelegate { } private func presentDonationUI(_ presentingController: UIViewController, id: String?) { +#if canImport(Stripe) analytics?.reportEvent?(.userAction, label: AnalyticsLabels.donationPushNotificationTapped, value: id) let learnMoreView = donationsManager.buildLearnMoreView(presentingController: presentingController, donationPushNotificationID: id) presentingController.present(UIHostingController(rootView: learnMoreView), animated: true) +#endif } // MARK: - Alerts Store @@ -414,9 +418,11 @@ public class Application: CoreApplication, PushServiceDelegate { @MainActor @objc public func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool { +#if canImport(Stripe) if StripeAPI.handleURLCallback(with: url) { return true } +#endif guard let scheme = Bundle.main.extensionURLScheme else { return false @@ -437,8 +443,10 @@ public class Application: CoreApplication, PushServiceDelegate { override public func apiServicesRefreshed() { super.apiServicesRefreshed() +#if canImport(Stripe) donationsManager.obacoService = obacoService donationsManager.refreshStripePublishableKey() +#endif } // MARK: - Appearance and Themes diff --git a/OBAKit/Settings/MoreViewController.swift b/OBAKit/Settings/MoreViewController.swift index 3d70d7874..c6ad1e10f 100644 --- a/OBAKit/Settings/MoreViewController.swift +++ b/OBAKit/Settings/MoreViewController.swift @@ -123,9 +123,12 @@ public class MoreViewController: UIViewController, private func showDonationUI() { guard application.donationsManager.donationsEnabled else { return } + +#if canImport(Stripe) let view = application.donationsManager.buildLearnMoreView(presentingController: self) let hostingController = UIHostingController(rootView: view) present(hostingController, animated: true) +#endif } // MARK: Updates and alerts section diff --git a/OBAKit/Settings/SettingsViewController.swift b/OBAKit/Settings/SettingsViewController.swift index e83aba47f..eead1231d 100644 --- a/OBAKit/Settings/SettingsViewController.swift +++ b/OBAKit/Settings/SettingsViewController.swift @@ -56,7 +56,7 @@ class SettingsViewController: FormViewController { AgencyAlertsStore.UserDefaultKeys.displayRegionalTestAlerts: application.userDefaults.bool(forKey: AgencyAlertsStore.UserDefaultKeys.displayRegionalTestAlerts), RegionsService.alwaysRefreshRegionsOnLaunchUserDefaultsKey: application.userDefaults.bool(forKey: RegionsService.alwaysRefreshRegionsOnLaunchUserDefaultsKey), MapRegionManager.mapViewShowsStopAnnotationLabelsDefaultsKey: application.userDefaults.bool(forKey: MapRegionManager.mapViewShowsStopAnnotationLabelsDefaultsKey), - DonationsManager.forceStripeTestModeDefaultsKey: application.userDefaults.bool(forKey: DonationsManager.forceStripeTestModeDefaultsKey), + DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue: application.userDefaults.bool(forKey: DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue), debugModeEnabled: application.userDataStore.debugMode ]) } @@ -110,8 +110,8 @@ class SettingsViewController: FormViewController { application.userDefaults.set(false, forKey: RegionsService.alwaysRefreshRegionsOnLaunchUserDefaultsKey) } - if let forceStripeTestMode = values[DonationsManager.forceStripeTestModeDefaultsKey] as? Bool { - application.userDefaults.set(forceStripeTestMode, forKey: DonationsManager.forceStripeTestModeDefaultsKey) + if application.donationsManager.donationsEnabled, let forceStripeTestMode = values[DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue] as? Bool { + application.userDefaults.set(forceStripeTestMode, forKey: DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue) application.donationsManager.refreshStripePublishableKey() } } @@ -235,12 +235,14 @@ class SettingsViewController: FormViewController { } } - section <<< SwitchRow { - $0.tag = DonationsManager.forceStripeTestModeDefaultsKey - $0.title = OBALoc("settings_controller.debug_section.force_stripe_test_mode", value: "Force Stripe test mode", comment: "Settings > Debug section > Force Stripe test mode") - $0.hidden = Condition.function([debugModeEnabled], { form in - return !((form.rowBy(tag: self.debugModeEnabled) as? SwitchRow)?.value ?? false) - }) + if application.donationsManager.donationsEnabled { + section <<< SwitchRow { + $0.tag = DonationsUserDefaultsKeys.forceStripeTestModeDefaultsKey.rawValue + $0.title = OBALoc("settings_controller.debug_section.force_stripe_test_mode", value: "Force Stripe test mode", comment: "Settings > Debug section > Force Stripe test mode") + $0.hidden = Condition.function([debugModeEnabled], { form in + return !((form.rowBy(tag: self.debugModeEnabled) as? SwitchRow)?.value ?? false) + }) + } } section <<< TextRow { diff --git a/OBAKit/Stops/StopViewController.swift b/OBAKit/Stops/StopViewController.swift index c17c6a770..d9ca433d7 100644 --- a/OBAKit/Stops/StopViewController.swift +++ b/OBAKit/Stops/StopViewController.swift @@ -11,7 +11,9 @@ import UIKit import OBAKitCore import CoreLocation import SwiftUI +#if canImport(Stripe) import StripePaymentSheet +#endif // swiftlint:disable file_length @@ -645,6 +647,7 @@ public class StopViewController: UIViewController, } private func showDonationUI() { +#if canImport(Stripe) guard application.donationsManager.donationsEnabled, let donationModel = application.donationsManager.buildObservableDonationModel() @@ -665,6 +668,7 @@ public class StopViewController: UIViewController, .environmentObject(AnalyticsModel(application.analytics)) present(UIHostingController(rootView: learnMoreView), animated: true) +#endif } private func showDonationDismissUI() { diff --git a/OBAKit/project.yml b/OBAKit/project.yml index ce77d1935..0079329d0 100644 --- a/OBAKit/project.yml +++ b/OBAKit/project.yml @@ -10,12 +10,6 @@ targets: - package: Eureka - package: FloatingPanel - package: MarqueeLabel - - package: stripe-ios-spm - product: Stripe - - package: stripe-ios-spm - product: StripeApplePay - - package: stripe-ios-spm - product: StripePaymentSheet postBuildScripts: - path: "../scripts/swiftlint.sh" name: Swiftlint