Files
Morgan Pretty d96ef57273 Merge remote-tracking branch 'origin/feature/swift-package-manager' into feature/groups-rebuild
# Conflicts:
#	Podfile
#	Podfile.lock
#	Session.xcodeproj/project.pbxproj
#	Session/Calls/Call Management/SessionCall.swift
#	Session/Calls/Call Management/SessionCallManager.swift
#	Session/Calls/CallVC.swift
#	Session/Conversations/ConversationVC+Interaction.swift
#	Session/Conversations/ConversationVC.swift
#	Session/Conversations/ConversationViewModel.swift
#	Session/Conversations/Message Cells/Content Views/MediaAlbumView.swift
#	Session/Conversations/Settings/ThreadSettingsViewModel.swift
#	Session/Emoji/Emoji+Available.swift
#	Session/Home/GlobalSearch/GlobalSearchViewController.swift
#	Session/Home/HomeVC.swift
#	Session/Home/HomeViewModel.swift
#	Session/Home/New Conversation/NewDMVC.swift
#	Session/Media Viewing & Editing/DocumentTitleViewController.swift
#	Session/Media Viewing & Editing/GIFs/GifPickerCell.swift
#	Session/Media Viewing & Editing/GIFs/GifPickerViewController.swift
#	Session/Media Viewing & Editing/ImagePickerController.swift
#	Session/Media Viewing & Editing/MediaTileViewController.swift
#	Session/Media Viewing & Editing/PhotoCapture.swift
#	Session/Media Viewing & Editing/PhotoCaptureViewController.swift
#	Session/Media Viewing & Editing/PhotoLibrary.swift
#	Session/Media Viewing & Editing/SendMediaNavigationController.swift
#	Session/Meta/AppDelegate.swift
#	Session/Meta/AppEnvironment.swift
#	Session/Meta/MainAppContext.swift
#	Session/Meta/SessionApp.swift
#	Session/Notifications/NotificationPresenter.swift
#	Session/Notifications/PushRegistrationManager.swift
#	Session/Notifications/SyncPushTokensJob.swift
#	Session/Notifications/UserNotificationsAdaptee.swift
#	Session/Onboarding/LandingVC.swift
#	Session/Onboarding/LinkDeviceVC.swift
#	Session/Onboarding/Onboarding.swift
#	Session/Onboarding/RegisterVC.swift
#	Session/Onboarding/RestoreVC.swift
#	Session/Settings/HelpViewModel.swift
#	Session/Settings/NukeDataModal.swift
#	Session/Shared/FullConversationCell.swift
#	Session/Shared/OWSBezierPathView.m
#	Session/Utilities/BackgroundPoller.swift
#	Session/Utilities/MockDataGenerator.swift
#	SessionMessagingKit/Configuration.swift
#	SessionMessagingKit/Crypto/Crypto+SessionMessagingKit.swift
#	SessionMessagingKit/Database/Migrations/_004_RemoveLegacyYDB.swift
#	SessionMessagingKit/Database/Migrations/_014_GenerateInitialUserConfigDumps.swift
#	SessionMessagingKit/Database/Migrations/_015_BlockCommunityMessageRequests.swift
#	SessionMessagingKit/Database/Migrations/_018_DisappearingMessagesConfiguration.swift
#	SessionMessagingKit/Database/Models/Attachment.swift
#	SessionMessagingKit/Database/Models/DisappearingMessageConfiguration.swift
#	SessionMessagingKit/Database/Models/Interaction.swift
#	SessionMessagingKit/Database/Models/Profile.swift
#	SessionMessagingKit/Database/Models/SessionThread.swift
#	SessionMessagingKit/File Server/FileServerAPI.swift
#	SessionMessagingKit/Jobs/AttachmentDownloadJob.swift
#	SessionMessagingKit/Jobs/CheckForAppUpdatesJob.swift
#	SessionMessagingKit/Jobs/DisappearingMessagesJob.swift
#	SessionMessagingKit/Jobs/FailedMessageSendsJob.swift
#	SessionMessagingKit/Jobs/MessageSendJob.swift
#	SessionMessagingKit/Jobs/Types/GroupLeavingJob.swift
#	SessionMessagingKit/LibSession/Config Handling/LibSession+Contacts.swift
#	SessionMessagingKit/LibSession/Config Handling/LibSession+ConvoInfoVolatile.swift
#	SessionMessagingKit/LibSession/Config Handling/LibSession+Shared.swift
#	SessionMessagingKit/LibSession/Config Handling/LibSession+UserGroups.swift
#	SessionMessagingKit/LibSession/LibSession+SessionMessagingKit.swift
#	SessionMessagingKit/Messages/Message.swift
#	SessionMessagingKit/Open Groups/Crypto/Crypto+OpenGroupAPI.swift
#	SessionMessagingKit/Open Groups/Models/SOGSMessage.swift
#	SessionMessagingKit/Open Groups/OpenGroupAPI.swift
#	SessionMessagingKit/Open Groups/OpenGroupManager.swift
#	SessionMessagingKit/Sending & Receiving/Attachments/SignalAttachment.swift
#	SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+ExpirationTimers.swift
#	SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+LegacyClosedGroups.swift
#	SessionMessagingKit/Sending & Receiving/Message Handling/MessageReceiver+VisibleMessages.swift
#	SessionMessagingKit/Sending & Receiving/Message Handling/MessageSender+LegacyClosedGroups.swift
#	SessionMessagingKit/Sending & Receiving/MessageReceiver.swift
#	SessionMessagingKit/Sending & Receiving/MessageSender+Convenience.swift
#	SessionMessagingKit/Sending & Receiving/MessageSender.swift
#	SessionMessagingKit/Sending & Receiving/Notifications/Models/SubscribeRequest.swift
#	SessionMessagingKit/Sending & Receiving/Notifications/Models/UnsubscribeRequest.swift
#	SessionMessagingKit/Sending & Receiving/Notifications/PushNotificationAPI.swift
#	SessionMessagingKit/Sending & Receiving/Pollers/CurrentUserPoller.swift
#	SessionMessagingKit/Sending & Receiving/Pollers/GroupPoller.swift
#	SessionMessagingKit/Sending & Receiving/Pollers/OpenGroupAPI+Poller.swift
#	SessionMessagingKit/Sending & Receiving/Pollers/Poller.swift
#	SessionMessagingKit/Utilities/ProfileManager.swift
#	SessionMessagingKitTests/Jobs/MessageSendJobSpec.swift
#	SessionMessagingKitTests/LibSession/LibSessionSpec.swift
#	SessionMessagingKitTests/LibSession/LibSessionUtilSpec.swift
#	SessionMessagingKitTests/Open Groups/Models/SOGSMessageSpec.swift
#	SessionMessagingKitTests/Open Groups/OpenGroupAPISpec.swift
#	SessionMessagingKitTests/Open Groups/OpenGroupManagerSpec.swift
#	SessionMessagingKitTests/Utilities/CryptoSMKSpec.swift
#	SessionMessagingKitTests/_TestUtilities/MockOGMCache.swift
#	SessionNotificationServiceExtension/NSENotificationPresenter.swift
#	SessionNotificationServiceExtension/NotificationServiceExtension.swift
#	SessionShareExtension/ShareAppExtensionContext.swift
#	SessionShareExtension/ShareNavController.swift
#	SessionShareExtension/ThreadPickerVC.swift
#	SessionSnodeKit/Crypto/Crypto+SessionSnodeKit.swift
#	SessionSnodeKit/Models/DeleteAllBeforeResponse.swift
#	SessionSnodeKit/Models/DeleteAllMessagesResponse.swift
#	SessionSnodeKit/Models/DeleteMessagesResponse.swift
#	SessionSnodeKit/Models/RevokeSubkeyRequest.swift
#	SessionSnodeKit/Models/RevokeSubkeyResponse.swift
#	SessionSnodeKit/Models/SendMessageResponse.swift
#	SessionSnodeKit/Models/SnodeAuthenticatedRequestBody.swift
#	SessionSnodeKit/Models/UpdateExpiryAllResponse.swift
#	SessionSnodeKit/Models/UpdateExpiryResponse.swift
#	SessionSnodeKit/Networking/SnodeAPI.swift
#	SessionTests/Conversations/Settings/ThreadDisappearingMessagesViewModelSpec.swift
#	SessionTests/Conversations/Settings/ThreadSettingsViewModelSpec.swift
#	SessionTests/Database/DatabaseSpec.swift
#	SessionTests/Settings/NotificationContentViewModelSpec.swift
#	SessionUIKit/Components/ToastController.swift
#	SessionUIKit/Style Guide/Values.swift
#	SessionUtilitiesKit/Crypto/Crypto+SessionUtilitiesKit.swift
#	SessionUtilitiesKit/Crypto/Crypto.swift
#	SessionUtilitiesKit/Database/Models/Identity.swift
#	SessionUtilitiesKit/Database/Models/Job.swift
#	SessionUtilitiesKit/Database/Storage.swift
#	SessionUtilitiesKit/Database/Types/Migration.swift
#	SessionUtilitiesKit/General/AppContext.swift
#	SessionUtilitiesKit/General/Data+Utilities.swift
#	SessionUtilitiesKit/General/Logging.swift
#	SessionUtilitiesKit/General/SNUserDefaults.swift
#	SessionUtilitiesKit/General/String+Trimming.swift
#	SessionUtilitiesKit/General/String+Utilities.swift
#	SessionUtilitiesKit/General/TimestampUtils.swift
#	SessionUtilitiesKit/General/UIEdgeInsets.swift
#	SessionUtilitiesKit/JobRunner/JobRunner.swift
#	SessionUtilitiesKit/LibSession/LibSessionError.swift
#	SessionUtilitiesKit/Media/DataSource.swift
#	SessionUtilitiesKit/Meta/SessionUtilitiesKit.h
#	SessionUtilitiesKit/Networking/NetworkType.swift
#	SessionUtilitiesKit/Networking/ProxiedContentDownloader.swift
#	SessionUtilitiesKit/Utilities/BackgroundTaskManager.swift
#	SessionUtilitiesKit/Utilities/BencodeResponse.swift
#	SessionUtilitiesKit/Utilities/CExceptionHelper.mm
#	SessionUtilitiesKit/Utilities/FileManagerType.swift
#	SessionUtilitiesKit/Utilities/KeychainStorageType.swift
#	SessionUtilitiesKitTests/Database/Models/IdentitySpec.swift
#	SessionUtilitiesKitTests/Database/Utilities/PersistableRecordUtilitiesSpec.swift
#	SessionUtilitiesKitTests/General/SessionIdSpec.swift
#	SessionUtilitiesKitTests/JobRunner/JobRunnerSpec.swift
#	SignalUtilitiesKit/Configuration.swift
#	SignalUtilitiesKit/Media Viewing & Editing/Attachment Approval/AttachmentApprovalInputAccessoryView.swift
#	SignalUtilitiesKit/Media Viewing & Editing/Attachment Approval/AttachmentApprovalViewController.swift
#	SignalUtilitiesKit/Media Viewing & Editing/Attachment Approval/AttachmentTextToolbar.swift
#	SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorCropViewController.swift
#	SignalUtilitiesKit/Media Viewing & Editing/Image Editing/ImageEditorModel.swift
#	SignalUtilitiesKit/Media Viewing & Editing/MediaMessageView.swift
#	SignalUtilitiesKit/Meta/SignalUtilitiesKit.h
#	SignalUtilitiesKit/Shared View Controllers/OWSViewController.swift
#	SignalUtilitiesKit/Shared Views/CircleView.swift
#	SignalUtilitiesKit/Shared Views/TappableView.swift
#	SignalUtilitiesKit/Utilities/AppSetup.swift
#	SignalUtilitiesKit/Utilities/Bench.swift
#	SignalUtilitiesKit/Utilities/NoopNotificationsManager.swift
#	_SharedTestUtilities/CommonMockedExtensions.swift
#	_SharedTestUtilities/MockCrypto.swift
#	_SharedTestUtilities/Mocked.swift
#	_SharedTestUtilities/SynchronousStorage.swift
2024-07-10 14:44:33 +10:00

