Update
This commit is contained in:
parent
038a6e928c
commit
dec912f2db
9 changed files with 254 additions and 19 deletions
|
|
@ -16,10 +16,9 @@ class UITests: XCTestCase {
|
||||||
func testLaunch() throws {
|
func testLaunch() throws {
|
||||||
app.launch()
|
app.launch()
|
||||||
XCTAssert(app.wait(for: .runningForeground, timeout: 10.0))
|
XCTAssert(app.wait(for: .runningForeground, timeout: 10.0))
|
||||||
let _ = app.buttons["___non_existing"].waitForExistence(timeout: 10000.0)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func testLoginToCodeEntry() throws {
|
func testLoginToSetName() throws {
|
||||||
app.launch()
|
app.launch()
|
||||||
|
|
||||||
// Welcome screen — tap Start Messaging
|
// Welcome screen — tap Start Messaging
|
||||||
|
|
@ -29,17 +28,16 @@ class UITests: XCTestCase {
|
||||||
|
|
||||||
// Phone entry screen — enter test phone number
|
// Phone entry screen — enter test phone number
|
||||||
let countryCodeField = app.textFields["Auth.PhoneEntry.CountryCodeField"]
|
let countryCodeField = app.textFields["Auth.PhoneEntry.CountryCodeField"]
|
||||||
XCTAssert(countryCodeField.waitForExistence(timeout: 5.0))
|
XCTAssert(countryCodeField.waitForExistence(timeout: 10.0))
|
||||||
countryCodeField.tap()
|
countryCodeField.tap()
|
||||||
countryCodeField.press(forDuration: 0.5)
|
for _ in 0..<10 {
|
||||||
if app.menuItems["Select All"].waitForExistence(timeout: 2.0) {
|
countryCodeField.typeText(XCUIKeyboardKey.delete.rawValue)
|
||||||
app.menuItems["Select All"].tap()
|
|
||||||
}
|
}
|
||||||
countryCodeField.typeText("999")
|
countryCodeField.typeText("999")
|
||||||
|
|
||||||
let phoneNumberField = app.textFields["Auth.PhoneEntry.PhoneNumberField"]
|
let phoneNumberField = app.textFields["Auth.PhoneEntry.PhoneNumberField"]
|
||||||
phoneNumberField.tap()
|
phoneNumberField.tap()
|
||||||
phoneNumberField.typeText("6621234")
|
phoneNumberField.typeText("6625678")
|
||||||
|
|
||||||
let continueButton = app.buttons["Auth.PhoneEntry.ContinueButton"]
|
let continueButton = app.buttons["Auth.PhoneEntry.ContinueButton"]
|
||||||
XCTAssert(continueButton.waitForExistence(timeout: 3.0))
|
XCTAssert(continueButton.waitForExistence(timeout: 3.0))
|
||||||
|
|
@ -51,8 +49,26 @@ class UITests: XCTestCase {
|
||||||
XCTAssert(confirmButton.waitForExistence(timeout: 5.0))
|
XCTAssert(confirmButton.waitForExistence(timeout: 5.0))
|
||||||
confirmButton.tap()
|
confirmButton.tap()
|
||||||
|
|
||||||
// Code entry screen — verify we arrived
|
// Code entry screen — enter verification code
|
||||||
let codeEntryTitle = app.staticTexts["Auth.CodeEntry.Title"]
|
let codeEntryTitle = app.staticTexts["Auth.CodeEntry.Title"]
|
||||||
XCTAssert(codeEntryTitle.waitForExistence(timeout: 10.0))
|
XCTAssert(codeEntryTitle.waitForExistence(timeout: 15.0))
|
||||||
|
|
||||||
|
let codeField = app.textFields["Auth.CodeEntry.CodeField"]
|
||||||
|
XCTAssert(codeField.waitForExistence(timeout: 3.0))
|
||||||
|
codeField.typeText("22222")
|
||||||
|
|
||||||
|
// Set name screen — enter name and submit
|
||||||
|
let firstNameField = app.textFields["Auth.SetName.FirstNameField"]
|
||||||
|
XCTAssert(firstNameField.waitForExistence(timeout: 15.0))
|
||||||
|
firstNameField.tap()
|
||||||
|
firstNameField.typeText("Test")
|
||||||
|
|
||||||
|
let lastNameField = app.textFields["Auth.SetName.LastNameField"]
|
||||||
|
lastNameField.tap()
|
||||||
|
lastNameField.typeText("User")
|
||||||
|
|
||||||
|
let signUpButton = app.buttons["Auth.SetName.ContinueButton"]
|
||||||
|
XCTAssert(signUpButton.waitForExistence(timeout: 3.0))
|
||||||
|
signUpButton.tap()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
23
build-system/test-helper/Package.resolved
Normal file
23
build-system/test-helper/Package.resolved
Normal file
|
|
@ -0,0 +1,23 @@
|
||||||
|
{
|
||||||
|
"pins" : [
|
||||||
|
{
|
||||||
|
"identity" : "tdlibframework",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/Swiftgram/TDLibFramework",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "fdda50b9335171329237fab2381cbc2e6e3ce86c",
|
||||||
|
"version" : "1.8.60-cb863c16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"identity" : "tdlibkit",
|
||||||
|
"kind" : "remoteSourceControl",
|
||||||
|
"location" : "https://github.com/Swiftgram/TDLibKit",
|
||||||
|
"state" : {
|
||||||
|
"revision" : "245888f853f5e304029f4fa423af14a045476f30",
|
||||||
|
"version" : "1.5.2-tdlib-1.8.60-cb863c16"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"version" : 2
|
||||||
|
}
|
||||||
16
build-system/test-helper/Package.swift
Normal file
16
build-system/test-helper/Package.swift
Normal file
|
|
@ -0,0 +1,16 @@
|
||||||
|
// swift-tools-version: 5.9
|
||||||
|
import PackageDescription
|
||||||
|
|
||||||
|
let package = Package(
|
||||||
|
name: "test-helper",
|
||||||
|
platforms: [.macOS(.v13)],
|
||||||
|
dependencies: [
|
||||||
|
.package(url: "https://github.com/Swiftgram/TDLibKit", exact: "1.5.2-tdlib-1.8.60-cb863c16"),
|
||||||
|
],
|
||||||
|
targets: [
|
||||||
|
.executableTarget(
|
||||||
|
name: "test-helper",
|
||||||
|
dependencies: ["TDLibKit"]
|
||||||
|
),
|
||||||
|
]
|
||||||
|
)
|
||||||
165
build-system/test-helper/Sources/main.swift
Normal file
165
build-system/test-helper/Sources/main.swift
Normal file
|
|
@ -0,0 +1,165 @@
|
||||||
|
import Foundation
|
||||||
|
import TDLibKit
|
||||||
|
import TDLibFramework
|
||||||
|
|
||||||
|
// MARK: - Argument parsing
|
||||||
|
|
||||||
|
func printUsage() -> Never {
|
||||||
|
fputs("Usage: test-helper delete-account --api-id <id> --api-hash <hash> --phone <number>\n", stderr)
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func parseArgs() -> (apiId: Int, apiHash: String, phone: String) {
|
||||||
|
let args = CommandLine.arguments
|
||||||
|
guard args.count >= 2, args[1] == "delete-account" else { printUsage() }
|
||||||
|
|
||||||
|
var apiId: Int?
|
||||||
|
var apiHash: String?
|
||||||
|
var phone: String?
|
||||||
|
|
||||||
|
var i = 2
|
||||||
|
while i < args.count {
|
||||||
|
switch args[i] {
|
||||||
|
case "--api-id":
|
||||||
|
i += 1; guard i < args.count, let v = Int(args[i]) else { printUsage() }
|
||||||
|
apiId = v
|
||||||
|
case "--api-hash":
|
||||||
|
i += 1; guard i < args.count else { printUsage() }
|
||||||
|
apiHash = args[i]
|
||||||
|
case "--phone":
|
||||||
|
i += 1; guard i < args.count else { printUsage() }
|
||||||
|
phone = args[i]
|
||||||
|
default:
|
||||||
|
printUsage()
|
||||||
|
}
|
||||||
|
i += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
guard let apiId, let apiHash, let phone else { printUsage() }
|
||||||
|
return (apiId, apiHash, phone)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Phone number validation
|
||||||
|
|
||||||
|
/// Parses a test phone number (format: 99966XYYYY or +99966XYYYY).
|
||||||
|
/// Returns (fullNumber with + prefix, verification code).
|
||||||
|
func parseTestPhone(_ phone: String) -> (fullNumber: String, code: String)? {
|
||||||
|
let digits = phone.hasPrefix("+") ? String(phone.dropFirst()) : phone
|
||||||
|
guard digits.count == 10, digits.hasPrefix("99966") else { return nil }
|
||||||
|
let dcDigit = digits[digits.index(digits.startIndex, offsetBy: 5)]
|
||||||
|
guard dcDigit >= "1", dcDigit <= "3" else { return nil }
|
||||||
|
let code = String(repeating: dcDigit, count: 5)
|
||||||
|
let fullNumber = "+\(digits)"
|
||||||
|
return (fullNumber, code)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - TDLib account deletion
|
||||||
|
|
||||||
|
func deleteTestAccount(apiId: Int, apiHash: String, phone: String, code: String) async throws {
|
||||||
|
let tmpDir = FileManager.default.temporaryDirectory
|
||||||
|
.appendingPathComponent("test-helper-\(ProcessInfo.processInfo.processIdentifier)")
|
||||||
|
try FileManager.default.createDirectory(at: tmpDir, withIntermediateDirectories: true)
|
||||||
|
defer { try? FileManager.default.removeItem(at: tmpDir) }
|
||||||
|
|
||||||
|
// Suppress TDLib's verbose C++ logging
|
||||||
|
td_execute("{\"@type\":\"setLogVerbosityLevel\",\"new_verbosity_level\":0}")
|
||||||
|
|
||||||
|
let manager = TDLibClientManager()
|
||||||
|
defer { manager.closeClients() }
|
||||||
|
|
||||||
|
let authState = AsyncStream.makeStream(of: AuthorizationState.self)
|
||||||
|
|
||||||
|
let client = manager.createClient { data, client in
|
||||||
|
guard let update = try? client.decoder.decode(Update.self, from: data) else { return }
|
||||||
|
if case .updateAuthorizationState(let s) = update {
|
||||||
|
authState.continuation.yield(s.authorizationState)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for await state in authState.stream {
|
||||||
|
switch state {
|
||||||
|
case .authorizationStateWaitTdlibParameters:
|
||||||
|
try await client.setTdlibParameters(
|
||||||
|
apiHash: apiHash,
|
||||||
|
apiId: apiId,
|
||||||
|
applicationVersion: "1.0",
|
||||||
|
databaseDirectory: tmpDir.path,
|
||||||
|
databaseEncryptionKey: Data(),
|
||||||
|
deviceModel: "test-helper",
|
||||||
|
filesDirectory: tmpDir.appendingPathComponent("files").path,
|
||||||
|
systemLanguageCode: "en",
|
||||||
|
systemVersion: "macOS",
|
||||||
|
useChatInfoDatabase: false,
|
||||||
|
useFileDatabase: false,
|
||||||
|
useMessageDatabase: false,
|
||||||
|
useSecretChats: false,
|
||||||
|
useTestDc: true
|
||||||
|
)
|
||||||
|
|
||||||
|
case .authorizationStateWaitPhoneNumber:
|
||||||
|
try await client.setAuthenticationPhoneNumber(
|
||||||
|
phoneNumber: phone,
|
||||||
|
settings: PhoneNumberAuthenticationSettings?.none
|
||||||
|
)
|
||||||
|
|
||||||
|
case .authorizationStateWaitCode:
|
||||||
|
try await client.checkAuthenticationCode(code: code)
|
||||||
|
|
||||||
|
case .authorizationStateWaitRegistration:
|
||||||
|
print("No account for \(phone) (sign-up requested). Nothing to delete.")
|
||||||
|
authState.continuation.finish()
|
||||||
|
return
|
||||||
|
|
||||||
|
case .authorizationStateReady:
|
||||||
|
print("Logged in. Deleting account...")
|
||||||
|
try await client.deleteAccount(password: String?.none, reason: "test cleanup")
|
||||||
|
print("Account deleted.")
|
||||||
|
authState.continuation.finish()
|
||||||
|
return
|
||||||
|
|
||||||
|
case .authorizationStateClosed:
|
||||||
|
authState.continuation.finish()
|
||||||
|
return
|
||||||
|
|
||||||
|
default:
|
||||||
|
fputs("Unexpected auth state: \(state)\n", stderr)
|
||||||
|
authState.continuation.finish()
|
||||||
|
throw NSError(domain: "test-helper", code: 1, userInfo: [
|
||||||
|
NSLocalizedDescriptionKey: "Unexpected auth state"
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Main
|
||||||
|
|
||||||
|
let (apiId, apiHash, phone) = parseArgs()
|
||||||
|
|
||||||
|
guard let parsed = parseTestPhone(phone) else {
|
||||||
|
fputs("Error: phone must match format 99966XYYYY (X = 1, 2, or 3)\n", stderr)
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
try await withThrowingTaskGroup(of: Void.self) { group in
|
||||||
|
group.addTask {
|
||||||
|
try await deleteTestAccount(apiId: apiId, apiHash: apiHash, phone: parsed.fullNumber, code: parsed.code)
|
||||||
|
}
|
||||||
|
group.addTask {
|
||||||
|
try await Task.sleep(for: .seconds(30))
|
||||||
|
throw NSError(domain: "test-helper", code: 1, userInfo: [
|
||||||
|
NSLocalizedDescriptionKey: "Timed out after 30 seconds"
|
||||||
|
])
|
||||||
|
}
|
||||||
|
try await group.next()
|
||||||
|
group.cancelAll()
|
||||||
|
}
|
||||||
|
} catch let error as TDLibKit.Error {
|
||||||
|
fputs("Error: [\(error.code)] \(error.message)\n", stderr)
|
||||||
|
exit(1)
|
||||||
|
} catch {
|
||||||
|
fputs("Error: \(error)\n", stderr)
|
||||||
|
exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
exit(0)
|
||||||
|
|
@ -96,20 +96,26 @@ field.typeText("9996621234")
|
||||||
|
|
||||||
The test environment uses 3 separate Telegram datacenters, completely independent from production.
|
The test environment uses 3 separate Telegram datacenters, completely independent from production.
|
||||||
|
|
||||||
|
### OS Environment
|
||||||
|
|
||||||
|
Test logins are guarded behind a specialized OS environment. The simulator or device must be configured for the test environment before test accounts can authenticate.
|
||||||
|
|
||||||
### Test Phone Numbers
|
### Test Phone Numbers
|
||||||
|
|
||||||
Test phone numbers follow the format `99966XYYYY`:
|
Test phone numbers follow the format `99966XYYYY`:
|
||||||
- `X` is the DC number (1, 2, or 3)
|
- `X` is the DC number (1, 2, or 3)
|
||||||
- `YYYY` is any random digits
|
- `YYYY` are random digits
|
||||||
|
|
||||||
Examples: `9996621234`, `9996710000`, `9996300001`.
|
The country code for test numbers is `999`, and the remaining digits are `66XYYYY`.
|
||||||
|
|
||||||
|
Examples: `+999 66 2 1234`, `+999 66 1 0000`, `+999 66 3 0001`.
|
||||||
|
|
||||||
### Verification Codes
|
### Verification Codes
|
||||||
|
|
||||||
Test accounts do not receive real SMS. The confirmation code is **the DC number repeated 5 times**:
|
Test accounts do not receive real SMS. The confirmation code is **the DC number repeated 5 times**:
|
||||||
- DC 1 (`999661YYYY`) -> code `11111`
|
- DC 1 (`+999 661 YYYY`) -> code `11111`
|
||||||
- DC 2 (`999662YYYY`) -> code `22222`
|
- DC 2 (`+999 662 YYYY`) -> code `22222`
|
||||||
- DC 3 (`999663YYYY`) -> code `33333`
|
- DC 3 (`+999 663 YYYY`) -> code `33333`
|
||||||
|
|
||||||
### Flood Limits
|
### Flood Limits
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -179,6 +179,7 @@ final class AuthorizationSequenceCodeEntryControllerNode: ASDisplayNode, UITextF
|
||||||
self.codeInputView.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
self.codeInputView.textField.keyboardAppearance = self.theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.codeInputView.textField.returnKeyType = .done
|
self.codeInputView.textField.returnKeyType = .done
|
||||||
self.codeInputView.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
self.codeInputView.textField.disableAutomaticKeyboardHandling = [.forward, .backward]
|
||||||
|
self.codeInputView.textField.accessibilityIdentifier = "Auth.CodeEntry.CodeField"
|
||||||
if #available(iOSApplicationExtension 12.0, iOS 12.0, *) {
|
if #available(iOSApplicationExtension 12.0, iOS 12.0, *) {
|
||||||
self.codeInputView.textField.textContentType = .oneTimeCode
|
self.codeInputView.textField.textContentType = .oneTimeCode
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -90,7 +90,8 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
||||||
self.titleNode.isUserInteractionEnabled = false
|
self.titleNode.isUserInteractionEnabled = false
|
||||||
self.titleNode.displaysAsynchronously = false
|
self.titleNode.displaysAsynchronously = false
|
||||||
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.semibold(28.0), textColor: theme.list.itemPrimaryTextColor)
|
self.titleNode.attributedText = NSAttributedString(string: self.strings.Login_InfoTitle, font: Font.semibold(28.0), textColor: theme.list.itemPrimaryTextColor)
|
||||||
|
self.titleNode.accessibilityIdentifier = "Auth.SetName.Title"
|
||||||
|
|
||||||
self.currentOptionNode = ASTextNode()
|
self.currentOptionNode = ASTextNode()
|
||||||
self.currentOptionNode.isUserInteractionEnabled = false
|
self.currentOptionNode.isUserInteractionEnabled = false
|
||||||
self.currentOptionNode.displaysAsynchronously = false
|
self.currentOptionNode.displaysAsynchronously = false
|
||||||
|
|
@ -125,7 +126,8 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
||||||
}
|
}
|
||||||
self.firstNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
self.firstNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.firstNameField.textField.tintColor = theme.list.itemAccentColor
|
self.firstNameField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
self.firstNameField.textField.accessibilityIdentifier = "Auth.SetName.FirstNameField"
|
||||||
|
|
||||||
self.lastNameField = TextFieldNode()
|
self.lastNameField = TextFieldNode()
|
||||||
self.lastNameField.textField.font = Font.regular(20.0)
|
self.lastNameField.textField.font = Font.regular(20.0)
|
||||||
self.lastNameField.textField.textColor = self.theme.list.itemPrimaryTextColor
|
self.lastNameField.textField.textColor = self.theme.list.itemPrimaryTextColor
|
||||||
|
|
@ -139,7 +141,8 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
||||||
}
|
}
|
||||||
self.lastNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
self.lastNameField.textField.keyboardAppearance = theme.rootController.keyboardColor.keyboardAppearance
|
||||||
self.lastNameField.textField.tintColor = theme.list.itemAccentColor
|
self.lastNameField.textField.tintColor = theme.list.itemAccentColor
|
||||||
|
self.lastNameField.textField.accessibilityIdentifier = "Auth.SetName.LastNameField"
|
||||||
|
|
||||||
self.currentPhotoNode = ASImageNode()
|
self.currentPhotoNode = ASImageNode()
|
||||||
self.currentPhotoNode.isUserInteractionEnabled = false
|
self.currentPhotoNode.isUserInteractionEnabled = false
|
||||||
self.currentPhotoNode.displaysAsynchronously = false
|
self.currentPhotoNode.displaysAsynchronously = false
|
||||||
|
|
@ -154,6 +157,7 @@ final class AuthorizationSequenceSignUpControllerNode: ASDisplayNode, UITextFiel
|
||||||
|
|
||||||
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), glass: false, height: 50.0, cornerRadius: 50.0 * 0.5)
|
self.proceedNode = SolidRoundedButtonNode(title: self.strings.Login_Continue, theme: SolidRoundedButtonTheme(theme: self.theme), glass: false, height: 50.0, cornerRadius: 50.0 * 0.5)
|
||||||
self.proceedNode.progressType = .embedded
|
self.proceedNode.progressType = .embedded
|
||||||
|
self.proceedNode.accessibilityIdentifier = "Auth.SetName.ContinueButton"
|
||||||
|
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -153,8 +153,10 @@ public final class CodeInputView: ASDisplayNode, UITextFieldDelegate {
|
||||||
super.init()
|
super.init()
|
||||||
|
|
||||||
self.addSubnode(self.prefixLabel)
|
self.addSubnode(self.prefixLabel)
|
||||||
|
self.textField.frame = CGRect(x: 0, y: 0, width: 1, height: 1)
|
||||||
|
self.textField.alpha = 0.01
|
||||||
self.view.addSubview(self.textField)
|
self.view.addSubview(self.textField)
|
||||||
|
|
||||||
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
self.view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapGesture(_:))))
|
||||||
self.textField.delegate = self
|
self.textField.delegate = self
|
||||||
self.textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged)
|
self.textField.addTarget(self, action: #selector(self.textFieldChanged(_:)), for: .editingChanged)
|
||||||
|
|
|
||||||
|
|
@ -656,7 +656,9 @@ private func extractAccountManagerState(records: AccountRecordsView<TelegramAcco
|
||||||
} else {
|
} else {
|
||||||
rootPath = rootPathForBasePath(appGroupUrl.path)
|
rootPath = rootPathForBasePath(appGroupUrl.path)
|
||||||
}
|
}
|
||||||
performAppGroupUpgrades(appGroupPath: appGroupUrl.path, rootPath: rootPath)
|
if !isUITest {
|
||||||
|
performAppGroupUpgrades(appGroupPath: appGroupUrl.path, rootPath: rootPath)
|
||||||
|
}
|
||||||
|
|
||||||
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
let deviceSpecificEncryptionParameters = BuildConfig.deviceSpecificEncryptionParameters(rootPath, baseAppBundleId: baseAppBundleId)
|
||||||
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
let encryptionParameters = ValueBoxEncryptionParameters(forceEncryptionIfNoSet: false, key: ValueBoxEncryptionParameters.Key(data: deviceSpecificEncryptionParameters.key)!, salt: ValueBoxEncryptionParameters.Salt(data: deviceSpecificEncryptionParameters.salt)!)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue