From 9e1ee4bebd2d2d154df35fa1da6c81cfe3257473 Mon Sep 17 00:00:00 2001 From: Fin Date: Fri, 3 Mar 2023 16:04:26 +0800 Subject: [PATCH] Add AESCryptoModel --- Bark.xcodeproj/project.pbxproj | 28 ++++++-- Common/CryptoSettingManager.swift | 41 ++++++++++++ Common/Defines.swift | 4 -- Common/Error+Extension.swift | 11 ++++ Common/NSLocalizedString+Extension.swift | 13 ++++ Controller/CryptoSettingController.swift | 68 +++++++++++--------- Controller/CryptoSettingModel.swift | 56 ---------------- Controller/CryptoSettingViewModel.swift | 82 ++++++++++++++++++++++++ Model/Algorithm.swift | 60 +++++++++++++++++ Podfile | 1 + Podfile.lock | 2 +- 11 files changed, 272 insertions(+), 94 deletions(-) create mode 100644 Common/CryptoSettingManager.swift create mode 100644 Common/Error+Extension.swift create mode 100644 Common/NSLocalizedString+Extension.swift delete mode 100644 Controller/CryptoSettingModel.swift create mode 100644 Controller/CryptoSettingViewModel.swift diff --git a/Bark.xcodeproj/project.pbxproj b/Bark.xcodeproj/project.pbxproj index 4769e2a..3d68dea 100644 --- a/Bark.xcodeproj/project.pbxproj +++ b/Bark.xcodeproj/project.pbxproj @@ -126,7 +126,14 @@ 06CF784C21C7A51200A052D7 /* NotificationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06CF784B21C7A51200A052D7 /* NotificationService.swift */; }; 06EE1FD326843E9300586708 /* BarkTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EE1FD226843E9300586708 /* BarkTests.swift */; }; 06EEF333291CCFF400CA228A /* CryptoSettingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF332291CCFF400CA228A /* CryptoSettingController.swift */; }; - 06EEF335291CD00000CA228A /* CryptoSettingModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF334291CD00000CA228A /* CryptoSettingModel.swift */; }; + 06EEF335291CD00000CA228A /* CryptoSettingViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */; }; + 06F08EA429B098DD006AB9CA /* CryptoSettingManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */; }; + 06F08EA529B1DDA7006AB9CA /* Algorithm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 061894C629A75BEA00E001C2 /* Algorithm.swift */; }; + 06F08EA729B1DDFE006AB9CA /* Error+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */; }; + 06F08EA829B1DE0A006AB9CA /* Error+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */; }; + 06F08EAA29B1DE9F006AB9CA /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 063C499720E36BF9001BCA35 /* Localizable.strings */; }; + 06F08EAC29B1DECD006AB9CA /* NSLocalizedString+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */; }; + 06F08EAD29B1DED6006AB9CA /* NSLocalizedString+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */; }; 06F11E7727D9D5FB00F00298 /* QRScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 06F11E7627D9D5FB00F00298 /* QRScannerViewController.swift */; }; 3428272069AFAFE2C683FEB0 /* libPods-Bark.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CCC722470308049D180876C7 /* libPods-Bark.a */; }; 879AE4D4178855A9672009E4 /* libPods-NotificationServiceExtension.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B7F8BDFAA047451561798F58 /* libPods-NotificationServiceExtension.a */; }; @@ -306,7 +313,10 @@ 06EE1FD226843E9300586708 /* BarkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BarkTests.swift; sourceTree = ""; }; 06EE1FD426843E9300586708 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 06EEF332291CCFF400CA228A /* CryptoSettingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingController.swift; sourceTree = ""; }; - 06EEF334291CD00000CA228A /* CryptoSettingModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingModel.swift; sourceTree = ""; }; + 06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingViewModel.swift; sourceTree = ""; }; + 06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CryptoSettingManager.swift; sourceTree = ""; }; + 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Error+Extension.swift"; sourceTree = ""; }; + 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSLocalizedString+Extension.swift"; sourceTree = ""; }; 06F11E7627D9D5FB00F00298 /* QRScannerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRScannerViewController.swift; sourceTree = ""; }; 121D9B1ED4E8D26F345BC5C0 /* Pods-BarkTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-BarkTests.release.xcconfig"; path = "Target Support Files/Pods-BarkTests/Pods-BarkTests.release.xcconfig"; sourceTree = ""; }; 138CE8CB688587E893BC5C44 /* Pods-Bark.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Bark.debug.xcconfig"; path = "Target Support Files/Pods-Bark/Pods-Bark.debug.xcconfig"; sourceTree = ""; }; @@ -387,7 +397,7 @@ 068EC15727ED99C900D5D11E /* ServerListViewController.swift */, 068EC15927ED99E700D5D11E /* ServerListViewModel.swift */, 06EEF332291CCFF400CA228A /* CryptoSettingController.swift */, - 06EEF334291CD00000CA228A /* CryptoSettingModel.swift */, + 06EEF334291CD00000CA228A /* CryptoSettingViewModel.swift */, ); path = Controller; sourceTree = ""; @@ -504,6 +514,9 @@ 0633E809256A091B00ED0680 /* MJRefresh+Rx.swift */, 06840DBA272298FB001B3193 /* BKColor.swift */, 065AE76A2987777F00323230 /* ArchiveSettingRelay.swift */, + 06F08EA329B098DD006AB9CA /* CryptoSettingManager.swift */, + 06F08EA629B1DDFE006AB9CA /* Error+Extension.swift */, + 06F08EAB29B1DECD006AB9CA /* NSLocalizedString+Extension.swift */, ); path = Common; sourceTree = ""; @@ -841,6 +854,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 06F08EAA29B1DE9F006AB9CA /* Localizable.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -988,12 +1002,14 @@ 06EEF333291CCFF400CA228A /* CryptoSettingController.swift in Sources */, 0603706D20E23EC000F4CA05 /* BarkSFSafariViewController.swift in Sources */, 06AE311A266F4E6600B39FBB /* GroupFilterViewModel.swift in Sources */, + 06F08EA429B098DD006AB9CA /* CryptoSettingManager.swift in Sources */, 06BD4DAA2901352E003364DB /* Object+Dictionary.swift in Sources */, 06C5953124811392006B98F3 /* ArchiveSettingCell.swift in Sources */, 068EC15A27ED99E700D5D11E /* ServerListViewModel.swift in Sources */, 06172FDC27F6DB06002333A4 /* ServerListTableViewCellViewModel.swift in Sources */, 061894C729A75BEA00E001C2 /* Algorithm.swift in Sources */, 065BE4502563D939002A8CA4 /* SoundCellViewModel.swift in Sources */, + 06F08EA729B1DDFE006AB9CA /* Error+Extension.swift in Sources */, 06B1158F247BB1FB006D91FB /* Message.swift in Sources */, 06172FDA27F6DAEF002333A4 /* ServerListTableViewCell.swift in Sources */, 061894C529962EB900E001C2 /* GradientButton.swift in Sources */, @@ -1029,7 +1045,7 @@ 06C2CF252685BDB80034B127 /* SpacerCell.swift in Sources */, 06BBB8BC2567B3AD0076F63E /* ArchiveSettingCellViewModel.swift in Sources */, 0642B55A27EB13F100453D91 /* MutableTextCell.swift in Sources */, - 06EEF335291CD00000CA228A /* CryptoSettingModel.swift in Sources */, + 06EEF335291CD00000CA228A /* CryptoSettingViewModel.swift in Sources */, 0637FA8020E0981E00E80174 /* BarkSettings.swift in Sources */, 065BE4402563D649002A8CA4 /* SoundsViewModel.swift in Sources */, 065BE4462563D7E5002A8CA4 /* ViewModelType.swift in Sources */, @@ -1039,6 +1055,7 @@ 06BBB8C12567B3EF0076F63E /* BaseTableViewCell.swift in Sources */, 0661A543204FDA4100965E4E /* AppDelegate.swift in Sources */, 065AE76B2987777F00323230 /* ArchiveSettingRelay.swift in Sources */, + 06F08EAC29B1DECD006AB9CA /* NSLocalizedString+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1047,8 +1064,11 @@ buildActionMask = 2147483647; files = ( 06CF784C21C7A51200A052D7 /* NotificationService.swift in Sources */, + 06F08EAD29B1DED6006AB9CA /* NSLocalizedString+Extension.swift in Sources */, + 06F08EA529B1DDA7006AB9CA /* Algorithm.swift in Sources */, 06BBB89125650CCF0076F63E /* ArchiveSettingManager.swift in Sources */, 06B11591247BC132006D91FB /* Message.swift in Sources */, + 06F08EA829B1DE0A006AB9CA /* Error+Extension.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/Common/CryptoSettingManager.swift b/Common/CryptoSettingManager.swift new file mode 100644 index 0000000..2ae3b52 --- /dev/null +++ b/Common/CryptoSettingManager.swift @@ -0,0 +1,41 @@ +// +// CryptoSettingManager.swift +// Bark +// +// Created by huangfeng on 2023/3/2. +// Copyright © 2023 Fin. All rights reserved. +// + +import Foundation +import RxCocoa + +class CryptoSettingManager: NSObject { + static let shared = CryptoSettingManager() + let defaults = UserDefaults(suiteName: "group.bark") + var fields: CryptoSettingFields? { + get { + return defaults?.value(forKey: "cryptoSettingFields") as? CryptoSettingFields + } + set { + defaults?.set(newValue, forKey: "cryptoSettingFields") + } + } + + override private init() { + super.init() + } +} + +class CryptoSettingRelay: NSObject { + static let shared = CryptoSettingRelay() + let fields: BehaviorRelay + + override private init() { + self.fields = BehaviorRelay(value: CryptoSettingManager.shared.fields) + super.init() + + self.fields.subscribe { val in + CryptoSettingManager.shared.fields = val + }.disposed(by: rx.disposeBag) + } +} diff --git a/Common/Defines.swift b/Common/Defines.swift index 2f84236..7aa05dc 100644 --- a/Common/Defines.swift +++ b/Common/Defines.swift @@ -28,10 +28,6 @@ extension UIViewController { } } -func NSLocalizedString(_ key: String) -> String { - return NSLocalizedString(key, comment: "") -} - let kNavigationHeight: CGFloat = { kSafeAreaInsets.top + 44 }() diff --git a/Common/Error+Extension.swift b/Common/Error+Extension.swift new file mode 100644 index 0000000..6f241e7 --- /dev/null +++ b/Common/Error+Extension.swift @@ -0,0 +1,11 @@ +// +// Error+Extension.swift +// Bark +// +// Created by huangfeng on 2023/3/3. +// Copyright © 2023 Fin. All rights reserved. +// + +import Foundation + +extension String: Error {} diff --git a/Common/NSLocalizedString+Extension.swift b/Common/NSLocalizedString+Extension.swift new file mode 100644 index 0000000..87dc0a4 --- /dev/null +++ b/Common/NSLocalizedString+Extension.swift @@ -0,0 +1,13 @@ +// +// NSLocalizedString+Extension.swift +// Bark +// +// Created by huangfeng on 2023/3/3. +// Copyright © 2023 Fin. All rights reserved. +// + +import Foundation + +func NSLocalizedString(_ key: String) -> String { + return NSLocalizedString(key, comment: "") +} diff --git a/Controller/CryptoSettingController.swift b/Controller/CryptoSettingController.swift index 8a10801..0675b82 100644 --- a/Controller/CryptoSettingController.swift +++ b/Controller/CryptoSettingController.swift @@ -6,14 +6,14 @@ // Copyright © 2022 Fin. All rights reserved. // -import UIKit import RxSwift +import UIKit -class CryptoSettingController: BaseViewController { +class CryptoSettingController: BaseViewController { let algorithmFeild = DropBoxView(values: ["AES128", "AES192", "AES256"]) let modeFeild = DropBoxView(values: ["CBC", "ECB", "GCM"]) let paddingField = DropBoxView(values: ["pkcs7"]) - + let keyTextField: BorderTextField = { let textField = BorderTextField(title: "Key") textField.font = UIFont.systemFont(ofSize: 14) @@ -26,14 +26,6 @@ class CryptoSettingController: BaseViewController { textField.font = UIFont.systemFont(ofSize: 14) textField.placeholder = NSLocalizedString("enterIv") return textField - }() - - let previewLabel: UILabel = { - let label = UILabel() - label.font = UIFont.systemFont(ofSize: 12) - label.textColor = BKColor.grey.darken4 - label.text = "\(NSLocalizedString("preview")): \"helloworld\" -> \"DASGKJLSAJKGH==\"" - return label }() let doneButton: BKButton = { @@ -57,7 +49,8 @@ class CryptoSettingController: BaseViewController { UIColor(r255: 36, g255: 51, b255: 236), UIColor(r255: 70, g255: 44, b255: 233), ], - gradientOrientation: .horizontal) + gradientOrientation: .horizontal + ) return btn }() @@ -74,7 +67,7 @@ class CryptoSettingController: BaseViewController { scrollView.snp.makeConstraints { make in make.edges.equalToSuperview() } - + func getTitleLabel(title: String) -> UILabel { let label = UILabel() label.font = UIFont.systemFont(ofSize: 14) @@ -104,7 +97,6 @@ class CryptoSettingController: BaseViewController { self.scrollView.addSubview(ivLabel) self.scrollView.addSubview(ivTextField) - self.scrollView.addSubview(previewLabel) self.scrollView.addSubview(copyButton) self.view.backgroundColor = UIColor.white @@ -157,16 +149,12 @@ class CryptoSettingController: BaseViewController { make.top.equalTo(ivLabel.snp.bottom).offset(5) } - previewLabel.snp.makeConstraints { make in - make.left.equalTo(ivLabel) - make.top.equalTo(ivTextField.snp.bottom).offset(20) - } copyButton.snp.makeConstraints { make in make.left.equalTo(ivTextField) make.right.equalTo(ivTextField) make.height.equalTo(42) - make.top.equalTo(previewLabel.snp.bottom).offset(10) + make.top.equalTo(ivTextField.snp.bottom).offset(25) make.bottom.equalToSuperview().offset(-20) } @@ -181,31 +169,53 @@ class CryptoSettingController: BaseViewController { super.viewDidLoad() self.view.backgroundColor = BKColor.white } - + override func bindViewModel() { - - let output = viewModel.transform(input: CryptoSettingModel.Input( + + func getFieldValues() -> CryptoSettingFields { + return CryptoSettingFields( + algorithm: self.algorithmFeild.currentValue!, + mode: self.modeFeild.currentValue!, + padding: self.paddingField.currentValue!, + key: self.keyTextField.text, + iv: self.ivTextField.text + ) + } + + let output = viewModel.transform(input: CryptoSettingViewModel.Input( algorithmChanged: self.algorithmFeild .rx .currentValueChanged - .compactMap{$0} + .compactMap { $0 } + .asDriver(onErrorDriveWith: .empty()), + + copyScript: copyButton + .rx + .tap + .map { getFieldValues() } + .asDriver(onErrorDriveWith: .empty()), + + done: doneButton + .rx + .tap + .map { getFieldValues() } .asDriver(onErrorDriveWith: .empty()) )) - + output.algorithmList - .map{$0.map {$0.rawValue}} + .map { $0.map { $0.rawValue }} .drive(self.algorithmFeild.rx.values) .disposed(by: rx.disposeBag) - + output.modeList .drive(self.modeFeild.rx.values) .disposed(by: rx.disposeBag) - + output.paddingList .drive(self.paddingField.rx.values) .disposed(by: rx.disposeBag) - - output.keyLenght.drive(onNext: {[weak self] keyLenght in + + output.keyLenght.drive(onNext: { [weak self] keyLenght in self?.keyTextField.placeholder = String(format: NSLocalizedString("enterKey"), keyLenght) }).disposed(by: rx.disposeBag) } diff --git a/Controller/CryptoSettingModel.swift b/Controller/CryptoSettingModel.swift deleted file mode 100644 index 843494c..0000000 --- a/Controller/CryptoSettingModel.swift +++ /dev/null @@ -1,56 +0,0 @@ -// -// CryptoSettingModel.swift -// Bark -// -// Created by huangfeng on 2022/11/10. -// Copyright © 2022 Fin. All rights reserved. -// - -import CryptoSwift -import Foundation -import RxCocoa -import RxSwift - -class CryptoSettingModel: ViewModel, ViewModelType { - struct Input { - let algorithmChanged: Driver - } - - struct Output { - let algorithmList: Driver<[Algorithm]> - let modeList: Driver<[String]> - let paddingList: Driver<[String]> - let keyLenght: Driver - } - - func transform(input: Input) -> Output { - let modeList = input - .algorithmChanged - .compactMap { Algorithm(rawValue: $0) } - .map { $0.modes } - - let keyLenght = input - .algorithmChanged - .compactMap { Algorithm(rawValue: $0) } - .map { $0.keyLenght } - - return Output( - algorithmList: Driver.just([Algorithm.aes128, Algorithm.aes192, Algorithm.aes256]), - modeList: Driver.merge(Driver.just(["CBC", "ECB", "GCM"]), modeList), - paddingList: Driver.just(["pkcs7"]), - keyLenght: Driver.merge(Driver.just(16), keyLenght) - ) - } - - override init() { - super.init() - - do { - let aes = try AES(key: "ABCDEFGHIJKLMNOP", iv: "1234567890123456") // aes128 - let ciphertext = try aes.encrypt(Array("hello,world".utf8)) - print("tttt \(ciphertext.toBase64())") - } catch { - print("tttt \(error.rawString())") - } - } -} diff --git a/Controller/CryptoSettingViewModel.swift b/Controller/CryptoSettingViewModel.swift new file mode 100644 index 0000000..2a1ad5a --- /dev/null +++ b/Controller/CryptoSettingViewModel.swift @@ -0,0 +1,82 @@ +// +// CryptoSettingViewModel.swift +// Bark +// +// Created by huangfeng on 2022/11/10. +// Copyright © 2022 Fin. All rights reserved. +// + +import CryptoSwift +import Foundation +import RxCocoa +import RxSwift + +class CryptoSettingViewModel: ViewModel, ViewModelType { + struct Input { + let algorithmChanged: Driver + let copyScript: Driver + let done: Driver + } + + struct Output { + let algorithmList: Driver<[Algorithm]> + let modeList: Driver<[String]> + let paddingList: Driver<[String]> + let keyLenght: Driver + var showSnackbar: Driver + } + + struct Dependencies { + let settingFieldRelay: BehaviorRelay + } + + private let dependencies: Dependencies + + init(dependencies: Dependencies = + Dependencies( + settingFieldRelay: CryptoSettingRelay.shared.fields + ) + ) { + self.dependencies = dependencies + } + + func transform(input: Input) -> Output { + + let showSnackbar = PublishRelay() + + let modeList = input + .algorithmChanged + .compactMap { Algorithm(rawValue: $0) } + .map { $0.modes } + + let keyLenght = input + .algorithmChanged + .compactMap { Algorithm(rawValue: $0) } + .map { $0.keyLenght } + + // 保存配置 + input.done + .filter { fields in + do { + _ = try AESCryptoModel(cryptoFields: fields) + return true + } + catch { + showSnackbar.accept(error.rawString()) + return false + } + }.drive(onNext: { [weak self] fields in + // 保存设置 + self?.dependencies.settingFieldRelay.accept(fields) + }).disposed(by: rx.disposeBag) + + return Output( + algorithmList: Driver.just([Algorithm.aes128, Algorithm.aes192, Algorithm.aes256]), + modeList: Driver.merge(Driver.just(["CBC", "ECB", "GCM"]), modeList), + paddingList: Driver.just(["pkcs7"]), + keyLenght: Driver.merge(Driver.just(16), keyLenght), + showSnackbar: showSnackbar.asDriver(onErrorDriveWith: .empty()) + ) + } + +} diff --git a/Model/Algorithm.swift b/Model/Algorithm.swift index 3205221..0c3a222 100644 --- a/Model/Algorithm.swift +++ b/Model/Algorithm.swift @@ -6,6 +6,7 @@ // Copyright © 2023 Fin. All rights reserved. // +import CryptoSwift import Foundation enum Algorithm: String { @@ -38,3 +39,62 @@ enum Algorithm: String { } } } + +struct CryptoSettingFields { + let algorithm: String + let mode: String + let padding: String + let key: String? + let iv: String? +} + +struct AESCryptoModel { + let key: String + let mode: BlockMode + let padding: Padding + let aes: AES + init(cryptoFields: CryptoSettingFields) throws { + guard let algorithm = Algorithm(rawValue: cryptoFields.algorithm) else { + throw "Invalid algorithm" + } + guard let key = cryptoFields.key else { + throw "Key is missing" + } + + guard algorithm.keyLenght == key.count else { + throw String(format: NSLocalizedString("enterKey"), algorithm.keyLenght) + } + + var iv = "" + if ["CBC", "GCM"].contains(cryptoFields.mode) { + if let ivField = cryptoFields.iv, ivField.count == 16 { + iv = ivField + } + } + + let mode: BlockMode + switch cryptoFields.mode { + case "CBC": + mode = CBC(iv: iv.bytes) + case "ECB": + mode = ECB() + case "GCM": + mode = GCM(iv: iv.bytes) + default: + throw "Invalid Mode" + } + + self.key = key + self.mode = mode + self.padding = Padding.pkcs7 + self.aes = try AES(key: key.bytes, blockMode: self.mode, padding: self.padding) + } + + func encrypt(text: String) throws -> String { + return try aes.encrypt(Array(text.utf8)).toBase64() + } + + func decrypt(ciphertext: String) throws -> String { + return String(data: Data(try aes.decrypt(Array(base64: ciphertext))), encoding: .utf8) ?? "" + } +} diff --git a/Podfile b/Podfile index 1d7c9b9..496d328 100644 --- a/Podfile +++ b/Podfile @@ -43,6 +43,7 @@ end target 'NotificationServiceExtension' do pod 'IceCream' pod 'Kingfisher' + pod 'CryptoSwift' end post_install do |installer| diff --git a/Podfile.lock b/Podfile.lock index 7bbf96e..5caa437 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -147,6 +147,6 @@ SPEC CHECKSUMS: SVProgressHUD: 1428aafac632c1f86f62aa4243ec12008d7a51d6 SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e -PODFILE CHECKSUM: a6d53e3d3f1c8c892f61c29cc990d7b70691d966 +PODFILE CHECKSUM: caaf0ea0ab301807957ab7217eb404aff861f92c COCOAPODS: 1.11.3