mirror of
git://jb55.com/damus
synced 2024-09-30 00:40:45 +00:00
Move device token sending logic to its own component
This commit moves the device token logic to a new PushNotificationClient, to move complexity from this specific feature away from damusApp.swift This commit also slightly improves the handling of device tokens, by caching it on the client struct even if the user is using local notifications, so that the device token can be sent to the server immediately after switching to push notifications mode. Signed-off-by: Daniel D’Aquino <daniel@daquino.me> Reviewed-by: William Casarin <jb55@jb55.com>
This commit is contained in:
parent
0a9bcb6189
commit
b148fb735e
@ -615,6 +615,7 @@
|
|||||||
D7CE1B472B0BE719002EDAD4 /* NativeObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9462A9AD44700DC3548 /* NativeObject.swift */; };
|
D7CE1B472B0BE719002EDAD4 /* NativeObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B9462A9AD44700DC3548 /* NativeObject.swift */; };
|
||||||
D7CE1B482B0BE719002EDAD4 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93D2A9AD44700DC3548 /* Message.swift */; };
|
D7CE1B482B0BE719002EDAD4 /* Message.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C32B93D2A9AD44700DC3548 /* Message.swift */; };
|
||||||
D7CE1B492B0BE729002EDAD4 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
|
D7CE1B492B0BE729002EDAD4 /* DisplayName.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C9BB83029C0ED4F00FC4E37 /* DisplayName.swift */; };
|
||||||
|
D7D2A3812BF815D000E4B42B /* PushNotificationClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */; };
|
||||||
D7DBD41F2B02F15E002A6197 /* NostrKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD32819DE8F00B3DE84 /* NostrKind.swift */; };
|
D7DBD41F2B02F15E002A6197 /* NostrKind.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C3BEFD32819DE8F00B3DE84 /* NostrKind.swift */; };
|
||||||
D7DEEF2F2A8C021E00E0C99F /* NostrEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */; };
|
D7DEEF2F2A8C021E00E0C99F /* NostrEventTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */; };
|
||||||
D7EDED152B11776B0018B19C /* LibreTranslateServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE45AF5297BB2E700C1D842 /* LibreTranslateServer.swift */; };
|
D7EDED152B11776B0018B19C /* LibreTranslateServer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE45AF5297BB2E700C1D842 /* LibreTranslateServer.swift */; };
|
||||||
@ -1437,6 +1438,7 @@
|
|||||||
D7CB5D5E2B11770C00AD4105 /* FollowState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowState.swift; sourceTree = "<group>"; };
|
D7CB5D5E2B11770C00AD4105 /* FollowState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FollowState.swift; sourceTree = "<group>"; };
|
||||||
D7CBD1D32B8D21DC00BFD889 /* DamusPurpleNotificationManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleNotificationManagement.swift; sourceTree = "<group>"; };
|
D7CBD1D32B8D21DC00BFD889 /* DamusPurpleNotificationManagement.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleNotificationManagement.swift; sourceTree = "<group>"; };
|
||||||
D7CBD1D52B8D509800BFD889 /* DamusPurpleImpendingExpirationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleImpendingExpirationTests.swift; sourceTree = "<group>"; };
|
D7CBD1D52B8D509800BFD889 /* DamusPurpleImpendingExpirationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleImpendingExpirationTests.swift; sourceTree = "<group>"; };
|
||||||
|
D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PushNotificationClient.swift; sourceTree = "<group>"; };
|
||||||
D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrEventTests.swift; sourceTree = "<group>"; };
|
D7DEEF2E2A8C021E00E0C99F /* NostrEventTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NostrEventTests.swift; sourceTree = "<group>"; };
|
||||||
D7EDED1B2B1178FE0018B19C /* NoteContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContent.swift; sourceTree = "<group>"; };
|
D7EDED1B2B1178FE0018B19C /* NoteContent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteContent.swift; sourceTree = "<group>"; };
|
||||||
D7EDED1D2B11797D0018B19C /* LongformEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongformEvent.swift; sourceTree = "<group>"; };
|
D7EDED1D2B11797D0018B19C /* LongformEvent.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LongformEvent.swift; sourceTree = "<group>"; };
|
||||||
@ -1663,6 +1665,7 @@
|
|||||||
D74AAFC12B153395006CF0F4 /* HeadlessDamusState.swift */,
|
D74AAFC12B153395006CF0F4 /* HeadlessDamusState.swift */,
|
||||||
B5C60C1F2B530D5100C5ECA7 /* MuteItem.swift */,
|
B5C60C1F2B530D5100C5ECA7 /* MuteItem.swift */,
|
||||||
B533694D2B66D791008A805E /* MutelistManager.swift */,
|
B533694D2B66D791008A805E /* MutelistManager.swift */,
|
||||||
|
D7D2A3802BF815D000E4B42B /* PushNotificationClient.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -3291,6 +3294,7 @@
|
|||||||
5CF2DCCC2AA3AF0B00984B8D /* RelayPicView.swift in Sources */,
|
5CF2DCCC2AA3AF0B00984B8D /* RelayPicView.swift in Sources */,
|
||||||
4C687C242A5FA86D0092C550 /* SearchHeaderView.swift in Sources */,
|
4C687C242A5FA86D0092C550 /* SearchHeaderView.swift in Sources */,
|
||||||
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */,
|
64FBD06F296255C400D9D3B2 /* Theme.swift in Sources */,
|
||||||
|
D7D2A3812BF815D000E4B42B /* PushNotificationClient.swift in Sources */,
|
||||||
4C1A9A2329DDDB8100516EAC /* IconLabel.swift in Sources */,
|
4C1A9A2329DDDB8100516EAC /* IconLabel.swift in Sources */,
|
||||||
4CA352AC2A76C07F003BB08B /* NewUnmutesNotify.swift in Sources */,
|
4CA352AC2A76C07F003BB08B /* NewUnmutesNotify.swift in Sources */,
|
||||||
4C3EA64928FF597700C48A62 /* bech32.c in Sources */,
|
4C3EA64928FF597700C48A62 /* bech32.c in Sources */,
|
||||||
|
@ -308,7 +308,7 @@ struct ContentView: View {
|
|||||||
active_sheet = .onboardingSuggestions
|
active_sheet = .onboardingSuggestions
|
||||||
hasSeenOnboardingSuggestions = true
|
hasSeenOnboardingSuggestions = true
|
||||||
}
|
}
|
||||||
self.appDelegate?.settings = damus_state?.settings
|
self.appDelegate?.state = damus_state
|
||||||
}
|
}
|
||||||
.sheet(item: $active_sheet) { item in
|
.sheet(item: $active_sheet) { item in
|
||||||
switch item {
|
switch item {
|
||||||
|
@ -36,6 +36,7 @@ class DamusState: HeadlessDamusState {
|
|||||||
let video: VideoController
|
let video: VideoController
|
||||||
let ndb: Ndb
|
let ndb: Ndb
|
||||||
var purple: DamusPurple
|
var purple: DamusPurple
|
||||||
|
var push_notification_client: PushNotificationClient
|
||||||
|
|
||||||
init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [RelayURL], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: VideoController, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter) {
|
init(pool: RelayPool, keypair: Keypair, likes: EventCounter, boosts: EventCounter, contacts: Contacts, mutelist_manager: MutelistManager, profiles: Profiles, dms: DirectMessagesModel, previews: PreviewCache, zaps: Zaps, lnurls: LNUrls, settings: UserSettingsStore, relay_filters: RelayFilters, relay_model_cache: RelayModelCache, drafts: Drafts, events: EventCache, bookmarks: BookmarksManager, postbox: PostBox, bootstrap_relays: [RelayURL], replies: ReplyCounter, wallet: WalletModel, nav: NavigationCoordinator, music: MusicController?, video: VideoController, ndb: Ndb, purple: DamusPurple? = nil, quote_reposts: EventCounter) {
|
||||||
self.pool = pool
|
self.pool = pool
|
||||||
@ -68,6 +69,7 @@ class DamusState: HeadlessDamusState {
|
|||||||
keypair: keypair
|
keypair: keypair
|
||||||
)
|
)
|
||||||
self.quote_reposts = quote_reposts
|
self.quote_reposts = quote_reposts
|
||||||
|
self.push_notification_client = PushNotificationClient(keypair: keypair, settings: settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
@discardableResult
|
@discardableResult
|
||||||
|
62
damus/Models/PushNotificationClient.swift
Normal file
62
damus/Models/PushNotificationClient.swift
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
//
|
||||||
|
// PushNotificationClient.swift
|
||||||
|
// damus
|
||||||
|
//
|
||||||
|
// Created by Daniel D’Aquino on 2024-05-17.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct PushNotificationClient {
|
||||||
|
let keypair: Keypair
|
||||||
|
let settings: UserSettingsStore
|
||||||
|
private(set) var device_token: Data? = nil
|
||||||
|
|
||||||
|
mutating func set_device_token(new_device_token: Data) async throws {
|
||||||
|
self.device_token = new_device_token
|
||||||
|
if settings.enable_experimental_push_notifications && settings.notifications_mode == .push {
|
||||||
|
try await self.send_token()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func send_token() async throws {
|
||||||
|
guard let device_token else { return }
|
||||||
|
// Send the device token and pubkey to the server
|
||||||
|
let token = device_token.map { String(format: "%02.2hhx", $0) }.joined()
|
||||||
|
|
||||||
|
Log.info("Sending device token to server: %s", for: .push_notifications, token)
|
||||||
|
|
||||||
|
let pubkey = self.keypair.pubkey
|
||||||
|
|
||||||
|
// Send those as JSON to the server
|
||||||
|
let json: [String: Any] = ["deviceToken": token, "pubkey": pubkey.hex()]
|
||||||
|
|
||||||
|
// create post request
|
||||||
|
let url = self.settings.send_device_token_to_localhost ? Constants.DEVICE_TOKEN_RECEIVER_TEST_URL : Constants.DEVICE_TOKEN_RECEIVER_PRODUCTION_URL
|
||||||
|
var request = URLRequest(url: url)
|
||||||
|
request.httpMethod = "POST"
|
||||||
|
|
||||||
|
// insert json data to the request
|
||||||
|
request.httpBody = try? JSONSerialization.data(withJSONObject: json, options: [])
|
||||||
|
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
||||||
|
|
||||||
|
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
||||||
|
guard let data = data, error == nil else {
|
||||||
|
print(error?.localizedDescription ?? "No data")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if let response = response as? HTTPURLResponse, !(200...299).contains(response.statusCode) {
|
||||||
|
print("Unexpected status code: \(response.statusCode)")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
|
||||||
|
if let responseJSON = responseJSON as? [String: Any] {
|
||||||
|
print(responseJSON)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
task.resume()
|
||||||
|
}
|
||||||
|
}
|
@ -54,14 +54,12 @@ struct MainView: View {
|
|||||||
.onAppear {
|
.onAppear {
|
||||||
orientationTracker.setDeviceMajorAxis()
|
orientationTracker.setDeviceMajorAxis()
|
||||||
keypair = get_saved_keypair()
|
keypair = get_saved_keypair()
|
||||||
appDelegate.keypair = keypair
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDelegate {
|
||||||
var keypair: Keypair? = nil
|
var state: DamusState? = nil
|
||||||
var settings: UserSettingsStore? = nil
|
|
||||||
|
|
||||||
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
|
||||||
UNUserNotificationCenter.current().delegate = self
|
UNUserNotificationCenter.current().delegate = self
|
||||||
@ -71,51 +69,13 @@ class AppDelegate: NSObject, UIApplicationDelegate, UNUserNotificationCenterDele
|
|||||||
}
|
}
|
||||||
|
|
||||||
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
|
||||||
// Return if this feature is disabled
|
guard let state else {
|
||||||
guard let settings = self.settings else { return }
|
|
||||||
if !settings.enable_experimental_push_notifications || settings.notifications_mode == .local {
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the device token and pubkey to the server
|
Task {
|
||||||
let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
|
try await state.push_notification_client.set_device_token(new_device_token: deviceToken)
|
||||||
|
|
||||||
print("Received device token: \(token)")
|
|
||||||
|
|
||||||
guard let pubkey = keypair?.pubkey else {
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send those as JSON to the server
|
|
||||||
let json: [String: Any] = ["deviceToken": token, "pubkey": pubkey.hex()]
|
|
||||||
|
|
||||||
// create post request
|
|
||||||
let url = settings.send_device_token_to_localhost ? Constants.DEVICE_TOKEN_RECEIVER_TEST_URL : Constants.DEVICE_TOKEN_RECEIVER_PRODUCTION_URL
|
|
||||||
var request = URLRequest(url: url)
|
|
||||||
request.httpMethod = "POST"
|
|
||||||
|
|
||||||
// insert json data to the request
|
|
||||||
request.httpBody = try? JSONSerialization.data(withJSONObject: json, options: [])
|
|
||||||
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
|
|
||||||
|
|
||||||
let task = URLSession.shared.dataTask(with: request) { data, response, error in
|
|
||||||
guard let data = data, error == nil else {
|
|
||||||
print(error?.localizedDescription ?? "No data")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if let response = response as? HTTPURLResponse, !(200...299).contains(response.statusCode) {
|
|
||||||
print("Unexpected status code: \(response.statusCode)")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
let responseJSON = try? JSONSerialization.jsonObject(with: data, options: [])
|
|
||||||
if let responseJSON = responseJSON as? [String: Any] {
|
|
||||||
print(responseJSON)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task.resume()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle the notification in the foreground state
|
// Handle the notification in the foreground state
|
||||||
|
Loading…
Reference in New Issue
Block a user