Skip to content

Commit 5b668a8

Browse files
committed
feat: PointFree Dependency library support added
1 parent 4c8e443 commit 5b668a8

File tree

11 files changed

+165
-69
lines changed

11 files changed

+165
-69
lines changed

Example/App/AppDelegate.swift

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@
77

88
import AppFeature
99
import Combine
10+
import Dependencies
1011
import SwiftUI
1112
import UserNotificationsClient
13+
import RemoteNotificationsClient
1214

1315
@main
1416
final class AppDelegate: NSObject, UIApplicationDelegate {
@@ -43,24 +45,30 @@ extension SceneDelegate {
4345
// The user notification client needs to be initialized here at the app start
4446
// to assign the UNNotificationCenter delegate soon enough to react to events
4547
// coming from the notifications that opened the app
46-
let environment = AppEnvironment(remoteNotificationsClient: .live,
47-
userNotificationsClient: .live())
48+
let remoteNotificationsClient = RemoteNotificationsClient.live
49+
let userNotificationsClient = UserNotificationClient.live()
50+
51+
let vm = withDependencies {
52+
$0.remoteNotificationsClient = remoteNotificationsClient
53+
$0.userNotificationClient = userNotificationsClient
54+
} operation: {
55+
AppViewModel()
56+
}
4857

49-
let vm = AppViewModel(environment: environment)
5058
let appView = AppView(viewModel: vm)
5159

5260
// Listen to the notification events and handle them
5361
Task {
54-
for await event in environment.userNotificationsClient.delegate() {
62+
for await event in userNotificationsClient.delegate() {
5563
handleNotificationEvent(event, appViewModel: vm)
5664
}
5765
}
5866

5967
// Register for remote notifications if the user granted the permissions
6068
Task {
61-
let allowed = await (environment.userNotificationsClient.getAuthorizationStatus() == .authorized)
69+
let allowed = await (userNotificationsClient.getAuthorizationStatus() == .authorized)
6270
if allowed {
63-
environment.remoteNotificationsClient.registerForRemoteNotifications()
71+
remoteNotificationsClient.registerForRemoteNotifications()
6472
}
6573
}
6674

Example/App/Info.plist

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
</array>
2828
</dict>
2929
</dict>
30-
<key>UIStatusBarStyle</key>
31-
<string>UIStatusBarStyleLightContent</string>
3230
<key>UISupportedExternalAccessoryProtocols</key>
3331
<array>
3432
<string>com.bixolon.protocol</string>

Example/Modules/Package.swift

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,19 +12,17 @@ let package = Package(
1212
.library(name: "AppFeature", targets: ["AppFeature"])
1313
],
1414
dependencies: [
15-
.package(url: "https://github.com/pointfreeco/combine-schedulers", from: "0.5.3"),
15+
.package(url: "https://github.com/pointfreeco/combine-schedulers", from: "0.9.0"),
1616
.package(url: "https://github.com/pointfreeco/swiftui-navigation", from: "0.1.0"),
17-
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "0.2.1"),
1817
// NotificationsClients library
1918
.package(path: "../..")
2019
],
2120
targets: [
2221
.target(
2322
name: "AppFeature",
2423
dependencies: [
25-
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
2624
.product(name: "SwiftUINavigation", package: "swiftui-navigation"),
27-
.product(name: "NotificationsClients", package: "NotificationsClients")
25+
.product(name: "NotificationsClients", package: "NotificationsClients"),
2826
],
2927
resources: []
3028
),

Example/Modules/Sources/AppFeature/AppViewModel.swift

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
import Combine
22
import SwiftUI
3+
import Dependencies
4+
import UserNotificationsClient
5+
import RemoteNotificationsClient
36

47
public class AppViewModel: ObservableObject {
5-
var environment: AppEnvironment
8+
public init() { }
69
@Published var permissionsCanBeRequested: Bool = true
710
@Published var notificationMessage: String?
8-
9-
public init(
10-
environment: AppEnvironment
11-
) {
12-
self.environment = environment
13-
}
11+
@Dependency(\.remoteNotificationsClient) public var remoteNotificationsClient
12+
@Dependency(\.userNotificationClient) public var userNotificationsClient
1413

1514
public func receiveNotificationMessage(_ message: String) {
1615
self.notificationMessage = nil
@@ -20,7 +19,7 @@ public class AppViewModel: ObservableObject {
2019
}
2120

2221
func checkPermissionStatus() async {
23-
let status = await environment.userNotificationsClient.getAuthorizationStatus()
22+
let status = await userNotificationsClient.getAuthorizationStatus()
2423
switch status {
2524
case .notDetermined:
2625
permissionsCanBeRequested = true
@@ -33,15 +32,15 @@ public class AppViewModel: ObservableObject {
3332
Task { @MainActor in
3433
do {
3534
// Get the authorization status
36-
switch await environment.userNotificationsClient.getAuthorizationStatus() {
35+
switch await userNotificationsClient.getAuthorizationStatus() {
3736
case .notDetermined:
3837
// Request the authorization
39-
let allowed = try await environment.userNotificationsClient.requestAuthorization([.alert, .badge, .sound])
38+
let allowed = try await userNotificationsClient.requestAuthorization([.alert, .badge, .sound])
4039
if allowed {
4140
// Register the app to receive remote notifications
4241
// You probably want to call this also on app start
4342
// for case when the user allows the push permissions in the iOS settings
44-
environment.remoteNotificationsClient.registerForRemoteNotifications()
43+
remoteNotificationsClient.registerForRemoteNotifications()
4544
}
4645
await checkPermissionStatus()
4746
default: return
@@ -61,7 +60,7 @@ public class AppViewModel: ObservableObject {
6160
content.userInfo["deeplink"] = "scheme://not_really_a_deeplink"
6261

6362
let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 1, repeats: false)
64-
try await environment.userNotificationsClient.addRequest(.init(identifier: UUID().uuidString,
63+
try await userNotificationsClient.addRequest(.init(identifier: UUID().uuidString,
6564
content: content,
6665
trigger: trigger))
6766

Example/NotificationClientsExample.xcodeproj/project.pbxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -291,6 +291,7 @@
291291
INFOPLIST_FILE = App/Info.plist;
292292
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
293293
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
294+
INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent;
294295
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
295296
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
296297
INFOPLIST_OUTPUT_FORMAT = XML;
@@ -448,6 +449,7 @@
448449
INFOPLIST_FILE = App/Info.plist;
449450
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
450451
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
452+
INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent;
451453
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
452454
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
453455
INFOPLIST_OUTPUT_FORMAT = XML;
@@ -482,6 +484,7 @@
482484
INFOPLIST_FILE = App/Info.plist;
483485
INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
484486
INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
487+
INFOPLIST_KEY_UIStatusBarStyle = UIStatusBarStyleLightContent;
485488
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
486489
INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
487490
INFOPLIST_OUTPUT_FORMAT = XML;

Example/NotificationClientsExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 56 additions & 40 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.resolved

Lines changed: 27 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,18 +14,24 @@ let package = Package(
1414
"UserNotificationsClient"]),
1515
],
1616
dependencies: [
17-
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "0.8.0"),
18-
// Dependencies declare other packages that this package depends on.
19-
// .package(url: /* package url */, from: "1.0.0"),
17+
.package(
18+
url: "https://github.com/pointfreeco/xctest-dynamic-overlay",
19+
from: "0.8.0"),
20+
.package(
21+
url: "https://github.com/pointfreeco/swift-dependencies",
22+
from: "0.1.0"
23+
),
2024
],
2125
targets: [
2226
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
2327
// Targets can depend on other targets in this package, and on products in packages this package depends on.
2428
.target(
2529
name: "RemoteNotificationsClient",
26-
dependencies: [.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay")]),
30+
dependencies: [.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
31+
.product(name: "Dependencies", package: "swift-dependencies")]),
2732
.target(
2833
name: "UserNotificationsClient",
29-
dependencies: [.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay")]),
34+
dependencies: [.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
35+
.product(name: "Dependencies", package: "swift-dependencies")]),
3036
]
3137
)

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,12 @@ func setupAppEnvironment() {
5555
}
5656
```
5757

58+
Both the `RemoteNotificationsClient` and the `UserNotificationsClient` are already prepared for integration using the [PointFree Dependencies library](https://github.com/pointfreeco/swift-dependencies). You can also define them as:
59+
```swift
60+
@Dependency(\.remoteNotificationsClient) var remoteNotificationsClient
61+
@Dependency(\.userNotificationClient) var userNotificationsClient
62+
```
63+
5864
### Requesting the push notifications authorization
5965
```swift
6066
func requestPushAuthorization() async {

Sources/RemoteNotificationsClient/Interface.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//
77

88
import Foundation
9+
import Dependencies
910

1011
/// Interface for a client that handles app registration for remote notifications
1112
public struct RemoteNotificationsClient {
@@ -19,3 +20,20 @@ public struct RemoteNotificationsClient {
1920
/// Unregister the app to receive remote notifications
2021
public var unregisterForRemoteNotifications: () async -> Void
2122
}
23+
24+
25+
extension RemoteNotificationsClient: DependencyKey {
26+
public static let liveValue = RemoteNotificationsClient.live
27+
#if DEBUG
28+
public static let previewValue = RemoteNotificationsClient.noop
29+
public static let testValue = RemoteNotificationsClient.failing
30+
#endif
31+
}
32+
33+
34+
public extension DependencyValues {
35+
var remoteNotificationsClient: RemoteNotificationsClient {
36+
get { self[RemoteNotificationsClient.self] }
37+
set { self[RemoteNotificationsClient.self] = newValue }
38+
}
39+
}

0 commit comments

Comments
 (0)