Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

19951 permissions #315

Merged
merged 2 commits into from
Nov 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions Sources/TripKitUI/managers/TKUINotificationManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ typealias Publisher = ([UNNotificationRequest]) -> Void

public class TKUINotificationManager: NSObject {

public weak var pushProvider: TKUINotificationPushProvider?
public weak var delegate: TKUINotificationManagerDelegate?

// List down Notification contexts here
let subscriptions: [TKUINotificationSubscription] = [.init(context: .tripAlerts), .init(context: .pushNotifications)]
Expand Down Expand Up @@ -94,17 +94,27 @@ public class TKUINotificationManager: NSObject {

}

public protocol TKUINotificationPushProvider: AnyObject {

/// - Returns: Whether push notifications are enabled for this device and permissions are granted
func notificationPushEnabled() -> Bool

/// Called before subscribing to push notifications for a specifc trip. This should then make sure
/// that `TKServer.shared.userToken` is set before returning. If this can't be set, it
/// should throw an error.
public protocol TKUINotificationManagerDelegate: AnyObject {

/// Check and, if necessary, ask for notification permissions. If no permissions are granted, this
/// should then also directly show an appropriate alert about how to enable them.
///
/// - Returns: Whether notifications are enabled for this device or permissions are not determined
func notificationsPermissionsNeeded() async -> Bool

/// Called before subscribing to push notifications for a specifc trip.
///
/// This should then make sure that `TKServer.shared.userToken` is set before returning.
/// If this can't be set, it should throw an error.
///
/// Only needed to implement, when enabling push notification-based trip notifications
func notificationRequireUserToken() async throws
}

extension TKUINotificationManagerDelegate {
public func notificationRequireUserToken() async throws {}
}

public class TKUINotificationSubscription {
public enum Context {
case tripAlerts
Expand Down
14 changes: 9 additions & 5 deletions Sources/TripKitUI/managers/TKUITripMonitorManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ import TripKit
/// - Project > Your Target > Capabilities > Background Modes: Enable "Location Updates"
/// - Project > Your Target > Info: Include both `NSLocationAlwaysAndWhenInUseUsageDescription` and `NSLocationWhenInUseUsageDescription`
/// - Then call `TKUINotificationManager.shared.subscribe(to: .tripAlerts) { ... }` in your app.
/// - Implement `TKUINotificationManagerDelegate` and set it on `TKUINotificationManager.shared.delegate`
///
/// ### Push notifications:
///
/// An additional feature is server-side notifications related to a trip being monitored. This requires additional
/// set-up:
///
/// - Implement `TKUINotificationPushProvider` and set it on `TKUINotificationManager.shared.pushProvider`
/// - Lastly, call `TKUINotificationManager.shared.subscribe(to: .pushNotifications) { _ in }`
///
@MainActor
Expand Down Expand Up @@ -127,11 +127,15 @@ public class TKUITripMonitorManager: NSObject, ObservableObject {
guard !notifications.isEmpty else {
return
}

guard let delegate = TKUINotificationManager.shared.delegate, await delegate.notificationsPermissionsNeeded() else {
return
}

// Subscribe to push-notifications, if enabled
if let provider = TKUINotificationManager.shared.pushProvider, provider.notificationPushEnabled(), let subscribeURL = trip.subscribeURL {
if let subscribeURL = trip.subscribeURL {
// If this fails, it'll abort enabling notifications
try await provider.notificationRequireUserToken()
try await delegate.notificationRequireUserToken()
let _ = await TKServer.shared.hit(url: subscribeURL)
}

Expand Down Expand Up @@ -159,9 +163,9 @@ public class TKUITripMonitorManager: NSObject, ObservableObject {
}

public func stopMonitoring() async {
if let provider = TKUINotificationManager.shared.pushProvider, let monitoredTrip, let unsubscribeURL = monitoredTrip.unsubscribeURL {
if let delegate = TKUINotificationManager.shared.delegate, let monitoredTrip, let unsubscribeURL = monitoredTrip.unsubscribeURL {
// If this fails, we'll disable the local notifications anyway
try? await provider.notificationRequireUserToken()
try? await delegate.notificationRequireUserToken()
let _ = await TKServer.shared.hit(url: unsubscribeURL)
}

Expand Down
Loading