mirror of
https://github.com/AU-COVIDSafe/mobile-ios.git
synced 2025-04-05 06:14:59 +00:00
142 lines
6 KiB
Swift
142 lines
6 KiB
Swift
import Foundation
|
|
|
|
class EncounterMessageManager {
|
|
let userDefaultsTempIdKey = "BROADCAST_MSG"
|
|
let userDefaultsAdvtKey = "ADVT_DATA"
|
|
let userDefaultsAdvtExpiryKey = "ADVT_EXPIRY"
|
|
|
|
static let shared = EncounterMessageManager()
|
|
|
|
var tempId: String? {
|
|
return UserDefaults.standard.string(forKey: userDefaultsTempIdKey)
|
|
}
|
|
|
|
var advertisedPayload: Data? {
|
|
do {
|
|
let broadcastPayload = EncounterBlob(modelC: nil,
|
|
rssi: nil,
|
|
txPower: nil,
|
|
modelP: DeviceIdentifier.getModel(),
|
|
msg: tempId,
|
|
timestamp: Date().timeIntervalSince1970)
|
|
let jsonMsg = try JSONEncoder().encode(broadcastPayload)
|
|
let encryptedJsonMsg = try Crypto.encrypt(dataToEncrypt: jsonMsg)
|
|
let peripheralCharStruct = PeripheralCharacteristicsData(modelP: BluetraceConfig.DummyModel, msg: encryptedJsonMsg, org: BluetraceConfig.OrgID, v: BluetraceConfig.ProtocolVersion)
|
|
return try JSONEncoder().encode(peripheralCharStruct)
|
|
} catch {
|
|
return nil
|
|
}
|
|
}
|
|
|
|
// This variable stores the expiry date of the broadcast message. At the same time, we will use this expiry date as the expiry date for the encryted advertisement payload
|
|
var advertisementPayloadExpiry: Date? {
|
|
return UserDefaults.standard.object(forKey: userDefaultsAdvtExpiryKey) as? Date
|
|
}
|
|
|
|
func setup() {
|
|
// Check payload validity
|
|
if advertisementPayloadExpiry == nil || Date() > advertisementPayloadExpiry! {
|
|
// Call API to get new tempId and expiry date
|
|
fetchTempIdFromApi { [unowned self] (error: Error?, resp:(tempId: String, expiry: Date)?) in
|
|
guard let response = resp else {
|
|
DLog("No response, Error: \(String(describing: error))")
|
|
return
|
|
}
|
|
UserDefaults.standard.set(response.tempId, forKey: self.userDefaultsTempIdKey)
|
|
}
|
|
}
|
|
}
|
|
|
|
func getTempId(onComplete: @escaping (String?) -> Void) {
|
|
// check refreshDate
|
|
if advertisementPayloadExpiry == nil || Date() > advertisementPayloadExpiry! {
|
|
fetchTempIdFromApi { [unowned self] (error: Error?, resp:(tempId: String, expiry: Date)?) in
|
|
guard let response = resp else {
|
|
DLog("No response, Error: \(String(describing: error))")
|
|
onComplete(nil)
|
|
return
|
|
}
|
|
UserDefaults.standard.set(response.tempId, forKey: self.userDefaultsTempIdKey)
|
|
UserDefaults.standard.set(response.expiry, forKey: self.userDefaultsAdvtExpiryKey)
|
|
|
|
onComplete(response.tempId)
|
|
return
|
|
}
|
|
return
|
|
}
|
|
|
|
// we know that tempId has not expired
|
|
if let msg = tempId {
|
|
onComplete(msg)
|
|
} else {
|
|
// this is not part of usual expected flow, just run setup and be done with it
|
|
setup()
|
|
onComplete(nil)
|
|
}
|
|
}
|
|
|
|
// gets the anon tempid for broadcasting
|
|
func getAdvertisementPayload(onComplete: @escaping (Data?) -> Void) {
|
|
// check expiry date of payload
|
|
if advertisementPayloadExpiry == nil || Date() > advertisementPayloadExpiry! {
|
|
fetchTempIdFromApi { [unowned self] (error: Error?, resp:(tempId: String, expiry: Date)?) in
|
|
guard let response = resp else {
|
|
DLog("No response, Error: \(String(describing: error))")
|
|
onComplete(nil)
|
|
return
|
|
}
|
|
UserDefaults.standard.set(response.tempId, forKey: self.userDefaultsTempIdKey)
|
|
UserDefaults.standard.set(response.expiry, forKey: self.userDefaultsAdvtExpiryKey)
|
|
|
|
if let newPayload = self.advertisedPayload {
|
|
onComplete(newPayload)
|
|
return
|
|
}
|
|
onComplete(nil)
|
|
}
|
|
return
|
|
}
|
|
|
|
// we know that payload has not expired
|
|
if let payload = advertisedPayload {
|
|
onComplete(payload)
|
|
} else {
|
|
// this is not part of usual expected flow, just run setup and be done with it
|
|
setup()
|
|
onComplete(nil)
|
|
}
|
|
}
|
|
|
|
private func fetchTempIdFromApi(onComplete: ((Error?, (String, Date)?) -> Void)?) {
|
|
DLog("Fetching tempId from API")
|
|
GetTempIdAPI.getTempId { (tempId: String?, expiry: Int?, error: Error?) in
|
|
guard error == nil else {
|
|
if let error = error as NSError? {
|
|
let code = error.code
|
|
let message = error.localizedDescription
|
|
let details = error.userInfo
|
|
DLog("API error. Code: \(String(describing: code)), Message: \(message), Details: \(String(describing: details))")
|
|
} else {
|
|
DLog("Cloud function error, unable to convert error to NSError.\(error!)")
|
|
}
|
|
// if we have an existing tempid and expiry, use that
|
|
if let msg = self.tempId, let exp = self.advertisementPayloadExpiry {
|
|
onComplete?(nil, (msg, exp))
|
|
} else {
|
|
onComplete?(error, nil)
|
|
}
|
|
return
|
|
}
|
|
|
|
guard let tempId = tempId,
|
|
let expiry = expiry else {
|
|
DLog("Unable to get tempId or expiry from API.")
|
|
onComplete?(NSError(domain: "BM", code: 9999, userInfo: nil), nil)
|
|
return
|
|
}
|
|
|
|
let date = Date(timeIntervalSince1970: TimeInterval(expiry))
|
|
onComplete?(nil, (tempId, date))
|
|
}
|
|
}
|
|
}
|