186 lines
7.1 KiB
Swift

// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
//
// stringlint:disable
import UIKit
// MARK: - Cache
public extension Cache {
static let appVersion: CacheConfig<AppVersionCacheType, AppVersionImmutableCacheType> = Dependencies.create(
identifier: "appVersion",
createInstance: { dependencies in AppVersion(using: dependencies) },
mutableInstance: { $0 },
immutableInstance: { $0 }
)
}
// MARK: - AppVersion
public class AppVersion: AppVersionCacheType {
private let dependencies: Dependencies
public let isValid: Bool
public let appVersion: String
public let buildNumber: String
public let commitHash: String
public let libSessionVersion: String
public var firstAppVersion: String?
public var lastAppVersion: String?
public var lastCompletedLaunchAppVersion: String?
public var lastCompletedLaunchMainAppVersion: String?
public var lastCompletedLaunchSAEAppVersion: String?
public var isFirstLaunch: Bool { self.firstAppVersion != nil }
public var didJustUpdate: Bool {
(lastAppVersion?.count ?? 0) > 0 &&
lastAppVersion != appVersion
}
public var versionInfo: String {
return [
"iOS \(UIDevice.current.systemVersion)",
[
"App: \(appVersion)",
[buildNumber.nullIfEmpty, commitHash.nullIfEmpty]
.compactMap { $0 }
.joined(separator: " - ")
.nullIfEmpty
.map { "(\($0))" }
].compactMap { $0 }.joined(separator: " "),
"libSession: \(LibSession.version)"
].joined(separator: ", ")
}
// MARK: - Initialization
fileprivate init(using dependencies: Dependencies) {
self.dependencies = dependencies
guard let appVersion: String = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String else {
self.isValid = false
self.appVersion = ""
self.buildNumber = ""
self.commitHash = ""
self.libSessionVersion = ""
self.firstAppVersion = nil
self.lastAppVersion = nil
self.lastCompletedLaunchAppVersion = nil
self.lastCompletedLaunchMainAppVersion = nil
self.lastCompletedLaunchSAEAppVersion = nil
return
}
let oldFirstAppVersion: String? = dependencies[defaults: .appGroup, key: .firstAppVersion]
self.isValid = true
self.appVersion = appVersion
self.buildNumber = (Bundle.main.infoDictionary?["CFBundleVersion"] as? String).defaulting(to: "")
self.commitHash = (Bundle.main.infoDictionary?["GitCommitHash"] as? String).defaulting(to: "")
self.libSessionVersion = LibSession.version
self.firstAppVersion = dependencies[defaults: .appGroup, key: .firstAppVersion]
.defaulting(to: appVersion)
self.lastAppVersion = dependencies[defaults: .appGroup, key: .lastAppVersion]
self.lastCompletedLaunchAppVersion = dependencies[defaults: .appGroup, key: .lastCompletedLaunchAppVersion]
self.lastCompletedLaunchMainAppVersion = dependencies[defaults: .appGroup, key: .lastCompletedLaunchMainAppVersion]
self.lastCompletedLaunchSAEAppVersion = dependencies[defaults: .appGroup, key: .lastCompletedLaunchSAEAppVersion]
// Ensure the value for the "first launched version".
if oldFirstAppVersion == nil {
dependencies[defaults: .appGroup, key: .firstAppVersion] = appVersion
}
// Update the value for the "most recently launched version".
dependencies[defaults: .appGroup, key: .lastAppVersion] = appVersion
}
// MARK: - Functions
private func anyLaunchDidComplete() {
lastCompletedLaunchAppVersion = appVersion
// Update the value for the "most recently launch-completed version".
dependencies[defaults: .appGroup, key: .lastCompletedLaunchAppVersion] = appVersion
}
public func mainAppLaunchDidComplete() {
lastCompletedLaunchMainAppVersion = appVersion
dependencies[defaults: .appGroup, key: .lastCompletedLaunchMainAppVersion] = appVersion
anyLaunchDidComplete()
}
public func saeLaunchDidComplete() {
lastCompletedLaunchSAEAppVersion = appVersion
dependencies[defaults: .appGroup, key: .lastCompletedLaunchSAEAppVersion] = appVersion
anyLaunchDidComplete()
}
}
// MARK: - AppVersionCacheType
/// This is a read-only version of the Cache designed to avoid unintentionally mutating the instance in a non-thread-safe way
public protocol AppVersionImmutableCacheType: ImmutableCacheType {
/// Flag indicating whether the version information is valid
var isValid: Bool { get }
/// The current app version
var appVersion: String { get }
/// The current build number
var buildNumber: String { get }
/// The commit hash for the current build
var commitHash: String { get }
/// The current `libSession` version
var libSessionVersion: String { get }
/// The version of the app when it was first launched (`nil` if the app has never been launched before)
var firstAppVersion: String? { get }
/// The version of the app the last time it was launched (`nil` if the app has never been launched before)
var lastAppVersion: String? { get }
/// The last app version where is successfully launched the main app
var lastCompletedLaunchAppVersion: String? { get }
/// The last app version where is successfully launched the main app
var lastCompletedLaunchMainAppVersion: String? { get }
/// The last app version where is successfully launched the main app
var lastCompletedLaunchSAEAppVersion: String? { get }
/// Flag indicating whether this is the first app launch
var isFirstLaunch: Bool { get }
/// Flag indicating whether the app was just updated
var didJustUpdate: Bool { get }
/// The full version information for the current version
var versionInfo: String { get }
}
public protocol AppVersionCacheType: AppVersionImmutableCacheType, MutableCacheType {
/// Function to call when the main app successfully completed a launch
func mainAppLaunchDidComplete()
/// Function to call when the share extension successfully completed a launch
func saeLaunchDidComplete()
}
// MARK: - UserDefaults Keys
private extension UserDefaults.StringKey {
/// The version of the app when it was first launched
static let firstAppVersion: UserDefaults.StringKey = "kNSUserDefaults_FirstAppVersion"
/// The version of the app when it was last launched
static let lastAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastVersion"
static let lastCompletedLaunchAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion"
static let lastCompletedLaunchMainAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_MainApp"
static let lastCompletedLaunchSAEAppVersion: UserDefaults.StringKey = "kNSUserDefaults_LastCompletedLaunchAppVersion_SAE"
}