Skip to content

Commit

Permalink
Merge pull request #87 from rees46/feat/optimize-automate-mobile-push…
Browse files Browse the repository at this point in the history
…-tokens

Feat/Optimize automate sending mobile push tokens
  • Loading branch information
TorinAsakura authored Jul 19, 2024
2 parents c1611f8 + 7fcdcf2 commit c869ee8
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 43 deletions.
Binary file not shown.
73 changes: 46 additions & 27 deletions REES46/Classes/SimplePersonalizationSDK.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,3 @@
//
// SimplePersonaliztionSDK.swift
// REES46
//
// Created by REES46
// Copyright (c) 2023. All rights reserved.
//

import UIKit
import Foundation
import AdSupport
Expand All @@ -17,6 +9,8 @@ class SimplePersonalizationSDK: PersonalizationSDK {

struct Constants {
static let shopId: String = "shop_id"
static let deviceIdKey = "device_id"
static let deviceToken = "device_token"
static let searchQuery: String = "search_query"
static let deviceId: String = "did"
static let userSeance: String = "seance"
Expand Down Expand Up @@ -44,12 +38,10 @@ class SimplePersonalizationSDK: PersonalizationSDK {
}

var storiesCode: String?

var shopId: String
var deviceId: String
var userSeance: String
var stream: String

var baseURL: String
let baseInitJsonFileName = ".json"
let autoSendPushToken: Bool
Expand All @@ -60,18 +52,13 @@ class SimplePersonalizationSDK: PersonalizationSDK {
var userEmail: String?
var userPhone: String?
var userLoyaltyId: String?

var segment: String
var urlSession: URLSession

var userInfo: InitResponse = InitResponse()

let sessionQueue = SessionQueue.manager

private var requestOperation: RequestOperation?

let bodyMutableData = NSMutableData()

private let initSemaphore = DispatchSemaphore(value: 0)
private let serialSemaphore = DispatchSemaphore(value: 0)

Expand Down Expand Up @@ -106,8 +93,6 @@ class SimplePersonalizationSDK: PersonalizationSDK {
autoSendPushToken: Bool = true,
completion: ((SDKError?) -> Void)? = nil
) {


self.shopId = shopId
self.autoSendPushToken = autoSendPushToken

Expand All @@ -127,7 +112,7 @@ class SimplePersonalizationSDK: PersonalizationSDK {
segment = ["A", "B"].randomElement() ?? "A"

// Trying to fetch user session (permanent user Id)
deviceId = UserDefaults.standard.string(forKey: "device_id") ?? ""
deviceId = UserDefaults.standard.string(forKey: Constants.deviceIdKey) ?? ""

urlSession = URLSession.shared
sessionQueue.addOperation {
Expand All @@ -138,25 +123,24 @@ class SimplePersonalizationSDK: PersonalizationSDK {
self.userInfo = res
self.userSeance = res.seance
self.deviceId = res.deviceId
if let completion = completion {
completion(nil)
completion?(nil)
// Automatically handle push token if autoSendPushToken is true
if self.autoSendPushToken {
self.handleAutoSendPushToken()
}
} else {
if let completion = completion {
completion(.decodeError)
}
completion?(.decodeError)
}
self.initSemaphore.signal()
case .failure(let error):
if let completion = completion {
completion(error)
}
completion?(error)
self.initSemaphore.signal()
break
}
}
self.initSemaphore.wait()
}

initializeNotificationRegistrar()
}

func getDeviceId() -> String {
Expand All @@ -179,6 +163,41 @@ class SimplePersonalizationSDK: PersonalizationSDK {
pushTokenService.setPushToken(token: token, isFirebaseNotification: isFirebaseNotification, completion: completion)
}

private func initializeNotificationRegistrar() {
if autoSendPushToken {
UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { [weak self] granted, error in
guard let self = self else { return }

if granted {
DispatchQueue.main.async {
UIApplication.shared.registerForRemoteNotifications()
}

// Attempt to send the push token if available
if let deviceToken = UserDefaults.standard.data(forKey: Constants.deviceToken) {
let notificationRegistrar = NotificationRegistrar(sdk: self)
notificationRegistrar.registerWithDeviceToken(deviceToken: deviceToken)
}
} else if let error = error {
#if DEBUG
print("Error requesting notification authorization: \(error.localizedDescription)")
#endif
}
}
} else {
#if DEBUG
print("Auto-send push token is disabled.")
#endif
}
}

private func handleAutoSendPushToken() {
if let deviceToken = UserDefaults.standard.data(forKey: Constants.deviceToken) {
let notificationRegistrar = NotificationRegistrar(sdk: self)
notificationRegistrar.registerWithDeviceToken(deviceToken: deviceToken)
}
}

func getAllNotifications(type: String, phone: String? = nil, email: String? = nil, userExternalId: String? = nil, userLoyaltyId: String? = nil, channel: String?, limit: Int?, page: Int?, dateFrom: String?, completion: @escaping (Result<UserPayloadResponse, SDKError>) -> Void) {
notificationService.getAllNotifications(type: type, phone: phone, email: email, userExternalId: userExternalId, userLoyaltyId: userLoyaltyId, channel: channel, limit: limit, page: page, dateFrom: dateFrom, completion: completion)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,47 +2,56 @@ import Foundation
import UIKit

class NotificationRegistrar {

private let sdk: PersonalizationSDK
private let mainPushTokenLastUploadDateKey = "mainPushTokenLastUploadDateKey"


struct Constants {
static let deviceIdKey = "device_id"
static let mainPushTokenLastUploadDateKey = "mainPushTokenLastUploadDateKey"
static let oneWeekInSeconds: TimeInterval = 7 * 24 * 60 * 60
}

init(sdk: PersonalizationSDK) {
self.sdk = sdk
}

func registerWithDeviceToken(deviceToken: Data) {
guard let sdk = sdk as? SimplePersonalizationSDK,
sdk.autoSendPushToken == true
else { return }

if let pushTokenLastUpdateDate = UserDefaults.standard.object(forKey: self.mainPushTokenLastUploadDateKey) as? Date {
if let pushTokenLastUpdateDate = UserDefaults.standard.object(forKey: Constants.mainPushTokenLastUploadDateKey) as? Date {
let currentDate = Date()
let timeSincePushTokenLastUpdate = currentDate.timeIntervalSince(pushTokenLastUpdateDate)
let oneWeekInSeconds: TimeInterval = 7 * 24 * 60 * 60

guard timeSincePushTokenLastUpdate >= oneWeekInSeconds else {
guard timeSincePushTokenLastUpdate >= Constants.oneWeekInSeconds else {
// Token was sent within the last week; no need to send again
let nextPossibleSendDate = pushTokenLastUpdateDate.addingTimeInterval(Constants.oneWeekInSeconds)
#if DEBUG
print("Push token already sent recently. Next possible send date: \(nextPossibleSendDate)")
#endif
return
}
}

let token = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
sdk.setPushTokenNotification(token: token) { [weak self] tokenResponse in
guard let self = self else { return }
switch tokenResponse {
case .success():
UserDefaults.standard.setValue(Date(), forKey: self.mainPushTokenLastUploadDateKey)
return
let currentDate = Date()
UserDefaults.standard.setValue(currentDate, forKey: Constants.mainPushTokenLastUploadDateKey)
let nextPossibleSendDate = currentDate.addingTimeInterval(Constants.oneWeekInSeconds)
#if DEBUG
print("Push token successfully sent. Last upload date: \(currentDate). Next possible send date: \(nextPossibleSendDate)")
#endif
case .failure(let error):
self.handleRegistrationError(error)
}
}
}

private func handleRegistrationError(_ error: SDKError) {
switch error {
case let .custom(customError):
print("SDK Push Token Error:", customError)
default:
print("SDK Push Token server, \(error.description)\n")
print("SDK Push Token server error: \(error.description)\n")
}
}
}

0 comments on commit c869ee8

Please sign in to comment.