diff --git a/AWSAPIGateway.podspec b/AWSAPIGateway.podspec
index 64d713a6e15..0629bed349e 100644
--- a/AWSAPIGateway.podspec
+++ b/AWSAPIGateway.podspec
@@ -9,7 +9,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSAuth.podspec b/AWSAuth.podspec
index d055132612f..8c943a43405 100644
--- a/AWSAuth.podspec
+++ b/AWSAuth.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSAuthCore.podspec b/AWSAuthCore.podspec
index b954059e4d7..5ebfaed7f07 100644
--- a/AWSAuthCore.podspec
+++ b/AWSAuthCore.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSAuthSDK/AWSAuthSDK.xcodeproj/project.pbxproj b/AWSAuthSDK/AWSAuthSDK.xcodeproj/project.pbxproj
index 90978bae3e3..3d745e3a0d5 100644
--- a/AWSAuthSDK/AWSAuthSDK.xcodeproj/project.pbxproj
+++ b/AWSAuthSDK/AWSAuthSDK.xcodeproj/project.pbxproj
@@ -4629,7 +4629,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSUserPoolsSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSUserPoolsSignIn;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -4646,7 +4646,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSUserPoolsSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSUserPoolsSignIn;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -4704,7 +4704,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = YES;
 				ONLY_ACTIVE_ARCH = YES;
 				SDKROOT = iphoneos;
@@ -4758,7 +4758,7 @@
 				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
 				GCC_WARN_UNUSED_FUNCTION = YES;
 				GCC_WARN_UNUSED_VARIABLE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = NO;
 				SDKROOT = iphoneos;
 				SWIFT_COMPILATION_MODE = wholemodule;
@@ -4779,7 +4779,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSFacebookSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSFacebookSignIn;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -4797,7 +4797,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSFacebookSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSFacebookSignIn;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -4816,7 +4816,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSAuthSDKTestAppUITests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
@@ -4842,7 +4842,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSAuthSDKTestAppUITests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_FAST_MATH = YES;
 				ONLY_ACTIVE_ARCH = YES;
@@ -4870,7 +4870,7 @@
 				);
 				INFOPLIST_FILE = Sources/AWSGoogleSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -4898,7 +4898,7 @@
 				);
 				INFOPLIST_FILE = Sources/AWSGoogleSignIn/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -4999,7 +4999,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSAuthSDKTestApp/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				MACH_O_TYPE = mh_execute;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
@@ -5034,7 +5034,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSAuthSDKTestApp/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				MACH_O_TYPE = mh_execute;
 				MTL_FAST_MATH = YES;
@@ -5091,7 +5091,7 @@
 				);
 				INFOPLIST_FILE = Sources/AWSMobileClientXCF/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				OTHER_SWIFT_FLAGS = "-Xfrontend -module-interface-preserve-types-as-written";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSMobileClient;
@@ -5131,7 +5131,7 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "USE_XCF=1";
 				INFOPLIST_FILE = Sources/AWSMobileClientXCF/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				OTHER_SWIFT_FLAGS = "-Xfrontend -module-interface-preserve-types-as-written";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSMobileClient;
@@ -5411,7 +5411,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSAuthCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSAuthCore;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -5430,7 +5430,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSAuthCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSAuthCore;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -5448,7 +5448,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSAuthUI/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSAuthUI;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -5466,7 +5466,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = Sources/AWSAuthUI/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSAuthUI;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -5497,7 +5497,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = Sources/AWSMobileClient/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSMobileClient;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -5531,7 +5531,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = Sources/AWSMobileClient/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSMobileClient;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
diff --git a/AWSAuthUI.podspec b/AWSAuthUI.podspec
index e5f208c7fb1..b0a4f5ba9bf 100644
--- a/AWSAuthUI.podspec
+++ b/AWSAuthUI.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSAutoScaling.podspec b/AWSAutoScaling.podspec
index 36af0c5b56d..c434427a5d6 100644
--- a/AWSAutoScaling.podspec
+++ b/AWSAutoScaling.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSChimeSDKIdentity.podspec b/AWSChimeSDKIdentity.podspec
index ea4b3c35f3a..eaf4a0586a6 100644
--- a/AWSChimeSDKIdentity.podspec
+++ b/AWSChimeSDKIdentity.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSChimeSDKMessaging.podspec b/AWSChimeSDKMessaging.podspec
index 8fe13a48c64..012979aaec8 100644
--- a/AWSChimeSDKMessaging.podspec
+++ b/AWSChimeSDKMessaging.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSCloudWatch.podspec b/AWSCloudWatch.podspec
index 34c92482a55..02da91b5e52 100644
--- a/AWSCloudWatch.podspec
+++ b/AWSCloudWatch.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSCloudWatch/AWSCloudWatchService.m b/AWSCloudWatch/AWSCloudWatchService.m
index 99d4cbad0d3..58d222a26d3 100644
--- a/AWSCloudWatch/AWSCloudWatchService.m
+++ b/AWSCloudWatch/AWSCloudWatchService.m
@@ -41,7 +41,6 @@ @implementation AWSCloudWatchResponseSerializer
 + (void)initialize {
     errorCodeDictionary = @{
                             @"InvalidParameterInput" : @(AWSCloudWatchErrorDashboardInvalidInput),
-                            @"ResourceNotFound" : @(AWSCloudWatchErrorDashboardNotFound),
                             @"InternalServiceError" : @(AWSCloudWatchErrorInternalService),
                             @"InvalidFormat" : @(AWSCloudWatchErrorInvalidFormat),
                             @"InvalidNextToken" : @(AWSCloudWatchErrorInvalidNextToken),
diff --git a/AWSCognitoAuth.podspec b/AWSCognitoAuth.podspec
index a87644f393b..1cf1377ce7a 100644
--- a/AWSCognitoAuth.podspec
+++ b/AWSCognitoAuth.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSCognitoAuth/AWSCognitoAuth.m b/AWSCognitoAuth/AWSCognitoAuth.m
index 3aea2899069..ecf28095eb5 100644
--- a/AWSCognitoAuth/AWSCognitoAuth.m
+++ b/AWSCognitoAuth/AWSCognitoAuth.m
@@ -51,7 +51,7 @@ @interface AWSCognitoAuth()<SFSafariViewControllerDelegate, NSURLConnectionDeleg
 API_AVAILABLE(ios(11.0))
 @interface AWSCognitoAuth()
 
-@property (nonatomic, strong) SFAuthenticationSession *sfAuthSession;
+@property (nonatomic, strong) ASWebAuthenticationSession *sfAuthSession;
 
 @end
 
@@ -358,10 +358,10 @@ - (void)launchSFWebAuthenticationSession:(NSURL *)hostedUIURL API_AVAILABLE(ios(
     self.sfAuthenticationSessionAvailable = YES;
     NSString *callbackURLScheme = [[self urlEncode:self.authConfiguration.signInRedirectUri] copy];
     __weak AWSCognitoAuth *weakSelf = self;
-    self.sfAuthSession = [[SFAuthenticationSession alloc] initWithURL:hostedUIURL
-                                                    callbackURLScheme:callbackURLScheme
-                                                    completionHandler:^(NSURL * _Nullable url,
-                                                                        NSError * _Nullable error) {
+    self.sfAuthSession = [[ASWebAuthenticationSession alloc] initWithURL:hostedUIURL
+                                                       callbackURLScheme:callbackURLScheme
+                                                       completionHandler:^(NSURL * _Nullable url,
+                                                                           NSError * _Nullable error) {
         __strong AWSCognitoAuth *strongSelf = weakSelf;
         [strongSelf handleSignInCallbackWithURL:url error:error];
     }];
@@ -403,7 +403,9 @@ - (void)handleSignInCallbackWithURL:(NSURL * _Nullable) url
 
 -(void)showSFSafariViewControllerForURL:(NSURL *)url
            withPresentingViewController:(UIViewController *)presentingViewController{
-    self.svc = [[SFSafariViewController alloc] initWithURL:url entersReaderIfAvailable:NO];
+    SFSafariViewControllerConfiguration *configuration = [[SFSafariViewControllerConfiguration alloc] init];
+    configuration.entersReaderIfAvailable = NO;
+    self.svc = [[SFSafariViewController alloc] initWithURL:url configuration:configuration];
     self.svc.delegate = self;
     self.svc.modalPresentationStyle = UIModalPresentationPopover;
     self.isProcessingSignIn = YES;
@@ -655,15 +657,15 @@ - (void)launchSFAuthenticationSessionForSignOut:(NSURL *) url API_AVAILABLE(ios(
     self.sfAuthenticationSessionAvailable = YES;
     NSString *callbackURLScheme = [[self urlEncode:self.authConfiguration.signOutRedirectUri] copy];
     __weak AWSCognitoAuth *weakSelf = self;
-    self.sfAuthSession = [[SFAuthenticationSession alloc] initWithURL:url
-                                                    callbackURLScheme:callbackURLScheme
-                                                    completionHandler:^(NSURL * _Nullable url,
-                                                                        NSError * _Nullable error) {
+    self.sfAuthSession = [[ASWebAuthenticationSession alloc] initWithURL:url
+                                                       callbackURLScheme:callbackURLScheme
+                                                       completionHandler:^(NSURL * _Nullable url,
+                                                                           NSError * _Nullable error) {
         __strong AWSCognitoAuth *strongSelf = weakSelf;
         if (url) {
             [strongSelf processURL:url forRedirection:NO];
         } else {
-            if (error.code != SFAuthenticationErrorCanceledLogin) {
+            if (error.code != ASWebAuthenticationSessionErrorCodeCanceledLogin) {
                 [strongSelf signOutLocallyAndClearLastKnownUser];
             }
             [strongSelf dismissSafariViewControllerAndCompleteSignOut:error];
@@ -674,7 +676,9 @@ - (void)launchSFAuthenticationSessionForSignOut:(NSURL *) url API_AVAILABLE(ios(
 
 - (void)signOutSFSafariVC: (UIViewController *) vc
                       url:(NSURL *)url {
-    self.svc = [[SFSafariViewController alloc] initWithURL:url entersReaderIfAvailable:NO];
+    SFSafariViewControllerConfiguration *configuration = [[SFSafariViewControllerConfiguration alloc] init];
+    configuration.entersReaderIfAvailable = NO;
+    self.svc = [[SFSafariViewController alloc] initWithURL:url configuration:configuration];
     self.svc.delegate = self;
     self.svc.modalPresentationStyle = UIModalPresentationPopover;
     self.isProcessingSignOut = YES;
diff --git a/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.h b/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.h
index 777f6631817..d44b8b92210 100644
--- a/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.h
+++ b/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.h
@@ -87,12 +87,12 @@ typedef NS_ENUM(NSInteger, AWSCognitoAuthUICKeyChainStoreAuthenticationType) {
 typedef NS_ENUM(NSInteger, AWSCognitoAuthUICKeyChainStoreAccessibility) {
     AWSCognitoAuthUICKeyChainStoreAccessibilityWhenUnlocked = 1,
     AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlock,
-    AWSCognitoAuthUICKeyChainStoreAccessibilityAlways,
+    AWSCognitoAuthUICKeyChainStoreAccessibilityAlways __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlock"),
     AWSCognitoAuthUICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly
     __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0),
     AWSCognitoAuthUICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly,
     AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly,
-    AWSCognitoAuthUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly,
+    AWSCognitoAuthUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSCognitoAuthUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly"),
 }
 __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
diff --git a/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.m b/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.m
index d79ee968248..bb536c018ca 100644
--- a/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.m
+++ b/AWSCognitoAuth/Internal/UICKeyChainStore/AWSCognitoAuthUICKeyChainStore.m
@@ -527,14 +527,7 @@ - (BOOL)setData:(NSData *)data forKey:(NSString *)key genericAttribute:(id)gener
     NSMutableDictionary *query = [self query];
     query[(__bridge __strong id)kSecAttrAccount] = key;
 #if TARGET_OS_IOS
-#pragma clang diagnostic push
-#pragma clang diagnostic ignored "-Wdeprecated-declarations"
-    if (floor(NSFoundationVersionNumber) > floor(1144.17)) { // iOS 9+
-        query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail;
-    } else if (floor(NSFoundationVersionNumber) > floor(1047.25)) { // iOS 8+
-        query[(__bridge __strong id)kSecUseNoAuthenticationUI] = (__bridge id)kCFBooleanTrue;
-    }
-#pragma clang diagnostic pop
+    query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail;
 #elif TARGET_OS_WATCH || TARGET_OS_TV
     query[(__bridge __strong id)kSecUseAuthenticationUI] = (__bridge id)kSecUseAuthenticationUIFail;
 #endif
@@ -1094,6 +1087,9 @@ + (NSString *)generatePassword
 
 #pragma mark -
 
+// These methods are deprecated, but still need to be implemented
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
 - (void)synchronize
 {
     // Deprecated, calling this method is no longer required
@@ -1104,6 +1100,7 @@ - (BOOL)synchronizeWithError:(NSError *__autoreleasing *)error
     // Deprecated, calling this method is no longer required
     return true;
 }
+#pragma clang diagnostic pop
 
 #pragma mark -
 
@@ -1348,6 +1345,11 @@ - (CFTypeRef)authenticationTypeObject
     }
 }
 
+// The following keys are deprecated, but they still need to be supported:
+// - AWSCognitoAuthUICKeyChainStoreAccessibilityAlways, kSecAttrAccessibleAlways,
+// - AWSCognitoAuthUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly, kSecAttrAccessibleAlwaysThisDeviceOnly
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 - (CFTypeRef)accessibilityObject
 {
     switch (_accessibility) {
@@ -1369,6 +1371,7 @@ - (CFTypeRef)accessibilityObject
             return nil;
     }
 }
+#pragma clang diagnostic pop
 
 + (NSError *)argumentError:(NSString *)message
 {
diff --git a/AWSCognitoIdentityProvider.podspec b/AWSCognitoIdentityProvider.podspec
index 11a0e251944..ddeb555222a 100644
--- a/AWSCognitoIdentityProvider.podspec
+++ b/AWSCognitoIdentityProvider.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSCognitoIdentityProvider/AWSCognitoIdentityUser.m b/AWSCognitoIdentityProvider/AWSCognitoIdentityUser.m
index 1d45dfff345..ae8caff475d 100644
--- a/AWSCognitoIdentityProvider/AWSCognitoIdentityUser.m
+++ b/AWSCognitoIdentityProvider/AWSCognitoIdentityUser.m
@@ -1169,6 +1169,9 @@ -(void) addSecretHashDeviceKeyAndUsername:(NSMutableDictionary<NSString *,NSStri
     [self addDeviceKey:authParameters];
 }
 
+// getMultiFactorAuthenticationCode is deprecated
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 /**
  * Invoke developer's ui to prompt user for mfa code and call enhanceAuth
  */
@@ -1208,6 +1211,7 @@ -(void) addSecretHashDeviceKeyAndUsername:(NSMutableDictionary<NSString *,NSStri
                 }];
     }
 }
+#pragma clang diagnostic pop
 
 -(AWSTask<AWSCognitoIdentityUserSession *>*) mfaAuthInternal: (NSString *) deliveryMedium
                                                  destination: (NSString *) destination
diff --git a/AWSCognitoIdentityProvider/Internal/NSData+AWSCognitoIdentityProvider.m b/AWSCognitoIdentityProvider/Internal/NSData+AWSCognitoIdentityProvider.m
index a471ebb7a7b..a0be5e98f7f 100644
--- a/AWSCognitoIdentityProvider/Internal/NSData+AWSCognitoIdentityProvider.m
+++ b/AWSCognitoIdentityProvider/Internal/NSData+AWSCognitoIdentityProvider.m
@@ -8,7 +8,7 @@
 #import "NSData+AWSCognitoIdentityProvider.h"
 #import "AWSJKBigInteger.h"
 
-void awsbigint_loadBigInt(){
+void awsbigint_loadBigInt(void){
 }
 
 AWSJKBigInteger *unsignedBigIntegerFromNSData(NSData* data) {
diff --git a/AWSCognitoIdentityProviderASF.podspec b/AWSCognitoIdentityProviderASF.podspec
index bb78690460a..b94f8824c21 100644
--- a/AWSCognitoIdentityProviderASF.podspec
+++ b/AWSCognitoIdentityProviderASF.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSComprehend.podspec b/AWSComprehend.podspec
index 8ca0bb3abe3..1f41cb4c47b 100644
--- a/AWSComprehend.podspec
+++ b/AWSComprehend.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSConnect.podspec b/AWSConnect.podspec
index 51cbfc0fa04..2b8c9ed7c92 100644
--- a/AWSConnect.podspec
+++ b/AWSConnect.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSConnectParticipant.podspec b/AWSConnectParticipant.podspec
index 8ae138b255e..dcb7ed477ef 100644
--- a/AWSConnectParticipant.podspec
+++ b/AWSConnectParticipant.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSCore.podspec b/AWSCore.podspec
index d3c3f53de18..18e26dd5b90 100644
--- a/AWSCore.podspec
+++ b/AWSCore.podspec
@@ -9,7 +9,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
 
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
@@ -18,7 +18,7 @@ Pod::Spec.new do |s|
   s.libraries    = 'z', 'sqlite3'
   s.requires_arc = true
 
-  s.source_files = 'AWSCore/*.{h,m}', 'AWSCore/**/*.{h,m}'
+  s.source_files = 'AWSCore/*.{h,m}', 'AWSCore/**/*.{h,m}', 'AWSCore/Logging/Extensions/*.swift'
   s.private_header_files = 'AWSCore/XMLWriter/**/*.h', 'AWSCore/FMDB/AWSFMDatabase+Private.h', 'AWSCore/Fabric/*.h', 'AWSCore/Mantle/extobjc/*.h', 'AWSCore/CognitoIdentity/AWSCognitoIdentity+Fabric.h'
   s.resource_bundle = { 'AWSCore' => ['AWSCore/PrivacyInfo.xcprivacy']}
 end
diff --git a/AWSCore/Bolts/AWSTask.m b/AWSCore/Bolts/AWSTask.m
index b668d1ff5a9..6654bb027b8 100644
--- a/AWSCore/Bolts/AWSTask.m
+++ b/AWSCore/Bolts/AWSTask.m
@@ -10,13 +10,13 @@
 
 #import "AWSTask.h"
 
-#import <libkern/OSAtomic.h>
+#import <stdatomic.h>
 
 #import "AWSBolts.h"
 
 NS_ASSUME_NONNULL_BEGIN
 
-__attribute__ ((noinline)) void awsbf_warnBlockingOperationOnMainThread() {
+__attribute__ ((noinline)) void awsbf_warnBlockingOperationOnMainThread(void) {
     NSLog(@"Warning: A long-running operation is being executed on the main thread. \n"
           " Break on awsbf_warnBlockingOperationOnMainThread() to debug.");
 }
@@ -98,12 +98,12 @@ + (instancetype)cancelledTask {
 }
 
 + (instancetype)taskForCompletionOfAllTasks:(nullable NSArray<AWSTask *> *)tasks {
-    __block int32_t total = (int32_t)tasks.count;
+    __block _Atomic(int32_t) total = (int32_t)tasks.count;
     if (total == 0) {
         return [self taskWithResult:nil];
     }
 
-    __block int32_t cancelled = 0;
+    __block _Atomic(int32_t) cancelled = 0;
     NSObject *lock = [[NSObject alloc] init];
     NSMutableArray *errors = [NSMutableArray array];
 
@@ -115,10 +115,11 @@ + (instancetype)taskForCompletionOfAllTasks:(nullable NSArray<AWSTask *> *)tasks
                     [errors addObject:t.error];
                 }
             } else if (t.cancelled) {
-                OSAtomicIncrement32Barrier(&cancelled);
+                atomic_fetch_add(&cancelled, 1);
             }
 
-            if (OSAtomicDecrement32Barrier(&total) == 0) {
+            atomic_fetch_sub(&total, 1);
+            if (total == 0) {
                 if (errors.count > 0) {
                     if (errors.count == 1) {
                         tcs.error = [errors firstObject];
@@ -148,14 +149,14 @@ + (instancetype)taskForCompletionOfAllTasksWithResults:(nullable NSArray<AWSTask
 
 + (instancetype)taskForCompletionOfAnyTask:(nullable NSArray<AWSTask *> *)tasks
 {
-    __block int32_t total = (int32_t)tasks.count;
+    __block _Atomic(int32_t) total = (int32_t)tasks.count;
     if (total == 0) {
         return [self taskWithResult:nil];
     }
     
-    __block int completed = 0;
-    __block int32_t cancelled = 0;
-    
+    __block _Atomic(BOOL) completed = NO;
+    __block _Atomic(int32_t) cancelled = 0;
+
     NSObject *lock = [NSObject new];
     NSMutableArray<NSError *> *errors = [NSMutableArray new];
     
@@ -167,15 +168,17 @@ + (instancetype)taskForCompletionOfAnyTask:(nullable NSArray<AWSTask *> *)tasks
                     [errors addObject:t.error];
                 }
             } else if (t.cancelled) {
-                OSAtomicIncrement32Barrier(&cancelled);
+                atomic_fetch_add(&cancelled, 1);
             } else {
-                if(OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
+                BOOL expected = NO;
+                if(atomic_compare_exchange_strong(&completed, &expected, YES)) {
                     [source setResult:t.result];
                 }
             }
-            
-            if (OSAtomicDecrement32Barrier(&total) == 0 &&
-                OSAtomicCompareAndSwap32Barrier(0, 1, &completed)) {
+
+            atomic_fetch_sub(&total, 1);
+            BOOL expected = NO;
+            if (total == 0 && atomic_compare_exchange_strong(&completed, &expected, YES)) {
                 if (cancelled > 0) {
                     [source cancel];
                 } else if (errors.count > 0) {
diff --git a/AWSCore/GZIP/AWSGZIP.m b/AWSCore/GZIP/AWSGZIP.m
index 14f55d5e646..c40677d03b9 100644
--- a/AWSCore/GZIP/AWSGZIP.m
+++ b/AWSCore/GZIP/AWSGZIP.m
@@ -34,7 +34,7 @@
 #import "AWSGZIP.h"
 #import <zlib.h>
 
-void awsgzip_loadGZIP(){
+void awsgzip_loadGZIP(void){
 }
 
 static const NSUInteger ChunkSize = 16384;
diff --git a/AWSCore/Logging/AWSCLIColor.h b/AWSCore/Logging/AWSCLIColor.h
new file mode 100644
index 00000000000..610ca606cb4
--- /dev/null
+++ b/AWSCore/Logging/AWSCLIColor.h
@@ -0,0 +1,54 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import <TargetConditionals.h>
+
+#if TARGET_OS_OSX
+
+#import <Foundation/Foundation.h>
+#import <QuartzCore/QuartzCore.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * This class represents an NSColor replacement for CLI projects that don't link with AppKit
+ **/
+@interface AWSCLIColor : NSObject
+
+/**
+ *  Convenience method for creating a `AWSCLIColor` instance from RGBA params
+ *
+ *  @param red   red channel, between 0 and 1
+ *  @param green green channel, between 0 and 1
+ *  @param blue  blue channel, between 0 and 1
+ *  @param alpha alpha channel, between 0 and 1
+ */
++ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha;
+
+/**
+ *  Get the RGBA components from a `AWSCLIColor`
+ *
+ *  @param red   red channel, between 0 and 1
+ *  @param green green channel, between 0 and 1
+ *  @param blue  blue channel, between 0 and 1
+ *  @param alpha alpha channel, between 0 and 1
+ */
+- (void)getRed:(nullable CGFloat *)red green:(nullable CGFloat *)green blue:(nullable CGFloat *)blue alpha:(nullable CGFloat *)alpha NS_SWIFT_NAME(get(red:green:blue:alpha:));
+
+@end
+
+NS_ASSUME_NONNULL_END
+
+#endif
diff --git a/AWSCore/Logging/AWSCLIColor.m b/AWSCore/Logging/AWSCLIColor.m
new file mode 100644
index 00000000000..701231ce0f9
--- /dev/null
+++ b/AWSCore/Logging/AWSCLIColor.m
@@ -0,0 +1,57 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import <TargetConditionals.h>
+
+#if TARGET_OS_OSX
+
+#import "AWSCLIColor.h"
+
+@interface AWSCLIColor () {
+    CGFloat _red, _green, _blue, _alpha;
+}
+
+@end
+
+
+@implementation AWSCLIColor
+
++ (instancetype)colorWithCalibratedRed:(CGFloat)red green:(CGFloat)green blue:(CGFloat)blue alpha:(CGFloat)alpha {
+    __auto_type color = [CLIColor new];
+    color->_red     = red;
+    color->_green   = green;
+    color->_blue    = blue;
+    color->_alpha   = alpha;
+    return color;
+}
+
+- (void)getRed:(CGFloat *)red green:(CGFloat *)green blue:(CGFloat *)blue alpha:(CGFloat *)alpha {
+    if (red) {
+        *red    = _red;
+    }
+    if (green) {
+        *green  = _green;
+    }
+    if (blue) {
+        *blue   = _blue;
+    }
+    if (alpha) {
+        *alpha  = _alpha;
+    }
+}
+
+@end
+
+#endif
diff --git a/AWSCore/Logging/AWSCocoaLumberjack.h b/AWSCore/Logging/AWSCocoaLumberjack.h
index 69047725982..0493199c92e 100644
--- a/AWSCore/Logging/AWSCocoaLumberjack.h
+++ b/AWSCore/Logging/AWSCocoaLumberjack.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -76,12 +76,24 @@
 #import "AWSDDASLLogCapture.h"
 
 // Loggers
+#import "AWSDDLoggerNames.h"
+
 #import "AWSDDTTYLogger.h"
 #import "AWSDDASLLogger.h"
 #import "AWSDDFileLogger.h"
 #import "AWSDDOSLogger.h"
 
+// Extensions
+#import "AWSDDContextFilterLogFormatter.h"
+#import "AWSDDContextFilterLogFormatter+Deprecated.h"
+#import "AWSDDDispatchQueueLogFormatter.h"
+#import "AWSDDMultiFormatter.h"
+#import "AWSDDFileLogger+Buffering.h"
+
 // CLI
-#if __has_include("CLIColor.h") && TARGET_OS_OSX
-#import "CLIColor.h"
-#endif
+#import "AWSCLIColor.h"
+
+// etc
+#import "AWSDDAbstractDatabaseLogger.h"
+#import "AWSDDLog+LOGV.h"
+#import "AWSDDLegacyMacros.h"
diff --git a/AWSCore/Logging/AWSDDASLLogCapture.h b/AWSCore/Logging/AWSDDASLLogCapture.h
index 708258365e4..aa3d2b1b9eb 100644
--- a/AWSCore/Logging/AWSDDASLLogCapture.h
+++ b/AWSCore/Logging/AWSDDASLLogCapture.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -17,9 +17,12 @@
 
 @protocol AWSDDLogger;
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  *  This class provides the ability to capture the ASL (Apple System Logs)
  */
+API_DEPRECATED("Use AWSDDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
 @interface AWSDDASLLogCapture : NSObject
 
 /**
@@ -39,3 +42,5 @@
 @property (class) AWSDDLogLevel captureLevel;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDASLLogCapture.m b/AWSCore/Logging/AWSDDASLLogCapture.m
index 2059dcb3e2d..0d078ba744f 100644
--- a/AWSCore/Logging/AWSDDASLLogCapture.m
+++ b/AWSCore/Logging/AWSDDASLLogCapture.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,56 +13,29 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDASLLogCapture.h"
-
-// Disable legacy macros
-#ifndef AWSDD_LEGACY_MACROS
-    #define AWSDD_LEGACY_MACROS 0
-#endif
+#import <TargetConditionals.h>
 
-#import "AWSDDLog.h"
+#if !TARGET_OS_WATCH
 
 #include <asl.h>
 #include <notify.h>
 #include <notify_keys.h>
 #include <sys/time.h>
 
-static BOOL _cancel = YES;
-static AWSDDLogLevel _captureLevel = AWSDDLogLevelVerbose;
+#import "AWSDDASLLogCapture.h"
 
-#ifdef __IPHONE_8_0
-    #define AWSDDASL_IOS_PIVOT_VERSION __IPHONE_8_0
-#endif
-#ifdef __MAC_10_10
-    #define AWSDDASL_OSX_PIVOT_VERSION __MAC_10_10
+// Disable legacy macros
+#ifndef AWSDD_LEGACY_MACROS
+    #define AWSDD_LEGACY_MACROS 0
 #endif
 
-@implementation AWSDDASLLogCapture
+static __auto_type _cancel = YES;
+static __auto_type _captureLevel = AWSDDLogLevelVerbose;
 
-static aslmsg (*dd_asl_next)(aslresponse obj);
-static void (*dd_asl_release)(aslresponse obj);
-
-+ (void)initialize
-{
-    #if (defined(AWSDDASL_IOS_PIVOT_VERSION) && __IPHONE_OS_VERSION_MAX_ALLOWED >= AWSDDASL_IOS_PIVOT_VERSION) || (defined(AWSDDASL_OSX_PIVOT_VERSION) && __MAC_OS_X_VERSION_MAX_ALLOWED >= AWSDDASL_OSX_PIVOT_VERSION)
-        #if __IPHONE_OS_VERSION_MIN_REQUIRED < AWSDDASL_IOS_PIVOT_VERSION || __MAC_OS_X_VERSION_MIN_REQUIRED < AWSDDASL_OSX_PIVOT_VERSION
-            #pragma GCC diagnostic push
-            #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
-                // Building on falsely advertised SDK, targeting deprecated API
-                dd_asl_next    = &aslresponse_next;
-                dd_asl_release = &aslresponse_free;
-            #pragma GCC diagnostic pop
-        #else
-            // Building on lastest, correct SDK, targeting latest API
-            dd_asl_next    = &asl_next;
-            dd_asl_release = &asl_release;
-        #endif
-    #else
-        // Building on old SDKs, targeting deprecated API
-        dd_asl_next    = &aslresponse_next;
-        dd_asl_release = &aslresponse_free;
-    #endif
-}
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+@implementation AWSDDASLLogCapture
+#pragma clang diagnostic pop
 
 + (void)start {
     // Ignore subsequent calls
@@ -93,29 +66,29 @@ + (void)setCaptureLevel:(AWSDDLogLevel)level {
 
 + (void)configureAslQuery:(aslmsg)query {
     const char param[] = "7";  // ASL_LEVEL_DEBUG, which is everything. We'll rely on regular AWSDDlog log level to filter
-    
+
     asl_set_query(query, ASL_KEY_LEVEL, param, ASL_QUERY_OP_LESS_EQUAL | ASL_QUERY_OP_NUMERIC);
 
     // Don't retrieve logs from our own AWSDDASLLogger
     asl_set_query(query, kAWSDDASLKeyAWSDDLog, kAWSDDASLAWSDDLogValue, ASL_QUERY_OP_NOT_EQUAL);
-    
-#if !TARGET_OS_IPHONE || TARGET_SIMULATOR
-    int processId = [[NSProcessInfo processInfo] processIdentifier];
+
+#if !TARGET_OS_IPHONE || (defined(TARGET_SIMULATOR) && TARGET_SIMULATOR)
+    __auto_type processId = [[NSProcessInfo processInfo] processIdentifier];
     char pid[16];
-    sprintf(pid, "%d", processId);
+    snprintf(pid, sizeof(pid), "%d", processId);
     asl_set_query(query, ASL_KEY_PID, pid, ASL_QUERY_OP_EQUAL | ASL_QUERY_OP_NUMERIC);
 #endif
 }
 
 + (void)aslMessageReceived:(aslmsg)msg {
-    const char* messageCString = asl_get( msg, ASL_KEY_MSG );
+    __auto_type messageCString = asl_get(msg, ASL_KEY_MSG);
     if (messageCString == NULL)
         return;
 
-    int flag;
+    AWSDDLogFlag flag;
     BOOL async;
 
-    const char* levelCString = asl_get(msg, ASL_KEY_LEVEL);
+    __auto_type levelCString = asl_get(msg, ASL_KEY_LEVEL);
     switch (levelCString? atoi(levelCString) : 0) {
         // By default all NSLog's with a ASL_LEVEL_WARNING level
         case ASL_LEVEL_EMERG    :
@@ -136,25 +109,25 @@ + (void)aslMessageReceived:(aslmsg)msg {
     //  NSString * sender = [NSString stringWithCString:asl_get(msg, ASL_KEY_SENDER) encoding:NSUTF8StringEncoding];
     NSString *message = @(messageCString);
 
-    const char* secondsCString = asl_get( msg, ASL_KEY_TIME );
-    const char* nanoCString = asl_get( msg, ASL_KEY_TIME_NSEC );
-    NSTimeInterval seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970;
-    double nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0;
-    NSTimeInterval totalSeconds = seconds + (nanoSeconds / 1e9);
-
-    NSDate *timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
-
-    AWSDDLogMessage *logMessage = [[AWSDDLogMessage alloc]initWithMessage:message
-                                                              level:_captureLevel
-                                                               flag:flag
-                                                            context:0
-                                                             file:@"AWSDDASLLogCapture"
-                                                           function:0
-                                                               line:0
-                                                                tag:nil
-                                                            options:0
-                                                          timestamp:timeStamp];
-    
+    __auto_type secondsCString = asl_get(msg, ASL_KEY_TIME);
+    __auto_type nanoCString = asl_get(msg, ASL_KEY_TIME_NSEC);
+    __auto_type seconds = secondsCString ? strtod(secondsCString, NULL) : [NSDate timeIntervalSinceReferenceDate] - NSTimeIntervalSince1970;
+    __auto_type nanoSeconds = nanoCString? strtod(nanoCString, NULL) : 0;
+    __auto_type totalSeconds = seconds + (nanoSeconds / 1e9);
+
+    __auto_type timeStamp = [NSDate dateWithTimeIntervalSince1970:totalSeconds];
+
+    __auto_type logMessage = [[AWSDDLogMessage alloc] initWithMessage:message
+                                                                level:_captureLevel
+                                                                 flag:flag
+                                                              context:0
+                                                                 file:@"AWSDDASLLogCapture"
+                                                             function:nil
+                                                                 line:0
+                                                                  tag:nil
+                                                              options:AWSDDLogMessageDontCopyMessage
+                                                            timestamp:timeStamp];
+
     [AWSDDLog log:async message:logMessage];
 }
 
@@ -171,7 +144,7 @@ + (void)captureAslLogs {
             .tv_sec = 0
         };
         gettimeofday(&timeval, NULL);
-        unsigned long long startTime = timeval.tv_sec;
+        __auto_type startTime = (unsigned long long)timeval.tv_sec;
         __block unsigned long long lastSeenID = 0;
 
         /*
@@ -190,7 +163,7 @@ syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
             // At least one message has been posted; build a search query.
             @autoreleasepool
             {
-                aslmsg query = asl_new(ASL_TYPE_QUERY);
+                __auto_type query = asl_new(ASL_TYPE_QUERY);
                 char stringValue[64];
 
                 if (lastSeenID > 0) {
@@ -205,16 +178,16 @@ syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
 
                 // Iterate over new messages.
                 aslmsg msg;
-                aslresponse response = asl_search(NULL, query);
-                
-                while ((msg = dd_asl_next(response)))
+                __auto_type response = asl_search(NULL, query);
+
+                while ((msg = asl_next(response)))
                 {
                     [self aslMessageReceived:msg];
 
                     // Keep track of which messages we've seen.
-                    lastSeenID = atoll(asl_get(msg, ASL_KEY_MSG_ID));
+                    lastSeenID = (unsigned long long)atoll(asl_get(msg, ASL_KEY_MSG_ID));
                 }
-                dd_asl_release(response);
+                asl_release(response);
                 asl_free(query);
 
                 if (_cancel) {
@@ -228,3 +201,5 @@ syslogd posts kNotifyASLDBUpdate (com.apple.system.logger.message)
 }
 
 @end
+
+#endif
diff --git a/AWSCore/Logging/AWSDDASLLogger.h b/AWSCore/Logging/AWSDDASLLogger.h
index 757708da8b8..ee730e23823 100644
--- a/AWSCore/Logging/AWSDDASLLogger.h
+++ b/AWSCore/Logging/AWSDDASLLogger.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -22,6 +22,8 @@
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 // Custom key set on messages sent to ASL
 extern const char* const kAWSDDASLKeyAWSDDLog;
 
@@ -41,6 +43,7 @@ extern const char* const kAWSDDASLAWSDDLogValue;
  * However, if you instead choose to use file logging (for faster performance),
  * you may choose to use a file logger and a tty logger.
  **/
+API_DEPRECATED("Use AWSDDOSLogger instead", macosx(10.4,10.12), ios(2.0,10.0), watchos(2.0,3.0), tvos(9.0,10.0))
 @interface AWSDDASLLogger : AWSDDAbstractLogger <AWSDDLogger>
 
 /**
@@ -48,7 +51,7 @@ extern const char* const kAWSDDASLAWSDDLogValue;
  *
  *  @return the shared instance
  */
-@property (class, readonly, strong) AWSDDASLLogger *sharedInstance;
+@property (nonatomic, class, readonly, strong) AWSDDASLLogger *sharedInstance;
 
 // Inherited from AWSDDAbstractLogger
 
@@ -56,3 +59,5 @@ extern const char* const kAWSDDASLAWSDDLogValue;
 // - (void)setLogFormatter:(id <AWSDDLogFormatter>)formatter;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDASLLogger.m b/AWSCore/Logging/AWSDDASLLogger.m
index 21a99f03d75..53a3df2e980 100644
--- a/AWSCore/Logging/AWSDDASLLogger.m
+++ b/AWSCore/Logging/AWSDDASLLogger.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,17 +13,26 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDASLLogger.h"
-#import <asl.h>
+#import <TargetConditionals.h>
+
+#if !TARGET_OS_WATCH
 
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
-const char* const kAWSDDASLKeyAWSDDLog = "AWSDDLog";
+#import <asl.h>
 
+#import "AWSDDASLLogger.h"
+
+const char* const kAWSDDASLKeyAWSDDLog = "AWSDDLog";
 const char* const kAWSDDASLAWSDDLogValue = "1";
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated"
+static AWSDDASLLogger *sharedInstance;
+#pragma clang diagnostic pop
+
 @interface AWSDDASLLogger () {
     aslclient _client;
 }
@@ -31,9 +40,10 @@ @interface AWSDDASLLogger () {
 @end
 
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
 @implementation AWSDDASLLogger
-
-static AWSDDASLLogger *sharedInstance;
+#pragma clang diagnostic pop
 
 + (instancetype)sharedInstance {
     static dispatch_once_t AWSDDASLLoggerOnceToken;
@@ -60,16 +70,20 @@ - (instancetype)init {
     return self;
 }
 
+- (AWSDDLoggerName)loggerName {
+    return AWSDDLoggerNameASL;
+}
+
 - (void)logMessage:(AWSDDLogMessage *)logMessage {
     // Skip captured log messages
     if ([logMessage->_fileName isEqualToString:@"AWSDDASLLogCapture"]) {
         return;
     }
 
-    NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
+    __auto_type message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
 
     if (message) {
-        const char *msg = [message UTF8String];
+        __auto_type msg = [message UTF8String];
 
         size_t aslLogLevel;
         switch (logMessage->_flag) {
@@ -86,11 +100,11 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
         static char const *const level_strings[] = { "0", "1", "2", "3", "4", "5", "6", "7" };
 
         // NSLog uses the current euid to set the ASL_KEY_READ_UID.
-        uid_t const readUID = geteuid();
+        const __auto_type readUID = geteuid();
 
         char readUIDString[16];
 #ifndef NS_BLOCK_ASSERTIONS
-        size_t l = snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
+        __auto_type l = (size_t)snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
 #else
         snprintf(readUIDString, sizeof(readUIDString), "%d", readUID);
 #endif
@@ -100,7 +114,7 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
         NSAssert(aslLogLevel < (sizeof(level_strings) / sizeof(level_strings[0])),
                  @"Unhandled ASL log level.");
 
-        aslmsg m = asl_new(ASL_TYPE_MSG);
+        __auto_type m = asl_new(ASL_TYPE_MSG);
         if (m != NULL) {
             if (asl_set(m, ASL_KEY_LEVEL, level_strings[aslLogLevel]) == 0 &&
                 asl_set(m, ASL_KEY_MSG, msg) == 0 &&
@@ -114,8 +128,6 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
     }
 }
 
-- (NSString *)loggerName {
-    return @"cocoa.lumberjack.aslLogger";
-}
-
 @end
+
+#endif
diff --git a/AWSCore/Logging/AWSDDAbstractDatabaseLogger.h b/AWSCore/Logging/AWSDDAbstractDatabaseLogger.h
index 347a7c33931..f82fb28d955 100644
--- a/AWSCore/Logging/AWSDDAbstractDatabaseLogger.h
+++ b/AWSCore/Logging/AWSDDAbstractDatabaseLogger.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -20,6 +20,8 @@
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  * This class provides an abstract implementation of a database logger.
  *
@@ -28,7 +30,7 @@
  * and override the methods in the implementation file that are prefixed with "db_".
  **/
 @interface AWSDDAbstractDatabaseLogger : AWSDDAbstractLogger {
-    
+
 @protected
     NSUInteger _saveThreshold;
     NSTimeInterval _saveInterval;
@@ -36,7 +38,7 @@
     NSTimeInterval _deleteInterval;
     BOOL _deleteOnEverySave;
     
-    BOOL _saveTimerSuspended;
+    NSInteger _saveTimerSuspended;
     NSUInteger _unsavedCount;
     dispatch_time_t _unsavedTime;
     dispatch_source_t _saveTimer;
@@ -121,3 +123,5 @@
 - (void)deleteOldLogEntries;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDAbstractDatabaseLogger.m b/AWSCore/Logging/AWSDDAbstractDatabaseLogger.m
index 62a2af28040..7a8c2618360 100644
--- a/AWSCore/Logging/AWSDDAbstractDatabaseLogger.m
+++ b/AWSCore/Logging/AWSDDAbstractDatabaseLogger.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,18 +13,20 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDAbstractDatabaseLogger.h"
-#import <math.h>
-
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import "AWSDDAbstractDatabaseLogger.h"
+
 @interface AWSDDAbstractDatabaseLogger ()
 
 - (void)destroySaveTimer;
+- (void)updateAndResumeSaveTimer;
+- (void)createSuspendedSaveTimer;
 - (void)destroyDeleteTimer;
+- (void)updateDeleteTimer;
+- (void)createAndStartDeleteTimer;
 
 @end
 
@@ -52,7 +54,7 @@ - (void)dealloc {
 #pragma mark Override Me
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-- (BOOL)db_log:(AWSDDLogMessage *)logMessage {
+- (BOOL)db_log:(__unused AWSDDLogMessage *)logMessage {
     // Override me and add your implementation.
     //
     // Return YES if an item was added to the buffer.
@@ -89,9 +91,9 @@ - (void)performSaveAndSuspendSaveTimer {
     _unsavedCount = 0;
     _unsavedTime = 0;
 
-    if (_saveTimer && !_saveTimerSuspended) {
+    if (_saveTimer != NULL && _saveTimerSuspended == 0) {
         dispatch_suspend(_saveTimer);
-        _saveTimerSuspended = YES;
+        _saveTimerSuspended = 1;
     }
 }
 
@@ -108,32 +110,37 @@ - (void)performDelete {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 - (void)destroySaveTimer {
-    if (_saveTimer) {
+    if (_saveTimer != NULL) {
         dispatch_source_cancel(_saveTimer);
 
-        if (_saveTimerSuspended) {
-            // Must resume a timer before releasing it (or it will crash)
+        // Must activate a timer before releasing it (or it will crash)
+        if (_saveTimerSuspended < 0) {
+            dispatch_activate(_saveTimer);
+        } else if (_saveTimerSuspended > 0) {
             dispatch_resume(_saveTimer);
-            _saveTimerSuspended = NO;
         }
 
-        #if !OS_OBJECT_USE_OBJC
+#if !OS_OBJECT_USE_OBJC
         dispatch_release(_saveTimer);
-        #endif
+#endif
         _saveTimer = NULL;
+        _saveTimerSuspended = 0;
     }
 }
 
 - (void)updateAndResumeSaveTimer {
-    if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0.0)) {
-        uint64_t interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC);
-        dispatch_time_t startTime = dispatch_time(_unsavedTime, interval);
+    if ((_saveTimer != NULL) && (_saveInterval > 0.0) && (_unsavedTime > 0)) {
+        __auto_type interval = (uint64_t)(_saveInterval * (NSTimeInterval) NSEC_PER_SEC);
+        __auto_type startTime = dispatch_time(_unsavedTime, (int64_t)interval);
 
         dispatch_source_set_timer(_saveTimer, startTime, interval, 1ull * NSEC_PER_SEC);
 
-        if (_saveTimerSuspended) {
+        if (_saveTimerSuspended < 0) {
+            dispatch_activate(_saveTimer);
+            _saveTimerSuspended = 0;
+        } else if (_saveTimerSuspended > 0) {
             dispatch_resume(_saveTimer);
-            _saveTimerSuspended = NO;
+            _saveTimerSuspended = 0;
         }
     }
 }
@@ -143,26 +150,26 @@ - (void)createSuspendedSaveTimer {
         _saveTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue);
 
         dispatch_source_set_event_handler(_saveTimer, ^{ @autoreleasepool {
-                                                            [self performSaveAndSuspendSaveTimer];
-                                                        } });
+            [self performSaveAndSuspendSaveTimer];
+        } });
 
-        _saveTimerSuspended = YES;
+        _saveTimerSuspended = -1;
     }
 }
 
 - (void)destroyDeleteTimer {
-    if (_deleteTimer) {
+    if (_deleteTimer != NULL) {
         dispatch_source_cancel(_deleteTimer);
-        #if !OS_OBJECT_USE_OBJC
+#if !OS_OBJECT_USE_OBJC
         dispatch_release(_deleteTimer);
-        #endif
+#endif
         _deleteTimer = NULL;
     }
 }
 
 - (void)updateDeleteTimer {
     if ((_deleteTimer != NULL) && (_deleteInterval > 0.0) && (_maxAge > 0.0)) {
-        uint64_t interval = (uint64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC);
+        __auto_type interval = (int64_t)(_deleteInterval * (NSTimeInterval) NSEC_PER_SEC);
         dispatch_time_t startTime;
 
         if (_lastDeleteTime > 0) {
@@ -171,7 +178,7 @@ - (void)updateDeleteTimer {
             startTime = dispatch_time(DISPATCH_TIME_NOW, interval);
         }
 
-        dispatch_source_set_timer(_deleteTimer, startTime, interval, 1ull * NSEC_PER_SEC);
+        dispatch_source_set_timer(_deleteTimer, startTime, (uint64_t)interval, 1ull * NSEC_PER_SEC);
     }
 }
 
@@ -181,14 +188,14 @@ - (void)createAndStartDeleteTimer {
 
         if (_deleteTimer != NULL) {
             dispatch_source_set_event_handler(_deleteTimer, ^{ @autoreleasepool {
-                                                                  [self performDelete];
-                                                              } });
+                [self performDelete];
+            } });
 
             [self updateDeleteTimer];
 
-            if (_deleteTimer != NULL) {
-                dispatch_resume(_deleteTimer);
-            }
+            // We are sure that -updateDeleteTimer did call dispatch_source_set_timer()
+            // since it has the same guards on _deleteInterval and _maxAge
+            dispatch_activate(_deleteTimer);
         }
     }
 }
@@ -208,14 +215,10 @@ - (NSUInteger)saveThreshold {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block NSUInteger result;
-
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_saveThreshold;
         });
@@ -248,10 +251,8 @@ - (void)setSaveThreshold:(NSUInteger)threshold {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -268,14 +269,10 @@ - (NSTimeInterval)saveInterval {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block NSTimeInterval result;
-
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_saveInterval;
         });
@@ -285,7 +282,7 @@ - (NSTimeInterval)saveInterval {
 }
 
 - (void)setSaveInterval:(NSTimeInterval)interval {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             // C99 recommended floating point comparison macro
             // Read: isLessThanOrGreaterThan(floatA, floatB)
@@ -339,10 +336,8 @@ - (void)setSaveInterval:(NSTimeInterval)interval {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -359,14 +354,11 @@ - (NSTimeInterval)maxAge {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block NSTimeInterval result;
 
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_maxAge;
         });
@@ -376,14 +368,14 @@ - (NSTimeInterval)maxAge {
 }
 
 - (void)setMaxAge:(NSTimeInterval)interval {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             // C99 recommended floating point comparison macro
             // Read: isLessThanOrGreaterThan(floatA, floatB)
 
             if (/* maxAge != interval */ islessgreater(self->_maxAge, interval)) {
-                NSTimeInterval oldMaxAge = self->_maxAge;
-                NSTimeInterval newMaxAge = interval;
+                __auto_type oldMaxAge = self->_maxAge;
+                __auto_type newMaxAge = interval;
 
                 self->_maxAge = interval;
 
@@ -401,7 +393,7 @@ - (void)setMaxAge:(NSTimeInterval)interval {
                 // 4. If the maxAge was decreased,
                 //    then we should do an immediate delete.
 
-                BOOL shouldDeleteNow = NO;
+                __auto_type shouldDeleteNow = NO;
 
                 if (oldMaxAge > 0.0) {
                     if (newMaxAge <= 0.0) {
@@ -436,10 +428,8 @@ - (void)setMaxAge:(NSTimeInterval)interval {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -456,14 +446,11 @@ - (NSTimeInterval)deleteInterval {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block NSTimeInterval result;
 
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_deleteInterval;
         });
@@ -473,7 +460,7 @@ - (NSTimeInterval)deleteInterval {
 }
 
 - (void)setDeleteInterval:(NSTimeInterval)interval {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             // C99 recommended floating point comparison macro
             // Read: isLessThanOrGreaterThan(floatA, floatB)
@@ -526,10 +513,9 @@ - (void)setDeleteInterval:(NSTimeInterval)interval {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
 
-        dispatch_async(globalLoggingQueue, ^{
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -546,14 +532,11 @@ - (BOOL)deleteOnEverySave {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block BOOL result;
 
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_deleteOnEverySave;
         });
@@ -563,7 +546,7 @@ - (BOOL)deleteOnEverySave {
 }
 
 - (void)setDeleteOnEverySave:(BOOL)flag {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         self->_deleteOnEverySave = flag;
     };
 
@@ -573,10 +556,8 @@ - (void)setDeleteOnEverySave:(BOOL)flag {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -587,7 +568,7 @@ - (void)setDeleteOnEverySave:(BOOL)flag {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 - (void)savePendingLogEntries {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self performSaveAndSuspendSaveTimer];
         }
@@ -601,7 +582,7 @@ - (void)savePendingLogEntries {
 }
 
 - (void)deleteOldLogEntries {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self performDelete];
         }
@@ -620,24 +601,20 @@ - (void)deleteOldLogEntries {
 
 - (void)didAddLogger {
     // If you override me be sure to invoke [super didAddLogger];
-
     [self createSuspendedSaveTimer];
-
     [self createAndStartDeleteTimer];
 }
 
 - (void)willRemoveLogger {
     // If you override me be sure to invoke [super willRemoveLogger];
-
     [self performSaveAndSuspendSaveTimer];
-
     [self destroySaveTimer];
     [self destroyDeleteTimer];
 }
 
 - (void)logMessage:(AWSDDLogMessage *)logMessage {
     if ([self db_log:logMessage]) {
-        BOOL firstUnsavedEntry = (++_unsavedCount == 1);
+        __auto_type firstUnsavedEntry = (++_unsavedCount == 1);
 
         if ((_unsavedCount >= _saveThreshold) && (_saveThreshold > 0)) {
             [self performSaveAndSuspendSaveTimer];
@@ -653,7 +630,6 @@ - (void)flush {
     //
     // It is called automatically when the application quits,
     // or if the developer invokes AWSDDLog's flushLog method prior to crashing or something.
-
     [self performSaveAndSuspendSaveTimer];
 }
 
diff --git a/AWSCore/Logging/AWSDDAssertMacros.h b/AWSCore/Logging/AWSDDAssertMacros.h
index e38cd75f6ee..83ed10dcf94 100644
--- a/AWSCore/Logging/AWSDDAssertMacros.h
+++ b/AWSCore/Logging/AWSDDAssertMacros.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -14,13 +14,17 @@
 //   prior written permission of Deusty, LLC.
 
 /**
- * NSAsset replacement that will output a log message even when assertions are disabled.
+ * NSAssert replacement that will output a log message even when assertions are disabled.
  **/
 #define AWSDDAssert(condition, frmt, ...)                                                \
         if (!(condition)) {                                                           \
             NSString *description = [NSString stringWithFormat:frmt, ## __VA_ARGS__]; \
             AWSDDLogError(@"%@", description);                                           \
-            NSAssert(NO, description);                                                \
+            NSAssert(NO, @"%@", description);                                         \
         }
-#define AWSDDAssertCondition(condition) AWSDDAssert(condition, @"Condition not satisfied: %s", #condition)
+#define AWSDDAssertCondition(condition) AWSDDAssert(condition, @"Condition not satisfied: %@", @(#condition))
 
+/**
+ * Analog to `AWSDDAssertionFailure` from AWSDDAssert.swift for use in Objective C
+ */
+#define AWSDDAssertionFailure(frmt, ...) AWSDDAssert(NO, frmt, ##__VA_ARGS__)
diff --git a/AWSCore/Logging/AWSDDFileLogger.h b/AWSCore/Logging/AWSDDFileLogger.h
index d172756d84a..ab9d0a167c6 100644
--- a/AWSCore/Logging/AWSDDFileLogger.h
+++ b/AWSCore/Logging/AWSDDFileLogger.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -22,6 +22,8 @@
 
 @class AWSDDLogFileInfo;
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  * This class provides a logger to write log statements to a file.
  **/
@@ -46,16 +48,51 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+
+/// The serializer is responsible for turning a log message into binary for writing into a file.
+/// It allows storing log messages in a non-text format.
+/// The serialier should not be used for filtering or formatting messages!
+/// Also, it must be fast!
+@protocol AWSDDFileLogMessageSerializer <NSObject>
+@required
+
+/// Returns the binary representation of the message.
+/// - Parameter message: The formatted log message to serialize.
+//
+
+/// Returns the binary representation of the message.
+/// - Parameters:
+///   - string: The string to serialize. Usually, this is the formatted message, but it can also be e.g. a log file header.
+///   - message: The message which represents the `string`. This is null, if `string` is e.g. a log file header.
+/// - Note: The `message` parameter should not be used for formatting! It should simply be used to extract the necessary metadata for serializing.
+- (NSData *)dataForString:(NSString *)string
+   originatingFromMessage:(nullable AWSDDLogMessage *)message NS_SWIFT_NAME(dataForString(_:originatingFrom:));
+
+@end
+
+/// The (default) plain text message serializer.
+@interface AWSDDFileLogPlainTextMessageSerializer : NSObject <AWSDDFileLogMessageSerializer>
+
+- (instancetype)init;
+
+@end
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+@class AWSDDFileLogger;
 /**
- *  The LogFileManager protocol is designed to allow you to control all aspects of your log files.
+ *  The AWSLogFileManager protocol is designed to allow you to control all aspects of your log files.
  *
  *  The primary purpose of this is to allow you to do something with the log files after they have been rolled.
  *  Perhaps you want to compress them to save disk space.
  *  Perhaps you want to upload them to an FTP server.
  *  Perhaps you want to run some analytics on the file.
  *
- *  A default LogFileManager is, of course, provided.
- *  The default LogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
+ *  A default AWSLogFileManager is, of course, provided.
+ *  The default AWSLogFileManager simply deletes old log files according to the maximumNumberOfLogFiles property.
  *
  *  This protocol provides various methods to fetch the list of log files.
  *
@@ -77,7 +114,7 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 /**
  * The maximum number of archived log files to keep on disk.
  * For example, if this property is set to 3,
- * then the LogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
+ * then the AWSLogFileManager will only keep 3 archived log files (plus the current active log file) on disk.
  * Once the active log file is rolled/archived, then the oldest of the existing 3 rolled/archived log files is deleted.
  *
  * You may optionally disable this option by setting it to zero.
@@ -85,7 +122,7 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
 
 /**
- * The maximum space that logs can take. On rolling logfile all old logfiles that exceed logFilesDiskQuota will
+ * The maximum space that logs can take. On rolling logfile all old log files that exceed logFilesDiskQuota will
  * be deleted.
  *
  * You may optionally disable this option by setting it to zero.
@@ -143,22 +180,45 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 
 /**
  * Generates a new unique log file path, and creates the corresponding log file.
+ * This method is executed directly on the file logger's internal queue.
+ * The file has to exist by the time the method returns.
  **/
-- (NSString *)createNewLogFile;
+- (nullable NSString *)createNewLogFileWithError:(NSError **)error;
 
 @optional
 
-// Notifications from AWSDDFileLogger
+/// The log message serializer.
+@property (nonatomic, readonly, strong) id<AWSDDFileLogMessageSerializer> logMessageSerializer;
 
-/**
- *  Called when a log file was archieved
- */
-- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:));
+/// Manually perform a cleanup of the log files managed by this manager.
+/// This can be called from any queue!
+- (BOOL)cleanupLogFilesWithError:(NSError **)error;
 
-/**
- *  Called when the roll action was executed and the log was archieved
- */
-- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:));
+// MARK: Private methods (only to be used by AWSDDFileLogger)
+
+// MARK: Notifications from AWSDDFileLogger
+/// Called when the log file manager was added to a file logger.
+/// This should be used to make the manager "active" - like starting internal timers etc.
+/// Executed on global queue with default priority.
+/// - Parameter fileLogger: The file logger this manager was added to.
+/// - Important: The manager **must not** keep a strong reference to `fileLogger` or a retain cycle will be created!
+- (void)didAddToFileLogger:(AWSDDFileLogger *)fileLogger;
+
+/// Called when a log file was archived. Executed on global queue with default priority.
+/// @param logFilePath The path to the log file that was archived.
+/// @param wasRolled Whether or not the archiving happend after rolling the log file.
+- (void)didArchiveLogFile:(NSString *)logFilePath wasRolled:(BOOL)wasRolled NS_SWIFT_NAME(didArchiveLogFile(atPath:wasRolled:));
+
+// MARK: Deprecated APIs
+/// Creates a new log file ignoring any errors. Deprecated in favor of `-createNewLogFileWithError:`.
+/// Will only be called if `-createNewLogFileWithError:` is not implemented.
+- (nullable NSString *)createNewLogFile __attribute__((deprecated("Use -createNewLogFileWithError:"))) NS_SWIFT_UNAVAILABLE("Use -createNewLogFileWithError:");
+
+/// Called when a log file was archived. Executed on global queue with default priority.
+- (void)didArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
+
+/// Called when the roll action was executed and the log was archived. Executed on global queue with default priority.
+- (void)didRollAndArchiveLogFile:(NSString *)logFilePath NS_SWIFT_NAME(didRollAndArchiveLogFile(atPath:)) __attribute__((deprecated("Use -didArchiveLogFile:wasRolled:")));
 
 @end
 
@@ -182,14 +242,10 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 @interface AWSDDLogFileManagerDefault : NSObject <AWSDDLogFileManager>
 
 /**
- *  Default initializer
- */
-- (instancetype)init;
-
-/**
- *  Designated initialized, requires the logs directory
+ *  If logDirectory is not specified, then a folder called "Logs" is created in the app's cache directory.
+ *  While running on the simulator, the "Logs" folder is located in the library temporary directory.
  */
-- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory NS_DESIGNATED_INITIALIZER;
+- (instancetype)initWithLogsDirectory:(nullable NSString *)logsDirectory NS_DESIGNATED_INITIALIZER;
 
 #if TARGET_OS_IPHONE
 /*
@@ -203,9 +259,13 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  *    null
  *    cy#
  **/
-- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel;
+- (instancetype)initWithLogsDirectory:(nullable NSString *)logsDirectory
+           defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel;
 #endif
 
+/// Convenience  initializer.
+- (instancetype)init;
+
 /*
  * Methods to override.
  *
@@ -214,7 +274,7 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  *
  * If you wish to change default filename, you can override following two methods.
  * - `newLogFileName` method would be called on new logfile creation.
- * - `isLogFile:` method would be called to filter logfiles from all other files in logsDirectory.
+ * - `isLogFile:` method would be called to filter log files from all other files in logsDirectory.
  *   You have to parse given filename and return YES if it is logFile.
  *
  * **NOTE**
@@ -248,6 +308,17 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  **/
 - (BOOL)isLogFile:(NSString *)fileName NS_SWIFT_NAME(isLogFile(withName:));
 
+/**
+ * New log files are created empty by default in `createNewLogFile:` method
+ *
+ * If you wish to specify a common file header to use in your log files,
+ * you can set the initial log file contents by overriding `logFileHeader`
+ **/
+@property (readonly, copy, nullable) NSString *logFileHeader;
+
+/// The log message serializer.
+@property (nonatomic, strong) id<AWSDDFileLogMessageSerializer> logMessageSerializer;
+
 /* Inherited from AWSDDLogFileManager protocol:
 
    @property (readwrite, assign, atomic) NSUInteger maximumNumberOfLogFiles;
@@ -262,7 +333,6 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
    - (NSArray *)sortedLogFilePaths;
    - (NSArray *)sortedLogFileNames;
    - (NSArray *)sortedLogFileInfos;
-
  */
 
 @end
@@ -283,15 +353,11 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  **/
 @interface AWSDDLogFileFormatterDefault : NSObject <AWSDDLogFormatter>
 
-/**
- *  Default initializer
- */
-- (instancetype)init;
+/// Designated initializer, requires a date formatter
+- (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
 
-/**
- *  Designated initializer, requires a date formatter
- */
-- (instancetype)initWithDateFormatter:(NSDateFormatter *)dateFormatter NS_DESIGNATED_INITIALIZER;
+/// Convenience initializer
+- (instancetype)init;
 
 @end
 
@@ -302,33 +368,59 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 /**
  *  The standard implementation for a file logger
  */
-@interface AWSDDFileLogger : AWSDDAbstractLogger <AWSDDLogger> {
-	AWSDDLogFileInfo *_currentLogFileInfo;
-}
+@interface AWSDDFileLogger : AWSDDAbstractLogger <AWSDDLogger>
 
 /**
- *  Default initializer
+ *  Default initializer.
  */
 - (instancetype)init;
 
 /**
- *  Designated initializer, requires a `AWSDDLogFileManager` instance
+ *  Designated initializer, requires a `AWSDDLogFileManager` instance.
+ *  A global queue w/ default priority is used to run callbacks.
+ *  If needed, specify queue using `initWithLogFileManager:completionQueue:`.
+ */
+- (instancetype)initWithLogFileManager:(id <AWSDDLogFileManager>)logFileManager;
+
+/**
+ *  Designated initializer, requires a `AWSDDLogFileManager` instance.
+ *  The completionQueue is used to execute `didArchiveLogFile:wasRolled:`,
+ *  and the callback in `rollLogFileWithCompletionBlock:`.
+ *  If nil, a global queue w/ default priority is used.
+ */
+- (instancetype)initWithLogFileManager:(id <AWSDDLogFileManager>)logFileManager
+                       completionQueue:(nullable dispatch_queue_t)dispatchQueue NS_DESIGNATED_INITIALIZER;
+
+/**
+ *  Deprecated. Use `willLogMessage:`
+ */
+- (void)willLogMessage __attribute__((deprecated("Use -willLogMessage:"))) NS_REQUIRES_SUPER;
+
+/**
+ *  Deprecated. Use `didLogMessage:`
  */
-- (instancetype)initWithLogFileManager:(id <AWSDDLogFileManager>)logFileManager NS_DESIGNATED_INITIALIZER;
+- (void)didLogMessage __attribute__((deprecated("Use -didLogMessage:"))) NS_REQUIRES_SUPER;
 
 /**
  *  Called when the logger is about to write message. Call super before your implementation.
  */
-- (void)willLogMessage NS_REQUIRES_SUPER;
+- (void)willLogMessage:(AWSDDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER;
 
 /**
  *  Called when the logger wrote message. Call super after your implementation.
  */
-- (void)didLogMessage NS_REQUIRES_SUPER;
+- (void)didLogMessage:(AWSDDLogFileInfo *)logFileInfo NS_REQUIRES_SUPER;
 
 /**
- *  Called when the logger checks archive or not current log file. 
- *  Override this method to exdend standart behavior. By default returns NO.
+ *  Writes all in-memory log data to the permanent storage. Call super before your implementation.
+ *  Don't call this method directly, instead use the `[AWSDDLog flushLog]` to ensure all log messages are included in flush.
+ */
+- (void)flush NS_REQUIRES_SUPER;
+
+/**
+ *  Called when the logger checks archive or not current log file.
+ *  Override this method to extend standard behavior. By default returns NO.
+ *  This is executed directly on the logger's internal queue, so keep processing light!
  */
 - (BOOL)shouldArchiveRecentLogFileInfo:(AWSDDLogFileInfo *)recentLogFileInfo;
 
@@ -397,13 +489,14 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  *  You can optionally force the current log file to be rolled with this method.
  *  CompletionBlock will be called on main queue.
  */
-- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock NS_SWIFT_NAME(rollLogFile(withCompletion:));
+- (void)rollLogFileWithCompletionBlock:(nullable void (^)(void))completionBlock
+    NS_SWIFT_NAME(rollLogFile(withCompletion:));
 
 /**
  *  Method is deprecated.
  *  @deprecated Use `rollLogFileWithCompletionBlock:` method instead.
  */
-- (void)rollLogFile __attribute((deprecated));
+- (void)rollLogFile __attribute__((deprecated("Use -rollLogFileWithCompletionBlock:")));
 
 // Inherited from AWSDDAbstractLogger
 
@@ -415,9 +508,9 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
  * If there is an existing log file that is suitable,
  * within the constraints of `maximumFileSize` and `rollingFrequency`, then it is returned.
  *
- * Otherwise a new file is created and returned.
+ * Otherwise a new file is created and returned. If this failes, `NULL` is returned.
  **/
-@property (nonatomic, readonly, strong) AWSDDLogFileInfo *currentLogFileInfo;
+@property (nonatomic, nullable, readonly, strong) AWSDDLogFileInfo *currentLogFileInfo;
 
 @end
 
@@ -444,22 +537,20 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 @property (strong, nonatomic, readonly) NSString *filePath;
 @property (strong, nonatomic, readonly) NSString *fileName;
 
-#if FOUNDATION_SWIFT_SDK_EPOCH_AT_LEAST(8)
 @property (strong, nonatomic, readonly) NSDictionary<NSFileAttributeKey, id> *fileAttributes;
-#else
-@property (strong, nonatomic, readonly) NSDictionary<NSString *, id> *fileAttributes;
-#endif
 
-@property (strong, nonatomic, readonly) NSDate *creationDate;
-@property (strong, nonatomic, readonly) NSDate *modificationDate;
+@property (strong, nonatomic, nullable, readonly) NSDate *creationDate;
+@property (strong, nonatomic, nullable, readonly) NSDate *modificationDate;
 
 @property (nonatomic, readonly) unsigned long long fileSize;
 
 @property (nonatomic, readonly) NSTimeInterval age;
 
+@property (nonatomic, readonly) BOOL isSymlink;
+
 @property (nonatomic, readwrite) BOOL isArchived;
 
-+ (instancetype)logFileWithPath:(NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
++ (nullable instancetype)logFileWithPath:(nullable NSString *)filePath NS_SWIFT_UNAVAILABLE("Use init(filePath:)");
 
 - (instancetype)init NS_UNAVAILABLE;
 - (instancetype)initWithFilePath:(NSString *)filePath NS_DESIGNATED_INITIALIZER;
@@ -467,46 +558,14 @@ extern unsigned long long const kAWSDDDefaultLogFilesDiskQuota;
 - (void)reset;
 - (void)renameFile:(NSString *)newFileName NS_SWIFT_NAME(renameFile(to:));
 
-#if TARGET_IPHONE_SIMULATOR
-
-// So here's the situation.
-// Extended attributes are perfect for what we're trying to do here (marking files as archived).
-// This is exactly what extended attributes were designed for.
-//
-// But Apple screws us over on the simulator.
-// Everytime you build-and-go, they copy the application into a new folder on the hard drive,
-// and as part of the process they strip extended attributes from our log files.
-// Normally, a copy of a file preserves extended attributes.
-// So obviously Apple has gone to great lengths to piss us off.
-//
-// Thus we use a slightly different tactic for marking log files as archived in the simulator.
-// That way it "just works" and there's no confusion when testing.
-//
-// The difference in method names is indicative of the difference in functionality.
-// On the simulator we add an attribute by appending a filename extension.
-//
-// For example:
-// "mylog.txt" -> "mylog.archived.txt"
-// "mylog"     -> "mylog.archived"
-
-- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName;
-
-- (void)addExtensionAttributeWithName:(NSString *)attrName;
-- (void)removeExtensionAttributeWithName:(NSString *)attrName;
-
-#else /* if TARGET_IPHONE_SIMULATOR */
-
-// Normal use of extended attributes used everywhere else,
-// such as on Macs and on iPhone devices.
-
 - (BOOL)hasExtendedAttributeWithName:(NSString *)attrName;
 
 - (void)addExtendedAttributeWithName:(NSString *)attrName;
 - (void)removeExtendedAttributeWithName:(NSString *)attrName;
 
-#endif /* if TARGET_IPHONE_SIMULATOR */
-
 - (NSComparisonResult)reverseCompareByCreationDate:(AWSDDLogFileInfo *)another;
 - (NSComparisonResult)reverseCompareByModificationDate:(AWSDDLogFileInfo *)another;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDFileLogger.m b/AWSCore/Logging/AWSDDFileLogger.m
index 1492591c6d6..6a95011d03c 100644
--- a/AWSCore/Logging/AWSDDFileLogger.m
+++ b/AWSCore/Logging/AWSDDFileLogger.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,17 +13,17 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDFileLogger.h"
-
-#import <unistd.h>
-#import <sys/attr.h>
-#import <sys/xattr.h>
-#import <libkern/OSAtomic.h>
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import <sys/xattr.h>
+#import <sys/file.h>
+#import <errno.h>
+#import <unistd.h>
+
+#import "AWSDDFileLogger+Internal.h"
+
 // We probably shouldn't be using AWSDDLog() statements within the AWSDDLog implementation.
 // But we still want to leave our log statements for any future debugging,
 // and to allow other developers to trace the implementation (which is a great learning tool).
@@ -43,7 +43,7 @@
 
 
 #if TARGET_OS_IPHONE
-BOOL awsDoesAppRunInBackground(void);
+BOOL doesAppRunInBackground(void);
 #endif
 
 unsigned long long const kAWSDDDefaultLogMaxFileSize      = 1024 * 1024;      // 1 MB
@@ -51,49 +51,66 @@
 NSUInteger         const kAWSDDDefaultLogMaxNumLogFiles   = 5;                // 5 Files
 unsigned long long const kAWSDDDefaultLogFilesDiskQuota   = 20 * 1024 * 1024; // 20 MB
 
+NSTimeInterval     const kAWSDDRollingLeeway              = 1.0;              // 1s
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
+////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+@implementation AWSDDFileLogPlainTextMessageSerializer
+
+- (instancetype)init {
+    return [super init];
+}
+
+- (NSData *)dataForString:(NSString *)string originatingFromMessage:(AWSDDLogMessage *)message {
+    return [string dataUsingEncoding:NSUTF8StringEncoding] ?: [NSData data];
+}
+
+@end
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 @interface AWSDDLogFileManagerDefault () {
+    NSDateFormatter *_fileDateFormatter;
     NSUInteger _maximumNumberOfLogFiles;
     unsigned long long _logFilesDiskQuota;
     NSString *_logsDirectory;
+    BOOL _wasAddedToLogger;
 #if TARGET_OS_IPHONE
-    NSString *_defaultFileProtectionLevel;
+    NSFileProtectionType _defaultFileProtectionLevel;
 #endif
 }
 
-- (void)deleteOldLogFiles;
-- (NSString *)defaultLogsDirectory;
-
 @end
 
 @implementation AWSDDLogFileManagerDefault
 
 @synthesize maximumNumberOfLogFiles = _maximumNumberOfLogFiles;
 @synthesize logFilesDiskQuota = _logFilesDiskQuota;
+@synthesize logMessageSerializer = _logMessageSerializer;
 
-
-- (instancetype)init {
-    return [self initWithLogsDirectory:nil];
-}
-
-- (instancetype)initWithLogsDirectory:(NSString *)aLogsDirectory {
+- (instancetype)initWithLogsDirectory:(nullable NSString *)aLogsDirectory {
     if ((self = [super init])) {
         _maximumNumberOfLogFiles = kAWSDDDefaultLogMaxNumLogFiles;
         _logFilesDiskQuota = kAWSDDDefaultLogFilesDiskQuota;
+        _wasAddedToLogger = NO;
 
-        if (aLogsDirectory) {
+        _fileDateFormatter = [[NSDateFormatter alloc] init];
+        [_fileDateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
+        [_fileDateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
+        [_fileDateFormatter setDateFormat: @"yyyy'-'MM'-'dd'--'HH'-'mm'-'ss'-'SSS'"];
+
+        if (aLogsDirectory.length > 0) {
             _logsDirectory = [aLogsDirectory copy];
         } else {
             _logsDirectory = [[self defaultLogsDirectory] copy];
         }
 
-        NSKeyValueObservingOptions kvoOptions = NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew;
-
-        [self addObserver:self forKeyPath:NSStringFromSelector(@selector(maximumNumberOfLogFiles)) options:kvoOptions context:nil];
-        [self addObserver:self forKeyPath:NSStringFromSelector(@selector(logFilesDiskQuota)) options:kvoOptions context:nil];
+        _logMessageSerializer = [[AWSDDFileLogPlainTextMessageSerializer alloc] init];
 
         NSLogVerbose(@"AWSDDFileLogManagerDefault: logsDirectory:\n%@", [self logsDirectory]);
         NSLogVerbose(@"AWSDDFileLogManagerDefault: sortedLogFileNames:\n%@", [self sortedLogFileNames]);
@@ -102,20 +119,10 @@ - (instancetype)initWithLogsDirectory:(NSString *)aLogsDirectory {
     return self;
 }
 
-+ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)theKey
-{
-    BOOL automatic = NO;
-    if ([theKey isEqualToString:@"maximumNumberOfLogFiles"] || [theKey isEqualToString:@"logFilesDiskQuota"]) {
-        automatic = NO;
-    } else {
-        automatic = [super automaticallyNotifiesObserversForKey:theKey];
-    }
-    
-    return automatic;
-}
-
 #if TARGET_OS_IPHONE
-- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProtectionLevel:(NSString *)fileProtectionLevel {
+- (instancetype)initWithLogsDirectory:(NSString *)logsDirectory
+           defaultFileProtectionLevel:(NSFileProtectionType)fileProtectionLevel {
+
     if ((self = [self initWithLogsDirectory:logsDirectory])) {
         if ([fileProtectionLevel isEqualToString:NSFileProtectionNone] ||
             [fileProtectionLevel isEqualToString:NSFileProtectionComplete] ||
@@ -127,43 +134,53 @@ - (instancetype)initWithLogsDirectory:(NSString *)logsDirectory defaultFileProte
 
     return self;
 }
-
 #endif
 
-- (void)dealloc {
-    // try-catch because the observer might be removed or never added. In this case, removeObserver throws and exception
-    @try {
-        [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(maximumNumberOfLogFiles))];
-        [self removeObserver:self forKeyPath:NSStringFromSelector(@selector(logFilesDiskQuota))];
-    } @catch (NSException *exception) {
-    }
+- (instancetype)init {
+    return [self initWithLogsDirectory:nil];
 }
 
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark Configuration
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+- (void)didAddToFileLogger:(AWSDDFileLogger *)fileLogger {
+    _wasAddedToLogger = YES;
+}
 
-- (void)observeValueForKeyPath:(NSString *)keyPath
-                      ofObject:(id)object
-                        change:(NSDictionary *)change
-                       context:(void *)context {
-    NSNumber *old = change[NSKeyValueChangeOldKey];
-    NSNumber *new = change[NSKeyValueChangeNewKey];
+- (void)deleteOldFilesForConfigurationChange {
+    if (!_wasAddedToLogger) return;
+    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+        @autoreleasepool {
+            // See method header for queue reasoning.
+            [self deleteOldLogFilesWithError:nil];
+        }
+    });
+}
 
-    if ([old isEqual:new]) {
-        // No change in value - don't bother with any processing.
-        return;
+- (void)setLogFilesDiskQuota:(unsigned long long)logFilesDiskQuota {
+    if (_logFilesDiskQuota != logFilesDiskQuota) {
+        _logFilesDiskQuota = logFilesDiskQuota;
+        NSLogInfo(@"AWSDDFileLogManagerDefault: Responding to configuration change: logFilesDiskQuota");
+        [self deleteOldFilesForConfigurationChange];
     }
+}
 
-    if ([keyPath isEqualToString:NSStringFromSelector(@selector(maximumNumberOfLogFiles))] ||
-        [keyPath isEqualToString:NSStringFromSelector(@selector(logFilesDiskQuota))]) {
-        NSLogInfo(@"AWSDDFileLogManagerDefault: Responding to configuration change: %@", keyPath);
+- (void)setMaximumNumberOfLogFiles:(NSUInteger)maximumNumberOfLogFiles {
+    if (_maximumNumberOfLogFiles != maximumNumberOfLogFiles) {
+        _maximumNumberOfLogFiles = maximumNumberOfLogFiles;
+        NSLogInfo(@"AWSDDFileLogManagerDefault: Responding to configuration change: maximumNumberOfLogFiles");
+        [self deleteOldFilesForConfigurationChange];
+    }
+}
 
-        dispatch_async([AWSDDLog loggingQueue], ^{ @autoreleasepool {
-                                                    [self deleteOldLogFiles];
-                                                } });
+#if TARGET_OS_IPHONE
+- (NSFileProtectionType)logFileProtection {
+    if (_defaultFileProtectionLevel.length > 0) {
+        return _defaultFileProtectionLevel;
+    } else if (doesAppRunInBackground()) {
+        return NSFileProtectionCompleteUntilFirstUserAuthentication;
+    } else {
+        return NSFileProtectionCompleteUnlessOpen;
     }
 }
+#endif
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark File Deleting
@@ -171,12 +188,16 @@ - (void)observeValueForKeyPath:(NSString *)keyPath
 
 /**
  * Deletes archived log files that exceed the maximumNumberOfLogFiles or logFilesDiskQuota configuration values.
+ * Method may take a while to execute since we're performing IO. It's not critical that this is synchronized with
+ * log output, since the files we're deleting are all archived and not in use, therefore this method is called on a
+ * background queue.
  **/
-- (void)deleteOldLogFiles {
-    NSLogVerbose(@"AWSDDLogFileManagerDefault: deleteOldLogFiles");
+- (BOOL)deleteOldLogFilesWithError:(NSError *__autoreleasing _Nullable *)error {
+    NSLogVerbose(@"AWSDDLogFileManagerDefault: %@", NSStringFromSelector(_cmd));
 
-    NSArray *sortedLogFileInfos = [self sortedLogFileInfos];
+    if (error) *error = nil;
 
+    __auto_type sortedLogFileInfos = [self sortedLogFileInfos];
     NSUInteger firstIndexToDelete = NSNotFound;
 
     const unsigned long long diskQuota = self.logFilesDiskQuota;
@@ -211,26 +232,37 @@ - (void)deleteOldLogFiles {
         // So in most cases, we do not want to consider this file for deletion.
 
         if (sortedLogFileInfos.count > 0) {
-            AWSDDLogFileInfo *logFileInfo = sortedLogFileInfos[0];
-
-            if (!logFileInfo.isArchived) {
+            if (!sortedLogFileInfos[0].isArchived) {
                 // Don't delete active file.
-                ++firstIndexToDelete;
+                firstIndexToDelete++;
             }
         }
     }
 
     if (firstIndexToDelete != NSNotFound) {
-        // removing all logfiles starting with firstIndexToDelete
-
+        // removing all log files starting with firstIndexToDelete
         for (NSUInteger i = firstIndexToDelete; i < sortedLogFileInfos.count; i++) {
-            AWSDDLogFileInfo *logFileInfo = sortedLogFileInfos[i];
+            __auto_type logFileInfo = sortedLogFileInfos[i];
 
-            NSLogInfo(@"AWSDDLogFileManagerDefault: Deleting file: %@", logFileInfo.fileName);
-
-            [[NSFileManager defaultManager] removeItemAtPath:logFileInfo.filePath error:nil];
+            __autoreleasing NSError *deletionError = nil;
+            __auto_type success = [[NSFileManager defaultManager] removeItemAtPath:logFileInfo.filePath error:&deletionError];
+            if (success) {
+                NSLogInfo(@"AWSDDLogFileManagerDefault: Deleting file: %@", logFileInfo.fileName);
+            } else {
+                NSLogError(@"AWSDDLogFileManagerDefault: Error deleting file %@", deletionError);
+                if (error) {
+                    *error = deletionError;
+                    return NO; // If we were given an error, stop after the first failure!
+                }
+            }
         }
     }
+
+    return YES;
+}
+
+- (BOOL)cleanupLogFilesWithError:(NSError *__autoreleasing _Nullable *)error {
+    return [self deleteOldLogFilesWithError:error];
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -243,133 +275,87 @@ - (void)deleteOldLogFiles {
  **/
 - (NSString *)defaultLogsDirectory {
 #if TARGET_OS_IPHONE
-    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
-    NSString *baseDir = paths.firstObject;
-    NSString *logsDirectory = [baseDir stringByAppendingPathComponent:@"Logs"];
-
+    __auto_type paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+    __auto_type baseDir = paths.firstObject;
+    __auto_type logsDirectory = [baseDir stringByAppendingPathComponent:@"Logs"];
 #else
-    NSString *appName = [[NSProcessInfo processInfo] processName];
-    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
-    NSString *basePath = ([paths count] > 0) ? paths[0] : NSTemporaryDirectory();
-    NSString *logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName];
-
+    __auto_type appName = [[NSProcessInfo processInfo] processName];
+    __auto_type paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES);
+    __auto_type basePath = ([paths count] > 0) ? paths[0] : NSTemporaryDirectory();
+    __auto_type logsDirectory = [[basePath stringByAppendingPathComponent:@"Logs"] stringByAppendingPathComponent:appName];
 #endif
 
     return logsDirectory;
 }
 
 - (NSString *)logsDirectory {
-    // We could do this check once, during initalization, and not bother again.
+    // We could do this check once, during initialization, and not bother again.
     // But this way the code continues to work if the directory gets deleted while the code is running.
 
-    if (![[NSFileManager defaultManager] fileExistsAtPath:_logsDirectory]) {
-        NSError *err = nil;
+    NSAssert(_logsDirectory.length > 0, @"Directory must be set.");
 
-        if (![[NSFileManager defaultManager] createDirectoryAtPath:_logsDirectory
-                                       withIntermediateDirectories:YES
-                                                        attributes:nil
-                                                             error:&err]) {
-            NSLogError(@"AWSDDFileLogManagerDefault: Error creating logsDirectory: %@", err);
-        }
+    __autoreleasing NSError *error = nil;
+    __auto_type success = [[NSFileManager defaultManager] createDirectoryAtPath:_logsDirectory
+                                                    withIntermediateDirectories:YES
+                                                                     attributes:nil
+                                                                          error:&error];
+    if (!success) {
+        NSLogError(@"AWSDDFileLogManagerDefault: Error creating logsDirectory: %@", error);
     }
 
     return _logsDirectory;
 }
 
 - (BOOL)isLogFile:(NSString *)fileName {
-    NSString *appName = [self applicationName];
-
-    BOOL hasProperPrefix = [fileName hasPrefix:appName];
-    BOOL hasProperSuffix = [fileName hasSuffix:@".log"];
-    BOOL hasProperDate = NO;
-
-    if (hasProperPrefix && hasProperSuffix) {
-        NSUInteger lengthOfMiddle = fileName.length - appName.length - @".log".length;
-
-        // Date string should have at least 16 characters - " 2013-12-03 17-14"
-        if (lengthOfMiddle >= 17) {
-            NSRange range = NSMakeRange(appName.length, lengthOfMiddle);
+    __auto_type appName = [self applicationName];
 
-            NSString *middle = [fileName substringWithRange:range];
-            NSArray *components = [middle componentsSeparatedByString:@" "];
-
-            // When creating logfile if there is existing file with the same name, we append attemp number at the end.
-            // Thats why here we can have three or four components. For details see createNewLogFile method.
-            //
-            // Components:
-            //     "", "2013-12-03", "17-14"
-            // or
-            //     "", "2013-12-03", "17-14", "1"
-            if (components.count == 3 || components.count == 4) {
-                NSString *dateString = [NSString stringWithFormat:@"%@ %@", components[1], components[2]];
-                NSDateFormatter *dateFormatter = [self logFileDateFormatter];
-
-                NSDate *date = [dateFormatter dateFromString:dateString];
-
-                if (date) {
-                    hasProperDate = YES;
-                }
-            }
-        }
-    }
-
-    return (hasProperPrefix && hasProperDate && hasProperSuffix);
+    // We need to add a space to the name as otherwise we could match applications that have the name prefix.
+    return [fileName hasPrefix:[appName stringByAppendingString:@" "]] && [fileName hasSuffix:@".log"];
 }
 
+// if you change formatter, then change sortedLogFileInfos method also accordingly
 - (NSDateFormatter *)logFileDateFormatter {
-    NSMutableDictionary *dictionary = [[NSThread currentThread]
-                                       threadDictionary];
-    NSString *dateFormat = @"yyyy'-'MM'-'dd' 'HH'-'mm'";
-    NSString *key = [NSString stringWithFormat:@"logFileDateFormatter.%@", dateFormat];
-    NSDateFormatter *dateFormatter = dictionary[key];
-
-    if (dateFormatter == nil) {
-        dateFormatter = [[NSDateFormatter alloc] init];
-        [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
-        [dateFormatter setDateFormat:dateFormat];
-        [dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
-        dictionary[key] = dateFormatter;
-    }
-
-    return dateFormatter;
+    return _fileDateFormatter;
 }
 
 - (NSArray *)unsortedLogFilePaths {
-    NSString *logsDirectory = [self logsDirectory];
-    NSArray *fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:logsDirectory error:nil];
+    __auto_type logsDirectory = [self logsDirectory];
+
+    __autoreleasing NSError *error = nil;
+    __auto_type fileNames = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:logsDirectory error:&error];
+    if (!fileNames && error) {
+        NSLogError(@"AWSDDFileLogManagerDefault: Error listing log file directory: %@", error);
+        return [[NSArray alloc] init];
+    }
 
-    NSMutableArray *unsortedLogFilePaths = [NSMutableArray arrayWithCapacity:[fileNames count]];
+    __auto_type unsortedLogFilePaths = [NSMutableArray arrayWithCapacity:[fileNames count]];
 
     for (NSString *fileName in fileNames) {
         // Filter out any files that aren't log files. (Just for extra safety)
-
-    #if TARGET_IPHONE_SIMULATOR
+#if TARGET_IPHONE_SIMULATOR
+        // This is only used on the iPhone simulator for backward compatibility reason.
+        //
         // In case of iPhone simulator there can be 'archived' extension. isLogFile:
         // method knows nothing about it. Thus removing it for this method.
-        //
-        // See full explanation in the header file.
-        NSString *theFileName = [fileName stringByReplacingOccurrencesOfString:@".archived"
-                                                                    withString:@""];
+        __auto_type theFileName = [fileName stringByReplacingOccurrencesOfString:@".archived"
+                                                                      withString:@""];
 
         if ([self isLogFile:theFileName])
-    #else
-
-        if ([self isLogFile:fileName])
-    #endif
-        {
-            NSString *filePath = [logsDirectory stringByAppendingPathComponent:fileName];
-
-            [unsortedLogFilePaths addObject:filePath];
-        }
+#else
+            if ([self isLogFile:fileName])
+#endif
+            {
+                __auto_type filePath = [logsDirectory stringByAppendingPathComponent:fileName];
+                [unsortedLogFilePaths addObject:filePath];
+            }
     }
 
     return unsortedLogFilePaths;
 }
 
 - (NSArray *)unsortedLogFileNames {
-    NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths];
-
-    NSMutableArray *unsortedLogFileNames = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]];
+    __auto_type unsortedLogFilePaths = [self unsortedLogFilePaths];
+    __auto_type unsortedLogFileNames = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]];
 
     for (NSString *filePath in unsortedLogFilePaths) {
         [unsortedLogFileNames addObject:[filePath lastPathComponent]];
@@ -379,13 +365,11 @@ - (NSArray *)unsortedLogFileNames {
 }
 
 - (NSArray *)unsortedLogFileInfos {
-    NSArray *unsortedLogFilePaths = [self unsortedLogFilePaths];
-
-    NSMutableArray *unsortedLogFileInfos = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]];
+    __auto_type unsortedLogFilePaths = [self unsortedLogFilePaths];
+    __auto_type unsortedLogFileInfos = [NSMutableArray arrayWithCapacity:[unsortedLogFilePaths count]];
 
     for (NSString *filePath in unsortedLogFilePaths) {
-        AWSDDLogFileInfo *logFileInfo = [[AWSDDLogFileInfo alloc] initWithFilePath:filePath];
-
+        __auto_type logFileInfo = [[AWSDDLogFileInfo alloc] initWithFilePath:filePath];
         [unsortedLogFileInfos addObject:logFileInfo];
     }
 
@@ -393,9 +377,8 @@ - (NSArray *)unsortedLogFileInfos {
 }
 
 - (NSArray *)sortedLogFilePaths {
-    NSArray *sortedLogFileInfos = [self sortedLogFileInfos];
-
-    NSMutableArray *sortedLogFilePaths = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]];
+    __auto_type sortedLogFileInfos = [self sortedLogFileInfos];
+    __auto_type sortedLogFilePaths = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]];
 
     for (AWSDDLogFileInfo *logFileInfo in sortedLogFileInfos) {
         [sortedLogFilePaths addObject:[logFileInfo filePath]];
@@ -405,9 +388,8 @@ - (NSArray *)sortedLogFilePaths {
 }
 
 - (NSArray *)sortedLogFileNames {
-    NSArray *sortedLogFileInfos = [self sortedLogFileInfos];
-
-    NSMutableArray *sortedLogFileNames = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]];
+    __auto_type sortedLogFileInfos = [self sortedLogFileInfos];
+    __auto_type sortedLogFileNames = [NSMutableArray arrayWithCapacity:[sortedLogFileInfos count]];
 
     for (AWSDDLogFileInfo *logFileInfo in sortedLogFileInfos) {
         [sortedLogFileNames addObject:[logFileInfo fileName]];
@@ -417,72 +399,139 @@ - (NSArray *)sortedLogFileNames {
 }
 
 - (NSArray *)sortedLogFileInfos {
-    return [[self unsortedLogFileInfos] sortedArrayUsingSelector:@selector(reverseCompareByCreationDate:)];
+    return [[self unsortedLogFileInfos] sortedArrayUsingComparator:^NSComparisonResult(AWSDDLogFileInfo *obj1,
+                                                                                       AWSDDLogFileInfo *obj2) {
+        NSDate *date1 = [NSDate date];
+        NSDate *date2 = [NSDate date];
+
+        __auto_type arrayComponent = [[obj1 fileName] componentsSeparatedByString:@" "];
+        if (arrayComponent.count > 0) {
+            NSString *stringDate = arrayComponent.lastObject;
+            stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
+#if TARGET_IPHONE_SIMULATOR
+            // This is only used on the iPhone simulator for backward compatibility reason.
+            stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
+#endif
+            date1 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj1 creationDate];
+        }
+
+        arrayComponent = [[obj2 fileName] componentsSeparatedByString:@" "];
+        if (arrayComponent.count > 0) {
+            NSString *stringDate = arrayComponent.lastObject;
+            stringDate = [stringDate stringByReplacingOccurrencesOfString:@".log" withString:@""];
+#if TARGET_IPHONE_SIMULATOR
+            // This is only used on the iPhone simulator for backward compatibility reason.
+            stringDate = [stringDate stringByReplacingOccurrencesOfString:@".archived" withString:@""];
+#endif
+            date2 = [[self logFileDateFormatter] dateFromString:stringDate] ?: [obj2 creationDate];
+        }
+
+        return [date2 compare:date1 ?: [NSDate date]];
+    }];
+
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark Creation
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+// If you change newLogFileName, then change `isLogFile:` method also accordingly.
 - (NSString *)newLogFileName {
-    NSString *appName = [self applicationName];
-
-    NSDateFormatter *dateFormatter = [self logFileDateFormatter];
-    NSString *formattedDate = [dateFormatter stringFromDate:[NSDate date]];
+    __auto_type appName = [self applicationName];
+    __auto_type dateFormatter = [self logFileDateFormatter];
+    __auto_type formattedDate = [dateFormatter stringFromDate:[NSDate date]];
 
     return [NSString stringWithFormat:@"%@ %@.log", appName, formattedDate];
 }
 
-- (NSString *)createNewLogFile {
-    NSString *fileName = [self newLogFileName];
-    NSString *logsDirectory = [self logsDirectory];
+- (nullable NSString *)logFileHeader {
+    return nil;
+}
 
+- (NSData *)logFileHeaderData {
+    NSString *fileHeaderStr = [self logFileHeader];
+
+    if (fileHeaderStr.length == 0) {
+        return nil;
+    }
+
+    if (![fileHeaderStr hasSuffix:@"\n"]) {
+        fileHeaderStr = [fileHeaderStr stringByAppendingString:@"\n"];
+    }
+
+    return [_logMessageSerializer dataForString:fileHeaderStr originatingFromMessage:nil];
+}
+
+- (NSString *)createNewLogFileWithError:(NSError *__autoreleasing _Nullable *)error {
+    static NSUInteger MAX_ALLOWED_ERROR = 5;
+
+    __auto_type fileName = [self newLogFileName];
+    __auto_type logsDirectory = [self logsDirectory];
+    __auto_type fileHeader = [self logFileHeaderData] ?: [NSData data];
+
+    NSString *baseName = nil;
+    NSString *extension;
     NSUInteger attempt = 1;
+    NSUInteger criticalErrors = 0;
+    NSError *lastCriticalError;
 
+    if (error) *error = nil;
     do {
-        NSString *actualFileName = fileName;
+        if (criticalErrors >= MAX_ALLOWED_ERROR) {
+            NSLogError(@"AWSDDLogFileManagerDefault: Bailing file creation, encountered %ld errors.",
+                       (unsigned long)criticalErrors);
+            if (error) *error = lastCriticalError;
+            return nil;
+        }
 
+        NSString *actualFileName;
         if (attempt > 1) {
-            NSString *extension = [actualFileName pathExtension];
-
-            actualFileName = [actualFileName stringByDeletingPathExtension];
-            actualFileName = [actualFileName stringByAppendingFormat:@" %lu", (unsigned long)attempt];
+            if (baseName == nil) {
+                baseName = [fileName stringByDeletingPathExtension];
+                extension = [fileName pathExtension];
+            }
 
+            actualFileName = [baseName stringByAppendingFormat:@" %lu", (unsigned long)attempt];
             if (extension.length) {
                 actualFileName = [actualFileName stringByAppendingPathExtension:extension];
             }
+        } else {
+            actualFileName = fileName;
         }
 
-        NSString *filePath = [logsDirectory stringByAppendingPathComponent:actualFileName];
-
-        if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
-            NSLogVerbose(@"AWSDDLogFileManagerDefault: Creating new log file: %@", actualFileName);
+        __auto_type filePath = [logsDirectory stringByAppendingPathComponent:actualFileName];
 
-            NSDictionary *attributes = nil;
+        __autoreleasing NSError *currentError = nil;
+        __auto_type success = [fileHeader writeToFile:filePath options:NSDataWritingAtomic error:&currentError];
 
-        #if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE && !TARGET_OS_MACCATALYST
+        if (success) {
             // When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen.
             //
             // But in case if app is able to launch from background we need to have an ability to open log file any time we
             // want (even if device is locked). Thats why that attribute have to be changed to
             // NSFileProtectionCompleteUntilFirstUserAuthentication.
+            NSDictionary *attributes = @{NSFileProtectionKey: [self logFileProtection]};
+            success = [[NSFileManager defaultManager] setAttributes:attributes
+                                                       ofItemAtPath:filePath
+                                                              error:&currentError];
+        }
+#endif
 
-            NSString *key = _defaultFileProtectionLevel ? :
-                (awsDoesAppRunInBackground() ? NSFileProtectionCompleteUntilFirstUserAuthentication : NSFileProtectionCompleteUnlessOpen);
-
-            attributes = @{
-                NSFileProtectionKey: key
-            };
-        #endif
-
-            [[NSFileManager defaultManager] createFileAtPath:filePath contents:nil attributes:attributes];
-
-            // Since we just created a new log file, we may need to delete some old log files
-            [self deleteOldLogFiles];
-
+        if (success) {
+            NSLogVerbose(@"AWSDDLogFileManagerDefault: Created new log file: %@", actualFileName);
+            dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+                // Since we just created a new log file, we may need to delete some old log files
+                // Note that we don't on errors here! The new log file was created, so this method technically succeeded!
+                [self deleteOldLogFilesWithError:nil];
+            });
             return filePath;
-        } else {
+        } else if (currentError.code == NSFileWriteFileExistsError) {
             attempt++;
+        } else {
+            NSLogError(@"AWSDDLogFileManagerDefault: Critical error while creating log file: %@", currentError);
+            criticalErrors++;
+            lastCriticalError = currentError;
         }
     } while (YES);
 }
@@ -498,11 +547,11 @@ - (NSString *)applicationName {
     dispatch_once(&onceToken, ^{
         _appName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIdentifier"];
 
-        if (!_appName) {
+        if (_appName.length == 0) {
             _appName = [[NSProcessInfo processInfo] processName];
         }
 
-        if (!_appName) {
+        if (_appName.length == 0) {
             _appName = @"";
         }
     });
@@ -528,13 +577,15 @@ - (instancetype)init {
     return [self initWithDateFormatter:nil];
 }
 
-- (instancetype)initWithDateFormatter:(NSDateFormatter *)aDateFormatter {
+- (instancetype)initWithDateFormatter:(nullable NSDateFormatter *)aDateFormatter {
     if ((self = [super init])) {
         if (aDateFormatter) {
             _dateFormatter = aDateFormatter;
         } else {
             _dateFormatter = [[NSDateFormatter alloc] init];
             [_dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4]; // 10.4+ style
+            [_dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
+            [_dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
             [_dateFormatter setDateFormat:@"yyyy/MM/dd HH:mm:ss:SSS"];
         }
     }
@@ -543,8 +594,8 @@ - (instancetype)initWithDateFormatter:(NSDateFormatter *)aDateFormatter {
 }
 
 - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
-    NSString *dateAndTime = [_dateFormatter stringFromDate:(logMessage->_timestamp)];
-
+    __auto_type dateAndTime = [_dateFormatter stringFromDate:logMessage->_timestamp];
+    // Note: There are two spaces between the date and the message.
     return [NSString stringWithFormat:@"%@  %@", dateAndTime, logMessage->_message];
 }
 
@@ -555,48 +606,82 @@ - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 @interface AWSDDFileLogger () {
-    __strong id <AWSDDLogFileManager> _logFileManager;
-    
+    id <AWSDDLogFileManager> _logFileManager;
+
+    AWSDDLogFileInfo *_currentLogFileInfo;
     NSFileHandle *_currentLogFileHandle;
-    
+
     dispatch_source_t _currentLogFileVnode;
+
+    NSTimeInterval _rollingFrequency;
     dispatch_source_t _rollingTimer;
-    
+
     unsigned long long _maximumFileSize;
-    NSTimeInterval _rollingFrequency;
-}
 
-- (void)rollLogFileNow;
-- (void)maybeRollLogFileDueToAge;
-- (void)maybeRollLogFileDueToSize;
+    dispatch_queue_t _completionQueue;
+}
 
 @end
 
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wincomplete-implementation"
 @implementation AWSDDFileLogger
+#pragma clang diagnostic pop
 
 - (instancetype)init {
-    AWSDDLogFileManagerDefault *defaultLogFileManager = [[AWSDDLogFileManagerDefault alloc] init];
+    return [self initWithLogFileManager:[[AWSDDLogFileManagerDefault alloc] init]
+                        completionQueue:nil];
+}
 
-    return [self initWithLogFileManager:defaultLogFileManager];
+- (instancetype)initWithLogFileManager:(id<AWSDDLogFileManager>)logFileManager {
+    return [self initWithLogFileManager:logFileManager completionQueue:nil];
 }
 
-- (instancetype)initWithLogFileManager:(id <AWSDDLogFileManager>)aLogFileManager {
+- (instancetype)initWithLogFileManager:(id <AWSDDLogFileManager>)aLogFileManager
+                       completionQueue:(nullable dispatch_queue_t)dispatchQueue {
     if ((self = [super init])) {
+        _completionQueue = dispatchQueue ?: dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
+
         _maximumFileSize = kAWSDDDefaultLogMaxFileSize;
         _rollingFrequency = kAWSDDDefaultLogRollingFrequency;
         _automaticallyAppendNewlineForCustomFormatters = YES;
 
-        logFileManager = aLogFileManager;
+        _logFileManager = aLogFileManager;
+        _logFormatter = [AWSDDLogFileFormatterDefault new];
 
-        self.logFormatter = [AWSDDLogFileFormatterDefault new];
+        if ([_logFileManager respondsToSelector:@selector(didAddToFileLogger:)]) {
+            [_logFileManager didAddToFileLogger:self];
+        }
     }
 
     return self;
 }
 
-- (void)dealloc {
-    [_currentLogFileHandle synchronizeFile];
-    [_currentLogFileHandle closeFile];
+- (void)lt_cleanup {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
+    if (_currentLogFileHandle != nil) {
+        if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+            __autoreleasing NSError *error = nil;
+            __auto_type success = [_currentLogFileHandle synchronizeAndReturnError:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", error);
+            }
+            success = [_currentLogFileHandle closeAndReturnError:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to close file: %@", error);
+            }
+        } else {
+            @try {
+                [_currentLogFileHandle synchronizeFile];
+            }
+            @catch (NSException *exception) {
+                NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", exception);
+            }
+            [_currentLogFileHandle closeFile];
+        }
+        _currentLogFileHandle = nil;
+    }
 
     if (_currentLogFileVnode) {
         dispatch_source_cancel(_currentLogFileVnode);
@@ -609,16 +694,24 @@ - (void)dealloc {
     }
 }
 
+- (void)dealloc {
+    if (self.isOnInternalLoggerQueue) {
+        [self lt_cleanup];
+    } else {
+        dispatch_sync(self.loggerQueue, ^{
+            [self lt_cleanup];
+        });
+    }
+}
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark Properties
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-@synthesize logFileManager;
-
 - (unsigned long long)maximumFileSize {
     __block unsigned long long result;
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         result = self->_maximumFileSize;
     };
 
@@ -632,12 +725,9 @@ - (unsigned long long)maximumFileSize {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, block);
     });
 
@@ -645,10 +735,12 @@ - (unsigned long long)maximumFileSize {
 }
 
 - (void)setMaximumFileSize:(unsigned long long)newMaximumFileSize {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             self->_maximumFileSize = newMaximumFileSize;
-            [self maybeRollLogFileDueToSize];
+            if (self->_currentLogFileHandle != nil) {
+                [self lt_maybeRollLogFileDueToSize];
+            }
         }
     };
 
@@ -662,12 +754,9 @@ - (void)setMaximumFileSize:(unsigned long long)newMaximumFileSize {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-
-    dispatch_async(globalLoggingQueue, ^{
+    dispatch_async(AWSDDLog.loggingQueue, ^{
         dispatch_async(self.loggerQueue, block);
     });
 }
@@ -675,7 +764,7 @@ - (void)setMaximumFileSize:(unsigned long long)newMaximumFileSize {
 - (NSTimeInterval)rollingFrequency {
     __block NSTimeInterval result;
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         result = self->_rollingFrequency;
     };
 
@@ -689,12 +778,9 @@ - (NSTimeInterval)rollingFrequency {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, block);
     });
 
@@ -702,10 +788,12 @@ - (NSTimeInterval)rollingFrequency {
 }
 
 - (void)setRollingFrequency:(NSTimeInterval)newRollingFrequency {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             self->_rollingFrequency = newRollingFrequency;
-            [self maybeRollLogFileDueToAge];
+            if (self->_currentLogFileHandle != nil) {
+                [self lt_maybeRollLogFileDueToAge];
+            }
         }
     };
 
@@ -719,12 +807,9 @@ - (void)setRollingFrequency:(NSTimeInterval)newRollingFrequency {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-    dispatch_async(globalLoggingQueue, ^{
+    dispatch_async(AWSDDLog.loggingQueue, ^{
         dispatch_async(self.loggerQueue, block);
     });
 }
@@ -733,7 +818,9 @@ - (void)setRollingFrequency:(NSTimeInterval)newRollingFrequency {
 #pragma mark File Rolling
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-- (void)scheduleTimerToRollLogFileDueToAge {
+- (void)lt_scheduleTimerToRollLogFileDueToAge {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
     if (_rollingTimer) {
         dispatch_source_cancel(_rollingTimer);
         _rollingTimer = NULL;
@@ -743,52 +830,51 @@ - (void)scheduleTimerToRollLogFileDueToAge {
         return;
     }
 
-    NSDate *logFileCreationDate = [_currentLogFileInfo creationDate];
-
-    NSTimeInterval ti = [logFileCreationDate timeIntervalSinceReferenceDate];
-    ti += _rollingFrequency;
-
-    NSDate *logFileRollingDate = [NSDate dateWithTimeIntervalSinceReferenceDate:ti];
+    __auto_type logFileCreationDate = [_currentLogFileInfo creationDate];
+    __auto_type frequency = MIN(_rollingFrequency, DBL_MAX - [logFileCreationDate timeIntervalSinceReferenceDate]);
+    __auto_type logFileRollingDate = [logFileCreationDate dateByAddingTimeInterval:frequency];
 
     NSLogVerbose(@"AWSDDFileLogger: scheduleTimerToRollLogFileDueToAge");
+    NSLogVerbose(@"AWSDDFileLogger: logFileCreationDate    : %@", logFileCreationDate);
+    NSLogVerbose(@"AWSDDFileLogger: actual rollingFrequency: %f", frequency);
+    NSLogVerbose(@"AWSDDFileLogger: logFileRollingDate     : %@", logFileRollingDate);
 
-    NSLogVerbose(@"AWSDDFileLogger: logFileCreationDate: %@", logFileCreationDate);
-    NSLogVerbose(@"AWSDDFileLogger: logFileRollingDate : %@", logFileRollingDate);
-
-    _rollingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, self.loggerQueue);
+    _rollingTimer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, _loggerQueue);
 
+    __weak __auto_type weakSelf = self;
     dispatch_source_set_event_handler(_rollingTimer, ^{ @autoreleasepool {
-                                                           [self maybeRollLogFileDueToAge];
-                                                       } });
+        [weakSelf lt_maybeRollLogFileDueToAge];
+    } });
 
-    #if !OS_OBJECT_USE_OBJC
+#if !OS_OBJECT_USE_OBJC
     dispatch_source_t theRollingTimer = _rollingTimer;
     dispatch_source_set_cancel_handler(_rollingTimer, ^{
         dispatch_release(theRollingTimer);
     });
-    #endif
+#endif
 
-    uint64_t delay = (uint64_t)([logFileRollingDate timeIntervalSinceNow] * (NSTimeInterval) NSEC_PER_SEC);
-    dispatch_time_t fireTime = dispatch_time(DISPATCH_TIME_NOW, delay);
+    static NSTimeInterval const kAWSDDMaxTimerDelay = LLONG_MAX / NSEC_PER_SEC;
+    __auto_type delay = (int64_t)(MIN([logFileRollingDate timeIntervalSinceNow], kAWSDDMaxTimerDelay) * (NSTimeInterval)NSEC_PER_SEC);
+    __auto_type fireTime = dispatch_walltime(NULL, delay); // `NULL` uses `gettimeofday` internally
 
-    dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, 1ull * NSEC_PER_SEC);
-    dispatch_resume(_rollingTimer);
+    dispatch_source_set_timer(_rollingTimer, fireTime, DISPATCH_TIME_FOREVER, (uint64_t)kAWSDDRollingLeeway * NSEC_PER_SEC);
+    dispatch_activate(_rollingTimer);
 }
 
 - (void)rollLogFile {
     [self rollLogFileWithCompletionBlock:nil];
 }
 
-- (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
+- (void)rollLogFileWithCompletionBlock:(nullable void (^)(void))completionBlock {
     // This method is public.
     // We need to execute the rolling on our logging thread/queue.
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
-            [self rollLogFileNow];
+            [self lt_rollLogFileNow];
 
             if (completionBlock) {
-                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
+                dispatch_async(self->_completionQueue, ^{
                     completionBlock();
                 });
             }
@@ -801,69 +887,115 @@ - (void)rollLogFileWithCompletionBlock:(void (^)(void))completionBlock {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
-- (void)rollLogFileNow {
-    NSLogVerbose(@"AWSDDFileLogger: rollLogFileNow");
+- (void)lt_rollLogFileNow {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+    NSLogVerbose(@"AWSDDFileLogger: %@", NSStringFromSelector(_cmd));
 
     if (_currentLogFileHandle == nil) {
         return;
     }
 
-    [_currentLogFileHandle synchronizeFile];
-    [_currentLogFileHandle closeFile];
+    if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+        __autoreleasing NSError *error = nil;
+        __auto_type success = [_currentLogFileHandle synchronizeAndReturnError:&error];
+        if (!success) {
+            NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", error);
+        }
+        success = [_currentLogFileHandle closeAndReturnError:&error];
+        if (!success) {
+            NSLogError(@"AWSDDFileLogger: Failed to close file: %@", error);
+        }
+    } else {
+        @try {
+            [_currentLogFileHandle synchronizeFile];
+        }
+        @catch (NSException *exception) {
+            NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", exception);
+        }
+        [_currentLogFileHandle closeFile];
+    }
     _currentLogFileHandle = nil;
 
     _currentLogFileInfo.isArchived = YES;
 
-    if ([logFileManager respondsToSelector:@selector(didRollAndArchiveLogFile:)]) {
-        [logFileManager didRollAndArchiveLogFile:(_currentLogFileInfo.filePath)];
-    }
-
+    const __auto_type logFileManagerRespondsToNewArchiveSelector = [_logFileManager respondsToSelector:@selector(didArchiveLogFile:wasRolled:)];
+    const __auto_type logFileManagerRespondsToSelector = (logFileManagerRespondsToNewArchiveSelector
+                                                          || [_logFileManager respondsToSelector:@selector(didRollAndArchiveLogFile:)]);
+    NSString *archivedFilePath = (logFileManagerRespondsToSelector) ? [_currentLogFileInfo.filePath copy] : nil;
     _currentLogFileInfo = nil;
 
+    if (logFileManagerRespondsToSelector) {
+        dispatch_block_t block;
+        if (logFileManagerRespondsToNewArchiveSelector) {
+            block = ^{
+                [self->_logFileManager didArchiveLogFile:archivedFilePath wasRolled:YES];
+            };
+        } else {
+            block = ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+                [self->_logFileManager didRollAndArchiveLogFile:archivedFilePath];
+#pragma clang diagnostic pop
+            };
+        }
+        dispatch_async(_completionQueue, block);
+    }
+
     if (_currentLogFileVnode) {
         dispatch_source_cancel(_currentLogFileVnode);
-        _currentLogFileVnode = NULL;
+        _currentLogFileVnode = nil;
     }
 
     if (_rollingTimer) {
         dispatch_source_cancel(_rollingTimer);
-        _rollingTimer = NULL;
+        _rollingTimer = nil;
     }
 }
 
-- (void)maybeRollLogFileDueToAge {
-    if (_rollingFrequency > 0.0 && _currentLogFileInfo.age >= _rollingFrequency) {
-        NSLogVerbose(@"AWSDDFileLogger: Rolling log file due to age...");
+- (void)lt_maybeRollLogFileDueToAge {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
 
-        [self rollLogFileNow];
+    if (_rollingFrequency > 0.0 && (_currentLogFileInfo.age + kAWSDDRollingLeeway) >= _rollingFrequency) {
+        NSLogVerbose(@"AWSDDFileLogger: Rolling log file due to age...");
+        [self lt_rollLogFileNow];
     } else {
-        [self scheduleTimerToRollLogFileDueToAge];
+        [self lt_scheduleTimerToRollLogFileDueToAge];
     }
 }
 
-- (void)maybeRollLogFileDueToSize {
+- (void)lt_maybeRollLogFileDueToSize {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
     // This method is called from logMessage.
     // Keep it FAST.
 
     // Note: Use direct access to maximumFileSize variable.
     // We specifically wrote our own getter/setter method to allow us to do this (for performance reasons).
 
-    if (_maximumFileSize > 0) {
-        unsigned long long fileSize = [_currentLogFileHandle offsetInFile];
+    if (_currentLogFileHandle != nil && _maximumFileSize > 0) {
+        unsigned long long fileSize;
+        if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+            __autoreleasing NSError *error = nil;
+            __auto_type success = [_currentLogFileHandle getOffset:&fileSize error:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to get offset: %@", error);
+                return;
+            }
+        } else {
+            fileSize = [_currentLogFileHandle offsetInFile];
+        }
 
         if (fileSize >= _maximumFileSize) {
             NSLogVerbose(@"AWSDDFileLogger: Rolling log file due to size (%qu)...", fileSize);
 
-            [self rollLogFileNow];
+            [self lt_rollLogFileNow];
         }
     }
 }
@@ -872,111 +1004,208 @@ - (void)maybeRollLogFileDueToSize {
 #pragma mark File Logging
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+- (BOOL)lt_shouldLogFileBeArchived:(AWSDDLogFileInfo *)mostRecentLogFileInfo {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
+    if ([self shouldArchiveRecentLogFileInfo:mostRecentLogFileInfo]) {
+        return YES;
+    } else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
+        return YES;
+    } else if (_rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= _rollingFrequency) {
+        return YES;
+    }
+
+#if TARGET_OS_IPHONE
+    // When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen.
+    //
+    // But in case if app is able to launch from background we need to have an ability to open log file any time we
+    // want (even if device is locked). Thats why that attribute have to be changed to
+    // NSFileProtectionCompleteUntilFirstUserAuthentication.
+    //
+    // If previous log was created when app wasn't running in background, but now it is - we archive it and create
+    // a new one.
+    //
+    // If user has overwritten to NSFileProtectionNone there is no need to create a new one.
+    if (doesAppRunInBackground()) {
+        NSFileProtectionType key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
+        __auto_type isUntilFirstAuth = [key isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication];
+        __auto_type isNone = [key isEqualToString:NSFileProtectionNone];
+
+        if (key != nil && !isUntilFirstAuth && !isNone) {
+            return YES;
+        }
+    }
+#endif
+
+    return NO;
+}
+
 /**
  * Returns the log file that should be used.
- * If there is an existing log file that is suitable,
- * within the constraints of maximumFileSize and rollingFrequency, then it is returned.
+ * If there is an existing log file that is suitable, within the
+ * constraints of maximumFileSize and rollingFrequency, then it is returned.
  *
  * Otherwise a new file is created and returned.
  **/
 - (AWSDDLogFileInfo *)currentLogFileInfo {
-    if (_currentLogFileInfo == nil) {
-        NSArray *sortedLogFileInfos = [logFileManager sortedLogFileInfos];
-
-        if ([sortedLogFileInfos count] > 0) {
-            AWSDDLogFileInfo *mostRecentLogFileInfo = sortedLogFileInfos[0];
-
-            BOOL shouldArchiveMostRecent = NO;
-
-            if (mostRecentLogFileInfo.isArchived) {
-                shouldArchiveMostRecent = NO;
-			} else if ([self shouldArchiveRecentLogFileInfo:mostRecentLogFileInfo]) {
-				shouldArchiveMostRecent = YES;
-			} else if (_maximumFileSize > 0 && mostRecentLogFileInfo.fileSize >= _maximumFileSize) {
-                shouldArchiveMostRecent = YES;
-            } else if (_rollingFrequency > 0.0 && mostRecentLogFileInfo.age >= _rollingFrequency) {
-                shouldArchiveMostRecent = YES;
-            }
+    // The design of this method is taken from the AWSDDAbstractLogger implementation.
+    // For extensive documentation please refer to the AWSDDAbstractLogger implementation.
+    // Do not access this method on any Lumberjack queue, will deadlock.
 
-        #if TARGET_OS_IPHONE
-            // When creating log file on iOS we're setting NSFileProtectionKey attribute to NSFileProtectionCompleteUnlessOpen.
-            //
-            // But in case if app is able to launch from background we need to have an ability to open log file any time we
-            // want (even if device is locked). Thats why that attribute have to be changed to
-            // NSFileProtectionCompleteUntilFirstUserAuthentication.
-            //
-            // If previous log was created when app wasn't running in background, but now it is - we archive it and create
-            // a new one.
-            //
-            // If user has overwritten to NSFileProtectionNone there is no neeed to create a new one.
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-            if (!_doNotReuseLogFiles && awsDoesAppRunInBackground()) {
-                NSString *key = mostRecentLogFileInfo.fileAttributes[NSFileProtectionKey];
+    __block AWSDDLogFileInfo *info = nil;
+    __auto_type block = ^{
+        info = [self lt_currentLogFileInfo];
+    };
 
-                if ([key length] > 0 && !([key isEqualToString:NSFileProtectionCompleteUntilFirstUserAuthentication] || [key isEqualToString:NSFileProtectionNone])) {
-                    shouldArchiveMostRecent = YES;
-                }
-            }
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
+        dispatch_sync(self->_loggerQueue, block);
+    });
 
-        #endif
+    return info;
+}
 
-            if (!_doNotReuseLogFiles && !mostRecentLogFileInfo.isArchived && !shouldArchiveMostRecent) {
-                NSLogVerbose(@"AWSDDFileLogger: Resuming logging with file %@", mostRecentLogFileInfo.fileName);
+- (AWSDDLogFileInfo *)lt_currentLogFileInfo {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
 
-                _currentLogFileInfo = mostRecentLogFileInfo;
-            } else {
-                if (shouldArchiveMostRecent) {
-                    mostRecentLogFileInfo.isArchived = YES;
+    // Get the current log file info ivar (might be nil).
+    __auto_type newCurrentLogFile = _currentLogFileInfo;
 
-                    if ([logFileManager respondsToSelector:@selector(didArchiveLogFile:)]) {
-                        [logFileManager didArchiveLogFile:(mostRecentLogFileInfo.filePath)];
-                    }
-                }
+    // Check if we're resuming and if so, get the first of the sorted log file infos.
+    __auto_type isResuming = newCurrentLogFile == nil;
+    if (isResuming) {
+        NSArray *sortedLogFileInfos = [_logFileManager sortedLogFileInfos];
+        newCurrentLogFile = sortedLogFileInfos.firstObject;
+    }
+
+    // Check if the file we've found is still valid. Otherwise create a new one.
+    if (newCurrentLogFile != nil && [self lt_shouldUseLogFile:newCurrentLogFile isResuming:isResuming]) {
+        if (isResuming) {
+            NSLogVerbose(@"AWSDDFileLogger: Resuming logging with file %@", newCurrentLogFile.fileName);
+        }
+        _currentLogFileInfo = newCurrentLogFile;
+    } else {
+        NSString *currentLogFilePath;
+        if ([_logFileManager respondsToSelector:@selector(createNewLogFileWithError:)]) {
+            __autoreleasing NSError *error; // Don't initialize error to nil since it will be done in -createNewLogFileWithError:
+            currentLogFilePath = [_logFileManager createNewLogFileWithError:&error];
+            if (!currentLogFilePath) {
+                NSLogError(@"AWSDDFileLogger: Failed to create new log file: %@", error);
+            }
+        } else {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+            NSAssert([_logFileManager respondsToSelector:@selector(createNewLogFile)],
+                     @"Invalid log file manager! Responds neither to `-createNewLogFileWithError:` nor `-createNewLogFile`!");
+            currentLogFilePath = [_logFileManager createNewLogFile];
+#pragma clang diagnostic pop
+            if (!currentLogFilePath) {
+                NSLogError(@"AWSDDFileLogger: Failed to create new log file");
             }
         }
+        // Use static factory method here, since it checks for nil (and is unavailable to Swift).
+        _currentLogFileInfo = [AWSDDLogFileInfo logFileWithPath:currentLogFilePath];
+    }
 
-        if (_currentLogFileInfo == nil) {
-            NSString *currentLogFilePath = [logFileManager createNewLogFile];
+    return _currentLogFileInfo;
+}
+
+- (BOOL)lt_shouldUseLogFile:(nonnull AWSDDLogFileInfo *)logFileInfo isResuming:(BOOL)isResuming {
+    NSParameterAssert(logFileInfo);
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
+    // Check if the log file is archived. We must not use archived log files.
+    if (logFileInfo.isArchived) {
+        return NO;
+    }
+
+    // Don't follow symlink
+    if (logFileInfo.isSymlink) {
+        return NO;
+    }
 
-            _currentLogFileInfo = [[AWSDDLogFileInfo alloc] initWithFilePath:currentLogFilePath];
+    // If we're resuming, we need to check if the log file is allowed for reuse or needs to be archived.
+    if (isResuming && (_doNotReuseLogFiles || [self lt_shouldLogFileBeArchived:logFileInfo])) {
+        logFileInfo.isArchived = YES;
+
+        const __auto_type logFileManagerRespondsToNewArchiveSelector = [_logFileManager respondsToSelector:@selector(didArchiveLogFile:wasRolled:)];
+        if (logFileManagerRespondsToNewArchiveSelector || [_logFileManager respondsToSelector:@selector(didArchiveLogFile:)]) {
+            NSString *archivedFilePath = [logFileInfo.filePath copy];
+            dispatch_block_t block;
+            if (logFileManagerRespondsToNewArchiveSelector) {
+                block = ^{
+                    [self->_logFileManager didArchiveLogFile:archivedFilePath wasRolled:NO];
+                };
+            } else {
+                block = ^{
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+                    [self->_logFileManager didArchiveLogFile:archivedFilePath];
+#pragma clang diagnostic pop
+                };
+            }
+            dispatch_async(_completionQueue, block);
         }
+
+        return NO;
     }
 
-    return _currentLogFileInfo;
+    // All checks have passed. It's valid.
+    return YES;
 }
 
-- (NSFileHandle *)currentLogFileHandle {
-    if (_currentLogFileHandle == nil) {
-        NSString *logFilePath = [[self currentLogFileInfo] filePath];
+- (void)lt_monitorCurrentLogFileForExternalChanges {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+    NSAssert(_currentLogFileHandle, @"Can not monitor without handle.");
+
+    // This seems to work around crashes when an active source is replaced / released.
+    // See https://github.com/CocoaLumberjack/CocoaLumberjack/issues/1341
+    // And https://stackoverflow.com/questions/36296528/what-does-this-dispatch-xref-dispose-error-mean
+    if (_currentLogFileVnode) {
+        dispatch_source_cancel(_currentLogFileVnode);
+    }
+
+    _currentLogFileVnode = dispatch_source_create(DISPATCH_SOURCE_TYPE_VNODE,
+                                                  (uintptr_t)[_currentLogFileHandle fileDescriptor],
+                                                  DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME | DISPATCH_VNODE_REVOKE,
+                                                  _loggerQueue);
+
+    __weak __auto_type weakSelf = self;
+    dispatch_source_set_event_handler(_currentLogFileVnode, ^{ @autoreleasepool {
+        NSLogInfo(@"AWSDDFileLogger: Current logfile was moved. Rolling it and creating a new one");
+        [weakSelf lt_rollLogFileNow];
+    } });
+
+#if !OS_OBJECT_USE_OBJC
+    dispatch_source_t vnode = _currentLogFileVnode;
+    dispatch_source_set_cancel_handler(_currentLogFileVnode, ^{
+        dispatch_release(vnode);
+    });
+#endif
 
+    dispatch_activate(_currentLogFileVnode);
+}
+
+- (NSFileHandle *)lt_currentLogFileHandle {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
+    if (_currentLogFileHandle == nil) {
+        __auto_type logFilePath = [[self lt_currentLogFileInfo] filePath];
         _currentLogFileHandle = [NSFileHandle fileHandleForWritingAtPath:logFilePath];
-        [_currentLogFileHandle seekToEndOfFile];
-
-        if (_currentLogFileHandle) {
-            [self scheduleTimerToRollLogFileDueToAge];
-
-            // Here we are monitoring the log file. In case if it would be deleted ormoved
-            // somewhere we want to roll it and use a new one.
-            _currentLogFileVnode = dispatch_source_create(
-                    DISPATCH_SOURCE_TYPE_VNODE,
-                    [_currentLogFileHandle fileDescriptor],
-                    DISPATCH_VNODE_DELETE | DISPATCH_VNODE_RENAME,
-                    self.loggerQueue
-                    );
-
-            dispatch_source_set_event_handler(_currentLogFileVnode, ^{ @autoreleasepool {
-                                                                          NSLogInfo(@"AWSDDFileLogger: Current logfile was moved. Rolling it and creating a new one");
-                                                                          [self rollLogFileNow];
-                                                                      } });
-
-            #if !OS_OBJECT_USE_OBJC
-            dispatch_source_t vnode = _currentLogFileVnode;
-            dispatch_source_set_cancel_handler(_currentLogFileVnode, ^{
-                dispatch_release(vnode);
-            });
-            #endif
+        if (_currentLogFileHandle != nil) {
+            if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+                __autoreleasing NSError *error = nil;
+                __auto_type success = [_currentLogFileHandle seekToEndReturningOffset:nil error:&error];
+                if (!success) {
+                    NSLogError(@"AWSDDFileLogger: Failed to seek to end of file: %@", error);
+                }
+            } else {
+                [_currentLogFileHandle seekToEndOfFile];
+            }
 
-            dispatch_resume(_currentLogFileVnode);
+            [self lt_scheduleTimerToRollLogFileDueToAge];
+            [self lt_monitorCurrentLogFileForExternalChanges];
         }
     }
 
@@ -988,63 +1217,225 @@ - (NSFileHandle *)currentLogFileHandle {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 static int exception_count = 0;
+
 - (void)logMessage:(AWSDDLogMessage *)logMessage {
-    NSString *message = logMessage->_message;
-    BOOL isFormatted = NO;
+    // Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us.
+    NSData *data = [self lt_dataForMessage:logMessage];
+    if (data.length == 0) {
+        return;
+    }
+
+    [self lt_logData:data];
+}
+
+- (void)willLogMessage:(AWSDDLogFileInfo *)logFileInfo {}
+
+- (void)didLogMessage:(AWSDDLogFileInfo *)logFileInfo {
+    [self lt_maybeRollLogFileDueToSize];
+}
+
+- (BOOL)shouldArchiveRecentLogFileInfo:(__unused AWSDDLogFileInfo *)recentLogFileInfo {
+    return NO;
+}
 
-    if (_logFormatter) {
-        message = [_logFormatter formatLogMessage:logMessage];
-        isFormatted = message != logMessage->_message;
+- (void)willRemoveLogger {
+    [self lt_rollLogFileNow];
+}
+
+- (void)flush {
+    // This method is public.
+    // We need to execute the rolling on our logging thread/queue.
+
+    dispatch_block_t block = ^{
+        @autoreleasepool {
+            [self lt_flush];
+        }
+    };
+
+    // The design of this method is taken from the AWSDDAbstractLogger implementation.
+    // For extensive documentation please refer to the AWSDDAbstractLogger implementation.
+
+    if ([self isOnInternalLoggerQueue]) {
+        block();
+    } else {
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_sync(AWSDDLog.loggingQueue, ^{
+            dispatch_sync(self.loggerQueue, block);
+        });
     }
+}
+
+- (void)lt_flush {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
 
-    if (message) {
-        if ((!isFormatted || _automaticallyAppendNewlineForCustomFormatters) &&
-            (![message hasSuffix:@"\n"])) {
-            message = [message stringByAppendingString:@"\n"];
+    if (_currentLogFileHandle != nil) {
+        if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+            __autoreleasing NSError *error = nil;
+            __auto_type success = [_currentLogFileHandle synchronizeAndReturnError:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", error);
+            }
+        } else {
+            @try {
+                [_currentLogFileHandle synchronizeFile];
+            } @catch (NSException *exception) {
+                NSLogError(@"AWSDDFileLogger: Failed to synchronize file: %@", exception);
+            }
         }
+    }
+}
 
-        NSData *logData = [message dataUsingEncoding:NSUTF8StringEncoding];
+- (AWSDDLoggerName)loggerName {
+    return AWSDDLoggerNameFile;
+}
 
-        @try {
+@end
+
+@implementation AWSDDFileLogger (Internal)
+
+- (void)logData:(NSData *)data {
+    // This method is public.
+    // We need to execute the rolling on our logging thread/queue.
+
+    __auto_type block = ^{
+        @autoreleasepool {
+            [self lt_logData:data];
+        }
+    };
+
+    // The design of this method is taken from the AWSDDAbstractLogger implementation.
+    // For extensive documentation please refer to the AWSDDAbstractLogger implementation.
+
+    if ([self isOnInternalLoggerQueue]) {
+        block();
+    } else {
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_sync(AWSDDLog.loggingQueue, ^{
+            dispatch_sync(self.loggerQueue, block);
+        });
+    }
+}
+
+- (void)lt_deprecationCatchAll {}
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {
+    if (aSelector == @selector(willLogMessage) || aSelector == @selector(didLogMessage)) {
+        // Ignore calls to deprecated methods.
+        return [self methodSignatureForSelector:@selector(lt_deprecationCatchAll)];
+    }
+
+    return [super methodSignatureForSelector:aSelector];
+}
+
+- (void)forwardInvocation:(NSInvocation *)anInvocation {
+    if (anInvocation.selector != @selector(lt_deprecationCatchAll)) {
+        [super forwardInvocation:anInvocation];
+    }
+}
+
+- (void)lt_logData:(NSData *)data {
+    static __auto_type implementsDeprecatedWillLog = NO;
+    static __auto_type implementsDeprecatedDidLog = NO;
+
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        implementsDeprecatedWillLog = [self respondsToSelector:@selector(willLogMessage)];
+        implementsDeprecatedDidLog = [self respondsToSelector:@selector(didLogMessage)];
+    });
+
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
+
+    if (data.length == 0) {
+        return;
+    }
+
+    @try {
+        // Make sure that _currentLogFileInfo is initialised before being used.
+        __auto_type handle = [self lt_currentLogFileHandle];
+
+        if (implementsDeprecatedWillLog) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
             [self willLogMessage];
-			
-            [[self currentLogFileHandle] writeData:logData];
+#pragma clang diagnostic pop
+        } else {
+            [self willLogMessage:_currentLogFileInfo];
+        }
+
+        // use an advisory lock to coordinate write with other processes
+        __auto_type fd = [handle fileDescriptor];
+        while(flock(fd, LOCK_EX) != 0) {
+            NSLogError(@"AWSDDFileLogger: Could not lock logfile, retrying in 1ms: %s (%d)", strerror(errno), errno);
+            usleep(1000);
+        }
+        if (@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)) {
+            __autoreleasing NSError *error = nil;
+            __auto_type success = [handle seekToEndReturningOffset:nil error:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to seek to end of file: %@", error);
+            }
+            success =  [handle writeData:data error:&error];
+            if (!success) {
+                NSLogError(@"AWSDDFileLogger: Failed to write data: %@", error);
+            }
+        } else {
+            [handle seekToEndOfFile];
+            [handle writeData:data];
+        }
+        flock(fd, LOCK_UN);
 
+        if (implementsDeprecatedDidLog) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
             [self didLogMessage];
-        } @catch (NSException *exception) {
-            exception_count++;
+#pragma clang diagnostic pop
+        } else {
+            [self didLogMessage:_currentLogFileInfo];
+        }
 
-            if (exception_count <= 10) {
-                NSLogError(@"AWSDDFileLogger.logMessage: %@", exception);
+    }
+    @catch (NSException *exception) {
+        exception_count++;
 
-                if (exception_count == 10) {
-                    NSLogError(@"AWSDDFileLogger.logMessage: Too many exceptions -- will not log any more of them.");
-                }
+        if (exception_count <= 10) {
+            NSLogError(@"AWSDDFileLogger.logMessage: %@", exception);
+
+            if (exception_count == 10) {
+                NSLogError(@"AWSDDFileLogger.logMessage: Too many exceptions -- will not log any more of them.");
             }
         }
     }
 }
 
-- (void)willLogMessage {
-	
+- (id <AWSDDFileLogMessageSerializer>)lt_logFileSerializer {
+    if ([_logFileManager respondsToSelector:@selector(logMessageSerializer)]) {
+        return _logFileManager.logMessageSerializer;
+    } else {
+        return [[AWSDDFileLogPlainTextMessageSerializer alloc] init];
+    }
 }
 
-- (void)didLogMessage {
-    [self maybeRollLogFileDueToSize];
-}
+- (NSData *)lt_dataForMessage:(AWSDDLogMessage *)logMessage {
+    AWSDDAbstractLoggerAssertOnInternalLoggerQueue();
 
-- (BOOL)shouldArchiveRecentLogFileInfo:(AWSDDLogFileInfo *)recentLogFileInfo {
-    return NO;
-}
+    __auto_type messageString = logMessage->_message;
+    __auto_type isFormatted = NO;
 
-- (void)willRemoveLogger {
-    // If you override me be sure to invoke [super willRemoveLogger];
+    if (_logFormatter != nil) {
+        messageString = [_logFormatter formatLogMessage:logMessage];
+        isFormatted = messageString != logMessage->_message;
+    }
 
-    [self rollLogFileNow];
-}
+    if (messageString.length == 0) {
+        return nil;
+    }
+
+    __auto_type shouldFormat = !isFormatted || _automaticallyAppendNewlineForCustomFormatters;
+    if (shouldFormat && ![messageString hasSuffix:@"\n"]) {
+        messageString = [messageString stringByAppendingString:@"\n"];
+    }
 
-- (NSString *)loggerName {
-    return @"cocoa.lumberjack.fileLogger";
+    return [[self lt_logFileSerializer] dataForString:messageString originatingFromMessage:logMessage];
 }
 
 @end
@@ -1053,24 +1444,26 @@ - (NSString *)loggerName {
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-#if TARGET_IPHONE_SIMULATOR
-    static NSString * const kAWSDDXAttrArchivedName = @"archived";
-#else
-    static NSString * const kAWSDDXAttrArchivedName = @"lumberjack.log.archived";
-#endif
+static NSString * const kDDXAttrArchivedName = @"lumberjack.log.archived";
 
 @interface AWSDDLogFileInfo () {
     __strong NSString *_filePath;
     __strong NSString *_fileName;
-    
+
     __strong NSDictionary *_fileAttributes;
-    
+
     __strong NSDate *_creationDate;
     __strong NSDate *_modificationDate;
-    
+
     unsigned long long _fileSize;
 }
 
+#if TARGET_IPHONE_SIMULATOR
+// Old implementation of extended attributes on the simulator.
+- (BOOL)_hasExtensionAttributeWithName:(NSString *)attrName;
+- (void)_removeExtensionAttributeWithName:(NSString *)attrName;
+#endif
+
 @end
 
 
@@ -1087,14 +1480,15 @@ @implementation AWSDDLogFileInfo
 
 @dynamic isArchived;
 
-
 #pragma mark Lifecycle
 
 + (instancetype)logFileWithPath:(NSString *)aFilePath {
+    if (!aFilePath) return nil;
     return [[self alloc] initWithFilePath:aFilePath];
 }
 
 - (instancetype)initWithFilePath:(NSString *)aFilePath {
+    NSParameterAssert(aFilePath);
     if ((self = [super init])) {
         filePath = [aFilePath copy];
     }
@@ -1108,10 +1502,14 @@ - (instancetype)initWithFilePath:(NSString *)aFilePath {
 
 - (NSDictionary *)fileAttributes {
     if (_fileAttributes == nil && filePath != nil) {
-        _fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
+        __autoreleasing NSError *error = nil;
+        _fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:&error];
+        if (!_fileAttributes) {
+            NSLogError(@"AWSDDLogFileInfo: Failed to read file attributes: %@", error);
+        }
     }
 
-    return _fileAttributes;
+    return _fileAttributes ?: @{};
 }
 
 - (NSString *)fileName {
@@ -1147,7 +1545,11 @@ - (unsigned long long)fileSize {
 }
 
 - (NSTimeInterval)age {
-    return [[self creationDate] timeIntervalSinceNow] * -1.0;
+    return -[[self creationDate] timeIntervalSinceNow];
+}
+
+- (BOOL)isSymlink {
+    return self.fileAttributes[NSFileType] == NSFileTypeSymbolicLink;
 }
 
 - (NSString *)description {
@@ -1166,43 +1568,15 @@ - (NSString *)description {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 - (BOOL)isArchived {
-#if TARGET_IPHONE_SIMULATOR
-
-    // Extended attributes don't work properly on the simulator.
-    // So we have to use a less attractive alternative.
-    // See full explanation in the header file.
-
-    return [self hasExtensionAttributeWithName:kAWSDDXAttrArchivedName];
-
-#else
-
-    return [self hasExtendedAttributeWithName:kAWSDDXAttrArchivedName];
-
-#endif
+    return [self hasExtendedAttributeWithName:kDDXAttrArchivedName];
 }
 
 - (void)setIsArchived:(BOOL)flag {
-#if TARGET_IPHONE_SIMULATOR
-
-    // Extended attributes don't work properly on the simulator.
-    // So we have to use a less attractive alternative.
-    // See full explanation in the header file.
-
     if (flag) {
-        [self addExtensionAttributeWithName:kAWSDDXAttrArchivedName];
+        [self addExtendedAttributeWithName:kDDXAttrArchivedName];
     } else {
-        [self removeExtensionAttributeWithName:kAWSDDXAttrArchivedName];
+        [self removeExtendedAttributeWithName:kDDXAttrArchivedName];
     }
-
-#else
-
-    if (flag) {
-        [self addExtendedAttributeWithName:kAWSDDXAttrArchivedName];
-    } else {
-        [self removeExtendedAttributeWithName:kAWSDDXAttrArchivedName];
-    }
-
-#endif
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1221,20 +1595,36 @@ - (void)renameFile:(NSString *)newFileName {
     // See full explanation in the header file.
 
     if (![newFileName isEqualToString:[self fileName]]) {
-        NSString *fileDir = [filePath stringByDeletingLastPathComponent];
-
-        NSString *newFilePath = [fileDir stringByAppendingPathComponent:newFileName];
-
-        NSLogVerbose(@"AWSDDLogFileInfo: Renaming file: '%@' -> '%@'", self.fileName, newFileName);
-
-        NSError *error = nil;
+        __auto_type fileManager = [NSFileManager defaultManager];
+        __auto_type fileDir = [filePath stringByDeletingLastPathComponent];
+        __auto_type newFilePath = [fileDir stringByAppendingPathComponent:newFileName];
+
+        // We only want to assert when we're not using the simulator, as we're "archiving" a log file with this method in the sim
+        // (in which case the file might not exist anymore and neither does it parent folder).
+#if defined(DEBUG) && (!defined(TARGET_IPHONE_SIMULATOR) || !TARGET_IPHONE_SIMULATOR)
+        __auto_type directory = NO;
+        [fileManager fileExistsAtPath:fileDir isDirectory:&directory];
+        NSAssert(directory, @"Containing directory must exist.");
+#endif
 
-        if ([[NSFileManager defaultManager] fileExistsAtPath:newFilePath] &&
-            ![[NSFileManager defaultManager] removeItemAtPath:newFilePath error:&error]) {
+        __autoreleasing NSError *error = nil;
+        __auto_type success = [fileManager removeItemAtPath:newFilePath error:&error];
+        if (!success && error.code != NSFileNoSuchFileError) {
             NSLogError(@"AWSDDLogFileInfo: Error deleting archive (%@): %@", self.fileName, error);
         }
 
-        if (![[NSFileManager defaultManager] moveItemAtPath:filePath toPath:newFilePath error:&error]) {
+        success = [fileManager moveItemAtPath:filePath toPath:newFilePath error:&error];
+
+        // When a log file is deleted, moved or renamed on the simulator, we attempt to rename it as a
+        // result of "archiving" it, but since the file doesn't exist anymore, needless error logs are printed
+        // We therefore ignore this error, and assert that the directory we are copying into exists (which
+        // is the only other case where this error code can come up).
+#if TARGET_IPHONE_SIMULATOR
+        if (!success && error.code != NSFileNoSuchFileError)
+#else
+        if (!success)
+#endif
+        {
             NSLogError(@"AWSDDLogFileInfo: Error renaming file (%@): %@", self.fileName, error);
         }
 
@@ -1249,13 +1639,26 @@ - (void)renameFile:(NSString *)newFileName {
 
 #if TARGET_IPHONE_SIMULATOR
 
-// Extended attributes don't work properly on the simulator.
-// So we have to use a less attractive alternative.
-// See full explanation in the header file.
+// Old implementation of extended attributes on the simulator.
 
-- (BOOL)hasExtensionAttributeWithName:(NSString *)attrName {
-    // This method is only used on the iPhone simulator, where normal extended attributes are broken.
-    // See full explanation in the header file.
+// Extended attributes were not working properly on the simulator
+// due to misuse of setxattr() function.
+// Now that this is fixed in the new implementation, we want to keep
+// backward compatibility with previous simulator installations.
+
+static NSString * const kDDExtensionSeparator = @".";
+
+static NSString *_xattrToExtensionName(NSString *attrName) {
+    static NSDictionary<NSString *, NSString *>* _xattrToExtensionNameMap;
+    static dispatch_once_t _token;
+    dispatch_once(&_token, ^{
+        _xattrToExtensionNameMap = @{ kDDXAttrArchivedName: @"archived" };
+    });
+    return [_xattrToExtensionNameMap objectForKey:attrName];
+}
+
+- (BOOL)_hasExtensionAttributeWithName:(NSString *)attrName {
+    // This method is only used on the iPhone simulator for backward compatibility reason.
 
     // Split the file name into components. File name may have various format, but generally
     // structure is same:
@@ -1266,14 +1669,12 @@ - (BOOL)hasExtensionAttributeWithName:(NSString *)attrName {
     //
     // So we want to search for the attrName in the components (ignoring the first array index).
 
-    NSArray *components = [[self fileName] componentsSeparatedByString:@"."];
+    __auto_type components = [[self fileName] componentsSeparatedByString:kDDExtensionSeparator];
 
     // Watch out for file names without an extension
 
     for (NSUInteger i = 1; i < components.count; i++) {
-        NSString *attr = components[i];
-
-        if ([attrName isEqualToString:attr]) {
+        if ([attrName isEqualToString:components[i]]) {
             return YES;
         }
     }
@@ -1281,66 +1682,8 @@ - (BOOL)hasExtensionAttributeWithName:(NSString *)attrName {
     return NO;
 }
 
-- (void)addExtensionAttributeWithName:(NSString *)attrName {
-    // This method is only used on the iPhone simulator, where normal extended attributes are broken.
-    // See full explanation in the header file.
-
-    if ([attrName length] == 0) {
-        return;
-    }
-
-    // Example:
-    // attrName = "archived"
-    //
-    // "mylog.txt" -> "mylog.archived.txt"
-    // "mylog"     -> "mylog.archived"
-
-    NSArray *components = [[self fileName] componentsSeparatedByString:@"."];
-
-    NSUInteger count = [components count];
-
-    NSUInteger estimatedNewLength = [[self fileName] length] + [attrName length] + 1;
-    NSMutableString *newFileName = [NSMutableString stringWithCapacity:estimatedNewLength];
-
-    if (count > 0) {
-        [newFileName appendString:components.firstObject];
-    }
-
-    NSString *lastExt = @"";
-
-    NSUInteger i;
-
-    for (i = 1; i < count; i++) {
-        NSString *attr = components[i];
-
-        if ([attr length] == 0) {
-            continue;
-        }
-
-        if ([attrName isEqualToString:attr]) {
-            // Extension attribute already exists in file name
-            return;
-        }
-
-        if ([lastExt length] > 0) {
-            [newFileName appendFormat:@".%@", lastExt];
-        }
-
-        lastExt = attr;
-    }
-
-    [newFileName appendFormat:@".%@", attrName];
-
-    if ([lastExt length] > 0) {
-        [newFileName appendFormat:@".%@", lastExt];
-    }
-
-    [self renameFile:newFileName];
-}
-
-- (void)removeExtensionAttributeWithName:(NSString *)attrName {
-    // This method is only used on the iPhone simulator, where normal extended attributes are broken.
-    // See full explanation in the header file.
+- (void)_removeExtensionAttributeWithName:(NSString *)attrName {
+    // This method is only used on the iPhone simulator for backward compatibility reason.
 
     if ([attrName length] == 0) {
         return;
@@ -1352,28 +1695,29 @@ - (void)removeExtensionAttributeWithName:(NSString *)attrName {
     // "mylog.archived.txt" -> "mylog.txt"
     // "mylog.archived"     -> "mylog"
 
-    NSArray *components = [[self fileName] componentsSeparatedByString:@"."];
+    __auto_type components = [[self fileName] componentsSeparatedByString:kDDExtensionSeparator];
 
-    NSUInteger count = [components count];
+    __auto_type count = [components count];
 
-    NSUInteger estimatedNewLength = [[self fileName] length];
-    NSMutableString *newFileName = [NSMutableString stringWithCapacity:estimatedNewLength];
+    __auto_type estimatedNewLength = [[self fileName] length];
+    __auto_type newFileName = [NSMutableString stringWithCapacity:estimatedNewLength];
 
     if (count > 0) {
-        [newFileName appendString:components.firstObject];
+        [newFileName appendString:components[0]];
     }
 
-    BOOL found = NO;
+    __auto_type found = NO;
 
     NSUInteger i;
 
     for (i = 1; i < count; i++) {
-        NSString *attr = components[i];
+        __auto_type attr = components[i];
 
         if ([attrName isEqualToString:attr]) {
             found = YES;
         } else {
-            [newFileName appendFormat:@".%@", attr];
+            [newFileName appendString:kDDExtensionSeparator];
+            [newFileName appendString:attr];
         }
     }
 
@@ -1382,46 +1726,80 @@ - (void)removeExtensionAttributeWithName:(NSString *)attrName {
     }
 }
 
-#else /* if TARGET_IPHONE_SIMULATOR */
+#endif /* if TARGET_IPHONE_SIMULATOR */
 
 - (BOOL)hasExtendedAttributeWithName:(NSString *)attrName {
-    const char *path = [filePath UTF8String];
-    const char *name = [attrName UTF8String];
+    __auto_type path = [filePath fileSystemRepresentation];
+    __auto_type name = [attrName UTF8String];
+    __auto_type hasExtendedAttribute = NO;
+    char buffer[1];
 
-    ssize_t result = getxattr(path, name, NULL, 0, 0, 0);
+    __auto_type result = getxattr(path, name, buffer, 1, 0, 0);
+
+    // Fast path
+    if (result > 0 && buffer[0] == '\1') {
+        hasExtendedAttribute = YES;
+    }
+    // Maintain backward compatibility, but fix it for future checks
+    else if (result >= 0) {
+        hasExtendedAttribute = YES;
+
+        [self addExtendedAttributeWithName:attrName];
+    }
+#if TARGET_IPHONE_SIMULATOR
+    else if ([self _hasExtensionAttributeWithName:_xattrToExtensionName(attrName)]) {
+        hasExtendedAttribute = YES;
 
-    return (result >= 0);
+        [self addExtendedAttributeWithName:attrName];
+    }
+#endif
+
+    return hasExtendedAttribute;
 }
 
 - (void)addExtendedAttributeWithName:(NSString *)attrName {
-    const char *path = [filePath UTF8String];
-    const char *name = [attrName UTF8String];
+    __auto_type path = [filePath fileSystemRepresentation];
+    __auto_type name = [attrName UTF8String];
 
-    int result = setxattr(path, name, NULL, 0, 0, 0);
+    __auto_type result = setxattr(path, name, "\1", 1, 0, 0);
 
     if (result < 0) {
-        NSLogError(@"AWSDDLogFileInfo: setxattr(%@, %@): error = %s",
-                   attrName,
-                   filePath,
-                   strerror(errno));
+        if (errno != ENOENT) {
+            NSLogError(@"AWSDDLogFileInfo: setxattr(%@, %@): error = %@",
+                       attrName,
+                       filePath,
+                       @(strerror(errno)));
+        } else {
+            NSLogDebug(@"AWSDDLogFileInfo: File does not exist in setxattr(%@, %@): error = %@",
+                       attrName,
+                       filePath,
+                       @(strerror(errno)));
+        }
+    }
+#if TARGET_IPHONE_SIMULATOR
+    else {
+        [self _removeExtensionAttributeWithName:_xattrToExtensionName(attrName)];
     }
+#endif
 }
 
 - (void)removeExtendedAttributeWithName:(NSString *)attrName {
-    const char *path = [filePath UTF8String];
-    const char *name = [attrName UTF8String];
+    __auto_type path = [filePath fileSystemRepresentation];
+    __auto_type name = [attrName UTF8String];
 
-    int result = removexattr(path, name, 0);
+    __auto_type result = removexattr(path, name, 0);
 
     if (result < 0 && errno != ENOATTR) {
-        NSLogError(@"AWSDDLogFileInfo: removexattr(%@, %@): error = %s",
+        NSLogError(@"AWSDDLogFileInfo: removexattr(%@, %@): error = %@",
                    attrName,
                    self.fileName,
-                   strerror(errno));
+                   @(strerror(errno)));
     }
-}
 
-#endif /* if TARGET_IPHONE_SIMULATOR */
+#if TARGET_IPHONE_SIMULATOR
+    [self _removeExtensionAttributeWithName:_xattrToExtensionName(attrName)];
+#endif
+}
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark Comparisons
@@ -1429,7 +1807,7 @@ - (void)removeExtendedAttributeWithName:(NSString *)attrName {
 
 - (BOOL)isEqual:(id)object {
     if ([object isKindOfClass:[self class]]) {
-        AWSDDLogFileInfo *another = (AWSDDLogFileInfo *)object;
+        __auto_type another = (AWSDDLogFileInfo *)object;
 
         return [filePath isEqualToString:[another filePath]];
     }
@@ -1437,42 +1815,25 @@ - (BOOL)isEqual:(id)object {
     return NO;
 }
 
--(NSUInteger)hash {
+- (NSUInteger)hash {
     return [filePath hash];
 }
 
-- (NSComparisonResult)reverseCompareByCreationDate:(AWSDDLogFileInfo *)another {
-    NSDate *us = [self creationDate];
-    NSDate *them = [another creationDate];
-
-    NSComparisonResult result = [us compare:them];
-
-    if (result == NSOrderedAscending) {
-        return NSOrderedDescending;
-    }
-
-    if (result == NSOrderedDescending) {
-        return NSOrderedAscending;
+- (NSComparisonResult)reverseCompareDatesUs:(NSDate *_Nullable)us them:(NSDate *_Nullable)them {
+    if (us != nil && them != nil) {
+        return [them compare:(NSDate * _Nonnull)us];
+    } else if (us == nil && them == nil) {
+        return NSOrderedSame;
     }
+    return them == nil ? NSOrderedAscending : NSOrderedDescending;
+}
 
-    return NSOrderedSame;
+- (NSComparisonResult)reverseCompareByCreationDate:(AWSDDLogFileInfo *)another {
+    return [self reverseCompareDatesUs:[self creationDate] them:[another creationDate]];
 }
 
 - (NSComparisonResult)reverseCompareByModificationDate:(AWSDDLogFileInfo *)another {
-    NSDate *us = [self modificationDate];
-    NSDate *them = [another modificationDate];
-
-    NSComparisonResult result = [us compare:them];
-
-    if (result == NSOrderedAscending) {
-        return NSOrderedDescending;
-    }
-
-    if (result == NSOrderedDescending) {
-        return NSOrderedAscending;
-    }
-
-    return NSOrderedSame;
+    return [self reverseCompareDatesUs:[self modificationDate] them:[another modificationDate]];
 }
 
 @end
@@ -1485,11 +1846,13 @@ - (NSComparisonResult)reverseCompareByModificationDate:(AWSDDLogFileInfo *)anoth
  * want (even if device is locked). Thats why that attribute have to be changed to
  * NSFileProtectionCompleteUntilFirstUserAuthentication.
  */
-BOOL awsDoesAppRunInBackground() {
-    BOOL answer = NO;
+BOOL doesAppRunInBackground(void) {
+    if ([[[NSBundle mainBundle] executablePath] containsString:@".appex/"]) {
+        return YES;
+    }
 
+    __auto_type answer = NO;
     NSArray *backgroundModes = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"UIBackgroundModes"];
-
     for (NSString *mode in backgroundModes) {
         if (mode.length > 0) {
             answer = YES;
@@ -1499,5 +1862,4 @@ BOOL awsDoesAppRunInBackground() {
 
     return answer;
 }
-
 #endif
diff --git a/AWSCore/Logging/AWSDDLegacyMacros.h b/AWSCore/Logging/AWSDDLegacyMacros.h
index 067ad6052b2..641fbd4aec7 100644
--- a/AWSCore/Logging/AWSDDLegacyMacros.h
+++ b/AWSCore/Logging/AWSDDLegacyMacros.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -20,9 +20,13 @@
  **/
 #if AWSDD_LEGACY_MACROS
 
-#warning CocoaLumberjack 1.9.x legacy macros enabled. \
+#warning AWSCocoaLumberjack 1.9.x legacy macros enabled. \
 Disable legacy macros by importing AWSCocoaLumberjack.h or AWSDDLogMacros.h instead of AWSDDLog.h or add `#define AWSDD_LEGACY_MACROS 0` before importing AWSDDLog.h.
 
+#ifndef LOG_LEVEL_DEF
+    #define LOG_LEVEL_DEF [AWSDDLog sharedInstance].logLevel
+#endif
+
 #define LOG_FLAG_ERROR    AWSDDLogFlagError
 #define LOG_FLAG_WARN     AWSDDLogFlagWarning
 #define LOG_FLAG_INFO     AWSDDLogFlagInfo
@@ -57,7 +61,7 @@ Disable legacy macros by importing AWSCocoaLumberjack.h or AWSDDLogMacros.h inst
                format : (frmt), ## __VA_ARGS__]
 
 #define AWSDD_LOG_MAYBE(async, lvl, flg, ctx, fnct, frmt, ...)                       \
-        do { if(lvl & flg) AWSDD_LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
+        do { if((lvl & flg) != 0) AWSDD_LOG_MACRO(async, lvl, flg, ctx, nil, fnct, frmt, ##__VA_ARGS__); } while(0)
 
 #define LOG_OBJC_MAYBE(async, lvl, flg, ctx, frmt, ...) \
         AWSDD_LOG_MAYBE(async, lvl, flg, ctx, __PRETTY_FUNCTION__, frmt, ## __VA_ARGS__)
diff --git a/AWSCore/Logging/AWSDDLog+LOGV.h b/AWSCore/Logging/AWSDDLog+LOGV.h
index b8ec799ffd9..84cc96e5342 100644
--- a/AWSCore/Logging/AWSDDLog+LOGV.h
+++ b/AWSCore/Logging/AWSDDLog+LOGV.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -20,6 +20,13 @@
 
 #import "AWSDDLog.h"
 
+/**
+ * The constant/variable/method responsible for controlling the current log level.
+ **/
+#ifndef LOG_LEVEL_DEF
+    #define LOG_LEVEL_DEF [AWSDDLog sharedInstance].logLevel
+#endif
+
 /**
  * Whether async should be used by log messages, excluding error messages that are always sent sync.
  **/
@@ -31,17 +38,17 @@
  * This is the single macro that all other macros below compile into.
  * This big multiline macro makes all the other macros easier to read.
  **/
-#define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist) \
-        [AWSDDLog log : isAsynchronous                                     \
-             level : lvl                                                \
-              flag : flg                                                \
-           context : ctx                                                \
-              file : __FILE__                                           \
-          function : fnct                                               \
-              line : __LINE__                                           \
-               tag : atag                                               \
-            format : frmt                                               \
-              args : avalist]
+#define LOGV_MACRO(isAsynchronous, lvl, flg, ctx, atag, fnct, frmt, avalist)    \
+        [AWSDDLog log : isAsynchronous                                          \
+                level : lvl                                                     \
+                 flag : flg                                                     \
+              context : ctx                                                     \
+                 file : __FILE__                                                \
+             function : fnct                                                    \
+                 line : __LINE__                                                \
+                  tag : atag                                                    \
+               format : frmt                                                    \
+                 args : avalist]
 
 /**
  * Define version of the macro that only execute if the log level is above the threshold.
@@ -73,4 +80,3 @@
 #define AWSDDLogVInfo(frmt, avalist)    LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagInfo,    0, nil, __PRETTY_FUNCTION__, frmt, avalist)
 #define AWSDDLogVDebug(frmt, avalist)   LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagDebug,   0, nil, __PRETTY_FUNCTION__, frmt, avalist)
 #define AWSDDLogVVerbose(frmt, avalist) LOGV_MAYBE(LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, avalist)
-
diff --git a/AWSCore/Logging/AWSDDLog.h b/AWSCore/Logging/AWSDDLog.h
index 215957a5277..c59eafad606 100644
--- a/AWSCore/Logging/AWSDDLog.h
+++ b/AWSCore/Logging/AWSDDLog.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -15,6 +15,23 @@
 
 #import <Foundation/Foundation.h>
 
+// The Swift Package integration has no support for the legacy macros.
+#if __has_include(<AWSDDLegacyMacros.h>)
+    // Enable 1.9.x legacy macros if imported directly and it's not a swift package build.
+    #ifndef AWSDD_LEGACY_MACROS
+        #define AWSDD_LEGACY_MACROS 1
+    #endif
+    // AWSDD_LEGACY_MACROS is checked in the file itself
+    #import <AWSDDLegacyMacros.h>
+#endif
+
+#ifndef AWSDD_LEGACY_MESSAGE_TAG
+    #define AWSDD_LEGACY_MESSAGE_TAG 1
+#endif
+
+// Names of loggers.
+#import "AWSDDLoggerNames.h"
+
 #if OS_OBJECT_USE_OBJC
     #define DISPATCH_QUEUE_REFERENCE_TYPE strong
 #else
@@ -26,6 +43,8 @@
 @protocol AWSDDLogger;
 @protocol AWSDDLogFormatter;
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  * Define the standard options.
  *
@@ -98,22 +117,22 @@ typedef NS_OPTIONS(NSUInteger, AWSDDLogFlag){
      *  0...00001 AWSDDLogFlagError
      */
     AWSDDLogFlagError      = (1 << 0),
-    
+
     /**
      *  0...00010 AWSDDLogFlagWarning
      */
     AWSDDLogFlagWarning    = (1 << 1),
-    
+
     /**
      *  0...00100 AWSDDLogFlagInfo
      */
     AWSDDLogFlagInfo       = (1 << 2),
-    
+
     /**
      *  0...01000 AWSDDLogFlagDebug
      */
     AWSDDLogFlagDebug      = (1 << 3),
-    
+
     /**
      *  0...10000 AWSDDLogFlagVerbose
      */
@@ -128,40 +147,38 @@ typedef NS_ENUM(NSUInteger, AWSDDLogLevel){
      *  No logs
      */
     AWSDDLogLevelOff       = 0,
-    
+
     /**
      *  Error logs only
      */
     AWSDDLogLevelError     = (AWSDDLogFlagError),
-    
+
     /**
      *  Error and warning logs
      */
     AWSDDLogLevelWarning   = (AWSDDLogLevelError   | AWSDDLogFlagWarning),
-    
+
     /**
      *  Error, warning and info logs
      */
     AWSDDLogLevelInfo      = (AWSDDLogLevelWarning | AWSDDLogFlagInfo),
-    
+
     /**
      *  Error, warning, info and debug logs
      */
     AWSDDLogLevelDebug     = (AWSDDLogLevelInfo    | AWSDDLogFlagDebug),
-    
+
     /**
      *  Error, warning, info, debug and verbose logs
      */
     AWSDDLogLevelVerbose   = (AWSDDLogLevelDebug   | AWSDDLogFlagVerbose),
-    
+
     /**
      *  All logs (1...11111)
      */
     AWSDDLogLevelAll       = NSUIntegerMax
 };
 
-NS_ASSUME_NONNULL_BEGIN
-
 /**
  *  Extracts just the file name, no path or extension
  *
@@ -170,21 +187,11 @@ NS_ASSUME_NONNULL_BEGIN
  *
  *  @return the file name
  */
-NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
-
-/**
- * The THIS_FILE macro gives you an NSString of the file name.
- * For simplicity and clarity, the file name does not include the full path or file extension.
- *
- * For example: AWSDDLogWarn(@"%@: Unable to find thingy", THIS_FILE) -> @"MyViewController: Unable to find thingy"
- **/
-#ifndef THIS_FILE
-    #define THIS_FILE         (AWSDDExtractFileNameWithoutExtension(__FILE__, NO))
-#endif
+FOUNDATION_EXTERN NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath, BOOL copy);
 
 /**
  * The AWS_THIS_FILE macro gives you an NSString of the file name.
- * Provided for convenience in case of name conflicts of the THIS_FILE macro with CocoaLumberjack.
+ * For simplicity and clarity, the file name does not include the full path or file extension.
  *
  * For example: AWSDDLogWarn(@"%@: Unable to find thingy", AWS_THIS_FILE) -> @"MyViewController: Unable to find thingy"
  **/
@@ -200,6 +207,20 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  **/
 #define THIS_METHOD       NSStringFromSelector(_cmd)
 
+/**
+ * Makes a declaration "Sendable" in Swift (if supported by the compiler).
+ */
+#ifndef AWSDD_SENDABLE
+#ifdef __has_attribute
+#if __has_attribute(swift_attr)
+#define AWSDD_SENDABLE __attribute__((swift_attr("@Sendable")))
+#endif
+#endif
+#endif
+#ifndef AWSDD_SENDABLE
+#define AWSDD_SENDABLE
+#endif
+
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark -
@@ -209,6 +230,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  *  The main class, exposes all logging mechanisms, loggers, ...
  *  For most of the users, this class is hidden behind the logging functions like `AWSDDLogInfo`
  */
+AWSDD_SENDABLE
 @interface AWSDDLog : NSObject
 
 /**
@@ -218,7 +240,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
 @property (class, nonatomic, strong, readonly) AWSDDLog *sharedInstance;
 
 /**
- * Log level setting.
+ * Log level setting.
  */
 @property (nonatomic, assign) AWSDDLogLevel logLevel;
 
@@ -249,9 +271,9 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
        flag:(AWSDDLogFlag)flag
     context:(NSInteger)context
        file:(const char *)file
-   function:(const char *)function
+   function:(nullable const char *)function
        line:(NSUInteger)line
-        tag:(id __nullable)tag
+        tag:(nullable id)tag
      format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
 
 /**
@@ -275,9 +297,9 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
        flag:(AWSDDLogFlag)flag
     context:(NSInteger)context
        file:(const char *)file
-   function:(const char *)function
+   function:(nullable const char *)function
        line:(NSUInteger)line
-        tag:(id __nullable)tag
+        tag:(nullable id)tag
      format:(NSString *)format, ... NS_FORMAT_FUNCTION(9,10);
 
 /**
@@ -302,9 +324,9 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
        flag:(AWSDDLogFlag)flag
     context:(NSInteger)context
        file:(const char *)file
-   function:(const char *)function
+   function:(nullable const char *)function
        line:(NSUInteger)line
-        tag:(id __nullable)tag
+        tag:(nullable id)tag
      format:(NSString *)format
        args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
 
@@ -330,16 +352,16 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
        flag:(AWSDDLogFlag)flag
     context:(NSInteger)context
        file:(const char *)file
-   function:(const char *)function
+   function:(nullable const char *)function
        line:(NSUInteger)line
-        tag:(id __nullable)tag
+        tag:(nullable id)tag
      format:(NSString *)format
        args:(va_list)argList NS_SWIFT_NAME(log(asynchronous:level:flag:context:file:function:line:tag:format:arguments:));
 
 /**
  * Logging Primitive.
  *
- * This method can be used if you manualy prepared AWSDDLogMessage.
+ * This method can be used if you manually prepared AWSDDLogMessage.
  *
  *  @param asynchronous YES if the logging is done async, NO if you want to force sync
  *  @param logMessage   the log message stored in a `AWSDDLogMessage` model object
@@ -350,7 +372,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
 /**
  * Logging Primitive.
  *
- * This method can be used if you manualy prepared AWSDDLogMessage.
+ * This method can be used if you manually prepared AWSDDLogMessage.
  *
  *  @param asynchronous YES if the logging is done async, NO if you want to force sync
  *  @param logMessage   the log message stored in a `AWSDDLogMessage` model object
@@ -583,7 +605,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  * If no formatter is set, the logger simply logs the message as it is given in logMessage,
  * or it may use its own built in formatting style.
  **/
-@property (nonatomic, strong) id <AWSDDLogFormatter> logFormatter;
+@property (nonatomic, strong, nullable) id <AWSDDLogFormatter> logFormatter;
 
 @optional
 
@@ -614,16 +636,16 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
 - (void)didAddLoggerInQueue:(dispatch_queue_t)queue;
 
 /**
- *  See the above description for `didAddLoger`
+ *  See the above description for `didAddLogger`
  */
 - (void)willRemoveLogger;
 
 /**
  * Some loggers may buffer IO for optimization purposes.
- * For example, a database logger may only save occasionaly as the disk IO is slow.
+ * For example, a database logger may only save occasionally as the disk IO is slow.
  * In such loggers, this method should be implemented to flush any pending IO.
  *
- * This allows invocations of AWSDDLog's flushLog method to be propogated to loggers that need it.
+ * This allows invocations of AWSDDLog's flushLog method to be propagated to loggers that need it.
  *
  * Note that AWSDDLog's flushLog method is invoked automatically when the application quits,
  * and it may be also invoked manually by the developer prior to application crashes, or other such reasons.
@@ -643,7 +665,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  * The created queue will receive its name from this method.
  * This may be helpful for debugging or profiling reasons.
  **/
-@property (nonatomic, readonly) NSString *loggerName;
+@property (copy, nonatomic, readonly) AWSDDLoggerName loggerName;
 
 @end
 
@@ -668,7 +690,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  * The formatter may also optionally filter the log message by returning nil,
  * in which case the logger will not log the message.
  **/
-- (NSString * __nullable)formatLogMessage:(AWSDDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
+- (nullable NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage NS_SWIFT_NAME(format(message:));
 
 @optional
 
@@ -678,7 +700,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  *
  * This is primarily for thread-safety.
  * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
- * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
+ * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter with 10.0 behavior),
  * it could possibly use these hooks to switch to thread-safe versions of the code.
  **/
 - (void)didAddToLogger:(id <AWSDDLogger>)logger;
@@ -689,7 +711,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
  *
  * This is primarily for thread-safety.
  * If a formatter is explicitly not thread-safe, it may wish to throw an exception if added to multiple loggers.
- * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter),
+ * Or if a formatter has potentially thread-unsafe code (e.g. NSDateFormatter with 10.0 behavior),
  * it could possibly use these hooks to switch to thread-safe versions of the code or use dispatch_set_specific()
 .* to add its own specific values.
  **/
@@ -709,7 +731,7 @@ NSString * __nullable AWSDDExtractFileNameWithoutExtension(const char *filePath,
 /**
  *  This protocol describes a dynamic logging component
  */
-@protocol AWSDDRegisteredDynamicLogging
+@protocol AWSDRegisteredDynamicLogging
 
 /**
  * Implement these methods to allow a file's log level to be managed from a central location.
@@ -768,11 +790,13 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
  * The `AWSDDLogMessage` class encapsulates information about the log message.
  * If you write custom loggers or formatters, you will be dealing with objects of this class.
  **/
+AWSDD_SENDABLE
 @interface AWSDDLogMessage : NSObject <NSCopying>
 {
     // Direct accessors to be used only for performance
     @public
     NSString *_message;
+    NSString *_messageFormat;
     AWSDDLogLevel _level;
     AWSDDLogFlag _flag;
     NSInteger _context;
@@ -780,12 +804,16 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
     NSString *_fileName;
     NSString *_function;
     NSUInteger _line;
-    id _tag;
+#if AWSDD_LEGACY_MESSAGE_TAG
+    id _tag __attribute__((deprecated("Use _representedObject instead", "_representedObject")));
+#endif
+    id _representedObject;
     AWSDDLogMessageOptions _options;
-    NSDate *_timestamp;
+    NSDate * _timestamp;
     NSString *_threadID;
     NSString *_threadName;
     NSString *_queueLabel;
+    NSUInteger _qos;
 }
 
 /**
@@ -807,6 +835,64 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
  * so it makes sense to optimize and skip the unnecessary allocations.
  * However, if you need them to be copied you may use the options parameter to specify this.
  *
+ *  @param messageFormat   the message format
+ *  @param message  the formatted message
+ *  @param level     the log level
+ *  @param flag      the log flag
+ *  @param context   the context (if any is defined)
+ *  @param file      the current file
+ *  @param function  the current function
+ *  @param line      the current code line
+ *  @param tag       potential tag
+ *  @param options   a bitmask which supports AWSDDLogMessageCopyFile and AWSDDLogMessageCopyFunction.
+ *  @param timestamp the log timestamp
+ *
+ *  @return a new instance of a log message model object
+ */
+- (instancetype)initWithFormat:(NSString *)messageFormat
+                     formatted:(NSString *)message
+                         level:(AWSDDLogLevel)level
+                          flag:(AWSDDLogFlag)flag
+                       context:(NSInteger)context
+                          file:(NSString *)file
+                      function:(nullable NSString *)function
+                          line:(NSUInteger)line
+                           tag:(nullable id)tag
+                       options:(AWSDDLogMessageOptions)options
+                     timestamp:(nullable NSDate *)timestamp NS_DESIGNATED_INITIALIZER;
+
+/**
+ *     Convenience initializer taking a `va_list` as arguments to create the formatted message.
+ *
+ *  @param messageFormat   the message format
+ *  @param messageArgs   the message arguments.
+ *  @param level     the log level
+ *  @param flag      the log flag
+ *  @param context   the context (if any is defined)
+ *  @param file      the current file
+ *  @param function  the current function
+ *  @param line      the current code line
+ *  @param tag       potential tag
+ *  @param options   a bitmask which supports AWSDDLogMessageCopyFile and AWSDDLogMessageCopyFunction.
+ *  @param timestamp the log timestamp
+ *
+ *  @return a new instance of a log message model object
+ */
+- (instancetype)initWithFormat:(NSString *)messageFormat
+                          args:(va_list)messageArgs
+                         level:(AWSDDLogLevel)level
+                          flag:(AWSDDLogFlag)flag
+                       context:(NSInteger)context
+                          file:(NSString *)file
+                      function:(nullable NSString *)function
+                          line:(NSUInteger)line
+                           tag:(nullable id)tag
+                       options:(AWSDDLogMessageOptions)options
+                     timestamp:(nullable NSDate *)timestamp;
+
+/**
+ *  Deprecated initialier. See initWithFormat:args:formatted:level:flag:context:file:function:line:tag:options:timestamp:.
+ *
  *  @param message   the message
  *  @param level     the log level
  *  @param flag      the log flag
@@ -825,33 +911,42 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
                            flag:(AWSDDLogFlag)flag
                         context:(NSInteger)context
                            file:(NSString *)file
-                       function:(NSString * __nullable)function
+                       function:(nullable NSString *)function
                            line:(NSUInteger)line
-                            tag:(id __nullable)tag
+                            tag:(nullable id)tag
                         options:(AWSDDLogMessageOptions)options
-                      timestamp:(NSDate * __nullable)timestamp NS_DESIGNATED_INITIALIZER;
+                      timestamp:(nullable NSDate *)timestamp
+__attribute__((deprecated("Use initializer taking unformatted message and args instead", "initWithFormat:formatted:level:flag:context:file:function:line:tag:options:timestamp:")));
 
 /**
  * Read-only properties
  **/
 
 /**
- *  The log message
+ *  The log message.
  */
 @property (readonly, nonatomic) NSString *message;
+/**
+ * The message format. When the deprecated initializer is used, this might be the same as `message`.
+ */
+@property (readonly, nonatomic) NSString *messageFormat;
 @property (readonly, nonatomic) AWSDDLogLevel level;
 @property (readonly, nonatomic) AWSDDLogFlag flag;
 @property (readonly, nonatomic) NSInteger context;
 @property (readonly, nonatomic) NSString *file;
 @property (readonly, nonatomic) NSString *fileName;
-@property (readonly, nonatomic) NSString * __nullable function;
+@property (readonly, nonatomic, nullable) NSString * function;
 @property (readonly, nonatomic) NSUInteger line;
-@property (readonly, nonatomic) id __nullable tag;
+#if AWSDD_LEGACY_MESSAGE_TAG
+@property (readonly, nonatomic, nullable) id tag __attribute__((deprecated("Use representedObject instead", "representedObject")));
+#endif
+@property (readonly, nonatomic, nullable) id representedObject;
 @property (readonly, nonatomic) AWSDDLogMessageOptions options;
 @property (readonly, nonatomic) NSDate *timestamp;
 @property (readonly, nonatomic) NSString *threadID; // ID as it appears in NSLog calculated from the machThreadID
-@property (readonly, nonatomic) NSString *threadName;
+@property (readonly, nonatomic, nullable) NSString *threadName;
 @property (readonly, nonatomic) NSString *queueLabel;
+@property (readonly, nonatomic) NSUInteger qos API_AVAILABLE(macos(10.10), ios(8.0));
 
 @end
 
@@ -863,10 +958,10 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
  * The `AWSDDLogger` protocol specifies that an optional formatter can be added to a logger.
  * Most (but not all) loggers will want to support formatters.
  *
- * However, writting getters and setters in a thread safe manner,
+ * However, writing getters and setters in a thread safe manner,
  * while still maintaining maximum speed for the logging process, is a difficult task.
  *
- * To do it right, the implementation of the getter/setter has strict requiremenets:
+ * To do it right, the implementation of the getter/setter has strict requirements:
  * - Must NOT require the `logMessage:` method to acquire a lock.
  * - Must NOT require the `logMessage:` method to access an atomic property (also a lock of sorts).
  *
@@ -879,7 +974,7 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
 {
     // Direct accessors to be used only for performance
     @public
-    id <AWSDDLogFormatter> _logFormatter;
+    _Nullable id <AWSDDLogFormatter> _logFormatter;
     dispatch_queue_t _loggerQueue;
 }
 
@@ -891,7 +986,7 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
 /**
  *  Return YES if the current logger uses a global queue for logging
  */
-@property (nonatomic, readonly, getter=isOnGlobalLoggingQueue)  BOOL onGlobalLoggingQueue;
+@property (nonatomic, readonly, getter=isOnGlobalLoggingQueue) BOOL onGlobalLoggingQueue;
 
 /**
  *  Return YES if the current logger uses the internal designated queue for logging
@@ -900,17 +995,34 @@ typedef NS_OPTIONS(NSInteger, AWSDDLogMessageOptions){
 
 @end
 
+#define _AWSDDAbstractLoggerSelectorMessage(msg) [NSStringFromSelector(_cmd) stringByAppendingString:@" " msg]
+// Note: we do not wrap these in any do {...} while 0 construct, because NSAssert does that for us.
+#define AWSDDAbstractLoggerAssertOnGlobalLoggingQueue() \
+NSAssert([self isOnGlobalLoggingQueue], _AWSDDAbstractLoggerSelectorMessage("must only be called on the global logging queue!"))
+#define AWSDDAbstractLoggerAssertOnInternalLoggerQueue() \
+NSAssert([self isOnInternalLoggerQueue], _AWSDDAbstractLoggerSelectorMessage("must only be called on the internal logger queue!"))
+#define AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue() \
+    NSAssert(![self isOnGlobalLoggingQueue], _AWSDDAbstractLoggerSelectorMessage("must not be called on the global logging queue!"))
+#define AWSDDAbstractLoggerAssertNotOnInternalLoggerQueue() \
+    NSAssert(![self isOnGlobalLoggingQueue], _AWSDDAbstractLoggerSelectorMessage("must not be called on the internal logger queue!"))
+
+#define AWSDDAbstractLoggerAssertLockedPropertyAccess() \
+    AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue(); \
+    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.")
+
+
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
+AWSDD_SENDABLE
 @interface AWSDDLoggerInformation : NSObject
 
 @property (nonatomic, readonly) id <AWSDDLogger> logger;
 @property (nonatomic, readonly) AWSDDLogLevel level;
 
-+ (AWSDDLoggerInformation *)informationWithLogger:(id <AWSDDLogger>)logger
-                           andLevel:(AWSDDLogLevel)level;
++ (instancetype)informationWithLogger:(id <AWSDDLogger>)logger
+                             andLevel:(AWSDDLogLevel)level;
 
 @end
 
diff --git a/AWSCore/Logging/AWSDDLog.m b/AWSCore/Logging/AWSDDLog.m
index 9c41e83f0ac..9eb505e2906 100644
--- a/AWSCore/Logging/AWSDDLog.m
+++ b/AWSCore/Logging/AWSDDLog.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,29 +13,28 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-// Disable legacy macros
-#ifndef AWSDD_LEGACY_MACROS
-    #define AWSDD_LEGACY_MACROS 0
+#if !__has_feature(objc_arc)
+#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
-#import "AWSDDLog.h"
-
 #import <pthread.h>
-#import <dispatch/dispatch.h>
 #import <objc/runtime.h>
-#import <mach/mach_host.h>
-#import <mach/host_info.h>
-#import <libkern/OSAtomic.h>
-#import <Availability.h>
+#import <sys/qos.h>
+
 #if TARGET_OS_IOS
     #import <UIKit/UIDevice.h>
+    #import <UIKit/UIApplication.h>
+#elif !defined(AWSDD_CLI) && __has_include(<AppKit/NSApplication.h>)
+    #import <AppKit/NSApplication.h>
 #endif
 
-
-#if !__has_feature(objc_arc)
-#error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
+// Disable legacy macros
+#ifndef AWSDD_LEGACY_MACROS
+    #define AWSDD_LEGACY_MACROS 0
 #endif
 
+#import "AWSDDLog.h"
+
 // We probably shouldn't be using AWSDDLog() statements within the AWSDDLog implementation.
 // But we still want to leave our log statements for any future debugging,
 // and to allow other developers to trace the implementation (which is a great learning tool).
@@ -44,25 +43,15 @@
 // We maintain the NS prefix on the macros to be explicit about the fact that we're using NSLog.
 
 #ifndef AWSDD_DEBUG
-    #define AWSDD_DEBUG NO
+    #define AWSDD_DEBUG 0
 #endif
 
 #define NSLogDebug(frmt, ...) do{ if(AWSDD_DEBUG) NSLog((frmt), ##__VA_ARGS__); } while(0)
 
-// Specifies the maximum queue size of the logging thread.
-//
-// Since most logging is asynchronous, its possible for rogue threads to flood the logging queue.
-// That is, to issue an abundance of log statements faster than the logging thread can keepup.
-// Typically such a scenario occurs when log statements are added haphazardly within large loops,
-// but may also be possible if relatively slow loggers are being used.
-//
-// This property caps the queue size at a given number of outstanding log statements.
-// If a thread attempts to issue a log statement when the queue is already maxed out,
-// the issuing thread will block until the queue size drops below the max again.
-
-#ifndef AWSDDLOG_MAX_QUEUE_SIZE
-    #define AWSDDLOG_MAX_QUEUE_SIZE 1000 // Should not exceed INT32_MAX
-#endif
+#define AWSDDLogAssertOnGlobalLoggingQueue() \
+NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey), @"This method must be called on the logging thread/queue!")
+#define AWSDDLogAssertNotOnGlobalLoggingQueue() \
+NSAssert(!dispatch_get_specific(GlobalLoggingQueueIdentityKey), @"This method must not be called on the logging thread/queue!")
 
 // The "global logging queue" refers to [AWSDDLog loggingQueue].
 // It is the queue that all log statements go through.
@@ -85,9 +74,9 @@ @interface AWSDDLoggerNode : NSObject
 @property (nonatomic, readonly) AWSDDLogLevel level;
 @property (nonatomic, readonly) dispatch_queue_t loggerQueue;
 
-+ (AWSDDLoggerNode *)nodeWithLogger:(id <AWSDDLogger>)logger
-                     loggerQueue:(dispatch_queue_t)loggerQueue
-                           level:(AWSDDLogLevel)level;
++ (instancetype)nodeWithLogger:(id <AWSDDLogger>)logger
+                   loggerQueue:(dispatch_queue_t)loggerQueue
+                         level:(AWSDDLogLevel)level;
 
 @end
 
@@ -110,13 +99,9 @@ @implementation AWSDDLog
 static dispatch_queue_t _loggingQueue;
 
 // Individual loggers are executed concurrently per log statement.
-// Each logger has it's own associated queue, and a dispatch group is used for synchrnoization.
+// Each logger has it's own associated queue, and a dispatch group is used for synchronization.
 static dispatch_group_t _loggingGroup;
 
-// In order to prevent to queue from growing infinitely large,
-// a maximum size is enforced (AWSDDLOG_MAX_QUEUE_SIZE).
-static dispatch_semaphore_t _queueSemaphore;
-
 // Minor optimization for uniprocessor machines
 static NSUInteger _numProcessors;
 
@@ -127,13 +112,13 @@ @implementation AWSDDLog
  *  @return The singleton `AWSDDLog`.
  */
 + (instancetype)sharedInstance {
-    static id sharedInstance = nil;
-    
+    static AWSDDLog *sharedInstance = nil;
+
     static dispatch_once_t onceToken;
     dispatch_once(&onceToken, ^{
         sharedInstance = [[self alloc] init];
     });
-    
+
     return sharedInstance;
 }
 
@@ -143,27 +128,25 @@ + (instancetype)sharedInstance {
  * method may never be invoked if the class is not used.) The runtime sends the initialize message to
  * classes in a thread-safe manner. Superclasses receive this message before their subclasses.
  *
- * This method may also be called directly (assumably by accident), hence the safety mechanism.
+ * This method may also be called directly, hence the safety mechanism.
  **/
 + (void)initialize {
     static dispatch_once_t AWSDDLogOnceToken;
-    
+
     dispatch_once(&AWSDDLogOnceToken, ^{
         NSLogDebug(@"AWSDDLog: Using grand central dispatch");
-        
+
         _loggingQueue = dispatch_queue_create("cocoa.lumberjack", NULL);
         _loggingGroup = dispatch_group_create();
-        
+
         void *nonNullValue = GlobalLoggingQueueIdentityKey; // Whatever, just not null
         dispatch_queue_set_specific(_loggingQueue, GlobalLoggingQueueIdentityKey, nonNullValue, NULL);
-        
-        _queueSemaphore = dispatch_semaphore_create(AWSDDLOG_MAX_QUEUE_SIZE);
-        
+
         // Figure out how many processors are available.
         // This may be used later for an optimization on uniprocessor machines.
-        
+
         _numProcessors = MAX([NSProcessInfo processInfo].processorCount, (NSUInteger) 1);
-        
+
         NSLogDebug(@"AWSDDLog: numProcessors = %@", @(_numProcessors));
     });
 }
@@ -174,37 +157,36 @@ + (void)initialize {
  *
  *  @return An initialized `AWSDDLog` instance.
  */
-- (id)init {
+- (instancetype)init {
     self = [super init];
-    
+
     if (self) {
         self._loggers = [[NSMutableArray alloc] initWithCapacity:4];
         self.logLevel = AWSDDLogLevelWarning;//default to warning
-        
+
 #if TARGET_OS_IOS
-        NSString *notificationName = @"UIApplicationWillTerminateNotification";
+        __auto_type notificationName = UIApplicationWillTerminateNotification;
 #else
         NSString *notificationName = nil;
-        
-        // On Command Line Tool apps AppKit may not be avaliable
-#ifdef NSAppKitVersionNumber10_0
-        
+
+        // On Command Line Tool apps AppKit may not be available
+#if !defined(AWSDD_CLI) && __has_include(<AppKit/NSApplication.h>)
         if (NSApp) {
-            notificationName = @"NSApplicationWillTerminateNotification";
+            notificationName = NSApplicationWillTerminateNotification;
         }
-        
 #endif
-        
+
         if (!notificationName) {
             // If there is no NSApp -> we are running Command Line Tool app.
             // In this case terminate notification wouldn't be fired, so we use workaround.
+            __weak __auto_type weakSelf = self;
             atexit_b (^{
-                [self applicationWillTerminate:nil];
+                [weakSelf applicationWillTerminate:nil];
             });
         }
-        
+
 #endif /* if TARGET_OS_IOS */
-        
+
         if (notificationName) {
             [[NSNotificationCenter defaultCenter] addObserver:self
                                                      selector:@selector(applicationWillTerminate:)
@@ -212,7 +194,7 @@ - (id)init {
                                                        object:nil];
         }
     }
-    
+
     return self;
 }
 
@@ -251,7 +233,7 @@ - (void)addLogger:(id <AWSDDLogger>)logger withLevel:(AWSDDLogLevel)level {
     if (!logger) {
         return;
     }
-    
+
     dispatch_async(_loggingQueue, ^{ @autoreleasepool {
         [self lt_addLogger:logger level:level];
     } });
@@ -265,7 +247,7 @@ - (void)removeLogger:(id <AWSDDLogger>)logger {
     if (!logger) {
         return;
     }
-    
+
     dispatch_async(_loggingQueue, ^{ @autoreleasepool {
         [self lt_removeLogger:logger];
     } });
@@ -287,11 +269,11 @@ - (void)removeAllLoggers {
 
 - (NSArray<id<AWSDDLogger>> *)allLoggers {
     __block NSArray *theLoggers;
-    
+
     dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
         theLoggers = [self lt_allLoggers];
     } });
-    
+
     return theLoggers;
 }
 
@@ -301,11 +283,11 @@ - (void)removeAllLoggers {
 
 - (NSArray<AWSDDLoggerInformation *> *)allLoggersWithLevel {
     __block NSArray *theLoggersWithLevel;
-    
+
     dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
         theLoggersWithLevel = [self lt_allLoggersWithLevel];
     } });
-    
+
     return theLoggersWithLevel;
 }
 
@@ -341,23 +323,9 @@ - (void)queueLogMessage:(AWSDDLogMessage *)logMessage asynchronously:(BOOL)async
     // Now assume we have another separate thread that attempts to issue log message G.
     // It should block until log messages A and B have been unqueued.
 
-
-    // We are using a counting semaphore provided by GCD.
-    // The semaphore is initialized with our AWSDDLOG_MAX_QUEUE_SIZE value.
-    // Everytime we want to queue a log message we decrement this value.
-    // If the resulting value is less than zero,
-    // the semaphore function waits in FIFO order for a signal to occur before returning.
-    //
-    // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
-    // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
-    // If the calling semaphore does not need to block, no kernel call is made.
-
-    dispatch_semaphore_wait(_queueSemaphore, DISPATCH_TIME_FOREVER);
-
-    // We've now sure we won't overflow the queue.
-    // It is time to queue our log message.
-
-    dispatch_block_t logBlock = ^{
+    __auto_type logBlock = ^{
+        // We're now sure we won't overflow the queue.
+        // It is time to queue our log message.
         @autoreleasepool {
             [self lt_log:logMessage];
         }
@@ -365,13 +333,14 @@ - (void)queueLogMessage:(AWSDDLogMessage *)logMessage asynchronously:(BOOL)async
 
     if (asyncFlag) {
         dispatch_async(_loggingQueue, logBlock);
+    } else if (dispatch_get_specific(GlobalLoggingQueueIdentityKey)) {
+        // We've logged an error message while on the logging queue...
+        logBlock();
     } else {
         dispatch_sync(_loggingQueue, logBlock);
     }
 }
 
-// Note: make sure to follow best security practices and ensure that all inputs are validated and sanitized.
-// Verify that the number of formatting directives in the format string corresponds to the number of arguments to be formatted.
 + (void)log:(BOOL)asynchronous
       level:(AWSDDLogLevel)level
        flag:(AWSDDLogFlag)flag
@@ -382,26 +351,21 @@ + (void)log:(BOOL)asynchronous
         tag:(id)tag
      format:(NSString *)format, ... {
     va_list args;
-    
+
     if (format) {
         va_start(args, format);
-        
-        NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
-        
-        va_end(args);
-        
-        va_start(args, format);
-        
+
         [self log:asynchronous
-          message:message
             level:level
              flag:flag
           context:context
              file:file
          function:function
              line:line
-              tag:tag];
-        
+              tag:tag
+           format:format
+             args:args];
+
         va_end(args);
     }
 }
@@ -416,26 +380,21 @@ - (void)log:(BOOL)asynchronous
         tag:(id)tag
      format:(NSString *)format, ... {
     va_list args;
-    
+
     if (format) {
         va_start(args, format);
-        
-        NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
-        
-        va_end(args);
-        
-        va_start(args, format);
-        
+
         [self log:asynchronous
-          message:message
             level:level
              flag:flag
           context:context
              file:file
          function:function
              line:line
-              tag:tag];
-        
+              tag:tag
+           format:format
+             args:args];
+
         va_end(args);
     }
 }
@@ -464,63 +423,31 @@ - (void)log:(BOOL)asynchronous
      format:(NSString *)format
        args:(va_list)args {
     if (format) {
-        NSString *message = [[NSString alloc] initWithFormat:format arguments:args];
-        [self log:asynchronous
-          message:message
-            level:level
-             flag:flag
-          context:context
-             file:file
-         function:function
-             line:line
-              tag:tag];
-    }
-}
+        // Null checks are handled by -initWithMessage:
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wnullable-to-nonnull-conversion"
+        __auto_type logMessage = [[AWSDDLogMessage alloc] initWithFormat:format
+                                                                    args:args
+                                                                   level:level
+                                                                    flag:flag
+                                                                 context:context
+                                                                    file:@(file)
+                                                                function:@(function)
+                                                                    line:line
+                                                                     tag:tag
+                                                                 options:(AWSDDLogMessageOptions)0
+                                                               timestamp:nil];
+#pragma clang diagnostic pop
 
-+ (void)log:(BOOL)asynchronous
-    message:(NSString *)message
-      level:(AWSDDLogLevel)level
-       flag:(AWSDDLogFlag)flag
-    context:(NSInteger)context
-       file:(const char *)file
-   function:(const char *)function
-       line:(NSUInteger)line
-        tag:(id)tag {
-    [self.sharedInstance log:asynchronous message:message level:level flag:flag context:context file:file function:function line:line tag:tag];
-}
-
-- (void)log:(BOOL)asynchronous
-    message:(NSString *)message
-      level:(AWSDDLogLevel)level
-       flag:(AWSDDLogFlag)flag
-    context:(NSInteger)context
-       file:(const char *)file
-   function:(const char *)function
-       line:(NSUInteger)line
-        tag:(id)tag {
-    if(level & flag){
-        AWSDDLogMessage *logMessage = [[AWSDDLogMessage alloc] initWithMessage:message
-                                                                         level:level
-                                                                          flag:flag
-                                                                       context:context
-                                                                          file:[NSString stringWithFormat:@"%s", file]
-                                                                      function:[NSString stringWithFormat:@"%s", function]
-                                                                          line:line
-                                                                           tag:tag
-                                                                       options:(AWSDDLogMessageOptions)0
-                                                                     timestamp:nil];
-        
         [self queueLogMessage:logMessage asynchronously:asynchronous];
     }
 }
 
-+ (void)log:(BOOL)asynchronous
-    message:(AWSDDLogMessage *)logMessage {
++ (void)log:(BOOL)asynchronous message:(AWSDDLogMessage *)logMessage {
     [self.sharedInstance log:asynchronous message:logMessage];
 }
 
-- (void)log:(BOOL)asynchronous
-    message:(AWSDDLogMessage *)logMessage {
+- (void)log:(BOOL)asynchronous message:(AWSDDLogMessage *)logMessage {
     [self queueLogMessage:logMessage asynchronously:asynchronous];
 }
 
@@ -529,9 +456,12 @@ + (void)flushLog {
 }
 
 - (void)flushLog {
-    dispatch_sync(_loggingQueue, ^{ @autoreleasepool {
-        [self lt_flush];
-    } });
+    AWSDDLogAssertNotOnGlobalLoggingQueue();
+    dispatch_sync(_loggingQueue, ^{
+        @autoreleasepool {
+            [self lt_flush];
+        }
+    });
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -539,69 +469,65 @@ - (void)flushLog {
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 + (BOOL)isRegisteredClass:(Class)class {
-    SEL getterSel = @selector(ddLogLevel);
-    SEL setterSel = @selector(ddSetLogLevel:);
-
-#if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR
+    __auto_type getterSel = @selector(ddLogLevel);
+    __auto_type setterSel = @selector(ddSetLogLevel:);
 
     // Issue #6 (GoogleCode) - Crashes on iOS 4.2.1 and iPhone 4
-    //
     // Crash caused by class_getClassMethod(2).
-    //
     //     "It's a bug with UIAccessibilitySafeCategory__NSObject so it didn't pop up until
     //      users had VoiceOver enabled [...]. I was able to work around it by searching the
     //      result of class_copyMethodList() instead of calling class_getClassMethod()"
+    //
+    // Issue #24 (GitHub) - Crashing in in ARC+Simulator
+    // The method +[AWSDDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
+    // For running in the Simulator, it needs to execute the non-iOS code. Unless we're running on iOS 17+.
 
-    BOOL result = NO;
+#if TARGET_OS_IPHONE
+#if TARGET_OS_SIMULATOR
+    if (@available(iOS 17, tvOS 17, *)) {
+#endif
+        __auto_type result = NO;
+        unsigned int methodCount, i;
+        __auto_type methodList = class_copyMethodList(object_getClass(class), &methodCount);
 
-    unsigned int methodCount, i;
-    Method *methodList = class_copyMethodList(object_getClass(class), &methodCount);
+        if (methodList != NULL) {
+            __auto_type getterFound = NO;
+            __auto_type setterFound = NO;
 
-    if (methodList != NULL) {
-        BOOL getterFound = NO;
-        BOOL setterFound = NO;
+            for (i = 0; i < methodCount; ++i) {
+                __auto_type currentSel = method_getName(methodList[i]);
 
-        for (i = 0; i < methodCount; ++i) {
-            SEL currentSel = method_getName(methodList[i]);
+                if (currentSel == getterSel) {
+                    getterFound = YES;
+                } else if (currentSel == setterSel) {
+                    setterFound = YES;
+                }
 
-            if (currentSel == getterSel) {
-                getterFound = YES;
-            } else if (currentSel == setterSel) {
-                setterFound = YES;
+                if (getterFound && setterFound) {
+                    result = YES;
+                    break;
+                }
             }
 
-            if (getterFound && setterFound) {
-                result = YES;
-                break;
-            }
+            free(methodList);
         }
 
-        free(methodList);
-    }
-
-    return result;
-
-#else /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */
-
-    // Issue #24 (GitHub) - Crashing in in ARC+Simulator
-    //
-    // The method +[AWSDDLog isRegisteredClass] will crash a project when using it with ARC + Simulator.
-    // For running in the Simulator, it needs to execute the non-iOS code.
-
-    Method getter = class_getClassMethod(class, getterSel);
-    Method setter = class_getClassMethod(class, setterSel);
-
-    if ((getter != NULL) && (setter != NULL)) {
-        return YES;
+        return result;
+#if TARGET_OS_SIMULATOR
+    } else {
+#endif /* TARGET_OS_SIMULATOR */
+#endif /* TARGET_OS_IPHONE */
+#if !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR
+        __auto_type getter = class_getClassMethod(class, getterSel);
+        __auto_type setter = class_getClassMethod(class, setterSel);
+        return (getter != NULL) && (setter != NULL);
+#endif /* !TARGET_OS_IPHONE || TARGET_OS_SIMULATOR */
+#if TARGET_OS_IPHONE && TARGET_OS_SIMULATOR
     }
-
-    return NO;
-
-#endif /* if TARGET_OS_IPHONE && !TARGET_OS_SIMULATOR */
+#endif /* TARGET_OS_IPHONE && TARGET_OS_SIMULATOR */
 }
 
 + (NSArray *)registeredClasses {
-
     // We're going to get the list of all registered classes.
     // The Objective-C runtime library automatically registers all the classes defined in your source code.
     //
@@ -617,33 +543,29 @@ + (NSArray *)registeredClasses {
     Class *classes = NULL;
 
     while (numClasses == 0) {
-
         numClasses = (NSUInteger)MAX(objc_getClassList(NULL, 0), 0);
 
         // numClasses now tells us how many classes we have (but it might change)
         // So we can allocate our buffer, and get pointers to all the class definitions.
-
-        NSUInteger bufferSize = numClasses;
-
-        classes = numClasses ? (Class *)malloc(sizeof(Class) * bufferSize) : NULL;
+        __auto_type bufferSize = numClasses;
+        classes = numClasses ? (Class *)calloc(bufferSize, sizeof(Class)) : NULL;
         if (classes == NULL) {
-            return @[]; //no memory or classes?
+            return @[]; // no memory or classes?
         }
 
         numClasses = (NSUInteger)MAX(objc_getClassList(classes, (int)bufferSize),0);
-
         if (numClasses > bufferSize || numClasses == 0) {
-            //apparently more classes added between calls (or a problem); try again
+            // apparently more classes added between calls (or a problem); try again
             free(classes);
+            classes = NULL;
             numClasses = 0;
         }
     }
 
     // We can now loop through the classes, and test each one to see if it is a AWSDDLogging class.
-
-    NSMutableArray *result = [NSMutableArray arrayWithCapacity:numClasses];
-
+    __auto_type result = [NSMutableArray arrayWithCapacity:numClasses];
     for (NSUInteger i = 0; i < numClasses; i++) {
+        // Cannot use `__auto_type` here, since this will lead to crashes when deallocating!
         Class class = classes[i];
 
         if ([self isRegisteredClass:class]) {
@@ -657,8 +579,8 @@ + (NSArray *)registeredClasses {
 }
 
 + (NSArray *)registeredClassNames {
-    NSArray *registeredClasses = [self registeredClasses];
-    NSMutableArray *result = [NSMutableArray arrayWithCapacity:[registeredClasses count]];
+    __auto_type registeredClasses = [self registeredClasses];
+    __auto_type result = [NSMutableArray arrayWithCapacity:[registeredClasses count]];
 
     for (Class class in registeredClasses) {
         [result addObject:NSStringFromClass(class)];
@@ -674,9 +596,9 @@ + (AWSDDLogLevel)levelForClass:(Class)aClass {
 }
 
 + (AWSDDLogLevel)levelForClassWithName:(NSString *)aClassName {
-    Class aClass = NSClassFromString(aClassName);
-
-    return [self levelForClass:aClass];
+    Class clazz = NSClassFromString(aClassName);
+    if (clazz == nil) return (AWSDDLogLevel)-1;
+    return [self levelForClass:clazz];
 }
 
 + (void)setLevel:(AWSDDLogLevel)level forClass:(Class)aClass {
@@ -686,8 +608,9 @@ + (void)setLevel:(AWSDDLogLevel)level forClass:(Class)aClass {
 }
 
 + (void)setLevel:(AWSDDLogLevel)level forClassWithName:(NSString *)aClassName {
-    Class aClass = NSClassFromString(aClassName);
-    [self setLevel:level forClass:aClass];
+    Class clazz = NSClassFromString(aClassName);
+    if (clazz == nil) return;
+    [self setLevel:level forClass:clazz];
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -698,39 +621,34 @@ - (void)lt_addLogger:(id <AWSDDLogger>)logger level:(AWSDDLogLevel)level {
     // Add to loggers array.
     // Need to create loggerQueue if loggerNode doesn't provide one.
 
-    for (AWSDDLoggerNode* node in self._loggers) {
-        if (node->_logger == logger
-            && node->_level == level) {
+    for (AWSDDLoggerNode *node in self._loggers) {
+        if (node->_logger == logger && node->_level == level) {
             // Exactly same logger already added, exit
             return;
         }
     }
 
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
+    AWSDDLogAssertOnGlobalLoggingQueue();
 
     dispatch_queue_t loggerQueue = NULL;
-
     if ([logger respondsToSelector:@selector(loggerQueue)]) {
         // Logger may be providing its own queue
-
-        loggerQueue = [logger loggerQueue];
+        loggerQueue = logger.loggerQueue;
     }
 
     if (loggerQueue == nil) {
         // Automatically create queue for the logger.
         // Use the logger name as the queue name if possible.
-
         const char *loggerQueueName = NULL;
 
         if ([logger respondsToSelector:@selector(loggerName)]) {
-            loggerQueueName = [[logger loggerName] UTF8String];
+            loggerQueueName = logger.loggerName.UTF8String;
         }
 
         loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
     }
 
-    AWSDDLoggerNode *loggerNode = [AWSDDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level];
+    __auto_type loggerNode = [AWSDDLoggerNode nodeWithLogger:logger loggerQueue:loggerQueue level:level];
     [self._loggers addObject:loggerNode];
 
     if ([logger respondsToSelector:@selector(didAddLoggerInQueue:)]) {
@@ -747,8 +665,7 @@ - (void)lt_addLogger:(id <AWSDDLogger>)logger level:(AWSDDLogLevel)level {
 - (void)lt_removeLogger:(id <AWSDDLogger>)logger {
     // Find associated loggerNode in list of added loggers
 
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
+    AWSDDLogAssertOnGlobalLoggingQueue();
 
     AWSDDLoggerNode *loggerNode = nil;
 
@@ -758,27 +675,26 @@ - (void)lt_removeLogger:(id <AWSDDLogger>)logger {
             break;
         }
     }
-    
+
     if (loggerNode == nil) {
         NSLogDebug(@"AWSDDLog: Request to remove logger which wasn't added");
         return;
     }
-    
+
     // Notify logger
     if ([logger respondsToSelector:@selector(willRemoveLogger)]) {
         dispatch_async(loggerNode->_loggerQueue, ^{ @autoreleasepool {
             [logger willRemoveLogger];
         } });
     }
-    
+
     // Remove from loggers array
     [self._loggers removeObject:loggerNode];
 }
 
 - (void)lt_removeAllLoggers {
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
-    
+    AWSDDLogAssertOnGlobalLoggingQueue();
+
     // Notify all loggers
     for (AWSDDLoggerNode *loggerNode in self._loggers) {
         if ([loggerNode->_logger respondsToSelector:@selector(willRemoveLogger)]) {
@@ -787,19 +703,18 @@ - (void)lt_removeAllLoggers {
             } });
         }
     }
-    
-    // Remove all loggers from array
 
+    // Remove all loggers from array
     [self._loggers removeAllObjects];
 }
 
 - (NSArray *)lt_allLoggers {
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
+    AWSDDLogAssertOnGlobalLoggingQueue();
 
-    NSMutableArray *theLoggers = [NSMutableArray new];
+    __auto_type loggerNodes = self._loggers;
+    __auto_type theLoggers = [NSMutableArray arrayWithCapacity:loggerNodes.count];
 
-    for (AWSDDLoggerNode *loggerNode in self._loggers) {
+    for (AWSDDLoggerNode *loggerNode in loggerNodes) {
         [theLoggers addObject:loggerNode->_logger];
     }
 
@@ -807,24 +722,24 @@ - (NSArray *)lt_allLoggers {
 }
 
 - (NSArray *)lt_allLoggersWithLevel {
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
-    
-    NSMutableArray *theLoggersWithLevel = [NSMutableArray new];
-    
-    for (AWSDDLoggerNode *loggerNode in self._loggers) {
+    AWSDDLogAssertOnGlobalLoggingQueue();
+
+
+    __auto_type loggerNodes = self._loggers;
+    __auto_type theLoggersWithLevel = [NSMutableArray arrayWithCapacity:loggerNodes.count];
+
+    for (AWSDDLoggerNode *loggerNode in loggerNodes) {
         [theLoggersWithLevel addObject:[AWSDDLoggerInformation informationWithLogger:loggerNode->_logger
                                                                          andLevel:loggerNode->_level]];
     }
-    
+
     return [theLoggersWithLevel copy];
 }
 
 - (void)lt_log:(AWSDDLogMessage *)logMessage {
-    // Execute the given log message on each of our loggers.
+    AWSDDLogAssertOnGlobalLoggingQueue();
 
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
+    // Execute the given log message on each of our loggers.
 
     if (_numProcessors > 1) {
         // Execute each logger concurrently, each within its own queue.
@@ -840,55 +755,54 @@ - (void)lt_log:(AWSDDLogMessage *)logMessage {
             if (!(logMessage->_flag & loggerNode->_level)) {
                 continue;
             }
-            
+
             dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool {
                 [loggerNode->_logger logMessage:logMessage];
             } });
         }
-        
+
         dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER);
     } else {
-        // Execute each logger serialy, each within its own queue.
-        
+        // Execute each logger serially, each within its own queue.
+
         for (AWSDDLoggerNode *loggerNode in self._loggers) {
             // skip the loggers that shouldn't write this message based on the log level
 
             if (!(logMessage->_flag & loggerNode->_level)) {
                 continue;
             }
-            
+
+#if AWSDD_DEBUG
+            // we must assure that we aren not on loggerNode->_loggerQueue.
+            if (loggerNode->_loggerQueue == NULL) {
+              // tell that we can't dispatch logger node on queue that is NULL.
+              NSLogDebug(@"AWSDDLog: current node has loggerQueue == NULL");
+            }
+            else {
+              dispatch_async(loggerNode->_loggerQueue, ^{
+                if (dispatch_get_specific(GlobalLoggingQueueIdentityKey)) {
+                  // tell that we somehow on logging queue?
+                  NSLogDebug(@"AWSDDLog: current node has loggerQueue == globalLoggingQueue");
+                }
+              });
+            }
+#endif
+            // next, we must check that node is OK.
             dispatch_sync(loggerNode->_loggerQueue, ^{ @autoreleasepool {
                 [loggerNode->_logger logMessage:logMessage];
             } });
         }
     }
-
-    // If our queue got too big, there may be blocked threads waiting to add log messages to the queue.
-    // Since we've now dequeued an item from the log, we may need to unblock the next thread.
-
-    // We are using a counting semaphore provided by GCD.
-    // The semaphore is initialized with our AWSDDLOG_MAX_QUEUE_SIZE value.
-    // When a log message is queued this value is decremented.
-    // When a log message is dequeued this value is incremented.
-    // If the value ever drops below zero,
-    // the queueing thread blocks and waits in FIFO order for us to signal it.
-    //
-    // A dispatch semaphore is an efficient implementation of a traditional counting semaphore.
-    // Dispatch semaphores call down to the kernel only when the calling thread needs to be blocked.
-    // If the calling semaphore does not need to block, no kernel call is made.
-
-    dispatch_semaphore_signal(_queueSemaphore);
 }
 
 - (void)lt_flush {
     // All log statements issued before the flush method was invoked have now been executed.
     //
-    // Now we need to propogate the flush request to any loggers that implement the flush method.
+    // Now we need to propagate the flush request to any loggers that implement the flush method.
     // This is designed for loggers that buffer IO.
-    
-    NSAssert(dispatch_get_specific(GlobalLoggingQueueIdentityKey),
-             @"This method should only be run on the logging thread/queue");
-    
+
+    AWSDDLogAssertOnGlobalLoggingQueue();
+
     for (AWSDDLoggerNode *loggerNode in self._loggers) {
         if ([loggerNode->_logger respondsToSelector:@selector(flush)]) {
             dispatch_group_async(_loggingGroup, loggerNode->_loggerQueue, ^{ @autoreleasepool {
@@ -896,7 +810,7 @@ - (void)lt_flush {
             } });
         }
     }
-    
+
     dispatch_group_wait(_loggingGroup, DISPATCH_TIME_FOREVER);
 }
 
@@ -912,8 +826,7 @@ - (void)lt_flush {
     char *lastSlash = NULL;
     char *lastDot = NULL;
 
-    char *p = (char *)filePath;
-
+    __auto_type p = (char *)filePath;
     while (*p != '\0') {
         if (*p == '/') {
             lastSlash = p;
@@ -979,9 +892,9 @@ - (instancetype)initWithLogger:(id <AWSDDLogger>)logger loggerQueue:(dispatch_qu
 
         if (loggerQueue) {
             _loggerQueue = loggerQueue;
-            #if !OS_OBJECT_USE_OBJC
+#if !OS_OBJECT_USE_OBJC
             dispatch_retain(loggerQueue);
-            #endif
+#endif
         }
 
         _level = level;
@@ -989,16 +902,16 @@ - (instancetype)initWithLogger:(id <AWSDDLogger>)logger loggerQueue:(dispatch_qu
     return self;
 }
 
-+ (AWSDDLoggerNode *)nodeWithLogger:(id <AWSDDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue level:(AWSDDLogLevel)level {
-    return [[AWSDDLoggerNode alloc] initWithLogger:logger loggerQueue:loggerQueue level:level];
++ (instancetype)nodeWithLogger:(id <AWSDDLogger>)logger loggerQueue:(dispatch_queue_t)loggerQueue level:(AWSDDLogLevel)level {
+    return [[self alloc] initWithLogger:logger loggerQueue:loggerQueue level:level];
 }
 
 - (void)dealloc {
-    #if !OS_OBJECT_USE_OBJC
+#if !OS_OBJECT_USE_OBJC
     if (_loggerQueue) {
         dispatch_release(_loggerQueue);
     }
-    #endif
+#endif
 }
 
 @end
@@ -1009,116 +922,97 @@ - (void)dealloc {
 
 @implementation AWSDDLogMessage
 
-// Can we use DISPATCH_CURRENT_QUEUE_LABEL ?
-// Can we use dispatch_get_current_queue (without it crashing) ?
-//
-// a) Compiling against newer SDK's (iOS 7+/OS X 10.9+) where DISPATCH_CURRENT_QUEUE_LABEL is defined
-//    on a (iOS 7.0+/OS X 10.9+) runtime version
-//
-// b) Systems where dispatch_get_current_queue is not yet deprecated and won't crash (< iOS 6.0/OS X 10.9)
-//
-//    dispatch_get_current_queue(void);
-//      __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_6,__MAC_10_9,__IPHONE_4_0,__IPHONE_6_0)
-
-#if TARGET_OS_IOS
-
-// Compiling for iOS
-
-static BOOL _use_dispatch_current_queue_label;
-static BOOL _use_dispatch_get_current_queue;
-
-static void _dispatch_queue_label_init_once(void * __attribute__((unused)) context)
-{
-    _use_dispatch_current_queue_label = (UIDevice.currentDevice.systemVersion.floatValue >= 7.0f);
-    _use_dispatch_get_current_queue = (!_use_dispatch_current_queue_label && UIDevice.currentDevice.systemVersion.floatValue >= 6.1f);
-}
-
-static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_init()
-{
-    static dispatch_once_t onceToken;
-    dispatch_once_f(&onceToken, NULL, _dispatch_queue_label_init_once);
+- (instancetype)init {
+    self = [super init];
+    return self;
 }
 
-  #define USE_DISPATCH_CURRENT_QUEUE_LABEL (_dispatch_queue_label_init(), _use_dispatch_current_queue_label)
-  #define USE_DISPATCH_GET_CURRENT_QUEUE   (_dispatch_queue_label_init(), _use_dispatch_get_current_queue)
-
-#elif TARGET_OS_WATCH || TARGET_OS_TV
-
-// Compiling for watchOS, tvOS
+- (instancetype)initWithFormat:(NSString *)messageFormat
+                     formatted:(NSString *)message
+                         level:(AWSDDLogLevel)level
+                          flag:(AWSDDLogFlag)flag
+                       context:(NSInteger)context
+                          file:(NSString *)file
+                      function:(NSString *)function
+                          line:(NSUInteger)line
+                           tag:(id)tag
+                       options:(AWSDDLogMessageOptions)options
+                     timestamp:(NSDate *)timestamp {
+    NSParameterAssert(messageFormat);
+    NSParameterAssert(message);
+    NSParameterAssert(file);
 
-  #define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
-  #define USE_DISPATCH_GET_CURRENT_QUEUE   NO
-
-#else
-
-// Compiling for Mac OS X
-
-  #ifndef MAC_OS_X_VERSION_10_9
-    #define MAC_OS_X_VERSION_10_9            1090
-  #endif
-
-  #if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_9 // Mac OS X 10.9 or later required
+    if ((self = [super init])) {
+        __auto_type copyMessage = (options & AWSDDLogMessageDontCopyMessage) == 0;
+        _messageFormat = copyMessage ? [messageFormat copy] : messageFormat;
+        _message       = copyMessage ? [message copy] : message;
+        _level         = level;
+        _flag          = flag;
+        _context       = context;
+
+        __auto_type copyFile = (options & AWSDDLogMessageCopyFile) != 0;
+        _file = copyFile ? [file copy] : file;
 
-    #define USE_DISPATCH_CURRENT_QUEUE_LABEL YES
-    #define USE_DISPATCH_GET_CURRENT_QUEUE   NO
+        __auto_type copyFunction = (options & AWSDDLogMessageCopyFunction) != 0;
+        _function = copyFunction ? [function copy] : function;
 
-  #else
+        _line         = line;
+        _representedObject = tag;
+#if AWSDD_LEGACY_MESSAGE_TAG
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+        _tag = tag;
+#pragma clang diagnostic pop
+#endif
+        _options      = options;
+        _timestamp    = timestamp ?: [NSDate date];
 
-static BOOL _use_dispatch_current_queue_label;
-static BOOL _use_dispatch_get_current_queue;
+        __uint64_t tid;
+        if (pthread_threadid_np(NULL, &tid) == 0) {
+            _threadID = [[NSString alloc] initWithFormat:@"%llu", tid];
+        } else {
+            _threadID = @"N/A";
+        }
+        _threadName   = NSThread.currentThread.name;
 
-static void _dispatch_queue_label_init_once(void * __attribute__((unused)) context)
-{
-    _use_dispatch_current_queue_label = [NSTimer instancesRespondToSelector : @selector(tolerance)]; // OS X 10.9+
-    _use_dispatch_get_current_queue = !_use_dispatch_current_queue_label;                            // < OS X 10.9
-}
+        // Get the file name without extension
+        _fileName = [_file lastPathComponent];
+        __auto_type dotLocation = [_fileName rangeOfString:@"." options:NSBackwardsSearch].location;
+        if (dotLocation != NSNotFound) {
+            _fileName = [_fileName substringToIndex:dotLocation];
+        }
 
-static __inline__ __attribute__((__always_inline__)) void _dispatch_queue_label_init()
-{
-    static dispatch_once_t onceToken;
-    dispatch_once_f(&onceToken, NULL, _dispatch_queue_label_init_once);
+        // Try to get the current queue's label
+        _queueLabel = @(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL));
+        _qos = (NSUInteger) qos_class_self();
+    }
+    return self;
 }
 
-    #define USE_DISPATCH_CURRENT_QUEUE_LABEL (_dispatch_queue_label_init(), _use_dispatch_current_queue_label)
-    #define USE_DISPATCH_GET_CURRENT_QUEUE   (_dispatch_queue_label_init(), _use_dispatch_get_current_queue)
-
-  #endif
-
-#endif /* if TARGET_OS_IOS */
-
-// Should we use pthread_threadid_np ?
-// With iOS 8+/OSX 10.10+ NSLog uses pthread_threadid_np instead of pthread_mach_thread_np
-
-#if TARGET_OS_IOS
-
-// Compiling for iOS
-
-  #ifndef kCFCoreFoundationVersionNumber_iOS_8_0
-    #define kCFCoreFoundationVersionNumber_iOS_8_0 1140.10
-  #endif
-
-  #define USE_PTHREAD_THREADID_NP                (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber_iOS_8_0)
-
-#elif TARGET_OS_WATCH || TARGET_OS_TV
-
-// Compiling for watchOS, tvOS
-
-  #define USE_PTHREAD_THREADID_NP                YES
-
-#else
-
-// Compiling for Mac OS X
-
-  #ifndef kCFCoreFoundationVersionNumber10_10
-    #define kCFCoreFoundationVersionNumber10_10    1151.16
-  #endif
-
-  #define USE_PTHREAD_THREADID_NP                (kCFCoreFoundationVersionNumber >= kCFCoreFoundationVersionNumber10_10)
-
-#endif /* if TARGET_OS_IOS */
-
-- (instancetype)init {
-    self = [super init];
+- (instancetype)initWithFormat:(NSString *)messageFormat
+                          args:(va_list)messageArgs
+                         level:(AWSDDLogLevel)level
+                          flag:(AWSDDLogFlag)flag
+                       context:(NSInteger)context
+                          file:(NSString *)file
+                      function:(NSString *)function
+                          line:(NSUInteger)line
+                           tag:(id)tag
+                       options:(AWSDDLogMessageOptions)options
+                     timestamp:(NSDate *)timestamp {
+    __auto_type copyMessage = (options & AWSDDLogMessageDontCopyMessage) == 0;
+    NSString *format = copyMessage ? [messageFormat copy] : messageFormat;
+    self = [self initWithFormat:format
+                      formatted:[[NSString alloc] initWithFormat:format arguments:messageArgs]
+                          level:level
+                           flag:flag
+                        context:context
+                           file:file
+                       function:function
+                           line:line
+                            tag:tag
+                        options:options | AWSDDLogMessageDontCopyMessage // we already did the copying if needed.
+                      timestamp:timestamp];
     return self;
 }
 
@@ -1132,60 +1026,79 @@ - (instancetype)initWithMessage:(NSString *)message
                             tag:(id)tag
                         options:(AWSDDLogMessageOptions)options
                       timestamp:(NSDate *)timestamp {
-    if ((self = [super init])) {
-        BOOL copyMessage = (options & AWSDDLogMessageDontCopyMessage) == 0;
-        _message      = copyMessage ? [message copy] : message;
-        _level        = level;
-        _flag         = flag;
-        _context      = context;
-
-        BOOL copyFile = (options & AWSDDLogMessageCopyFile) != 0;
-        _file = copyFile ? [file copy] : file;
-
-        BOOL copyFunction = (options & AWSDDLogMessageCopyFunction) != 0;
-        _function = copyFunction ? [function copy] : function;
-
-        _line         = line;
-        _tag          = tag;
-        _options      = options;
-        _timestamp    = timestamp ?: [NSDate new];
+    self = [self initWithFormat:message
+                      formatted:message
+                          level:level
+                           flag:flag
+                        context:context
+                           file:file
+                       function:function
+                           line:line
+                            tag:tag
+                        options:options
+                      timestamp:timestamp];
+    return self;
+}
 
-        if (USE_PTHREAD_THREADID_NP) {
-            __uint64_t tid;
-            pthread_threadid_np(NULL, &tid);
-            _threadID = [[NSString alloc] initWithFormat:@"%llu", tid];
-        } else {
-            _threadID = [[NSString alloc] initWithFormat:@"%x", pthread_mach_thread_np(pthread_self())];
+NS_INLINE BOOL _nullable_strings_equal(NSString* _Nullable lhs, NSString* _Nullable rhs)
+{
+    if (lhs == nil) {
+        if (rhs == nil) {
+            return YES;
         }
-        _threadName   = NSThread.currentThread.name;
+    } else if (rhs != nil && [lhs isEqualToString:(NSString* _Nonnull)rhs]) {
+        return YES;
+    }
+    return NO;
+}
 
-        // Get the file name without extension
-        _fileName = [_file lastPathComponent];
-        NSUInteger dotLocation = [_fileName rangeOfString:@"." options:NSBackwardsSearch].location;
-        if (dotLocation != NSNotFound)
-        {
-            _fileName = [_fileName substringToIndex:dotLocation];
-        }
-        
-        // Try to get the current queue's label
-        if (USE_DISPATCH_CURRENT_QUEUE_LABEL) {
-            _queueLabel = [[NSString alloc] initWithFormat:@"%s", dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL)];
-        } else if (USE_DISPATCH_GET_CURRENT_QUEUE) {
-            #pragma clang diagnostic push
-            #pragma clang diagnostic ignored "-Wdeprecated-declarations"
-            dispatch_queue_t currentQueue = dispatch_get_current_queue();
-            #pragma clang diagnostic pop
-            _queueLabel = [[NSString alloc] initWithFormat:@"%s", dispatch_queue_get_label(currentQueue)];
-        } else {
-            _queueLabel = @""; // iOS 6.x only
-        }
+- (BOOL)isEqual:(id)other {
+    // Subclasses of NSObject should not call [super isEqual:] here.
+    // See https://stackoverflow.com/questions/36593038/confused-about-the-default-isequal-and-hash-implements
+    if (other == self) {
+        return YES;
+    } else if (!other || ![other isKindOfClass:[AWSDDLogMessage class]]) {
+        return NO;
+    } else {
+        __auto_type otherMsg = (AWSDDLogMessage *)other;
+        return [otherMsg->_message isEqualToString:_message]
+        && [otherMsg->_messageFormat isEqualToString:_messageFormat]
+        && otherMsg->_level == _level
+        && otherMsg->_flag == _flag
+        && otherMsg->_context == _context
+        && [otherMsg->_file isEqualToString:_file]
+        && _nullable_strings_equal(otherMsg->_function, _function)
+        && otherMsg->_line == _line
+        && (([otherMsg->_representedObject respondsToSelector:@selector(isEqual:)] && [otherMsg->_representedObject isEqual:_representedObject]) || otherMsg->_representedObject == _representedObject)
+        && [otherMsg->_timestamp isEqualToDate:_timestamp]
+        && [otherMsg->_threadID isEqualToString:_threadID] // If the thread ID is the same, the name will likely be the same as well.
+        && [otherMsg->_queueLabel isEqualToString:_queueLabel]
+        && otherMsg->_qos == _qos;
     }
-    return self;
+}
+
+- (NSUInteger)hash {
+    // Subclasses of NSObject should not call [super hash] here.
+    // See https://stackoverflow.com/questions/36593038/confused-about-the-default-isequal-and-hash-implements
+    return _message.hash
+    ^ _messageFormat.hash
+    ^ _level
+    ^ _flag
+    ^ _context
+    ^ _file.hash
+    ^ _function.hash
+    ^ _line
+    ^ ([_representedObject respondsToSelector:@selector(hash)] ? [_representedObject hash] : (NSUInteger)_representedObject)
+    ^ _timestamp.hash
+    ^ _threadID.hash
+    ^ _queueLabel.hash
+    ^ _qos;
 }
 
 - (id)copyWithZone:(NSZone * __attribute__((unused)))zone {
     AWSDDLogMessage *newMessage = [AWSDDLogMessage new];
-    
+
+    newMessage->_messageFormat = _messageFormat;
     newMessage->_message = _message;
     newMessage->_level = _level;
     newMessage->_flag = _flag;
@@ -1194,16 +1107,28 @@ - (id)copyWithZone:(NSZone * __attribute__((unused)))zone {
     newMessage->_fileName = _fileName;
     newMessage->_function = _function;
     newMessage->_line = _line;
+    newMessage->_representedObject = _representedObject;
+#if AWSDD_LEGACY_MESSAGE_TAG
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
     newMessage->_tag = _tag;
+#pragma clang diagnostic pop
+#endif
     newMessage->_options = _options;
     newMessage->_timestamp = _timestamp;
     newMessage->_threadID = _threadID;
     newMessage->_threadName = _threadName;
     newMessage->_queueLabel = _queueLabel;
+    newMessage->_qos = _qos;
 
     return newMessage;
 }
 
+// ensure compatibility even when built with AWSDD_LEGACY_MESSAGE_TAG to 0.
+- (id)tag {
+    return _representedObject;
+}
+
 @end
 
 
@@ -1218,7 +1143,7 @@ - (instancetype)init {
         const char *loggerQueueName = NULL;
 
         if ([self respondsToSelector:@selector(loggerName)]) {
-            loggerQueueName = [[self loggerName] UTF8String];
+            loggerQueueName = self.loggerName.UTF8String;
         }
 
         _loggerQueue = dispatch_queue_create(loggerQueueName, NULL);
@@ -1237,8 +1162,8 @@ - (instancetype)init {
         //
         // This is used primarily for thread-safety assertions (via the isOnInternalLoggerQueue method below).
 
-        void *key = (__bridge void *)self;
-        void *nonNullValue = (__bridge void *)self;
+        __auto_type key = (__bridge void *)self;
+        __auto_type nonNullValue = (__bridge void *)self;
 
         dispatch_queue_set_specific(_loggerQueue, key, nonNullValue, NULL);
     }
@@ -1247,13 +1172,11 @@ - (instancetype)init {
 }
 
 - (void)dealloc {
-    #if !OS_OBJECT_USE_OBJC
-
+#if !OS_OBJECT_USE_OBJC
     if (_loggerQueue) {
         dispatch_release(_loggerQueue);
     }
-
-    #endif
+#endif
 }
 
 - (void)logMessage:(AWSDDLogMessage * __attribute__((unused)))logMessage {
@@ -1298,7 +1221,7 @@ - (void)logMessage:(AWSDDLogMessage * __attribute__((unused)))logMessage {
     //
     // globalLoggingQueue : The queue that all log messages go through before they arrive in our loggerQueue.
     //
-    // All log statements go through the serial gloabalLoggingQueue before they arrive at our loggerQueue.
+    // All log statements go through the serial globalLoggingQueue before they arrive at our loggerQueue.
     // Thus this method also goes through the serial globalLoggingQueue to ensure intuitive operation.
 
     // IMPORTANT NOTE:
@@ -1310,14 +1233,10 @@ - (void)logMessage:(AWSDDLogMessage * __attribute__((unused)))logMessage {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
     __block id <AWSDDLogFormatter> result;
-
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self->_loggerQueue, ^{
             result = self->_logFormatter;
         });
@@ -1329,10 +1248,9 @@ - (void)logMessage:(AWSDDLogMessage * __attribute__((unused)))logMessage {
 - (void)setLogFormatter:(id <AWSDDLogFormatter>)logFormatter {
     // The design of this method is documented extensively in the logFormatter message (above in code).
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             if (self->_logFormatter != logFormatter) {
                 if ([self->_logFormatter respondsToSelector:@selector(willRemoveFromLogger:)]) {
@@ -1340,7 +1258,7 @@ - (void)setLogFormatter:(id <AWSDDLogFormatter>)logFormatter {
                 }
 
                 self->_logFormatter = logFormatter;
- 
+
                 if ([self->_logFormatter respondsToSelector:@selector(didAddToLogger:inQueue:)]) {
                     [self->_logFormatter didAddToLogger:self inQueue:self->_loggerQueue];
                 } else if ([self->_logFormatter respondsToSelector:@selector(didAddToLogger:)]) {
@@ -1350,9 +1268,7 @@ - (void)setLogFormatter:(id <AWSDDLogFormatter>)logFormatter {
         }
     };
 
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-
-    dispatch_async(globalLoggingQueue, ^{
+    dispatch_async(AWSDDLog.loggingQueue, ^{
         dispatch_async(self->_loggerQueue, block);
     });
 }
@@ -1370,9 +1286,7 @@ - (BOOL)isOnGlobalLoggingQueue {
 }
 
 - (BOOL)isOnInternalLoggerQueue {
-    void *key = (__bridge void *)self;
-
-    return (dispatch_get_specific(key) != NULL);
+    return dispatch_get_specific((__bridge void *)self) != NULL;
 }
 
 @end
@@ -1401,8 +1315,8 @@ - (instancetype)initWithLogger:(id <AWSDDLogger>)logger andLevel:(AWSDDLogLevel)
     return self;
 }
 
-+ (AWSDDLoggerInformation *)informationWithLogger:(id <AWSDDLogger>)logger andLevel:(AWSDDLogLevel)level {
-    return [[AWSDDLoggerInformation alloc] initWithLogger:logger andLevel:level];
++ (instancetype)informationWithLogger:(id <AWSDDLogger>)logger andLevel:(AWSDDLogLevel)level {
+    return [[self alloc] initWithLogger:logger andLevel:level];
 }
 
 @end
diff --git a/AWSCore/Logging/AWSDDLogMacros.h b/AWSCore/Logging/AWSDDLogMacros.h
index 1b035453b44..521db77987f 100644
--- a/AWSCore/Logging/AWSDDLogMacros.h
+++ b/AWSCore/Logging/AWSDDLogMacros.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -20,6 +20,13 @@
 
 #import "AWSDDLog.h"
 
+/**
+ * The constant/variable/method responsible for controlling the current log level.
+ **/
+#ifndef LOG_LEVEL_DEF
+    #define LOG_LEVEL_DEF [AWSDDLog sharedInstance].logLevel
+#endif
+
 /**
  * Whether async should be used by log messages, excluding error messages that are always sent sync.
  **/
@@ -73,22 +80,22 @@
  * We also define shorthand versions for asynchronous and synchronous logging.
  **/
 #define AWSDD_LOG_MAYBE(async, lvl, flg, ctx, tag, fnct, frmt, ...) \
-        do { AWSDD_LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
+        do { if(((NSUInteger)lvl & (NSUInteger)flg) != 0) AWSDD_LOG_MACRO(async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
 
 #define LOG_MAYBE_TO_AWSDDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ...) \
-        do { LOG_MACRO_TO_AWSDDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
+        do { if(((NSUInteger)lvl & (NSUInteger)flg) != 0) LOG_MACRO_TO_AWSDDLOG(ddlog, async, lvl, flg, ctx, tag, fnct, frmt, ##__VA_ARGS__); } while(0)
 
 /**
  * Ready to use log macros with no context or tag.
  **/
-#define AWSDDLogError(frmt, ...)   AWSDD_LOG_MAYBE(NO,                [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagError,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogWarn(frmt, ...)    AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogInfo(frmt, ...)    AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagInfo,    0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogDebug(frmt, ...)   AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagDebug,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogVerbose(frmt, ...) AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogError(frmt, ...)   AWSDD_LOG_MAYBE(NO,                      LOG_LEVEL_DEF, AWSDDLogFlagError,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogWarn(frmt, ...)    AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogInfo(frmt, ...)    AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagInfo,    0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogDebug(frmt, ...)   AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagDebug,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogVerbose(frmt, ...) AWSDD_LOG_MAYBE(AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
 
-#define AWSDDLogErrorToAWSDDLog(ddlog, frmt, ...)   LOG_MAYBE_TO_AWSDDLOG(ddlog, NO,                [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagError,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogWarnToAWSDDLog(ddlog, frmt, ...)    LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogInfoToAWSDDLog(ddlog, frmt, ...)    LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagInfo,    0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogDebugToAWSDDLog(ddlog, frmt, ...)   LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagDebug,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
-#define AWSDDLogVerboseToAWSDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, [AWSDDLog sharedInstance].logLevel, AWSDDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogErrorToAWSDDLog(ddlog, frmt, ...)   LOG_MAYBE_TO_AWSDDLOG(ddlog, NO,                      LOG_LEVEL_DEF, AWSDDLogFlagError,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogWarnToAWSDDLog(ddlog, frmt, ...)    LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagWarning, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogInfoToAWSDDLog(ddlog, frmt, ...)    LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagInfo,    0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogDebugToAWSDDLog(ddlog, frmt, ...)   LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagDebug,   0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
+#define AWSDDLogVerboseToAWSDDLog(ddlog, frmt, ...) LOG_MAYBE_TO_AWSDDLOG(ddlog, AWSDD_LOG_ASYNC_ENABLED, LOG_LEVEL_DEF, AWSDDLogFlagVerbose, 0, nil, __PRETTY_FUNCTION__, frmt, ##__VA_ARGS__)
diff --git a/AWSCore/Logging/AWSDDLoggerNames.h b/AWSCore/Logging/AWSDDLoggerNames.h
new file mode 100644
index 00000000000..d26e42862c8
--- /dev/null
+++ b/AWSCore/Logging/AWSDDLoggerNames.h
@@ -0,0 +1,30 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+typedef NSString *AWSDDLoggerName NS_EXTENSIBLE_STRING_ENUM;
+
+FOUNDATION_EXPORT AWSDDLoggerName const AWSDDLoggerNameOS NS_SWIFT_NAME(AWSDDLoggerName.os);     // AWSDDOSLogger
+FOUNDATION_EXPORT AWSDDLoggerName const AWSDDLoggerNameFile NS_SWIFT_NAME(AWSDDLoggerName.file); // AWSDDFileLogger
+
+FOUNDATION_EXPORT AWSDDLoggerName const AWSDDLoggerNameTTY NS_SWIFT_NAME(AWSDDLoggerName.tty);   // AWSDDTTYLogger
+
+API_DEPRECATED("Use AWSDDOSLogger instead", macosx(10.4, 10.12), ios(2.0, 10.0), watchos(2.0, 3.0), tvos(9.0, 10.0))
+FOUNDATION_EXPORT AWSDDLoggerName const AWSDDLoggerNameASL NS_SWIFT_NAME(AWSDDLoggerName.asl);   // AWSDDASLLogger
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDLoggerNames.m b/AWSCore/Logging/AWSDDLoggerNames.m
new file mode 100644
index 00000000000..78ba52cb416
--- /dev/null
+++ b/AWSCore/Logging/AWSDDLoggerNames.m
@@ -0,0 +1,21 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import "AWSDDLoggerNames.h"
+
+AWSDDLoggerName const AWSDDLoggerNameASL    = @"cocoa.lumberjack.aslLogger";
+AWSDDLoggerName const AWSDDLoggerNameTTY    = @"cocoa.lumberjack.ttyLogger";
+AWSDDLoggerName const AWSDDLoggerNameOS     = @"cocoa.lumberjack.osLogger";
+AWSDDLoggerName const AWSDDLoggerNameFile   = @"cocoa.lumberjack.fileLogger";
diff --git a/AWSCore/Logging/AWSDDMultiFormatter.m b/AWSCore/Logging/AWSDDMultiFormatter.m
index e3909f67af0..a2f8d16191b 100644
--- a/AWSCore/Logging/AWSDDMultiFormatter.m
+++ b/AWSCore/Logging/AWSDDMultiFormatter.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,33 +13,11 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDMultiFormatter.h"
-
-
-#if TARGET_OS_IOS
-// Compiling for iOS
-#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 60000 // iOS 6.0 or later
-#define NEEDS_DISPATCH_RETAIN_RELEASE 0
-#else                                         // iOS 5.X or earlier
-#define NEEDS_DISPATCH_RETAIN_RELEASE 1
-#endif
-#elif TARGET_OS_WATCH || TARGET_OS_TV
-// Compiling for watchOS, tvOS
-#define NEEDS_DISPATCH_RETAIN_RELEASE 0
-#else
-// Compiling for Mac OS X
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1080     // Mac OS X 10.8 or later
-#define NEEDS_DISPATCH_RETAIN_RELEASE 0
-#else                                         // Mac OS X 10.7 or earlier
-#define NEEDS_DISPATCH_RETAIN_RELEASE 1
-#endif
-#endif
-
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import "AWSDDMultiFormatter.h"
 
 @interface AWSDDMultiFormatter () {
     dispatch_queue_t _queue;
@@ -57,32 +35,21 @@ - (instancetype)init {
     self = [super init];
 
     if (self) {
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 1070
         _queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", DISPATCH_QUEUE_CONCURRENT);
-#else
-        _queue = dispatch_queue_create("cocoa.lumberjack.multiformatter", NULL);
-#endif
         _formatters = [NSMutableArray new];
     }
 
     return self;
 }
 
-#if NEEDS_DISPATCH_RETAIN_RELEASE
-- (void)dealloc {
-    dispatch_release(_queue);
-}
-
-#endif
-
 #pragma mark Processing
 
 - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
-    __block NSString *line = logMessage->_message;
+    __block __auto_type line = logMessage->_message;
 
     dispatch_sync(_queue, ^{
         for (id<AWSDDLogFormatter> formatter in self->_formatters) {
-            AWSDDLogMessage *message = [self logMessageForLine:line originalMessage:logMessage];
+            __auto_type message = [self logMessageForLine:line originalMessage:logMessage];
             line = [formatter formatLogMessage:message];
 
             if (!line) {
@@ -96,7 +63,6 @@ - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
 
 - (AWSDDLogMessage *)logMessageForLine:(NSString *)line originalMessage:(AWSDDLogMessage *)message {
     AWSDDLogMessage *newMessage = [message copy];
-
     newMessage->_message = line;
     return newMessage;
 }
diff --git a/AWSCore/Logging/AWSDDOSLogger.h b/AWSCore/Logging/AWSDDOSLogger.h
index e93d817d65c..0a51d9661ce 100644
--- a/AWSCore/Logging/AWSDDOSLogger.h
+++ b/AWSCore/Logging/AWSDDOSLogger.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -16,23 +16,41 @@
 #import <Foundation/Foundation.h>
 
 // Disable legacy macros
-#ifndef DD_LEGACY_MACROS
-    #define DD_LEGACY_MACROS 0
+#ifndef AWSDD_LEGACY_MACROS
+    #define AWSDD_LEGACY_MACROS 0
 #endif
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  * This class provides a logger for the Apple os_log facility.
  **/
-API_AVAILABLE(ios(10.0), macos(10.12), tvos(10.0), watchos(3.0))
+API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
+AWSDD_SENDABLE
 @interface AWSDDOSLogger : AWSDDAbstractLogger <AWSDDLogger>
 
 /**
  *  Singleton method
  *
- *  @return the shared instance
+ *  @return the shared instance with OS_LOG_DEFAULT.
  */
-@property (class, readonly, strong) AWSDDOSLogger *sharedInstance;
+@property (nonatomic, class, readonly, strong) AWSDDOSLogger *sharedInstance;
+
+/**
+ Designated initializer
+ 
+ @param subsystem Desired subsystem in log. E.g. "org.example"
+ @param category Desired category in log. E.g. "Point of interests."
+ @return New instance of AWSDDOSLogger.
+ 
+ @discussion This method requires either both or no parameter to be set. Much like `(String, String)?` in Swift.
+ If both parameters are nil, this method will return a logger configured with `OS_LOG_DEFAULT`.
+ If both parameters are non-nil, it will return a logger configured with `os_log_create(subsystem, category)`
+ */
+- (instancetype)initWithSubsystem:(nullable NSString *)subsystem category:(nullable NSString *)category NS_DESIGNATED_INITIALIZER;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDOSLogger.m b/AWSCore/Logging/AWSDDOSLogger.m
index 0f3a3a6a9ea..864ca807c5b 100644
--- a/AWSCore/Logging/AWSDDOSLogger.m
+++ b/AWSCore/Logging/AWSDDOSLogger.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,13 +13,48 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDOSLogger.h"
 #import <os/log.h>
 
+#import "AWSDDOSLogger.h"
+
+@interface AWSDDOSLogger () {
+    NSString *_subsystem;
+    NSString *_category;
+}
+
+@property (copy, nonatomic, readonly, nullable) NSString *subsystem;
+@property (copy, nonatomic, readonly, nullable) NSString *category;
+@property (strong, nonatomic, readwrite, nonnull) os_log_t logger;
+
+@end
+
 @implementation AWSDDOSLogger
 
+@synthesize subsystem = _subsystem;
+@synthesize category = _category;
+
+#pragma mark - Initialization
+
+/**
+ * Assertion
+ * Swift: (String, String)?
+ */
+- (instancetype)initWithSubsystem:(NSString *)subsystem category:(NSString *)category {
+    NSAssert((subsystem == nil) == (category == nil), @"Either both subsystem and category or neither should be nil.");
+    if (self = [super init]) {
+        _subsystem = [subsystem copy];
+        _category = [category copy];
+    }
+    return self;
+}
+
+API_AVAILABLE(macos(10.12), ios(10.0), watchos(3.0), tvos(10.0))
 static AWSDDOSLogger *sharedInstance;
 
+- (instancetype)init {
+    return [self initWithSubsystem:nil category:nil];
+}
+
 + (instancetype)sharedInstance {
     static dispatch_once_t AWSDDOSLoggerOnceToken;
 
@@ -30,16 +65,26 @@ + (instancetype)sharedInstance {
     return sharedInstance;
 }
 
-- (instancetype)init {
-    if (sharedInstance != nil) {
-        return nil;
+#pragma mark - os_log
+
+- (os_log_t)getLogger {
+    if (self.subsystem == nil || self.category == nil) {
+        return OS_LOG_DEFAULT;
     }
+    return os_log_create(self.subsystem.UTF8String, self.category.UTF8String);
+}
 
-    if (self = [super init]) {
-        return self;
+- (os_log_t)logger {
+    if (_logger == nil)  {
+        _logger = [self getLogger];
     }
+    return _logger;
+}
+
+#pragma mark - AWSDDLogger
 
-    return nil;
+- (AWSDDLoggerName)loggerName {
+    return AWSDDLoggerNameOS;
 }
 
 - (void)logMessage:(AWSDDLogMessage *)logMessage {
@@ -47,31 +92,28 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
     if ([logMessage->_fileName isEqualToString:@"AWSDDASLLogCapture"]) {
         return;
     }
-    
-    NSString * message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
-    
-    if (message) {
-        const char *msg = [message UTF8String];
-        
-        switch (logMessage->_flag) {
-            case AWSDDLogFlagError     :
-                os_log_error(OS_LOG_DEFAULT, "%{public}s", msg);
-                break;
-            case AWSDDLogFlagWarning   :
-            case AWSDDLogFlagInfo      :
-                os_log_info(OS_LOG_DEFAULT, "%{public}s", msg);
-                break;
-            case AWSDDLogFlagDebug     :
-            case AWSDDLogFlagVerbose   :
-            default                 :
-                os_log_debug(OS_LOG_DEFAULT, "%{public}s", msg);
-                break;
+
+    if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
+        __auto_type message = _logFormatter ? [_logFormatter formatLogMessage:logMessage] : logMessage->_message;
+        if (message != nil) {
+            __auto_type msg = [message UTF8String];
+            __auto_type logger = [self logger];
+            switch (logMessage->_flag) {
+                case AWSDDLogFlagError  :
+                    os_log_error(logger, "%{public}s", msg);
+                    break;
+                case AWSDDLogFlagWarning:
+                case AWSDDLogFlagInfo   :
+                    os_log_info(logger, "%{public}s", msg);
+                    break;
+                case AWSDDLogFlagDebug  :
+                case AWSDDLogFlagVerbose:
+                default              :
+                    os_log_debug(logger, "%{public}s", msg);
+                    break;
+            }
         }
     }
 }
 
-- (NSString *)loggerName {
-    return @"cocoa.lumberjack.osLogger";
-}
-
 @end
diff --git a/AWSCore/Logging/AWSDDTTYLogger.h b/AWSCore/Logging/AWSDDTTYLogger.h
index b387e908462..90e88bd03a5 100644
--- a/AWSCore/Logging/AWSDDTTYLogger.h
+++ b/AWSCore/Logging/AWSDDTTYLogger.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -28,20 +28,21 @@
     // iOS or tvOS or watchOS
     #import <UIKit/UIColor.h>
     typedef UIColor AWSDDColor;
-    static inline AWSDDColor* AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
+    static inline AWSDDColor* _Nonnull AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithRed:(r/(CGFloat)255.0) green:(g/(CGFloat)255.0) blue:(b/(CGFloat)255.0) alpha:1.0];}
 #elif defined(AWSDD_CLI) || !__has_include(<AppKit/NSColor.h>)
     // OS X CLI
-    #import "CLIColor.h"
+    #import "AWSCLIColor.h"
     typedef CLIColor AWSDDColor;
-    static inline AWSDDColor* AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
+    static inline AWSDDColor* _Nonnull AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithCalibratedRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];}
 #else
     // OS X with AppKit
     #import <AppKit/NSColor.h>
     typedef NSColor AWSDDColor;
-    static inline AWSDDColor* AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithCalibratedRed:(r/255.0f) green:(g/255.0f) blue:(b/255.0f) alpha:1.0f];}
+    static inline AWSDDColor  * _Nonnull AWSDDMakeColor(CGFloat r, CGFloat g, CGFloat b) {return [AWSDDColor colorWithCalibratedRed:(r/255.0) green:(g/255.0) blue:(b/255.0) alpha:1.0];}
 #endif
 #pragma clang diagnostic pop
 
+NS_ASSUME_NONNULL_BEGIN
 
 /**
  * This class provides a logger for Terminal output or Xcode console output,
@@ -60,9 +61,9 @@
 @interface AWSDDTTYLogger : AWSDDAbstractLogger <AWSDDLogger>
 
 /**
- *  Singleton method
+ *  Singleton instance. Returns `nil` if the initialization of the AWSDDTTYLogger fails.
  */
-@property (class, readonly, strong) AWSDDTTYLogger *sharedInstance;
+@property (nonatomic, class, readonly, strong, nullable) AWSDDTTYLogger *sharedInstance;
 
 /* Inherited from the AWSDDLogger protocol:
  *
@@ -103,6 +104,11 @@
  **/
 @property (nonatomic, readwrite, assign) BOOL automaticallyAppendNewlineForCustomFormatters;
 
+/**
+ Using this initializer is not supported. Please use `AWSDDTTYLogger.sharedInstance`.
+ **/
+- (instancetype)init NS_UNAVAILABLE;
+
 /**
  * The default color set (foregroundColor, backgroundColor) is:
  *
@@ -125,7 +131,7 @@
  *
  * This method invokes setForegroundColor:backgroundColor:forFlag:context: and applies it to `LOG_CONTEXT_ALL`.
  **/
-- (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)bgColor forFlag:(AWSDDLogFlag)mask;
+- (void)setForegroundColor:(nullable AWSDDColor *)txtColor backgroundColor:(nullable AWSDDColor *)bgColor forFlag:(AWSDDLogFlag)mask;
 
 /**
  * Just like setForegroundColor:backgroundColor:flag, but allows you to specify a particular logging context.
@@ -133,12 +139,12 @@
  * A logging context is often used to identify log messages coming from a 3rd party framework,
  * although logging context's can be used for many different functions.
  *
- * Use LOG_CONTEXT_ALL to set the deafult color for all contexts that have no specific color set defined.
+ * Use LOG_CONTEXT_ALL to set the default color for all contexts that have no specific color set defined.
  *
  * Logging context's are explained in further detail here:
  * Documentation/CustomContext.md
  **/
-- (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)bgColor forFlag:(AWSDDLogFlag)mask context:(NSInteger)ctxt;
+- (void)setForegroundColor:(nullable AWSDDColor *)txtColor backgroundColor:(nullable AWSDDColor *)bgColor forFlag:(AWSDDLogFlag)mask context:(NSInteger)ctxt;
 
 /**
  * Similar to the methods above, but allows you to map AWSDDLogMessage->tag to a particular color profile.
@@ -147,14 +153,14 @@
  * static NSString *const PurpleTag = @"PurpleTag";
  *
  * #define AWSDDLogPurple(frmt, ...) LOG_OBJC_TAG_MACRO(NO, 0, 0, 0, PurpleTag, frmt, ##__VA_ARGS__)
- * 
+ *
  * And then where you configure CocoaLumberjack:
  *
  * purple = AWSDDMakeColor((64/255.0), (0/255.0), (128/255.0));
  *
  * or any UIColor/NSColor constructor.
  *
- * Note: For CLI OS X projects that don't link with AppKit use CLIColor objects instead
+ * Note: For CLI OS X projects that don't link with AppKit use AWSCLIColor objects instead
  *
  * [[AWSDDTTYLogger sharedInstance] setForegroundColor:purple backgroundColor:nil forTag:PurpleTag];
  * [AWSDDLog addLogger:[AWSDDTTYLogger sharedInstance]];
@@ -163,7 +169,7 @@
  *
  * AWSDDLogPurple(@"I'm a purple log message!");
  **/
-- (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)bgColor forTag:(id <NSCopying>)tag;
+- (void)setForegroundColor:(nullable AWSDDColor *)txtColor backgroundColor:(nullable AWSDDColor *)bgColor forTag:(id <NSCopying>)tag;
 
 /**
  * Clearing color profiles.
@@ -176,3 +182,5 @@
 - (void)clearAllColors;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/AWSDDTTYLogger.m b/AWSCore/Logging/AWSDDTTYLogger.m
index 09d08d78659..cbd5ff40c7a 100644
--- a/AWSCore/Logging/AWSDDTTYLogger.m
+++ b/AWSCore/Logging/AWSDDTTYLogger.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,15 +13,14 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDTTYLogger.h"
-
-#import <unistd.h>
-#import <sys/uio.h>
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import <sys/uio.h>
+
+#import "AWSDDTTYLogger.h"
+
 // We probably shouldn't be using AWSDDLog() statements within the AWSDDLog implementation.
 // But we still want to leave our log statements for any future debugging,
 // and to allow other developers to trace the implementation (which is a great learning tool).
@@ -79,19 +78,19 @@
 
 #define MAP_TO_TERMINAL_APP_COLORS 1
 
+typedef struct {
+    uint8_t r;
+    uint8_t g;
+    uint8_t b;
+} AWSDDRGBColor;
 
 @interface AWSDDTTYLoggerColorProfile : NSObject {
-    @public
+@public
     AWSDDLogFlag mask;
     NSInteger context;
 
-    uint8_t fg_r;
-    uint8_t fg_g;
-    uint8_t fg_b;
-
-    uint8_t bg_r;
-    uint8_t bg_g;
-    uint8_t bg_b;
+    AWSDDRGBColor fg;
+    AWSDDRGBColor bg;
 
     NSUInteger fgCodeIndex;
     NSString *fgCodeRaw;
@@ -109,23 +108,19 @@ @interface AWSDDTTYLoggerColorProfile : NSObject {
     size_t resetCodeLen;
 }
 
-- (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(AWSDDColor *)bgColor flag:(AWSDDLogFlag)mask context:(NSInteger)ctxt;
+- (nullable instancetype)initWithForegroundColor:(nullable AWSDDColor *)fgColor backgroundColor:(nullable AWSDDColor *)bgColor flag:(AWSDDLogFlag)mask context:(NSInteger)ctxt;
 
 @end
 
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-
 @interface AWSDDTTYLogger () {
     NSString *_appName;
     char *_app;
     size_t _appLen;
-    
+
     NSString *_processID;
     char *_pid;
     size_t _pidLen;
-    
+
     BOOL _colorsEnabled;
     NSMutableArray *_colorProfilesArray;
     NSMutableDictionary *_colorProfilesDict;
@@ -133,6 +128,7 @@ @interface AWSDDTTYLogger () {
 
 @end
 
+#pragma mark -
 
 @implementation AWSDDTTYLogger
 
@@ -140,138 +136,141 @@ @implementation AWSDDTTYLogger
 static BOOL isaColor256TTY;
 static BOOL isaXcodeColorTTY;
 
-static NSArray *codes_fg = nil;
-static NSArray *codes_bg = nil;
+static NSArray *codesFg = nil;
+static NSArray *codesBg = nil;
 static NSArray *colors   = nil;
 
 static AWSDDTTYLogger *sharedInstance;
 
 /**
- * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 16 color mode.
+ * Initializes the colors array, as well as the `codesFg` and `codesBg` arrays, for 16 color mode.
  *
  * This method is used when the application is running from within a shell that only supports 16 color mode.
  * This method is not invoked if the application is running within Xcode, or via normal UI app launch.
  **/
-+ (void)initialize_colors_16 {
-    if (codes_fg || codes_bg || colors) {
++ (void)initializeColors16 {
+    if (codesFg || codesBg || colors) {
         return;
     }
 
-    NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:16];
-    NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:16];
-    NSMutableArray *m_colors   = [NSMutableArray arrayWithCapacity:16];
+    __auto_type mColors = [NSMutableArray arrayWithCapacity:16];
 
     // In a standard shell only 16 colors are supported.
     //
     // More information about ansi escape codes can be found online.
     // http://en.wikipedia.org/wiki/ANSI_escape_code
-
-    [m_codes_fg addObject:@"30m"];   // normal - black
-    [m_codes_fg addObject:@"31m"];   // normal - red
-    [m_codes_fg addObject:@"32m"];   // normal - green
-    [m_codes_fg addObject:@"33m"];   // normal - yellow
-    [m_codes_fg addObject:@"34m"];   // normal - blue
-    [m_codes_fg addObject:@"35m"];   // normal - magenta
-    [m_codes_fg addObject:@"36m"];   // normal - cyan
-    [m_codes_fg addObject:@"37m"];   // normal - gray
-    [m_codes_fg addObject:@"1;30m"]; // bright - darkgray
-    [m_codes_fg addObject:@"1;31m"]; // bright - red
-    [m_codes_fg addObject:@"1;32m"]; // bright - green
-    [m_codes_fg addObject:@"1;33m"]; // bright - yellow
-    [m_codes_fg addObject:@"1;34m"]; // bright - blue
-    [m_codes_fg addObject:@"1;35m"]; // bright - magenta
-    [m_codes_fg addObject:@"1;36m"]; // bright - cyan
-    [m_codes_fg addObject:@"1;37m"]; // bright - white
-
-    [m_codes_bg addObject:@"40m"];   // normal - black
-    [m_codes_bg addObject:@"41m"];   // normal - red
-    [m_codes_bg addObject:@"42m"];   // normal - green
-    [m_codes_bg addObject:@"43m"];   // normal - yellow
-    [m_codes_bg addObject:@"44m"];   // normal - blue
-    [m_codes_bg addObject:@"45m"];   // normal - magenta
-    [m_codes_bg addObject:@"46m"];   // normal - cyan
-    [m_codes_bg addObject:@"47m"];   // normal - gray
-    [m_codes_bg addObject:@"1;40m"]; // bright - darkgray
-    [m_codes_bg addObject:@"1;41m"]; // bright - red
-    [m_codes_bg addObject:@"1;42m"]; // bright - green
-    [m_codes_bg addObject:@"1;43m"]; // bright - yellow
-    [m_codes_bg addObject:@"1;44m"]; // bright - blue
-    [m_codes_bg addObject:@"1;45m"]; // bright - magenta
-    [m_codes_bg addObject:@"1;46m"]; // bright - cyan
-    [m_codes_bg addObject:@"1;47m"]; // bright - white
+    codesFg = @[
+        @"30m",  // normal - black
+        @"31m",  // normal - red
+        @"32m",  // normal - green
+        @"33m",  // normal - yellow
+        @"34m",  // normal - blue
+        @"35m",  // normal - magenta
+        @"36m",  // normal - cyan
+        @"37m",  // normal - gray
+        @"1;30m",  // bright - darkgray
+        @"1;31m",  // bright - red
+        @"1;32m",  // bright - green
+        @"1;33m",  // bright - yellow
+        @"1;34m",  // bright - blue
+        @"1;35m",  // bright - magenta
+        @"1;36m",  // bright - cyan
+        @"1;37m",  // bright - white
+    ];
+
+    codesBg = @[
+        @"40m",  // normal - black
+        @"41m",  // normal - red
+        @"42m",  // normal - green
+        @"43m",  // normal - yellow
+        @"44m",  // normal - blue
+        @"45m",  // normal - magenta
+        @"46m",  // normal - cyan
+        @"47m",  // normal - gray
+        @"1;40m",  // bright - darkgray
+        @"1;41m",  // bright - red
+        @"1;42m",  // bright - green
+        @"1;43m",  // bright - yellow
+        @"1;44m",  // bright - blue
+        @"1;45m",  // bright - magenta
+        @"1;46m",  // bright - cyan
+        @"1;47m",  // bright - white
+    ];
 
 #if MAP_TO_TERMINAL_APP_COLORS
 
     // Standard Terminal.app colors:
     //
     // These are the default colors used by Apple's Terminal.app.
-
-    [m_colors addObject:AWSDDMakeColor(  0,   0,   0)]; // normal - black
-    [m_colors addObject:AWSDDMakeColor(194,  54,  33)]; // normal - red
-    [m_colors addObject:AWSDDMakeColor( 37, 188,  36)]; // normal - green
-    [m_colors addObject:AWSDDMakeColor(173, 173,  39)]; // normal - yellow
-    [m_colors addObject:AWSDDMakeColor( 73,  46, 225)]; // normal - blue
-    [m_colors addObject:AWSDDMakeColor(211,  56, 211)]; // normal - magenta
-    [m_colors addObject:AWSDDMakeColor( 51, 187, 200)]; // normal - cyan
-    [m_colors addObject:AWSDDMakeColor(203, 204, 205)]; // normal - gray
-    [m_colors addObject:AWSDDMakeColor(129, 131, 131)]; // bright - darkgray
-    [m_colors addObject:AWSDDMakeColor(252,  57,  31)]; // bright - red
-    [m_colors addObject:AWSDDMakeColor( 49, 231,  34)]; // bright - green
-    [m_colors addObject:AWSDDMakeColor(234, 236,  35)]; // bright - yellow
-    [m_colors addObject:AWSDDMakeColor( 88,  51, 255)]; // bright - blue
-    [m_colors addObject:AWSDDMakeColor(249,  53, 248)]; // bright - magenta
-    [m_colors addObject:AWSDDMakeColor( 20, 240, 240)]; // bright - cyan
-    [m_colors addObject:AWSDDMakeColor(233, 235, 235)]; // bright - white
+    const AWSDDRGBColor rgbColors[] = {
+        {  0,   0,   0}, // normal - black
+        {194,  54,  33}, // normal - red
+        { 37, 188,  36}, // normal - green
+        {173, 173,  39}, // normal - yellow
+        { 73,  46, 225}, // normal - blue
+        {211,  56, 211}, // normal - magenta
+        { 51, 187, 200}, // normal - cyan
+        {203, 204, 205}, // normal - gray
+        {129, 131, 131}, // bright - darkgray
+        {252,  57,  31}, // bright - red
+        { 49, 231,  34}, // bright - green
+        {234, 236,  35}, // bright - yellow
+        { 88,  51, 255}, // bright - blue
+        {249,  53, 248}, // bright - magenta
+        { 20, 240, 240}, // bright - cyan
+        {233, 235, 235}, // bright - white
+    };
 
 #else /* if MAP_TO_TERMINAL_APP_COLORS */
 
     // Standard xterm colors:
     //
     // These are the default colors used by most xterm shells.
-
-    [m_colors addObject:AWSDDMakeColor(  0,   0,   0)]; // normal - black
-    [m_colors addObject:AWSDDMakeColor(205,   0,   0)]; // normal - red
-    [m_colors addObject:AWSDDMakeColor(  0, 205,   0)]; // normal - green
-    [m_colors addObject:AWSDDMakeColor(205, 205,   0)]; // normal - yellow
-    [m_colors addObject:AWSDDMakeColor(  0,   0, 238)]; // normal - blue
-    [m_colors addObject:AWSDDMakeColor(205,   0, 205)]; // normal - magenta
-    [m_colors addObject:AWSDDMakeColor(  0, 205, 205)]; // normal - cyan
-    [m_colors addObject:AWSDDMakeColor(229, 229, 229)]; // normal - gray
-    [m_colors addObject:AWSDDMakeColor(127, 127, 127)]; // bright - darkgray
-    [m_colors addObject:AWSDDMakeColor(255,   0,   0)]; // bright - red
-    [m_colors addObject:AWSDDMakeColor(  0, 255,   0)]; // bright - green
-    [m_colors addObject:AWSDDMakeColor(255, 255,   0)]; // bright - yellow
-    [m_colors addObject:AWSDDMakeColor( 92,  92, 255)]; // bright - blue
-    [m_colors addObject:AWSDDMakeColor(255,   0, 255)]; // bright - magenta
-    [m_colors addObject:AWSDDMakeColor(  0, 255, 255)]; // bright - cyan
-    [m_colors addObject:AWSDDMakeColor(255, 255, 255)]; // bright - white
-
+    const AWSDDRGBColor rgbColors[] = {
+        {  0,   0,   0}, // normal - black
+        {205,   0,   0}, // normal - red
+        {  0, 205,   0}, // normal - green
+        {205, 205,   0}, // normal - yellow
+        {  0,   0, 238}, // normal - blue
+        {205,   0, 205}, // normal - magenta
+        {  0, 205, 205}, // normal - cyan
+        {229, 229, 229}, // normal - gray
+        {127, 127, 127}, // bright - darkgray
+        {255,   0,   0}, // bright - red
+        {  0, 255,   0}, // bright - green
+        {255, 255,   0}, // bright - yellow
+        { 92,  92, 255}, // bright - blue
+        {255,   0, 255}, // bright - magenta
+        {  0, 255, 255}, // bright - cyan
+        {255, 255, 255}, // bright - white
+    };
 #endif /* if MAP_TO_TERMINAL_APP_COLORS */
 
-    codes_fg = [m_codes_fg copy];
-    codes_bg = [m_codes_bg copy];
-    colors   = [m_colors   copy];
+    for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) {
+        [mColors addObject:AWSDDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)];
+    }
+    colors = [mColors copy];
 
-    NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)");
-    NSAssert([codes_fg count] == [colors count],   @"Invalid colors/codes array(s)");
+    NSAssert([codesFg count] == [codesBg count], @"Invalid colors/codes array(s)");
+    NSAssert([codesFg count] == [colors count],   @"Invalid colors/codes array(s)");
 }
 
 /**
- * Initializes the colors array, as well as the codes_fg and codes_bg arrays, for 256 color mode.
+ * Initializes the colors array, as well as the `codesFg` and `codesBg` arrays, for 256 color mode.
  *
  * This method is used when the application is running from within a shell that supports 256 color mode.
  * This method is not invoked if the application is running within Xcode, or via normal UI app launch.
  **/
-+ (void)initialize_colors_256 {
-    if (codes_fg || codes_bg || colors) {
++ (void)initializeColors256 {
+    if (codesFg || codesBg || colors) {
         return;
     }
 
-    NSMutableArray *m_codes_fg = [NSMutableArray arrayWithCapacity:(256 - 16)];
-    NSMutableArray *m_codes_bg = [NSMutableArray arrayWithCapacity:(256 - 16)];
-    NSMutableArray *m_colors   = [NSMutableArray arrayWithCapacity:(256 - 16)];
+    __auto_type mCodesFg = [NSMutableArray arrayWithCapacity:(256 - 16)];
+    __auto_type mCodesBg = [NSMutableArray arrayWithCapacity:(256 - 16)];
+    __auto_type mColors  = [NSMutableArray arrayWithCapacity:(256 - 16)];
 
-    #if MAP_TO_TERMINAL_APP_COLORS
+#if MAP_TO_TERMINAL_APP_COLORS
 
     // Standard Terminal.app colors:
     //
@@ -298,301 +297,304 @@ + (void)initialize_colors_256 {
     // http://en.wikipedia.org/wiki/ANSI_escape_code
 
     // Colors
+    const AWSDDRGBColor rgbColors[] = {
+        { 47,  49,  49},
+        { 60,  42, 144},
+        { 66,  44, 183},
+        { 73,  46, 222},
+        { 81,  50, 253},
+        { 88,  51, 255},
+
+        { 42, 128,  37},
+        { 42, 127, 128},
+        { 44, 126, 169},
+        { 56, 125, 209},
+        { 59, 124, 245},
+        { 66, 123, 255},
+
+        { 51, 163,  41},
+        { 39, 162, 121},
+        { 42, 161, 162},
+        { 53, 160, 202},
+        { 45, 159, 240},
+        { 58, 158, 255},
+
+        { 31, 196,  37},
+        { 48, 196, 115},
+        { 39, 195, 155},
+        { 49, 195, 195},
+        { 32, 194, 235},
+        { 53, 193, 255},
+
+        { 50, 229,  35},
+        { 40, 229, 109},
+        { 27, 229, 149},
+        { 49, 228, 189},
+        { 33, 228, 228},
+        { 53, 227, 255},
+
+        { 27, 254,  30},
+        { 30, 254, 103},
+        { 45, 254, 143},
+        { 38, 253, 182},
+        { 38, 253, 222},
+        { 42, 253, 252},
+
+        {140,  48,  40},
+        {136,  51, 136},
+        {135,  52, 177},
+        {134,  52, 217},
+        {135,  56, 248},
+        {134,  53, 255},
+
+        {125, 125,  38},
+        {124, 125, 125},
+        {122, 124, 166},
+        {123, 124, 207},
+        {123, 122, 247},
+        {124, 121, 255},
+
+        {119, 160,  35},
+        {117, 160, 120},
+        {117, 160, 160},
+        {115, 159, 201},
+        {116, 158, 240},
+        {117, 157, 255},
+
+        {113, 195,  39},
+        {110, 194, 114},
+        {111, 194, 154},
+        {108, 194, 194},
+        {109, 193, 234},
+        {108, 192, 255},
+
+        {105, 228,  30},
+        {103, 228, 109},
+        {105, 228, 148},
+        {100, 227, 188},
+        { 99, 227, 227},
+        { 99, 226, 253},
+
+        { 92, 253,  34},
+        { 96, 253, 103},
+        { 97, 253, 142},
+        { 88, 253, 182},
+        { 93, 253, 221},
+        { 88, 254, 251},
+
+        {177,  53,  34},
+        {174,  54, 131},
+        {172,  55, 172},
+        {171,  57, 213},
+        {170,  55, 249},
+        {170,  57, 255},
+
+        {165, 123,  37},
+        {163, 123, 123},
+        {162, 123, 164},
+        {161, 122, 205},
+        {161, 121, 241},
+        {161, 121, 255},
+
+        {158, 159,  33},
+        {157, 158, 118},
+        {157, 158, 159},
+        {155, 157, 199},
+        {155, 157, 239},
+        {154, 156, 255},
+
+        {152, 193,  40},
+        {151, 193, 113},
+        {150, 193, 153},
+        {150, 192, 193},
+        {148, 192, 232},
+        {149, 191, 253},
+
+        {146, 227,  28},
+        {144, 227, 108},
+        {144, 227, 147},
+        {144, 227, 187},
+        {142, 226, 227},
+        {142, 225, 252},
+
+        {138, 253,  36},
+        {137, 253, 102},
+        {136, 253, 141},
+        {138, 254, 181},
+        {135, 255, 220},
+        {133, 255, 250},
+
+        {214,  57,  30},
+        {211,  59, 126},
+        {209,  57, 168},
+        {208,  55, 208},
+        {207,  58, 247},
+        {206,  61, 255},
+
+        {204, 121,  32},
+        {202, 121, 121},
+        {201, 121, 161},
+        {200, 120, 202},
+        {200, 120, 241},
+        {198, 119, 255},
+
+        {198, 157,  37},
+        {196, 157, 116},
+        {195, 156, 157},
+        {195, 156, 197},
+        {194, 155, 236},
+        {193, 155, 255},
+
+        {191, 192,  36},
+        {190, 191, 112},
+        {189, 191, 152},
+        {189, 191, 191},
+        {188, 190, 230},
+        {187, 190, 253},
+
+        {185, 226,  28},
+        {184, 226, 106},
+        {183, 225, 146},
+        {183, 225, 186},
+        {182, 225, 225},
+        {181, 224, 252},
+
+        {178, 255,  35},
+        {178, 255, 101},
+        {177, 254, 141},
+        {176, 254, 180},
+        {176, 254, 220},
+        {175, 253, 249},
+
+        {247,  56,  30},
+        {245,  57, 122},
+        {243,  59, 163},
+        {244,  60, 204},
+        {242,  59, 241},
+        {240,  55, 255},
+
+        {241, 119,  36},
+        {240, 120, 118},
+        {238, 119, 158},
+        {237, 119, 199},
+        {237, 118, 238},
+        {236, 118, 255},
+
+        {235, 154,  36},
+        {235, 154, 114},
+        {234, 154, 154},
+        {232, 154, 194},
+        {232, 153, 234},
+        {232, 153, 255},
+
+        {230, 190,  30},
+        {229, 189, 110},
+        {228, 189, 150},
+        {227, 189, 190},
+        {227, 189, 229},
+        {226, 188, 255},
+
+        {224, 224,  35},
+        {223, 224, 105},
+        {222, 224, 144},
+        {222, 223, 184},
+        {222, 223, 224},
+        {220, 223, 253},
+
+        {217, 253,  28},
+        {217, 253,  99},
+        {216, 252, 139},
+        {216, 252, 179},
+        {215, 252, 218},
+        {215, 251, 250},
+
+        {255,  61,  30},
+        {255,  60, 118},
+        {255,  58, 159},
+        {255,  56, 199},
+        {255,  55, 238},
+        {255,  59, 255},
+
+        {255, 117,  29},
+        {255, 117, 115},
+        {255, 117, 155},
+        {255, 117, 195},
+        {255, 116, 235},
+        {254, 116, 255},
+
+        {255, 152,  27},
+        {255, 152, 111},
+        {254, 152, 152},
+        {255, 152, 192},
+        {254, 151, 231},
+        {253, 151, 253},
+
+        {255, 187,  33},
+        {253, 187, 107},
+        {252, 187, 148},
+        {253, 187, 187},
+        {254, 187, 227},
+        {252, 186, 252},
+
+        {252, 222,  34},
+        {251, 222, 103},
+        {251, 222, 143},
+        {250, 222, 182},
+        {251, 221, 222},
+        {252, 221, 252},
+
+        {251, 252,  15},
+        {251, 252,  97},
+        {249, 252, 137},
+        {247, 252, 177},
+        {247, 253, 217},
+        {254, 255, 255},
+
+        // Grayscale
+
+        { 52,  53,  53},
+        { 57,  58,  59},
+        { 66,  67,  67},
+        { 75,  76,  76},
+        { 83,  85,  85},
+        { 92,  93,  94},
+
+        {101, 102, 102},
+        {109, 111, 111},
+        {118, 119, 119},
+        {126, 127, 128},
+        {134, 136, 136},
+        {143, 144, 145},
+
+        {151, 152, 153},
+        {159, 161, 161},
+        {167, 169, 169},
+        {176, 177, 177},
+        {184, 185, 186},
+        {192, 193, 194},
+
+        {200, 201, 202},
+        {208, 209, 210},
+        {216, 218, 218},
+        {224, 226, 226},
+        {232, 234, 234},
+        {240, 242, 242},
+    };
 
-    [m_colors addObject:AWSDDMakeColor( 47,  49,  49)];
-    [m_colors addObject:AWSDDMakeColor( 60,  42, 144)];
-    [m_colors addObject:AWSDDMakeColor( 66,  44, 183)];
-    [m_colors addObject:AWSDDMakeColor( 73,  46, 222)];
-    [m_colors addObject:AWSDDMakeColor( 81,  50, 253)];
-    [m_colors addObject:AWSDDMakeColor( 88,  51, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor( 42, 128,  37)];
-    [m_colors addObject:AWSDDMakeColor( 42, 127, 128)];
-    [m_colors addObject:AWSDDMakeColor( 44, 126, 169)];
-    [m_colors addObject:AWSDDMakeColor( 56, 125, 209)];
-    [m_colors addObject:AWSDDMakeColor( 59, 124, 245)];
-    [m_colors addObject:AWSDDMakeColor( 66, 123, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor( 51, 163,  41)];
-    [m_colors addObject:AWSDDMakeColor( 39, 162, 121)];
-    [m_colors addObject:AWSDDMakeColor( 42, 161, 162)];
-    [m_colors addObject:AWSDDMakeColor( 53, 160, 202)];
-    [m_colors addObject:AWSDDMakeColor( 45, 159, 240)];
-    [m_colors addObject:AWSDDMakeColor( 58, 158, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor( 31, 196,  37)];
-    [m_colors addObject:AWSDDMakeColor( 48, 196, 115)];
-    [m_colors addObject:AWSDDMakeColor( 39, 195, 155)];
-    [m_colors addObject:AWSDDMakeColor( 49, 195, 195)];
-    [m_colors addObject:AWSDDMakeColor( 32, 194, 235)];
-    [m_colors addObject:AWSDDMakeColor( 53, 193, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor( 50, 229,  35)];
-    [m_colors addObject:AWSDDMakeColor( 40, 229, 109)];
-    [m_colors addObject:AWSDDMakeColor( 27, 229, 149)];
-    [m_colors addObject:AWSDDMakeColor( 49, 228, 189)];
-    [m_colors addObject:AWSDDMakeColor( 33, 228, 228)];
-    [m_colors addObject:AWSDDMakeColor( 53, 227, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor( 27, 254,  30)];
-    [m_colors addObject:AWSDDMakeColor( 30, 254, 103)];
-    [m_colors addObject:AWSDDMakeColor( 45, 254, 143)];
-    [m_colors addObject:AWSDDMakeColor( 38, 253, 182)];
-    [m_colors addObject:AWSDDMakeColor( 38, 253, 222)];
-    [m_colors addObject:AWSDDMakeColor( 42, 253, 252)];
-    
-    [m_colors addObject:AWSDDMakeColor(140,  48,  40)];
-    [m_colors addObject:AWSDDMakeColor(136,  51, 136)];
-    [m_colors addObject:AWSDDMakeColor(135,  52, 177)];
-    [m_colors addObject:AWSDDMakeColor(134,  52, 217)];
-    [m_colors addObject:AWSDDMakeColor(135,  56, 248)];
-    [m_colors addObject:AWSDDMakeColor(134,  53, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(125, 125,  38)];
-    [m_colors addObject:AWSDDMakeColor(124, 125, 125)];
-    [m_colors addObject:AWSDDMakeColor(122, 124, 166)];
-    [m_colors addObject:AWSDDMakeColor(123, 124, 207)];
-    [m_colors addObject:AWSDDMakeColor(123, 122, 247)];
-    [m_colors addObject:AWSDDMakeColor(124, 121, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(119, 160,  35)];
-    [m_colors addObject:AWSDDMakeColor(117, 160, 120)];
-    [m_colors addObject:AWSDDMakeColor(117, 160, 160)];
-    [m_colors addObject:AWSDDMakeColor(115, 159, 201)];
-    [m_colors addObject:AWSDDMakeColor(116, 158, 240)];
-    [m_colors addObject:AWSDDMakeColor(117, 157, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(113, 195,  39)];
-    [m_colors addObject:AWSDDMakeColor(110, 194, 114)];
-    [m_colors addObject:AWSDDMakeColor(111, 194, 154)];
-    [m_colors addObject:AWSDDMakeColor(108, 194, 194)];
-    [m_colors addObject:AWSDDMakeColor(109, 193, 234)];
-    [m_colors addObject:AWSDDMakeColor(108, 192, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(105, 228,  30)];
-    [m_colors addObject:AWSDDMakeColor(103, 228, 109)];
-    [m_colors addObject:AWSDDMakeColor(105, 228, 148)];
-    [m_colors addObject:AWSDDMakeColor(100, 227, 188)];
-    [m_colors addObject:AWSDDMakeColor( 99, 227, 227)];
-    [m_colors addObject:AWSDDMakeColor( 99, 226, 253)];
-    
-    [m_colors addObject:AWSDDMakeColor( 92, 253,  34)];
-    [m_colors addObject:AWSDDMakeColor( 96, 253, 103)];
-    [m_colors addObject:AWSDDMakeColor( 97, 253, 142)];
-    [m_colors addObject:AWSDDMakeColor( 88, 253, 182)];
-    [m_colors addObject:AWSDDMakeColor( 93, 253, 221)];
-    [m_colors addObject:AWSDDMakeColor( 88, 254, 251)];
-    
-    [m_colors addObject:AWSDDMakeColor(177,  53,  34)];
-    [m_colors addObject:AWSDDMakeColor(174,  54, 131)];
-    [m_colors addObject:AWSDDMakeColor(172,  55, 172)];
-    [m_colors addObject:AWSDDMakeColor(171,  57, 213)];
-    [m_colors addObject:AWSDDMakeColor(170,  55, 249)];
-    [m_colors addObject:AWSDDMakeColor(170,  57, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(165, 123,  37)];
-    [m_colors addObject:AWSDDMakeColor(163, 123, 123)];
-    [m_colors addObject:AWSDDMakeColor(162, 123, 164)];
-    [m_colors addObject:AWSDDMakeColor(161, 122, 205)];
-    [m_colors addObject:AWSDDMakeColor(161, 121, 241)];
-    [m_colors addObject:AWSDDMakeColor(161, 121, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(158, 159,  33)];
-    [m_colors addObject:AWSDDMakeColor(157, 158, 118)];
-    [m_colors addObject:AWSDDMakeColor(157, 158, 159)];
-    [m_colors addObject:AWSDDMakeColor(155, 157, 199)];
-    [m_colors addObject:AWSDDMakeColor(155, 157, 239)];
-    [m_colors addObject:AWSDDMakeColor(154, 156, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(152, 193,  40)];
-    [m_colors addObject:AWSDDMakeColor(151, 193, 113)];
-    [m_colors addObject:AWSDDMakeColor(150, 193, 153)];
-    [m_colors addObject:AWSDDMakeColor(150, 192, 193)];
-    [m_colors addObject:AWSDDMakeColor(148, 192, 232)];
-    [m_colors addObject:AWSDDMakeColor(149, 191, 253)];
-    
-    [m_colors addObject:AWSDDMakeColor(146, 227,  28)];
-    [m_colors addObject:AWSDDMakeColor(144, 227, 108)];
-    [m_colors addObject:AWSDDMakeColor(144, 227, 147)];
-    [m_colors addObject:AWSDDMakeColor(144, 227, 187)];
-    [m_colors addObject:AWSDDMakeColor(142, 226, 227)];
-    [m_colors addObject:AWSDDMakeColor(142, 225, 252)];
-    
-    [m_colors addObject:AWSDDMakeColor(138, 253,  36)];
-    [m_colors addObject:AWSDDMakeColor(137, 253, 102)];
-    [m_colors addObject:AWSDDMakeColor(136, 253, 141)];
-    [m_colors addObject:AWSDDMakeColor(138, 254, 181)];
-    [m_colors addObject:AWSDDMakeColor(135, 255, 220)];
-    [m_colors addObject:AWSDDMakeColor(133, 255, 250)];
-    
-    [m_colors addObject:AWSDDMakeColor(214,  57,  30)];
-    [m_colors addObject:AWSDDMakeColor(211,  59, 126)];
-    [m_colors addObject:AWSDDMakeColor(209,  57, 168)];
-    [m_colors addObject:AWSDDMakeColor(208,  55, 208)];
-    [m_colors addObject:AWSDDMakeColor(207,  58, 247)];
-    [m_colors addObject:AWSDDMakeColor(206,  61, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(204, 121,  32)];
-    [m_colors addObject:AWSDDMakeColor(202, 121, 121)];
-    [m_colors addObject:AWSDDMakeColor(201, 121, 161)];
-    [m_colors addObject:AWSDDMakeColor(200, 120, 202)];
-    [m_colors addObject:AWSDDMakeColor(200, 120, 241)];
-    [m_colors addObject:AWSDDMakeColor(198, 119, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(198, 157,  37)];
-    [m_colors addObject:AWSDDMakeColor(196, 157, 116)];
-    [m_colors addObject:AWSDDMakeColor(195, 156, 157)];
-    [m_colors addObject:AWSDDMakeColor(195, 156, 197)];
-    [m_colors addObject:AWSDDMakeColor(194, 155, 236)];
-    [m_colors addObject:AWSDDMakeColor(193, 155, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(191, 192,  36)];
-    [m_colors addObject:AWSDDMakeColor(190, 191, 112)];
-    [m_colors addObject:AWSDDMakeColor(189, 191, 152)];
-    [m_colors addObject:AWSDDMakeColor(189, 191, 191)];
-    [m_colors addObject:AWSDDMakeColor(188, 190, 230)];
-    [m_colors addObject:AWSDDMakeColor(187, 190, 253)];
-    
-    [m_colors addObject:AWSDDMakeColor(185, 226,  28)];
-    [m_colors addObject:AWSDDMakeColor(184, 226, 106)];
-    [m_colors addObject:AWSDDMakeColor(183, 225, 146)];
-    [m_colors addObject:AWSDDMakeColor(183, 225, 186)];
-    [m_colors addObject:AWSDDMakeColor(182, 225, 225)];
-    [m_colors addObject:AWSDDMakeColor(181, 224, 252)];
-    
-    [m_colors addObject:AWSDDMakeColor(178, 255,  35)];
-    [m_colors addObject:AWSDDMakeColor(178, 255, 101)];
-    [m_colors addObject:AWSDDMakeColor(177, 254, 141)];
-    [m_colors addObject:AWSDDMakeColor(176, 254, 180)];
-    [m_colors addObject:AWSDDMakeColor(176, 254, 220)];
-    [m_colors addObject:AWSDDMakeColor(175, 253, 249)];
-    
-    [m_colors addObject:AWSDDMakeColor(247,  56,  30)];
-    [m_colors addObject:AWSDDMakeColor(245,  57, 122)];
-    [m_colors addObject:AWSDDMakeColor(243,  59, 163)];
-    [m_colors addObject:AWSDDMakeColor(244,  60, 204)];
-    [m_colors addObject:AWSDDMakeColor(242,  59, 241)];
-    [m_colors addObject:AWSDDMakeColor(240,  55, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(241, 119,  36)];
-    [m_colors addObject:AWSDDMakeColor(240, 120, 118)];
-    [m_colors addObject:AWSDDMakeColor(238, 119, 158)];
-    [m_colors addObject:AWSDDMakeColor(237, 119, 199)];
-    [m_colors addObject:AWSDDMakeColor(237, 118, 238)];
-    [m_colors addObject:AWSDDMakeColor(236, 118, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(235, 154,  36)];
-    [m_colors addObject:AWSDDMakeColor(235, 154, 114)];
-    [m_colors addObject:AWSDDMakeColor(234, 154, 154)];
-    [m_colors addObject:AWSDDMakeColor(232, 154, 194)];
-    [m_colors addObject:AWSDDMakeColor(232, 153, 234)];
-    [m_colors addObject:AWSDDMakeColor(232, 153, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(230, 190,  30)];
-    [m_colors addObject:AWSDDMakeColor(229, 189, 110)];
-    [m_colors addObject:AWSDDMakeColor(228, 189, 150)];
-    [m_colors addObject:AWSDDMakeColor(227, 189, 190)];
-    [m_colors addObject:AWSDDMakeColor(227, 189, 229)];
-    [m_colors addObject:AWSDDMakeColor(226, 188, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(224, 224,  35)];
-    [m_colors addObject:AWSDDMakeColor(223, 224, 105)];
-    [m_colors addObject:AWSDDMakeColor(222, 224, 144)];
-    [m_colors addObject:AWSDDMakeColor(222, 223, 184)];
-    [m_colors addObject:AWSDDMakeColor(222, 223, 224)];
-    [m_colors addObject:AWSDDMakeColor(220, 223, 253)];
-    
-    [m_colors addObject:AWSDDMakeColor(217, 253,  28)];
-    [m_colors addObject:AWSDDMakeColor(217, 253,  99)];
-    [m_colors addObject:AWSDDMakeColor(216, 252, 139)];
-    [m_colors addObject:AWSDDMakeColor(216, 252, 179)];
-    [m_colors addObject:AWSDDMakeColor(215, 252, 218)];
-    [m_colors addObject:AWSDDMakeColor(215, 251, 250)];
-    
-    [m_colors addObject:AWSDDMakeColor(255,  61,  30)];
-    [m_colors addObject:AWSDDMakeColor(255,  60, 118)];
-    [m_colors addObject:AWSDDMakeColor(255,  58, 159)];
-    [m_colors addObject:AWSDDMakeColor(255,  56, 199)];
-    [m_colors addObject:AWSDDMakeColor(255,  55, 238)];
-    [m_colors addObject:AWSDDMakeColor(255,  59, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(255, 117,  29)];
-    [m_colors addObject:AWSDDMakeColor(255, 117, 115)];
-    [m_colors addObject:AWSDDMakeColor(255, 117, 155)];
-    [m_colors addObject:AWSDDMakeColor(255, 117, 195)];
-    [m_colors addObject:AWSDDMakeColor(255, 116, 235)];
-    [m_colors addObject:AWSDDMakeColor(254, 116, 255)];
-    
-    [m_colors addObject:AWSDDMakeColor(255, 152,  27)];
-    [m_colors addObject:AWSDDMakeColor(255, 152, 111)];
-    [m_colors addObject:AWSDDMakeColor(254, 152, 152)];
-    [m_colors addObject:AWSDDMakeColor(255, 152, 192)];
-    [m_colors addObject:AWSDDMakeColor(254, 151, 231)];
-    [m_colors addObject:AWSDDMakeColor(253, 151, 253)];
-    
-    [m_colors addObject:AWSDDMakeColor(255, 187,  33)];
-    [m_colors addObject:AWSDDMakeColor(253, 187, 107)];
-    [m_colors addObject:AWSDDMakeColor(252, 187, 148)];
-    [m_colors addObject:AWSDDMakeColor(253, 187, 187)];
-    [m_colors addObject:AWSDDMakeColor(254, 187, 227)];
-    [m_colors addObject:AWSDDMakeColor(252, 186, 252)];
-    
-    [m_colors addObject:AWSDDMakeColor(252, 222,  34)];
-    [m_colors addObject:AWSDDMakeColor(251, 222, 103)];
-    [m_colors addObject:AWSDDMakeColor(251, 222, 143)];
-    [m_colors addObject:AWSDDMakeColor(250, 222, 182)];
-    [m_colors addObject:AWSDDMakeColor(251, 221, 222)];
-    [m_colors addObject:AWSDDMakeColor(252, 221, 252)];
-    
-    [m_colors addObject:AWSDDMakeColor(251, 252,  15)];
-    [m_colors addObject:AWSDDMakeColor(251, 252,  97)];
-    [m_colors addObject:AWSDDMakeColor(249, 252, 137)];
-    [m_colors addObject:AWSDDMakeColor(247, 252, 177)];
-    [m_colors addObject:AWSDDMakeColor(247, 253, 217)];
-    [m_colors addObject:AWSDDMakeColor(254, 255, 255)];
-    
-    // Grayscale
-    
-    [m_colors addObject:AWSDDMakeColor( 52,  53,  53)];
-    [m_colors addObject:AWSDDMakeColor( 57,  58,  59)];
-    [m_colors addObject:AWSDDMakeColor( 66,  67,  67)];
-    [m_colors addObject:AWSDDMakeColor( 75,  76,  76)];
-    [m_colors addObject:AWSDDMakeColor( 83,  85,  85)];
-    [m_colors addObject:AWSDDMakeColor( 92,  93,  94)];
-    
-    [m_colors addObject:AWSDDMakeColor(101, 102, 102)];
-    [m_colors addObject:AWSDDMakeColor(109, 111, 111)];
-    [m_colors addObject:AWSDDMakeColor(118, 119, 119)];
-    [m_colors addObject:AWSDDMakeColor(126, 127, 128)];
-    [m_colors addObject:AWSDDMakeColor(134, 136, 136)];
-    [m_colors addObject:AWSDDMakeColor(143, 144, 145)];
-    
-    [m_colors addObject:AWSDDMakeColor(151, 152, 153)];
-    [m_colors addObject:AWSDDMakeColor(159, 161, 161)];
-    [m_colors addObject:AWSDDMakeColor(167, 169, 169)];
-    [m_colors addObject:AWSDDMakeColor(176, 177, 177)];
-    [m_colors addObject:AWSDDMakeColor(184, 185, 186)];
-    [m_colors addObject:AWSDDMakeColor(192, 193, 194)];
-    
-    [m_colors addObject:AWSDDMakeColor(200, 201, 202)];
-    [m_colors addObject:AWSDDMakeColor(208, 209, 210)];
-    [m_colors addObject:AWSDDMakeColor(216, 218, 218)];
-    [m_colors addObject:AWSDDMakeColor(224, 226, 226)];
-    [m_colors addObject:AWSDDMakeColor(232, 234, 234)];
-    [m_colors addObject:AWSDDMakeColor(240, 242, 242)];
-    
-    // Color codes
+    for (size_t i = 0; i < sizeof(rgbColors) / sizeof(rgbColors[0]); ++i) {
+        [mColors addObject:AWSDDMakeColor(rgbColors[i].r, rgbColors[i].g, rgbColors[i].b)];
+    }
 
+    // Color codes
     int index = 16;
-
     while (index < 256) {
-        [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
-        [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
+        [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
+        [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
 
         index++;
     }
 
-    #else /* if MAP_TO_TERMINAL_APP_COLORS */
+#else /* if MAP_TO_TERMINAL_APP_COLORS */
 
     // Standard xterm colors:
     //
@@ -638,9 +640,9 @@ + (void)initialize_colors_256 {
             for (bi = 0; bi < 6; bi++) {
                 b = (bi == 0) ? 0 : 95 + (40 * (bi - 1));
 
-                [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
-                [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
-                [m_colors addObject:AWSDDMakeColor(r, g, b)];
+                [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
+                [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
+                [mColors  addObject:AWSDDMakeColor(r, g, b)];
 
                 index++;
             }
@@ -654,9 +656,9 @@ + (void)initialize_colors_256 {
     b = 8;
 
     while (index < 256) {
-        [m_codes_fg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
-        [m_codes_bg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
-        [m_colors addObject:AWSDDMakeColor(r, g, b)];
+        [mCodesFg addObject:[NSString stringWithFormat:@"38;5;%dm", index]];
+        [mCodesBg addObject:[NSString stringWithFormat:@"48;5;%dm", index]];
+        [mColor s addObject:AWSDDMakeColor(r, g, b)];
 
         r += 10;
         g += 10;
@@ -665,22 +667,21 @@ + (void)initialize_colors_256 {
         index++;
     }
 
-    #endif /* if MAP_TO_TERMINAL_APP_COLORS */
+#endif /* if MAP_TO_TERMINAL_APP_COLORS */
 
-    codes_fg = [m_codes_fg copy];
-    codes_bg = [m_codes_bg copy];
-    colors   = [m_colors   copy];
+    codesFg = [mCodesFg copy];
+    codesBg = [mCodesBg copy];
+    colors  = [mColors  copy];
 
-    NSAssert([codes_fg count] == [codes_bg count], @"Invalid colors/codes array(s)");
-    NSAssert([codes_fg count] == [colors count],   @"Invalid colors/codes array(s)");
+    NSAssert([codesFg count] == [codesBg count], @"Invalid colors/codes array(s)");
+    NSAssert([codesFg count] == [colors count],   @"Invalid colors/codes array(s)");
 }
 
 + (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromColor:(AWSDDColor *)color {
-    #if TARGET_OS_IPHONE
+#if TARGET_OS_IPHONE
 
     // iOS
-
-    BOOL done = NO;
+    __auto_type done = NO;
 
     if ([color respondsToSelector:@selector(getRed:green:blue:alpha:)]) {
         done = [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
@@ -690,44 +691,49 @@ + (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromCo
         // The method getRed:green:blue:alpha: was only available starting iOS 5.
         // So in iOS 4 and earlier, we have to jump through hoops.
 
-        CGColorSpaceRef rgbColorSpace = CGColorSpaceCreateDeviceRGB();
+        __auto_type rgbColorSpace = CGColorSpaceCreateDeviceRGB();
 
         unsigned char pixel[4];
-        CGContextRef context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)(kCGBitmapAlphaInfoMask & kCGImageAlphaNoneSkipLast));
+        __auto_type context = CGBitmapContextCreate(&pixel, 1, 1, 8, 4, rgbColorSpace, (CGBitmapInfo)(kCGBitmapAlphaInfoMask & kCGImageAlphaNoneSkipLast));
 
         CGContextSetFillColorWithColor(context, [color CGColor]);
         CGContextFillRect(context, CGRectMake(0, 0, 1, 1));
 
         if (rPtr) {
-            *rPtr = pixel[0] / 255.0f;
+            *rPtr = pixel[0] / 255.0;
         }
-
         if (gPtr) {
-            *gPtr = pixel[1] / 255.0f;
+            *gPtr = pixel[1] / 255.0;
         }
-
         if (bPtr) {
-            *bPtr = pixel[2] / 255.0f;
+            *bPtr = pixel[2] / 255.0;
         }
 
         CGContextRelease(context);
         CGColorSpaceRelease(rgbColorSpace);
     }
 
-    #elif defined(AWSDD_CLI) || !__has_include(<AppKit/NSColor.h>)
+#elif defined(AWSDD_CLI) || !__has_include(<AppKit/NSColor.h>)
 
     // OS X without AppKit
-
     [color getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
 
-    #else /* if TARGET_OS_IPHONE */
+#else /* if TARGET_OS_IPHONE */
 
     // OS X with AppKit
-
-    NSColor *safeColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+    NSColor *safeColor;
+    if (@available(macOS 10.14,*)) {
+        safeColor = [color colorUsingColorSpace:NSColorSpace.deviceRGBColorSpace];
+    } else {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
+        safeColor = [color colorUsingColorSpaceName:NSCalibratedRGBColorSpace];
+#pragma clang diagnostic pop
+    }
 
     [safeColor getRed:rPtr green:gPtr blue:bPtr alpha:NULL];
-    #endif /* if TARGET_OS_IPHONE */
+
+#endif /* if TARGET_OS_IPHONE */
 }
 
 /**
@@ -736,7 +742,7 @@ + (void)getRed:(CGFloat *)rPtr green:(CGFloat *)gPtr blue:(CGFloat *)bPtr fromCo
  *
  * This method loops through the known supported color set, and calculates the closest color.
  * The array index of that color, within the colors array, is then returned.
- * This array index may also be used as the index within the codes_fg and codes_bg arrays.
+ * This array index may also be used as the index within the `codesFg` and `codesBg` arrays.
  **/
 + (NSUInteger)codeIndexForColor:(AWSDDColor *)inColor {
     CGFloat inR, inG, inB;
@@ -744,7 +750,7 @@ + (NSUInteger)codeIndexForColor:(AWSDDColor *)inColor {
     [self getRed:&inR green:&inG blue:&inB fromColor:inColor];
 
     NSUInteger bestIndex = 0;
-    CGFloat lowestDistance = 100.0f;
+    CGFloat lowestDistance = 100.0;
 
     NSUInteger i = 0;
 
@@ -754,14 +760,14 @@ + (NSUInteger)codeIndexForColor:(AWSDDColor *)inColor {
         CGFloat r, g, b;
         [self getRed:&r green:&g blue:&b fromColor:color];
 
-    #if CGFLOAT_IS_DOUBLE
-        CGFloat distance = sqrt(pow(r - inR, 2.0) + pow(g - inG, 2.0) + pow(b - inB, 2.0));
-    #else
-        CGFloat distance = sqrtf(powf(r - inR, 2.0f) + powf(g - inG, 2.0f) + powf(b - inB, 2.0f));
-    #endif
+#if CGFLOAT_IS_DOUBLE
+        __auto_type distance = sqrt(pow(r - inR, 2.0) + pow(g - inG, 2.0) + pow(b - inB, 2.0));
+#else
+        __auto_type distance = sqrtf(powf(r - inR, 2.0f) + powf(g - inG, 2.0f) + powf(b - inB, 2.0f));
+#endif
 
         NSLogVerbose(@"AWSDDTTYLogger: %3lu : %.3f,%.3f,%.3f & %.3f,%.3f,%.3f = %.6f",
-                     (unsigned long)i, inR, inG, inB, r, g, b, distance);
+                     (unsigned long)i, (double)inR, (double)inG, (double)inB, (double)r, (double)g, (double)b, (double)distance);
 
         if (distance < lowestDistance) {
             bestIndex = i;
@@ -785,10 +791,10 @@ + (instancetype)sharedInstance {
         //
         // PS - Please read the header file before diving into the source code.
 
-        char *xcode_colors = getenv("XcodeColors");
-        char *term = getenv("TERM");
+        __auto_type xcodeColors = getenv("XcodeColors");
+        __auto_type term = getenv("TERM");
 
-        if (xcode_colors && (strcmp(xcode_colors, "YES") == 0)) {
+        if (xcodeColors && (strcmp(xcodeColors, "YES") == 0)) {
             isaXcodeColorTTY = YES;
         } else if (term) {
             if (strcasestr(term, "color") != NULL) {
@@ -796,9 +802,9 @@ + (instancetype)sharedInstance {
                 isaColor256TTY = (strcasestr(term, "256") != NULL);
 
                 if (isaColor256TTY) {
-                    [self initialize_colors_256];
+                    [self initializeColors256];
                 } else {
-                    [self initialize_colors_16];
+                    [self initializeColors16];
                 }
             }
         }
@@ -807,7 +813,7 @@ + (instancetype)sharedInstance {
         NSLogInfo(@"AWSDDTTYLogger: isaColor256TTY: %@", (isaColor256TTY ? @"YES" : @"NO"));
         NSLogInfo(@"AWSDDTTYLogger: isaXcodeColorTTY: %@", (isaXcodeColorTTY ? @"YES" : @"NO"));
 
-        sharedInstance = [[[self class] alloc] init];
+        sharedInstance = [[self alloc] init];
     });
 
     return sharedInstance;
@@ -818,11 +824,15 @@ - (instancetype)init {
         return nil;
     }
 
-    if ((self = [super init])) {
-        // Initialze 'app' variable (char *)
+#if !defined(AWSDD_CLI) || __has_include(<AppKit/NSColor.h>)
+    if (@available(iOS 10.0, macOS 10.12, tvOS 10.0, watchOS 3.0, *)) {
+        NSLogWarn(@"CocoaLumberjack: Warning: Usage of AWSDDTTYLogger detected when AWSDDOSLogger is available and can be used! Please consider migrating to AWSDDOSLogger.");
+    }
+#endif
 
+    if ((self = [super init])) {
+        // Initialize 'app' variable (char *)
         _appName = [[NSProcessInfo processInfo] processName];
-
         _appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
         if (_appLen == 0) {
@@ -830,15 +840,13 @@ - (instancetype)init {
             _appLen = [_appName lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
         }
 
-        _app = (char *)malloc(_appLen + 1);
-
+        _app = (char *)calloc(_appLen + 1, sizeof(char));
         if (_app == NULL) {
             return nil;
         }
 
         BOOL processedAppName = [_appName getCString:_app maxLength:(_appLen + 1) encoding:NSUTF8StringEncoding];
-
-        if (NO == processedAppName) {
+        if (!processedAppName) {
             free(_app);
             return nil;
         }
@@ -848,7 +856,7 @@ - (instancetype)init {
         _processID = [NSString stringWithFormat:@"%i", (int)getpid()];
 
         _pidLen = [_processID lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-        _pid = (char *)malloc(_pidLen + 1);
+        _pid = (char *)calloc(_pidLen + 1, sizeof(char));
 
         if (_pid == NULL) {
             free(_app);
@@ -856,8 +864,7 @@ - (instancetype)init {
         }
 
         BOOL processedID = [_processID getCString:_pid maxLength:(_pidLen + 1) encoding:NSUTF8StringEncoding];
-
-        if (NO == processedID) {
+        if (!processedID) {
             free(_app);
             free(_pid);
             return nil;
@@ -875,6 +882,10 @@ - (instancetype)init {
     return self;
 }
 
+- (AWSDDLoggerName)loggerName {
+    return AWSDDLoggerNameTTY;
+}
+
 - (void)loadDefaultColorProfiles {
     [self setForegroundColor:AWSDDMakeColor(214,  57,  30) backgroundColor:nil forFlag:AWSDDLogFlagError];
     [self setForegroundColor:AWSDDMakeColor(204, 121,  32) backgroundColor:nil forFlag:AWSDDLogFlagWarning];
@@ -891,14 +902,9 @@ - (BOOL)colorsEnabled {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
     __block BOOL result;
-
-    dispatch_sync(globalLoggingQueue, ^{
+    dispatch_sync(AWSDDLog.loggingQueue, ^{
         dispatch_sync(self.loggerQueue, ^{
             result = self->_colorsEnabled;
         });
@@ -908,7 +914,7 @@ - (BOOL)colorsEnabled {
 }
 
 - (void)setColorsEnabled:(BOOL)newColorsEnabled {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             self->_colorsEnabled = newColorsEnabled;
 
@@ -928,12 +934,8 @@ - (void)setColorsEnabled:(BOOL)newColorsEnabled {
     // This is the intended result. Fix it by accessing the ivar directly.
     // Great strides have been take to ensure this is safe to do. Plus it's MUCH faster.
 
-    NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-    NSAssert(![self isOnInternalLoggerQueue], @"MUST access ivar directly, NOT via self.* syntax.");
-
-    dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-
-    dispatch_async(globalLoggingQueue, ^{
+    AWSDDAbstractLoggerAssertLockedPropertyAccess();
+    dispatch_async(AWSDDLog.loggingQueue, ^{
         dispatch_async(self.loggerQueue, block);
     });
 }
@@ -945,11 +947,11 @@ - (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)
 - (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)bgColor forFlag:(AWSDDLogFlag)mask context:(NSInteger)ctxt {
     dispatch_block_t block = ^{
         @autoreleasepool {
-            AWSDDTTYLoggerColorProfile *newColorProfile =
-                [[AWSDDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
-                                                         backgroundColor:bgColor
-                                                                    flag:mask
-                                                                 context:ctxt];
+            AWSDDTTYLoggerColorProfile *newColorProfile = [[AWSDDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
+                                                                                                      backgroundColor:bgColor
+                                                                                                                 flag:mask
+                                                                                                              context:ctxt];
+            if (!newColorProfile) return;
 
             NSLogInfo(@"AWSDDTTYLogger: newColorProfile: %@", newColorProfile);
 
@@ -977,25 +979,22 @@ - (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)bgColor forTag:(id <NSCopying>)tag {
-    NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
+    NSAssert([(id <NSObject>)tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
-            AWSDDTTYLoggerColorProfile *newColorProfile =
-                [[AWSDDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
-                                                         backgroundColor:bgColor
-                                                                    flag:(AWSDDLogFlag)0
-                                                                 context:0];
+            __auto_type newColorProfile = [[AWSDDTTYLoggerColorProfile alloc] initWithForegroundColor:txtColor
+                                                                                      backgroundColor:bgColor
+                                                                                                 flag:(AWSDDLogFlag)0
+                                                                                              context:0];
 
             NSLogInfo(@"AWSDDTTYLogger: newColorProfile: %@", newColorProfile);
 
@@ -1009,10 +1008,8 @@ - (void)setForegroundColor:(AWSDDColor *)txtColor backgroundColor:(AWSDDColor *)
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
@@ -1023,7 +1020,7 @@ - (void)clearColorsForFlag:(AWSDDLogFlag)mask {
 }
 
 - (void)clearColorsForFlag:(AWSDDLogFlag)mask context:(NSInteger)context {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             NSUInteger i = 0;
 
@@ -1047,19 +1044,17 @@ - (void)clearColorsForFlag:(AWSDDLogFlag)mask context:(NSInteger)context {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)clearColorsForTag:(id <NSCopying>)tag {
-    NSAssert([(id < NSObject >) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
+    NSAssert([(id <NSObject>) tag conformsToProtocol: @protocol(NSCopying)], @"Invalid tag");
 
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self->_colorProfilesDict removeObjectForKey:tag];
         }
@@ -1071,17 +1066,15 @@ - (void)clearColorsForTag:(id <NSCopying>)tag {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)clearColorsForAllFlags {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self->_colorProfilesArray removeAllObjects];
         }
@@ -1093,17 +1086,15 @@ - (void)clearColorsForAllFlags {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)clearColorsForAllTags {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self->_colorProfilesDict removeAllObjects];
         }
@@ -1115,17 +1106,15 @@ - (void)clearColorsForAllTags {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)clearAllColors {
-    dispatch_block_t block = ^{
+    __auto_type block = ^{
         @autoreleasepool {
             [self->_colorProfilesArray removeAllObjects];
             [self->_colorProfilesDict removeAllObjects];
@@ -1138,32 +1127,30 @@ - (void)clearAllColors {
     if ([self isOnInternalLoggerQueue]) {
         block();
     } else {
-        dispatch_queue_t globalLoggingQueue = [AWSDDLog loggingQueue];
-        NSAssert(![self isOnGlobalLoggingQueue], @"Core architecture requirement failure");
-
-        dispatch_async(globalLoggingQueue, ^{
+        AWSDDAbstractLoggerAssertNotOnGlobalLoggingQueue();
+        dispatch_async(AWSDDLog.loggingQueue, ^{
             dispatch_async(self.loggerQueue, block);
         });
     }
 }
 
 - (void)logMessage:(AWSDDLogMessage *)logMessage {
-    NSString *logMsg = logMessage->_message;
-    BOOL isFormatted = NO;
+    __auto_type logMsg = logMessage->_message;
+    __auto_type isFormatted = NO;
 
     if (_logFormatter) {
         logMsg = [_logFormatter formatLogMessage:logMessage];
         isFormatted = logMsg != logMessage->_message;
     }
-    
+
     if (logMsg) {
         // Search for a color profile associated with the log message
 
         AWSDDTTYLoggerColorProfile *colorProfile = nil;
 
         if (_colorsEnabled) {
-            if (logMessage->_tag) {
-                colorProfile = _colorProfilesDict[logMessage->_tag];
+            if (logMessage->_representedObject) {
+                colorProfile = _colorProfilesDict[logMessage->_representedObject];
             }
 
             if (colorProfile == nil) {
@@ -1193,23 +1180,24 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
         // We use the stack instead of the heap for speed if possible.
         // But we're extra cautious to avoid a stack overflow.
 
-        NSUInteger msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-        const BOOL useStack = msgLen < (1024 * 4);
-
-        char msgStack[useStack ? (msgLen + 1) : 1]; // Analyzer doesn't like zero-size array, hence the 1
-        char *msg = useStack ? msgStack : (char *)malloc(msgLen + 1);
+        __auto_type msgLen = [logMsg lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+        const __auto_type useStack = msgLen < (1024 * 4);
 
+        char *msg;
+        if (useStack) {
+            msg = (char *)alloca(msgLen + 1);
+        } else {
+            msg = (char *)calloc(msgLen + 1, sizeof(char));
+        }
         if (msg == NULL) {
             return;
         }
 
         BOOL logMsgEnc = [logMsg getCString:msg maxLength:(msgLen + 1) encoding:NSUTF8StringEncoding];
-
         if (!logMsgEnc) {
-            if (!useStack && msg != NULL) {
+            if (!useStack) {
                 free(msg);
             }
-
             return;
         }
 
@@ -1217,8 +1205,9 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
 
         if (isFormatted) {
             // The log message has already been formatted.
-            int iovec_len = (_automaticallyAppendNewlineForCustomFormatters) ? 5 : 4;
-            struct iovec v[iovec_len];
+            const size_t maxIovecLen = 5;
+            size_t iovecLen = _automaticallyAppendNewlineForCustomFormatters ? 5 : 4;
+            struct iovec v[maxIovecLen] = { 0 };
 
             if (colorProfile) {
                 v[0].iov_base = colorProfile->fgCode;
@@ -1227,28 +1216,20 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
                 v[1].iov_base = colorProfile->bgCode;
                 v[1].iov_len = colorProfile->bgCodeLen;
 
-                v[iovec_len - 1].iov_base = colorProfile->resetCode;
-                v[iovec_len - 1].iov_len = colorProfile->resetCodeLen;
-            } else {
-                v[0].iov_base = "";
-                v[0].iov_len = 0;
-
-                v[1].iov_base = "";
-                v[1].iov_len = 0;
-
-                v[iovec_len - 1].iov_base = "";
-                v[iovec_len - 1].iov_len = 0;
+                v[maxIovecLen - 1].iov_base = colorProfile->resetCode;
+                v[maxIovecLen - 1].iov_len = colorProfile->resetCodeLen;
             }
 
-            v[2].iov_base = (char *)msg;
-            v[2].iov_len = msgLen;
+            v[2].iov_base = msg;
+            v[2].iov_len = (msgLen > SIZE_MAX - 1) ? SIZE_MAX - 1 : msgLen;
 
-            if (iovec_len == 5) {
+            if (_automaticallyAppendNewlineForCustomFormatters && (v[2].iov_len == 0 || msg[v[2].iov_len - 1] != '\n')) {
                 v[3].iov_base = "\n";
-                v[3].iov_len = (msg[msgLen] == '\n') ? 0 : 1;
+                v[3].iov_len = 1;
+                iovecLen = 5;
             }
 
-            writev(STDERR_FILENO, v, iovec_len);
+            writev(STDERR_FILENO, v, (int)iovecLen);
         } else {
             // The log message is unformatted, so apply standard NSLog style formatting.
 
@@ -1259,13 +1240,15 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
             // Calculate timestamp.
             // The technique below is faster than using NSDateFormatter.
             if (logMessage->_timestamp) {
-                NSTimeInterval epoch = [logMessage->_timestamp timeIntervalSince1970];
+                __auto_type epoch = [logMessage->_timestamp timeIntervalSince1970];
+                double integral;
+                __auto_type fract = modf(epoch, &integral);
                 struct tm tm;
-                time_t time = (time_t)epoch;
+                __auto_type time = (time_t)integral;
                 (void)localtime_r(&time, &tm);
-                int milliseconds = (int)((epoch - floor(epoch)) * 1000.0);
+                __auto_type milliseconds = (long)(fract * 1000.0);
 
-                len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03d", // yyyy-MM-dd HH:mm:ss:SSS
+                len = snprintf(ts, 24, "%04d-%02d-%02d %02d:%02d:%02d:%03ld", // yyyy-MM-dd HH:mm:ss:SSS
                                tm.tm_year + 1900,
                                tm.tm_mon + 1,
                                tm.tm_mday,
@@ -1287,7 +1270,7 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
             char tid[9];
             len = snprintf(tid, 9, "%s", [logMessage->_threadID cStringUsingEncoding:NSUTF8StringEncoding]);
 
-            size_t tidLen = (NSUInteger)MAX(MIN(9 - 1, len), 0);
+            __auto_type tidLen = (NSUInteger)MAX(MIN(9 - 1, len), 0);
 
             // Here is our format: "%s %s[%i:%s] %s", timestamp, appName, processID, threadID, logMsg
 
@@ -1352,13 +1335,9 @@ - (void)logMessage:(AWSDDLogMessage *)logMessage {
     }
 }
 
-- (NSString *)loggerName {
-    return @"cocoa.lumberjack.ttyLogger";
-}
-
 @end
 
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+#pragma mark -
 
 @implementation AWSDDTTYLoggerColorProfile
 
@@ -1372,31 +1351,31 @@ - (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(A
         if (fgColor) {
             [AWSDDTTYLogger getRed:&r green:&g blue:&b fromColor:fgColor];
 
-            fg_r = (uint8_t)(r * 255.0f);
-            fg_g = (uint8_t)(g * 255.0f);
-            fg_b = (uint8_t)(b * 255.0f);
+            fg.r = (uint8_t)(r * (CGFloat)255.0);
+            fg.g = (uint8_t)(g * (CGFloat)255.0);
+            fg.b = (uint8_t)(b * (CGFloat)255.0);
         }
 
         if (bgColor) {
             [AWSDDTTYLogger getRed:&r green:&g blue:&b fromColor:bgColor];
 
-            bg_r = (uint8_t)(r * 255.0f);
-            bg_g = (uint8_t)(g * 255.0f);
-            bg_b = (uint8_t)(b * 255.0f);
+            bg.r = (uint8_t)(r * (CGFloat)255.0);
+            bg.g = (uint8_t)(g * (CGFloat)255.0);
+            bg.b = (uint8_t)(b * (CGFloat)255.0);
         }
 
         if (fgColor && isaColorTTY) {
             // Map foreground color to closest available shell color
 
             fgCodeIndex = [AWSDDTTYLogger codeIndexForColor:fgColor];
-            fgCodeRaw   = codes_fg[fgCodeIndex];
+            fgCodeRaw   = codesFg[fgCodeIndex];
 
-            NSString *escapeSeq = @"\033[";
+            const __auto_type escapeSeq = @"\033[";
 
-            NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-            NSUInteger len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+            __auto_type len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+            __auto_type len2 = [fgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
-            BOOL escapeSeqEnc = [escapeSeq getCString:(fgCode)      maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
+            BOOL escapeSeqEnc = [escapeSeq getCString:(fgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
             BOOL fgCodeRawEsc = [fgCodeRaw getCString:(fgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding];
 
             if (!escapeSeqEnc || !fgCodeRawEsc) {
@@ -1406,14 +1385,11 @@ - (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(A
             fgCodeLen = len1 + len2;
         } else if (fgColor && isaXcodeColorTTY) {
             // Convert foreground color to color code sequence
-
             const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ;
-
-            int result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg_r, fg_g, fg_b);
+            __auto_type result = snprintf(fgCode, 24, "%sfg%u,%u,%u;", escapeSeq, fg.r, fg.g, fg.b);
             fgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0);
         } else {
             // No foreground color or no color support
-
             fgCode[0] = '\0';
             fgCodeLen = 0;
         }
@@ -1422,14 +1398,14 @@ - (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(A
             // Map background color to closest available shell color
 
             bgCodeIndex = [AWSDDTTYLogger codeIndexForColor:bgColor];
-            bgCodeRaw   = codes_bg[bgCodeIndex];
+            bgCodeRaw   = codesBg[bgCodeIndex];
 
-            NSString *escapeSeq = @"\033[";
+            const __auto_type escapeSeq = @"\033[";
 
-            NSUInteger len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
-            NSUInteger len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+            __auto_type len1 = [escapeSeq lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
+            __auto_type len2 = [bgCodeRaw lengthOfBytesUsingEncoding:NSUTF8StringEncoding];
 
-            BOOL escapeSeqEnc = [escapeSeq getCString:(bgCode)      maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
+            BOOL escapeSeqEnc = [escapeSeq getCString:(bgCode) maxLength:(len1 + 1) encoding:NSUTF8StringEncoding];
             BOOL bgCodeRawEsc = [bgCodeRaw getCString:(bgCode + len1) maxLength:(len2 + 1) encoding:NSUTF8StringEncoding];
 
             if (!escapeSeqEnc || !bgCodeRawEsc) {
@@ -1439,14 +1415,11 @@ - (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(A
             bgCodeLen = len1 + len2;
         } else if (bgColor && isaXcodeColorTTY) {
             // Convert background color to color code sequence
-
             const char *escapeSeq = XCODE_COLORS_ESCAPE_SEQ;
-
-            int result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg_r, bg_g, bg_b);
+            __auto_type result = snprintf(bgCode, 24, "%sbg%u,%u,%u;", escapeSeq, bg.r, bg.g, bg.b);
             bgCodeLen = (NSUInteger)MAX(MIN(result, (24 - 1)), 0);
         } else {
             // No background color or no color support
-
             bgCode[0] = '\0';
             bgCodeLen = 0;
         }
@@ -1466,8 +1439,8 @@ - (instancetype)initWithForegroundColor:(AWSDDColor *)fgColor backgroundColor:(A
 
 - (NSString *)description {
     return [NSString stringWithFormat:
-            @"<AWSDDTTYLoggerColorProfile: %p mask:%i ctxt:%ld fg:%u,%u,%u bg:%u,%u,%u fgCode:%@ bgCode:%@>",
-            self, (int)mask, (long)context, fg_r, fg_g, fg_b, bg_r, bg_g, bg_b, fgCodeRaw, bgCodeRaw];
+            @"<DDTTYLoggerColorProfile: %p mask:%i ctxt:%ld fg:%u,%u,%u bg:%u,%u,%u fgCode:%@ bgCode:%@>",
+            self, (int)mask, (long)context, fg.r, fg.g, fg.b, bg.r, bg.g, bg.b, fgCodeRaw, bgCodeRaw];
 }
 
 @end
diff --git a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.h b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.h
new file mode 100644
index 00000000000..1c3981b73c6
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.h
@@ -0,0 +1,119 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import "AWSDDContextFilterLogFormatter.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+/**
+ * This class provides a log formatter that filters log statements from a logging context not on the whitelist.
+ * @deprecated Use AWSDDContextAllowlistFilterLogFormatter instead.
+ *
+ * A log formatter can be added to any logger to format and/or filter its output.
+ * You can learn more about log formatters here:
+ * Documentation/CustomFormatters.md
+ *
+ * You can learn more about logging context's here:
+ * Documentation/CustomContext.md
+ *
+ * But here's a quick overview / refresher:
+ *
+ * Every log statement has a logging context.
+ * These come from the underlying logging macros defined in AWSDDLog.h.
+ * The default logging context is zero.
+ * You can define multiple logging context's for use in your application.
+ * For example, logically separate parts of your app each have a different logging context.
+ * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
+ **/
+__attribute__((deprecated("Use AWSDDContextAllowlistFilterLogFormatter instead")))
+typedef AWSDDContextAllowlistFilterLogFormatter AWSDDContextWhitelistFilterLogFormatter;
+
+@interface AWSDDContextAllowlistFilterLogFormatter (Deprecated)
+
+/**
+ *  Add a context to the whitelist
+ *  @deprecated Use -addToAllowlist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (void)addToWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -addToAllowlist: instead")));
+
+/**
+ *  Remove context from whitelist
+ *  @deprecated Use -removeFromAllowlist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (void)removeFromWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -removeFromAllowlist: instead")));
+
+/**
+ *  Return the whitelist
+ *  @deprecated Use allowlist instead.
+ */
+@property (nonatomic, readonly, copy) NSArray<NSNumber *> *whitelist __attribute__((deprecated("Use allowlist instead")));
+
+/**
+ *  Check if a context is on the whitelist
+ *  @deprecated Use -isOnAllowlist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (BOOL)isOnWhitelist:(NSInteger)loggingContext __attribute__((deprecated("Use -isOnAllowlist: instead")));
+
+@end
+
+
+/**
+ * This class provides a log formatter that filters log statements from a logging context on the blacklist.
+ * @deprecated Use AWSDDContextDenylistFilterLogFormatter instead.
+ **/
+__attribute__((deprecated("Use AWSDDContextDenylistFilterLogFormatter instead")))
+typedef AWSDDContextDenylistFilterLogFormatter AWSDDContextBlacklistFilterLogFormatter;
+
+@interface AWSDDContextDenylistFilterLogFormatter (Deprecated)
+
+/**
+ *  Add a context to the blacklist
+ *  @deprecated Use -addToDenylist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (void)addToBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -addToDenylist: instead")));
+
+/**
+ *  Remove context from blacklist
+ *  @deprecated Use -removeFromDenylist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (void)removeFromBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -removeFromDenylist: instead")));
+
+/**
+ *  Return the blacklist
+ *  @deprecated Use denylist instead.
+ */
+@property (readonly, copy) NSArray<NSNumber *> *blacklist __attribute__((deprecated("Use denylist instead")));
+
+/**
+ *  Check if a context is on the blacklist
+ *  @deprecated Use -isOnDenylist: instead.
+ *
+ *  @param loggingContext the context
+ */
+- (BOOL)isOnBlacklist:(NSInteger)loggingContext __attribute__((deprecated("Use -isOnDenylist: instead")));
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.m b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.m
new file mode 100644
index 00000000000..c44f61c4d40
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter+Deprecated.m
@@ -0,0 +1,57 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import "AWSDDContextFilterLogFormatter+Deprecated.h"
+
+@implementation AWSDDContextAllowlistFilterLogFormatter (Deprecated)
+
+- (void)addToWhitelist:(NSInteger)loggingContext {
+    [self addToAllowlist:loggingContext];
+}
+
+- (void)removeFromWhitelist:(NSInteger)loggingContext {
+    [self removeFromAllowlist:loggingContext];
+}
+
+- (NSArray *)whitelist {
+    return [self allowlist];
+}
+
+- (BOOL)isOnWhitelist:(NSInteger)loggingContext {
+    return [self isOnAllowlist:loggingContext];
+}
+
+@end
+
+
+@implementation AWSDDContextDenylistFilterLogFormatter (Deprecated)
+
+- (void)addToBlacklist:(NSInteger)loggingContext {
+    [self addToDenylist:loggingContext];
+}
+
+- (void)removeFromBlacklist:(NSInteger)loggingContext {
+    [self removeFromDenylist:loggingContext];
+}
+
+- (NSArray *)blacklist {
+    return [self denylist];
+}
+
+- (BOOL)isOnBlacklist:(NSInteger)loggingContext {
+    return [self isOnDenylist:loggingContext];
+}
+
+@end
diff --git a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.h b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.h
index b4f9936426c..1f64ccfe849 100644
--- a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.h
+++ b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -22,8 +22,10 @@
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
- * This class provides a log formatter that filters log statements from a logging context not on the whitelist.
+ * This class provides a log formatter that filters log statements from a logging context not on the allowlist.
  *
  * A log formatter can be added to any logger to format and/or filter its output.
  * You can learn more about log formatters here:
@@ -41,7 +43,7 @@
  * For example, logically separate parts of your app each have a different logging context.
  * Also 3rd party frameworks that make use of Lumberjack generally use their own dedicated logging context.
  **/
-@interface AWSDDContextWhitelistFilterLogFormatter : NSObject <AWSDDLogFormatter>
+@interface AWSDDContextAllowlistFilterLogFormatter : NSObject <AWSDDLogFormatter>
 
 /**
  *  Designated default initializer
@@ -49,69 +51,67 @@
 - (instancetype)init NS_DESIGNATED_INITIALIZER;
 
 /**
- *  Add a context to the whitelist
+ *  Add a context to the allowlist
  *
  *  @param loggingContext the context
  */
-- (void)addToWhitelist:(NSUInteger)loggingContext;
+- (void)addToAllowlist:(NSInteger)loggingContext;
 
 /**
- *  Remove context from whitelist
+ *  Remove context from allowlist
  *
  *  @param loggingContext the context
  */
-- (void)removeFromWhitelist:(NSUInteger)loggingContext;
+- (void)removeFromAllowlist:(NSInteger)loggingContext;
 
 /**
- *  Return the whitelist
+ *  Return the allowlist
  */
-@property (readonly, copy) NSArray<NSNumber *> *whitelist;
+@property (nonatomic, readonly, copy) NSArray<NSNumber *> *allowlist;
 
 /**
- *  Check if a context is on the whitelist
+ *  Check if a context is on the allowlist
  *
  *  @param loggingContext the context
  */
-- (BOOL)isOnWhitelist:(NSUInteger)loggingContext;
+- (BOOL)isOnAllowlist:(NSInteger)loggingContext;
 
 @end
 
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 /**
- * This class provides a log formatter that filters log statements from a logging context on the blacklist.
+ * This class provides a log formatter that filters log statements from a logging context on the denylist.
  **/
-@interface AWSDDContextBlacklistFilterLogFormatter : NSObject <AWSDDLogFormatter>
+@interface AWSDDContextDenylistFilterLogFormatter : NSObject <AWSDDLogFormatter>
 
 - (instancetype)init NS_DESIGNATED_INITIALIZER;
 
 /**
- *  Add a context to the blacklist
+ *  Add a context to the denylist
  *
  *  @param loggingContext the context
  */
-- (void)addToBlacklist:(NSUInteger)loggingContext;
+- (void)addToDenylist:(NSInteger)loggingContext;
 
 /**
- *  Remove context from blacklist
+ *  Remove context from denylist
  *
  *  @param loggingContext the context
  */
-- (void)removeFromBlacklist:(NSUInteger)loggingContext;
+- (void)removeFromDenylist:(NSInteger)loggingContext;
 
 /**
- *  Return the blacklist
+ *  Return the denylist
  */
-@property (readonly, copy) NSArray<NSNumber *> *blacklist;
-
+@property (readonly, copy) NSArray<NSNumber *> *denylist;
 
 /**
- *  Check if a context is on the blacklist
+ *  Check if a context is on the denylist
  *
  *  @param loggingContext the context
  */
-- (BOOL)isOnBlacklist:(NSUInteger)loggingContext;
+- (BOOL)isOnDenylist:(NSInteger)loggingContext;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.m b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.m
old mode 100644
new mode 100755
index 7b5ef2cec55..acfbf93970c
--- a/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.m
+++ b/AWSCore/Logging/Extensions/AWSDDContextFilterLogFormatter.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,21 +13,22 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDContextFilterLogFormatter.h"
-#import <libkern/OSAtomic.h>
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import <pthread/pthread.h>
+
+#import "AWSDDContextFilterLogFormatter.h"
+
 @interface AWSDDLoggingContextSet : NSObject
 
-- (void)addToSet:(NSUInteger)loggingContext;
-- (void)removeFromSet:(NSUInteger)loggingContext;
+@property (readonly, copy, nonnull) NSArray *currentSet;
 
-@property (readonly, copy) NSArray *currentSet;
+- (void)addToSet:(NSInteger)loggingContext;
+- (void)removeFromSet:(NSInteger)loggingContext;
 
-- (BOOL)isInSet:(NSUInteger)loggingContext;
+- (BOOL)isInSet:(NSInteger)loggingContext;
 
 @end
 
@@ -35,41 +36,38 @@ - (BOOL)isInSet:(NSUInteger)loggingContext;
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-@interface AWSDDContextWhitelistFilterLogFormatter () {
+@interface AWSDDContextAllowlistFilterLogFormatter () {
     AWSDDLoggingContextSet *_contextSet;
 }
-
 @end
 
-
-@implementation AWSDDContextWhitelistFilterLogFormatter
+@implementation AWSDDContextAllowlistFilterLogFormatter
 
 - (instancetype)init {
     if ((self = [super init])) {
         _contextSet = [[AWSDDLoggingContextSet alloc] init];
     }
-
     return self;
 }
 
-- (void)addToWhitelist:(NSUInteger)loggingContext {
+- (void)addToAllowlist:(NSInteger)loggingContext {
     [_contextSet addToSet:loggingContext];
 }
 
-- (void)removeFromWhitelist:(NSUInteger)loggingContext {
+- (void)removeFromAllowlist:(NSInteger)loggingContext {
     [_contextSet removeFromSet:loggingContext];
 }
 
-- (NSArray *)whitelist {
+- (NSArray *)allowlist {
     return [_contextSet currentSet];
 }
 
-- (BOOL)isOnWhitelist:(NSUInteger)loggingContext {
+- (BOOL)isOnAllowlist:(NSInteger)loggingContext {
     return [_contextSet isInSet:loggingContext];
 }
 
 - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
-    if ([self isOnWhitelist:logMessage->_context]) {
+    if ([self isOnAllowlist:logMessage->_context]) {
         return logMessage->_message;
     } else {
         return nil;
@@ -78,45 +76,39 @@ - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
 
 @end
 
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
-#pragma mark -
-////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-@interface AWSDDContextBlacklistFilterLogFormatter () {
+@interface AWSDDContextDenylistFilterLogFormatter () {
     AWSDDLoggingContextSet *_contextSet;
 }
-
 @end
 
-
-@implementation AWSDDContextBlacklistFilterLogFormatter
+@implementation AWSDDContextDenylistFilterLogFormatter
 
 - (instancetype)init {
     if ((self = [super init])) {
         _contextSet = [[AWSDDLoggingContextSet alloc] init];
     }
-
     return self;
 }
 
-- (void)addToBlacklist:(NSUInteger)loggingContext {
+- (void)addToDenylist:(NSInteger)loggingContext {
     [_contextSet addToSet:loggingContext];
 }
 
-- (void)removeFromBlacklist:(NSUInteger)loggingContext {
+- (void)removeFromDenylist:(NSInteger)loggingContext {
     [_contextSet removeFromSet:loggingContext];
 }
 
-- (NSArray *)blacklist {
+- (NSArray *)denylist {
     return [_contextSet currentSet];
 }
 
-- (BOOL)isOnBlacklist:(NSUInteger)loggingContext {
+- (BOOL)isOnDenylist:(NSInteger)loggingContext {
     return [_contextSet isInSet:loggingContext];
 }
 
 - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
-    if ([self isOnBlacklist:logMessage->_context]) {
+    if ([self isOnDenylist:logMessage->_context]) {
         return nil;
     } else {
         return logMessage->_message;
@@ -129,62 +121,63 @@ - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
 #pragma mark -
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
-
 @interface AWSDDLoggingContextSet () {
-    OSSpinLock _lock;
+    pthread_mutex_t _mutex;
     NSMutableSet *_set;
 }
-
 @end
 
-
 @implementation AWSDDLoggingContextSet
 
 - (instancetype)init {
     if ((self = [super init])) {
         _set = [[NSMutableSet alloc] init];
-        _lock = OS_SPINLOCK_INIT;
+        pthread_mutex_init(&_mutex, NULL);
     }
 
     return self;
 }
 
-- (void)addToSet:(NSUInteger)loggingContext {
-    OSSpinLockLock(&_lock);
+- (void)dealloc {
+    pthread_mutex_destroy(&_mutex);
+}
+
+- (void)addToSet:(NSInteger)loggingContext {
+    pthread_mutex_lock(&_mutex);
     {
         [_set addObject:@(loggingContext)];
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 }
 
-- (void)removeFromSet:(NSUInteger)loggingContext {
-    OSSpinLockLock(&_lock);
+- (void)removeFromSet:(NSInteger)loggingContext {
+    pthread_mutex_lock(&_mutex);
     {
         [_set removeObject:@(loggingContext)];
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 }
 
 - (NSArray *)currentSet {
     NSArray *result = nil;
 
-    OSSpinLockLock(&_lock);
+    pthread_mutex_lock(&_mutex);
     {
         result = [_set allObjects];
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 
     return result;
 }
 
-- (BOOL)isInSet:(NSUInteger)loggingContext {
-    BOOL result = NO;
+- (BOOL)isInSet:(NSInteger)loggingContext {
+    __auto_type result = NO;
 
-    OSSpinLockLock(&_lock);
+    pthread_mutex_lock(&_mutex);
     {
         result = [_set containsObject:@(loggingContext)];
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 
     return result;
 }
diff --git a/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.h b/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.h
index 8c561e85434..44f8e49f27a 100644
--- a/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.h
+++ b/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -14,7 +14,6 @@
 //   prior written permission of Deusty, LLC.
 
 #import <Foundation/Foundation.h>
-#import <libkern/OSAtomic.h>
 
 // Disable legacy macros
 #ifndef AWSDD_LEGACY_MACROS
@@ -23,9 +22,12 @@
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  *  Log formatter mode
  */
+__attribute__((deprecated("AWSDDDispatchQueueLogFormatter is always shareable")))
 typedef NS_ENUM(NSUInteger, AWSDDDispatchQueueLogFormatterMode){
     /**
      *  This is the default option, means the formatter can be reused between multiple loggers and therefore is thread-safe.
@@ -39,6 +41,36 @@ typedef NS_ENUM(NSUInteger, AWSDDDispatchQueueLogFormatterMode){
     AWSDDDispatchQueueLogFormatterModeNonShareble,
 };
 
+/**
+ * Quality of Service names.
+ *
+ * Since macOS 10.10 and iOS 8.0, pthreads, dispatch queues and NSOperations express their
+ * scheduling priority by using an abstract classification called Quality of Service (QOS).
+ *
+ * This formatter will add a representation of this QOS in the log message by using those
+ * string constants.
+ * For example:
+ *
+ * `2011-10-17 20:21:45.435 AppName[19928:5207 (QOS:DF)] Your log message here`
+ *
+ * Where QOS is one of:
+ * `- UI = User Interactive`
+ * `- IN = User Initiated`
+ * `- DF = Default`
+ * `- UT = Utility`
+ * `- BG = Background`
+ * `- UN = Unspecified`
+ *
+ * Note: QOS will be absent in the log messages if running on OS versions that don't support it.
+ **/
+typedef NSString * AWSDDQualityOfServiceName NS_STRING_ENUM;
+
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceUserInteractive NS_SWIFT_NAME(AWSDDQualityOfServiceName.userInteractive) API_AVAILABLE(macos(10.10), ios(8.0));
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceUserInitiated NS_SWIFT_NAME(AWSDDQualityOfServiceName.userInitiated) API_AVAILABLE(macos(10.10), ios(8.0));
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceDefault NS_SWIFT_NAME(AWSDDQualityOfServiceName.default) API_AVAILABLE(macos(10.10), ios(8.0));
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceUtility NS_SWIFT_NAME(AWSDDQualityOfServiceName.utility) API_AVAILABLE(macos(10.10), ios(8.0));
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceBackground NS_SWIFT_NAME(AWSDDQualityOfServiceName.background) API_AVAILABLE(macos(10.10), ios(8.0));
+FOUNDATION_EXPORT AWSDDQualityOfServiceName const AWSDDQualityOfServiceUnspecified NS_SWIFT_NAME(AWSDDQualityOfServiceName.unspecified) API_AVAILABLE(macos(10.10), ios(8.0));
 
 /**
  * This class provides a log formatter that prints the dispatch_queue label instead of the mach_thread_id.
@@ -90,7 +122,7 @@ typedef NS_ENUM(NSUInteger, AWSDDDispatchQueueLogFormatterMode){
  *
  *  @param mode choose between AWSDDDispatchQueueLogFormatterModeShareble and AWSDDDispatchQueueLogFormatterModeNonShareble, depending if the formatter is shared between several loggers or not
  */
-- (instancetype)initWithMode:(AWSDDDispatchQueueLogFormatterMode)mode;
+- (instancetype)initWithMode:(AWSDDDispatchQueueLogFormatterMode)mode __attribute__((deprecated("AWSDDDispatchQueueLogFormatter is always shareable")));
 
 /**
  * The minQueueLength restricts the minimum size of the [detail box].
@@ -141,12 +173,12 @@ typedef NS_ENUM(NSUInteger, AWSDDDispatchQueueLogFormatterMode){
  *
  * To remove/undo a previous replacement, invoke this method with nil for the 'shortLabel' parameter.
  **/
-- (NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
+- (nullable NSString *)replacementStringForQueueLabel:(NSString *)longLabel;
 
 /**
  *  See the `replacementStringForQueueLabel:` description
  */
-- (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
+- (void)setReplacementString:(nullable NSString *)shortLabel forQueueLabel:(NSString *)longLabel;
 
 @end
 
@@ -170,9 +202,22 @@ typedef NS_ENUM(NSUInteger, AWSDDDispatchQueueLogFormatterMode){
  */
 - (NSString *)queueThreadLabelForLogMessage:(AWSDDLogMessage *)logMessage;
 
-/**
- *  The actual method that formats a message (transforms a `AWSDDLogMessage` model into a printable string)
- */
-- (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage;
+@end
+
+#pragma mark - AWSDDAtomicCountable
+
+__attribute__((deprecated("AWSDDAtomicCountable is useless since AWSDDDispatchQueueLogFormatter is always shareable now")))
+@protocol AWSDDAtomicCountable <NSObject>
 
+- (instancetype)initWithDefaultValue:(int32_t)defaultValue;
+- (int32_t)increment;
+- (int32_t)decrement;
+- (int32_t)value;
+
+@end
+
+__attribute__((deprecated("AWSDDAtomicCountable is deprecated")))
+@interface AWSDDAtomicCounter: NSObject<AWSDDAtomicCountable>
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.m b/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.m
old mode 100644
new mode 100755
index 3527f9fe977..8156a5d65c9
--- a/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.m
+++ b/AWSCore/Logging/Extensions/AWSDDDispatchQueueLogFormatter.m
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -13,29 +13,45 @@
 //   to endorse or promote products derived from this software without specific
 //   prior written permission of Deusty, LLC.
 
-#import "AWSDDDispatchQueueLogFormatter.h"
-#import <libkern/OSAtomic.h>
-#import <objc/runtime.h>
-
-
 #if !__has_feature(objc_arc)
 #error This file must be compiled with ARC. Use -fobjc-arc flag (or convert project to ARC).
 #endif
 
+#import <pthread/pthread.h>
+#import <stdatomic.h>
+#import <sys/qos.h>
+
+#import "AWSDDDispatchQueueLogFormatter.h"
+
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceUserInteractive = @"UI";
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceUserInitiated   = @"IN";
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceDefault         = @"DF";
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceUtility         = @"UT";
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceBackground      = @"BG";
+AWSDDQualityOfServiceName const AWSDDQualityOfServiceUnspecified     = @"UN";
+
+static AWSDDQualityOfServiceName _qos_name(NSUInteger qos) {
+    switch ((qos_class_t) qos) {
+        case QOS_CLASS_USER_INTERACTIVE: return AWSDDQualityOfServiceUserInteractive;
+        case QOS_CLASS_USER_INITIATED:   return AWSDDQualityOfServiceUserInitiated;
+        case QOS_CLASS_DEFAULT:          return AWSDDQualityOfServiceDefault;
+        case QOS_CLASS_UTILITY:          return AWSDDQualityOfServiceUtility;
+        case QOS_CLASS_BACKGROUND:       return AWSDDQualityOfServiceBackground;
+        default:                         return AWSDDQualityOfServiceUnspecified;
+    }
+}
+
+#pragma mark - AWSDDDispatchQueueLogFormatter
+
 @interface AWSDDDispatchQueueLogFormatter () {
-    AWSDDDispatchQueueLogFormatterMode _mode;
-    NSString *_dateFormatterKey;
-    
-    int32_t _atomicLoggerCount;
-    NSDateFormatter *_threadUnsafeDateFormatter; // Use [self stringFromDate]
-    
-    OSSpinLock _lock;
-    
+    NSDateFormatter *_dateFormatter;      // Use [self stringFromDate]
+
+    pthread_mutex_t _mutex;
+
     NSUInteger _minQueueLength;           // _prefix == Only access via atomic property
     NSUInteger _maxQueueLength;           // _prefix == Only access via atomic property
     NSMutableDictionary *_replacements;   // _prefix == Only access from within spinlock
 }
-
 @end
 
 
@@ -43,31 +59,12 @@ @implementation AWSDDDispatchQueueLogFormatter
 
 - (instancetype)init {
     if ((self = [super init])) {
-        _mode = AWSDDDispatchQueueLogFormatterModeShareble;
-
-        // We need to carefully pick the name for storing in thread dictionary to not
-        // use a formatter configured by subclass and avoid surprises.
-        Class cls = [self class];
-        Class superClass = class_getSuperclass(cls);
-        SEL configMethodName = @selector(configureDateFormatter:);
-        Method configMethod = class_getInstanceMethod(cls, configMethodName);
-        while (class_getInstanceMethod(superClass, configMethodName) == configMethod) {
-            cls = superClass;
-            superClass = class_getSuperclass(cls);
-        }
-        // now `cls` is the class that provides implementation for `configureDateFormatter:`
-        _dateFormatterKey = [NSString stringWithFormat:@"%s_NSDateFormatter", class_getName(cls)];
+        _dateFormatter = [self createDateFormatter];
 
-        _atomicLoggerCount = 0;
-        _threadUnsafeDateFormatter = nil;
-
-        _minQueueLength = 0;
-        _maxQueueLength = 0;
-        _lock = OS_SPINLOCK_INIT;
+        pthread_mutex_init(&_mutex, NULL);
         _replacements = [[NSMutableDictionary alloc] init];
 
         // Set default replacements:
-
         _replacements[@"com.apple.main-thread"] = @"main";
     }
 
@@ -75,10 +72,11 @@ - (instancetype)init {
 }
 
 - (instancetype)initWithMode:(AWSDDDispatchQueueLogFormatterMode)mode {
-    if ((self = [self init])) {
-        _mode = mode;
-    }
-    return self;
+    return [self init];
+}
+
+- (void)dealloc {
+    pthread_mutex_destroy(&_mutex);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -91,17 +89,17 @@ - (instancetype)initWithMode:(AWSDDDispatchQueueLogFormatterMode)mode {
 - (NSString *)replacementStringForQueueLabel:(NSString *)longLabel {
     NSString *result = nil;
 
-    OSSpinLockLock(&_lock);
+    pthread_mutex_lock(&_mutex);
     {
         result = _replacements[longLabel];
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 
     return result;
 }
 
 - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)longLabel {
-    OSSpinLockLock(&_lock);
+    pthread_mutex_lock(&_mutex);
     {
         if (shortLabel) {
             _replacements[longLabel] = shortLabel;
@@ -109,7 +107,7 @@ - (void)setReplacementString:(NSString *)shortLabel forQueueLabel:(NSString *)lo
             [_replacements removeObjectForKey:longLabel];
         }
     }
-    OSSpinLockUnlock(&_lock);
+    pthread_mutex_unlock(&_mutex);
 }
 
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -126,153 +124,117 @@ - (void)configureDateFormatter:(NSDateFormatter *)dateFormatter {
     [dateFormatter setFormatterBehavior:NSDateFormatterBehavior10_4];
     [dateFormatter setDateFormat:@"yyyy-MM-dd HH:mm:ss:SSS"];
     [dateFormatter setLocale:[NSLocale localeWithLocaleIdentifier:@"en_US_POSIX"]];
-
-    NSString *calendarIdentifier = nil;
-#if defined(__IPHONE_8_0) || defined(__MAC_10_10)
-    calendarIdentifier = NSCalendarIdentifierGregorian;
-#else
-    calendarIdentifier = NSGregorianCalendar;
-#endif
-
-    [dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:calendarIdentifier]];
+    [dateFormatter setCalendar:[[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]];
 }
 
 - (NSString *)stringFromDate:(NSDate *)date {
-
-    NSDateFormatter *dateFormatter = nil;
-    if (_mode == AWSDDDispatchQueueLogFormatterModeNonShareble) {
-        // Single-threaded mode.
-
-        dateFormatter = _threadUnsafeDateFormatter;
-        if (dateFormatter == nil) {
-            dateFormatter = [self createDateFormatter];
-            _threadUnsafeDateFormatter = dateFormatter;
-        }
-    } else {
-        // Multi-threaded mode.
-        // NSDateFormatter is NOT thread-safe.
-
-        NSString *key = _dateFormatterKey;
-
-        NSMutableDictionary *threadDictionary = [[NSThread currentThread] threadDictionary];
-        dateFormatter = threadDictionary[key];
-
-        if (dateFormatter == nil) {
-            dateFormatter = [self createDateFormatter];
-            threadDictionary[key] = dateFormatter;
-        }
-    }
-
-    return [dateFormatter stringFromDate:date];
+    return [_dateFormatter stringFromDate:date];
 }
 
 - (NSString *)queueThreadLabelForLogMessage:(AWSDDLogMessage *)logMessage {
     // As per the AWSDDLogFormatter contract, this method is always invoked on the same thread/dispatch_queue
 
-    NSUInteger minQueueLength = self.minQueueLength;
-    NSUInteger maxQueueLength = self.maxQueueLength;
-
-    // Get the name of the queue, thread, or machID (whichever we are to use).
-
-    NSString *queueThreadLabel = nil;
-
-    BOOL useQueueLabel = YES;
-    BOOL useThreadName = NO;
-
+    __auto_type useQueueLabel = NO;
     if (logMessage->_queueLabel) {
+        useQueueLabel = YES;
+
         // If you manually create a thread, it's dispatch_queue will have one of the thread names below.
         // Since all such threads have the same name, we'd prefer to use the threadName or the machThreadID.
-
-        NSArray *names = @[
+        const NSArray<NSString *> *names = @[
             @"com.apple.root.low-priority",
             @"com.apple.root.default-priority",
             @"com.apple.root.high-priority",
             @"com.apple.root.low-overcommit-priority",
             @"com.apple.root.default-overcommit-priority",
-            @"com.apple.root.high-overcommit-priority"
+            @"com.apple.root.high-overcommit-priority",
+            @"com.apple.root.default-qos.overcommit",
         ];
-
-        for (NSString * name in names) {
+        for (NSString *name in names) {
             if ([logMessage->_queueLabel isEqualToString:name]) {
                 useQueueLabel = NO;
-                useThreadName = [logMessage->_threadName length] > 0;
                 break;
             }
         }
-    } else {
-        useQueueLabel = NO;
-        useThreadName = [logMessage->_threadName length] > 0;
     }
 
-    if (useQueueLabel || useThreadName) {
-        NSString *fullLabel;
-        NSString *abrvLabel;
-
-        if (useQueueLabel) {
-            fullLabel = logMessage->_queueLabel;
-        } else {
-            fullLabel = logMessage->_threadName;
-        }
+    // Get the name of the queue, thread, or machID (whichever we are to use).
+    NSString *queueThreadLabel;
+    if (useQueueLabel || [logMessage->_threadName length] > 0) {
+        __auto_type fullLabel = useQueueLabel ? logMessage->_queueLabel : logMessage->_threadName;
 
-        OSSpinLockLock(&_lock);
+        NSString *abrvLabel;
+        pthread_mutex_lock(&_mutex);
         {
             abrvLabel = _replacements[fullLabel];
         }
-        OSSpinLockUnlock(&_lock);
+        pthread_mutex_unlock(&_mutex);
 
-        if (abrvLabel) {
-            queueThreadLabel = abrvLabel;
-        } else {
-            queueThreadLabel = fullLabel;
-        }
+        queueThreadLabel = abrvLabel ?: fullLabel;
     } else {
         queueThreadLabel = logMessage->_threadID;
     }
 
     // Now use the thread label in the output
-
-    NSUInteger labelLength = [queueThreadLabel length];
-
     // labelLength > maxQueueLength : truncate
     // labelLength < minQueueLength : padding
     //                              : exact
-
-    if ((maxQueueLength > 0) && (labelLength > maxQueueLength)) {
+    __auto_type minQueueLength = self.minQueueLength;
+    __auto_type maxQueueLength = self.maxQueueLength;
+    __auto_type labelLength = [queueThreadLabel length];
+    if (maxQueueLength > 0 && labelLength > maxQueueLength) {
         // Truncate
-
         return [queueThreadLabel substringToIndex:maxQueueLength];
     } else if (labelLength < minQueueLength) {
         // Padding
-
-        NSUInteger numSpaces = minQueueLength - labelLength;
-
-        char spaces[numSpaces + 1];
-        memset(spaces, ' ', numSpaces);
-        spaces[numSpaces] = '\0';
-
-        return [NSString stringWithFormat:@"%@%s", queueThreadLabel, spaces];
+        return [queueThreadLabel stringByPaddingToLength:minQueueLength
+                                              withString:@" "
+                                         startingAtIndex:0];
     } else {
         // Exact
-
         return queueThreadLabel;
     }
 }
 
 - (NSString *)formatLogMessage:(AWSDDLogMessage *)logMessage {
-    NSString *timestamp = [self stringFromDate:(logMessage->_timestamp)];
-    NSString *queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage];
+    __auto_type timestamp = [self stringFromDate:logMessage->_timestamp];
+    __auto_type queueThreadLabel = [self queueThreadLabelForLogMessage:logMessage];
+
+    return [NSString stringWithFormat:@"%@ [%@ (QOS:%@)] %@", timestamp, queueThreadLabel, _qos_name(logMessage->_qos), logMessage->_message];
+}
+
+@end
+
+#pragma mark - AWSDDAtomicCounter
+
+@interface AWSDDAtomicCounter() {
+    atomic_int_fast32_t _value;
+}
+@end
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-implementations"
+@implementation AWSDDAtomicCounter
+#pragma clang diagnostic pop
+
+- (instancetype)initWithDefaultValue:(int32_t)defaultValue {
+    if ((self = [super init])) {
+        atomic_init(&_value, defaultValue);
+    }
+    return self;
+}
 
-    return [NSString stringWithFormat:@"%@ [%@] %@", timestamp, queueThreadLabel, logMessage->_message];
+- (int32_t)value {
+    return atomic_load_explicit(&_value, memory_order_relaxed);
 }
 
-- (void)didAddToLogger:(id <AWSDDLogger>  __attribute__((unused)))logger {
-    int32_t count = 0;
-    count = OSAtomicIncrement32(&_atomicLoggerCount);
-    NSAssert(count <= 1 || _mode == AWSDDDispatchQueueLogFormatterModeShareble, @"Can't reuse formatter with multiple loggers in non-shareable mode.");
+- (int32_t)increment {
+    int32_t old = atomic_fetch_add_explicit(&_value, 1, memory_order_relaxed);
+    return (old + 1);
 }
 
-- (void)willRemoveFromLogger:(id <AWSDDLogger> __attribute__((unused)))logger {
-    OSAtomicDecrement32(&_atomicLoggerCount);
+- (int32_t)decrement {
+    int32_t old = atomic_fetch_sub_explicit(&_value, 1, memory_order_relaxed);
+    return (old - 1);
 }
 
 @end
diff --git a/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.h b/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.h
new file mode 100644
index 00000000000..03caafd2f86
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.h
@@ -0,0 +1,27 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import "AWSDDFileLogger.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface AWSDDFileLogger (Buffering)
+
+- (instancetype)wrapWithBuffer;
+- (instancetype)unwrapFromBuffer;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.m b/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.m
new file mode 100644
index 00000000000..1571e82f449
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDFileLogger+Buffering.m
@@ -0,0 +1,202 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import <sys/mount.h>
+
+#import "AWSDDFileLogger+Buffering.h"
+#import "AWSDDFileLogger+Internal.h"
+
+static const NSUInteger kAWSDDDefaultBufferSize = 4096; // 4 kB, block f_bsize on iphone7
+static const NSUInteger kAWSDDMaxBufferSize = 1048576; // ~1 mB, f_iosize on iphone7
+
+// Reads attributes from base file system to determine buffer size.
+// see statfs in sys/mount.h for descriptions of f_iosize and f_bsize.
+// f_bsize == "default", and f_iosize == "max"
+static inline NSUInteger p_AWSDDGetDefaultBufferSizeBytesMax(const BOOL max) {
+    struct statfs *mountedFileSystems = NULL;
+    __auto_type count = getmntinfo(&mountedFileSystems, 0);
+
+    for (int i = 0; i < count; i++) {
+        __auto_type mounted = mountedFileSystems[i];
+        __auto_type name = mounted.f_mntonname;
+
+        // We can use 2 as max here, since any length > 1 will fail the if-statement.
+        if (strnlen(name, 2) == 1 && *name == '/') {
+            return max ? (NSUInteger)mounted.f_iosize : (NSUInteger)mounted.f_bsize;
+        }
+    }
+
+    return max ? kAWSDDMaxBufferSize : kAWSDDDefaultBufferSize;
+}
+
+static NSUInteger AWSDDGetMaxBufferSizeBytes(void) {
+    static NSUInteger maxBufferSize = 0;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        maxBufferSize = p_AWSDDGetDefaultBufferSizeBytesMax(YES);
+    });
+    return maxBufferSize;
+}
+
+static NSUInteger AWSDDGetDefaultBufferSizeBytes(void) {
+    static NSUInteger defaultBufferSize = 0;
+    static dispatch_once_t onceToken;
+    dispatch_once(&onceToken, ^{
+        defaultBufferSize = p_AWSDDGetDefaultBufferSizeBytesMax(NO);
+    });
+    return defaultBufferSize;
+}
+
+@interface AWSDDBufferedProxy : NSProxy
+
+@property (nonatomic) AWSDDFileLogger *fileLogger;
+@property (nonatomic) NSOutputStream *buffer;
+
+@property (nonatomic) NSUInteger maxBufferSizeBytes;
+@property (nonatomic) NSUInteger currentBufferSizeBytes;
+
+@end
+
+@implementation AWSDDBufferedProxy
+
+- (instancetype)initWithFileLogger:(AWSDDFileLogger *)fileLogger {
+    _fileLogger = fileLogger;
+    _maxBufferSizeBytes = AWSDDGetDefaultBufferSizeBytes();
+    [self flushBuffer];
+
+    return self;
+}
+
+- (void)dealloc {
+    __auto_type block = ^{
+        [self lt_sendBufferedDataToFileLogger];
+        self.fileLogger = nil;
+    };
+
+    if ([self->_fileLogger isOnInternalLoggerQueue]) {
+        block();
+    } else {
+        dispatch_sync(self->_fileLogger.loggerQueue, block);
+    }
+}
+
+#pragma mark - Buffering
+
+- (void)flushBuffer {
+    [_buffer close];
+    _buffer = [NSOutputStream outputStreamToMemory];
+    [_buffer open];
+    _currentBufferSizeBytes = 0;
+}
+
+- (void)lt_sendBufferedDataToFileLogger {
+    NSData *data = [_buffer propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
+    [_fileLogger lt_logData:data];
+    [self flushBuffer];
+}
+
+#pragma mark - Logging
+
+- (void)logMessage:(AWSDDLogMessage *)logMessage {
+    // Don't need to check for isOnInternalLoggerQueue, -lt_dataForMessage: will do it for us.
+    __auto_type data = [_fileLogger lt_dataForMessage:logMessage];
+
+    if (data.length == 0) {
+        return;
+    }
+
+    [data enumerateByteRangesUsingBlock:^(const void * __nonnull bytes, NSRange byteRange, BOOL * __nonnull __unused stop) {
+        __auto_type bytesLength = byteRange.length;
+#ifdef NS_BLOCK_ASSERTIONS
+        __unused
+#endif
+        __auto_type written = [_buffer write:bytes maxLength:bytesLength];
+        NSAssert(written > 0 && (NSUInteger)written == bytesLength, @"Failed to write to memory buffer.");
+
+        _currentBufferSizeBytes += bytesLength;
+
+        if (_currentBufferSizeBytes >= _maxBufferSizeBytes) {
+            [self lt_sendBufferedDataToFileLogger];
+        }
+    }];
+}
+
+- (void)flush {
+    // This method is public.
+    // We need to execute the rolling on our logging thread/queue.
+
+    __auto_type block = ^{
+        @autoreleasepool {
+            [self lt_sendBufferedDataToFileLogger];
+            [self.fileLogger flush];
+        }
+    };
+
+    // The design of this method is taken from the AWSDDAbstractLogger implementation.
+    // For extensive documentation please refer to the AWSDDAbstractLogger implementation.
+
+    if ([self.fileLogger isOnInternalLoggerQueue]) {
+        block();
+    } else {
+        NSAssert(![self.fileLogger isOnGlobalLoggingQueue], @"Core architecture requirement failure");
+        dispatch_sync(AWSDDLog.loggingQueue, ^{
+            dispatch_sync(self.fileLogger.loggerQueue, block);
+        });
+    }
+}
+
+#pragma mark - Properties
+
+- (void)setMaxBufferSizeBytes:(NSUInteger)newBufferSizeBytes {
+    _maxBufferSizeBytes = MIN(newBufferSizeBytes, AWSDDGetMaxBufferSizeBytes());
+}
+
+#pragma mark - Wrapping
+
+- (AWSDDFileLogger *)wrapWithBuffer {
+    return (AWSDDFileLogger *)self;
+}
+
+- (AWSDDFileLogger *)unwrapFromBuffer {
+    return (AWSDDFileLogger *)self.fileLogger;
+}
+
+#pragma mark - NSProxy
+
+- (NSMethodSignature *)methodSignatureForSelector:(SEL)sel {
+    return [self.fileLogger methodSignatureForSelector:sel];
+}
+
+- (BOOL)respondsToSelector:(SEL)aSelector {
+    return [self.fileLogger respondsToSelector:aSelector];
+}
+
+- (void)forwardInvocation:(NSInvocation *)invocation {
+    [invocation invokeWithTarget:self.fileLogger];
+}
+
+@end
+
+@implementation AWSDDFileLogger (Buffering)
+
+- (instancetype)wrapWithBuffer {
+    return (AWSDDFileLogger *)[[AWSDDBufferedProxy alloc] initWithFileLogger:self];
+}
+
+- (instancetype)unwrapFromBuffer {
+    return self;
+}
+
+@end
diff --git a/AWSCore/Logging/Extensions/AWSDDFileLogger+Internal.h b/AWSCore/Logging/Extensions/AWSDDFileLogger+Internal.h
new file mode 100644
index 00000000000..8c418dc0786
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDFileLogger+Internal.h
@@ -0,0 +1,31 @@
+// Software License Agreement (BSD License)
+//
+// Copyright (c) 2010-2024, Deusty, LLC
+// All rights reserved.
+//
+// Redistribution and use of this software in source and binary forms,
+// with or without modification, are permitted provided that the following conditions are met:
+//
+// * Redistributions of source code must retain the above copyright notice,
+//   this list of conditions and the following disclaimer.
+//
+// * Neither the name of Deusty nor the names of its contributors may be used
+//   to endorse or promote products derived from this software without specific
+//   prior written permission of Deusty, LLC.
+
+#import "AWSDDFileLogger.h"
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface AWSDDFileLogger (Internal)
+
+- (void)logData:(NSData *)data;
+
+// Will assert if used outside logger's queue.
+- (void)lt_logData:(NSData *)data;
+
+- (nullable NSData *)lt_dataForMessage:(AWSDDLogMessage *)message;
+
+@end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Logging/Extensions/AWSDDLog+Optional.swift b/AWSCore/Logging/Extensions/AWSDDLog+Optional.swift
new file mode 100644
index 00000000000..0264ae82e8b
--- /dev/null
+++ b/AWSCore/Logging/Extensions/AWSDDLog+Optional.swift
@@ -0,0 +1,129 @@
+//
+// Copyright 2010-2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License").
+// You may not use this file except in compliance with the License.
+// A copy of the License is located at
+//
+// http://aws.amazon.com/apache2.0
+//
+// or in the "license" file accompanying this file. This file is distributed
+// on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
+// express or implied. See the License for the specific language governing
+// permissions and limitations under the License.
+//
+
+import Foundation
+
+public extension AWSDDLog {
+
+    /**
+     * Adds the logger to the system.
+     *
+     * This is equivalent to invoking `[AWSDDLog addLogger:logger withLogLevel:AWSDDLogLevelAll]`.
+     */
+    @available(*, deprecated, message: "Providing a nil logger will fail silently. Use add(_:) with a non-optional logger instead.")
+    static func add(_ logger: AWSDDLogger?) {
+        if let logger = logger {
+            add(logger)
+        }
+    }
+
+    /**
+     * Adds the logger to the system.
+     *
+     * The level that you provide here is a preemptive filter (for performance).
+     * That is, the level specified here will be used to filter out logMessages so that
+     * the logger is never even invoked for the messages.
+     *
+     * More information:
+     * When you issue a log statement, the logging framework iterates over each logger,
+     * and checks to see if it should forward the logMessage to the logger.
+     * This check is done using the level parameter passed to this method.
+     *
+     * For example:
+     *
+     * `[AWSDDLog addLogger:consoleLogger withLogLevel:AWSDDLogLevelVerbose];`
+     * `[AWSDDLog addLogger:fileLogger    withLogLevel:AWSDDLogLevelWarning];`
+     *
+     * `AWSDDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
+     * `AWSDDLogInfo(@"hi");`     => gets forwarded to consoleLogger only
+     *
+     * It is important to remember that Lumberjack uses a BITMASK.
+     * Many developers & third party frameworks may define extra log levels & flags.
+     * For example:
+     *
+     * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
+     *
+     * So if you specify `AWSDDLogLevelVerbose` to this method, you won't see the framework's trace messages.
+     *
+     * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & AWSDDLogLevelVerbose) => (01000000 & 00011111) => NO`
+     *
+     * Consider passing `AWSDDLogLevelAll` to this method, which has all bits set.
+     * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
+     * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
+     *
+     * `((AWSDDLogLevelAll ^ AWSDDLogLevelVerbose) | AWSDDLogLevelInfo)`
+     */
+    @available(*, deprecated, message: "Providing a nil logger will fail silently. Use add(_:with:) with a non-optional logger instead.")
+    class func add(_ logger: AWSDDLogger?, with level: AWSDDLogLevel) {
+        if let logger = logger {
+            add(logger, with: level)
+        }
+    }
+
+    /**
+     * Adds the logger to the system.
+     *
+     * This is equivalent to invoking `[AWSDDLog addLogger:logger withLogLevel:AWSDDLogLevelAll]`.
+     */
+    @available(*, deprecated, message: "Providing a nil logger will fail silently. Use add(_:) with a non-optional logger instead.")
+    func add(_ logger: AWSDDLogger?) {
+        if let logger = logger {
+            add(logger)
+        }
+    }
+
+    /**
+     * Adds the logger to the system.
+     *
+     * The level that you provide here is a preemptive filter (for performance).
+     * That is, the level specified here will be used to filter out logMessages so that
+     * the logger is never even invoked for the messages.
+     *
+     * More information:
+     * When you issue a log statement, the logging framework iterates over each logger,
+     * and checks to see if it should forward the logMessage to the logger.
+     * This check is done using the level parameter passed to this method.
+     *
+     * For example:
+     *
+     * `[AWSDDLog addLogger:consoleLogger withLogLevel:AWSDDLogLevelVerbose];`
+     * `[AWSDDLog addLogger:fileLogger    withLogLevel:AWSDDLogLevelWarning];`
+     *
+     * `AWSDDLogError(@"oh no");` => gets forwarded to consoleLogger & fileLogger
+     * `AWSDDLogInfo(@"hi");`     => gets forwarded to consoleLogger only
+     *
+     * It is important to remember that Lumberjack uses a BITMASK.
+     * Many developers & third party frameworks may define extra log levels & flags.
+     * For example:
+     *
+     * `#define SOME_FRAMEWORK_LOG_FLAG_TRACE (1 << 6) // 0...1000000`
+     *
+     * So if you specify `AWSDDLogLevelVerbose` to this method, you won't see the framework's trace messages.
+     *
+     * `(SOME_FRAMEWORK_LOG_FLAG_TRACE & AWSDDLogLevelVerbose) => (01000000 & 00011111) => NO`
+     *
+     * Consider passing `AWSDDLogLevelAll` to this method, which has all bits set.
+     * You can also use the exclusive-or bitwise operator to get a bitmask that has all flags set,
+     * except the ones you explicitly don't want. For example, if you wanted everything except verbose & debug:
+     *
+     * `((AWSDDLogLevelAll ^ AWSDDLogLevelVerbose) | AWSDDLogLevelInfo)`
+     */
+    @available(*, deprecated, message: "Providing a nil logger will fail silently. Use add(_:with:) with a non-optional logger instead.")
+    func add(_ logger: AWSDDLogger?, with level: AWSDDLogLevel) {
+        if let logger = logger {
+            add(logger, with: level)
+        }
+    }
+}
diff --git a/AWSCore/Logging/Extensions/AWSDDMultiFormatter.h b/AWSCore/Logging/Extensions/AWSDDMultiFormatter.h
index 3650abcf380..caa64774d83 100644
--- a/AWSCore/Logging/Extensions/AWSDDMultiFormatter.h
+++ b/AWSCore/Logging/Extensions/AWSDDMultiFormatter.h
@@ -1,6 +1,6 @@
 // Software License Agreement (BSD License)
 //
-// Copyright (c) 2010-2016, Deusty, LLC
+// Copyright (c) 2010-2024, Deusty, LLC
 // All rights reserved.
 //
 // Redistribution and use of this software in source and binary forms,
@@ -22,6 +22,8 @@
 
 #import "AWSDDLog.h"
 
+NS_ASSUME_NONNULL_BEGIN
+
 /**
  * This formatter can be used to chain different formatters together.
  * The log message will processed in the order of the formatters added.
@@ -31,7 +33,7 @@
 /**
  *  Array of chained formatters
  */
-@property (readonly) NSArray<id<AWSDDLogFormatter>> *formatters;
+@property (nonatomic, readonly) NSArray<id<AWSDDLogFormatter>> *formatters;
 
 /**
  *  Add a new formatter
@@ -54,3 +56,5 @@
 - (BOOL)isFormattingWithFormatter:(id<AWSDDLogFormatter>)formatter;
 
 @end
+
+NS_ASSUME_NONNULL_END
diff --git a/AWSCore/Mantle/AWSMTLModel+NSCoding.m b/AWSCore/Mantle/AWSMTLModel+NSCoding.m
index c8b4d32d597..cecdd655151 100644
--- a/AWSCore/Mantle/AWSMTLModel+NSCoding.m
+++ b/AWSCore/Mantle/AWSMTLModel+NSCoding.m
@@ -12,7 +12,7 @@
 #import "AWSMTLReflection.h"
 #import <objc/runtime.h>
 
-void awsmtl_loadMTLNSCoding(){
+void awsmtl_loadMTLNSCoding(void){
 }
 
 // Used in archives to store the modelVersion of the archived instance.
diff --git a/AWSCore/Mantle/NSValueTransformer+AWSMTLPredefinedTransformerAdditions.m b/AWSCore/Mantle/NSValueTransformer+AWSMTLPredefinedTransformerAdditions.m
index 4d9c6528dfc..ee0e91a286a 100644
--- a/AWSCore/Mantle/NSValueTransformer+AWSMTLPredefinedTransformerAdditions.m
+++ b/AWSCore/Mantle/NSValueTransformer+AWSMTLPredefinedTransformerAdditions.m
@@ -11,7 +11,7 @@
 #import "AWSMTLModel.h"
 #import "AWSMTLValueTransformer.h"
 
-void awsmtl_loadMTLPredefinedTransformerAdditions(){
+void awsmtl_loadMTLPredefinedTransformerAdditions(void){
 }
 
 NSString * const AWSMTLURLValueTransformerName = @"AWSMTLURLValueTransformerName";
diff --git a/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.h b/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.h
index c63fc09a28d..2920e5f1f30 100644
--- a/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.h
+++ b/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.h
@@ -87,12 +87,12 @@ typedef NS_ENUM(NSInteger, AWSUICKeyChainStoreAuthenticationType) {
 typedef NS_ENUM(NSInteger, AWSUICKeyChainStoreAccessibility) {
     AWSUICKeyChainStoreAccessibilityWhenUnlocked = 1,
     AWSUICKeyChainStoreAccessibilityAfterFirstUnlock,
-    AWSUICKeyChainStoreAccessibilityAlways,
+    AWSUICKeyChainStoreAccessibilityAlways __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSUICKeyChainStoreAccessibilityAfterFirstUnlock"),
     AWSUICKeyChainStoreAccessibilityWhenPasscodeSetThisDeviceOnly
     __OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0),
     AWSUICKeyChainStoreAccessibilityWhenUnlockedThisDeviceOnly,
     AWSUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly,
-    AWSUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly,
+    AWSUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSUICKeyChainStoreAccessibilityAfterFirstUnlockThisDeviceOnly"),
 }
 __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_4_0);
 
diff --git a/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.m b/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.m
index b6f8dbd5b0a..ccd729a3a90 100644
--- a/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.m
+++ b/AWSCore/UICKeyChainStore/AWSUICKeyChainStore.m
@@ -1337,6 +1337,11 @@ - (CFTypeRef)authenticationTypeObject
     }
 }
 
+// The following keys are deprecated, but they still need to be supported:
+// - AWSUICKeyChainStoreAccessibilityAlways, kSecAttrAccessibleAlways,
+// - AWSUICKeyChainStoreAccessibilityAlwaysThisDeviceOnly, kSecAttrAccessibleAlwaysThisDeviceOnly
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 - (CFTypeRef)accessibilityObject
 {
     switch (_accessibility) {
@@ -1358,6 +1363,7 @@ - (CFTypeRef)accessibilityObject
             return nil;
     }
 }
+#pragma clang diagnostic pop
 
 + (NSError *)argumentError:(NSString *)message
 {
diff --git a/AWSCore/Utility/AWSNSCodingUtilities.m b/AWSCore/Utility/AWSNSCodingUtilities.m
index c4af7b3ac3e..0d11bd2a8c0 100644
--- a/AWSCore/Utility/AWSNSCodingUtilities.m
+++ b/AWSCore/Utility/AWSNSCodingUtilities.m
@@ -23,17 +23,12 @@ @implementation AWSNSCodingUtilities
 + (nullable NSData *)versionSafeArchivedDataWithRootObject:(id)obj
                                      requiringSecureCoding:(BOOL)requireSecureCoding
                                                      error:(NSError *__autoreleasing *)error {
-    NSData *archivedData;
-    if (@available(iOS 11, *)) {
-        archivedData = [NSKeyedArchiver archivedDataWithRootObject:obj
-                                             requiringSecureCoding:requireSecureCoding
-                                                             error:error];
-        if (error && *error) {
-            AWSDDLogError(@"Error archiving object: %@", *error);
-            return nil;
-        }
-    } else {
-        archivedData = [NSKeyedArchiver archivedDataWithRootObject:obj];
+    NSData *archivedData = [NSKeyedArchiver archivedDataWithRootObject:obj
+                                                 requiringSecureCoding:requireSecureCoding
+                                                                 error:error];
+    if (error && *error) {
+        AWSDDLogError(@"Error archiving object: %@", *error);
+        return nil;
     }
 
     return archivedData;
@@ -44,18 +39,12 @@ + (nullable NSData *)versionSafeArchivedDataWithRootObject:(id)obj
 + (nullable id)versionSafeUnarchivedObjectOfClass:(Class)cls
                                          fromData:(NSData *)data
                                             error:(NSError *__autoreleasing *)error {
-    id returnValue;
-
-    if (@available(iOS 11, *)) {
-        returnValue = [NSKeyedUnarchiver unarchivedObjectOfClass:cls
-                                                        fromData:data
-                                                           error:error];
-        if (error && *error) {
-            AWSDDLogError(@"Error unarchiving class `%@`: %@", cls, *error);
-            return nil;
-        }
-    } else {
-        returnValue = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+    id returnValue = [NSKeyedUnarchiver unarchivedObjectOfClass:cls
+                                                       fromData:data
+                                                          error:error];
+    if (error && *error) {
+        AWSDDLogError(@"Error unarchiving class `%@`: %@", cls, *error);
+        return nil;
     }
 
     return returnValue;
@@ -64,18 +53,12 @@ + (nullable id)versionSafeUnarchivedObjectOfClass:(Class)cls
 + (nullable id)versionSafeUnarchivedObjectOfClasses:(NSSet<Class> *)classes
                                            fromData:(NSData *)data
                                               error:(NSError *__autoreleasing *)error {
-    id returnValue;
-
-    if (@available(iOS 11, *)) {
-        returnValue = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
-                                                          fromData:data
-                                                             error:error];
-        if (error && *error) {
-            AWSDDLogError(@"Error unarchiving data into allowed classes `%@`: %@", classes, *error);
-            return nil;
-        }
-    } else {
-        returnValue = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+    id returnValue = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes
+                                                         fromData:data
+                                                            error:error];
+    if (error && *error) {
+        AWSDDLogError(@"Error unarchiving data into allowed classes `%@`: %@", classes, *error);
+        return nil;
     }
 
     return returnValue;
@@ -83,27 +66,20 @@ + (nullable id)versionSafeUnarchivedObjectOfClasses:(NSSet<Class> *)classes
 
 + (NSMutableDictionary *)versionSafeMutableDictionaryFromData:(NSData *)data
                                                         error:(NSError *__autoreleasing *)error {
-    NSMutableDictionary *returnValue;
-
-    if (@available(iOS 11, *)) {
-        NSSet *allowableClasses = [[NSSet alloc] initWithObjects:[NSMutableString class],
-                                   [NSNumber class],
-                                   [NSString class],
-                                   [NSDictionary class],
-                                   nil];
-        NSDictionary *immutableDict = [AWSNSCodingUtilities versionSafeUnarchivedObjectOfClasses:allowableClasses
-                                                                                        fromData:data
-                                                                                           error:error];
-        if (error && *error) {
-            AWSDDLogError(@"Error unarchiving data into allowed classes `%@`: %@", allowableClasses, *error);
-            return nil;
-        }
-
-        returnValue = [immutableDict mutableCopy];
-    } else {
-        returnValue = [NSKeyedUnarchiver unarchiveObjectWithData:data];
+    NSSet *allowableClasses = [[NSSet alloc] initWithObjects:[NSMutableString class],
+                               [NSNumber class],
+                               [NSString class],
+                               [NSDictionary class],
+                               nil];
+    NSDictionary *immutableDict = [AWSNSCodingUtilities versionSafeUnarchivedObjectOfClasses:allowableClasses
+                                                                                    fromData:data
+                                                                                       error:error];
+    if (error && *error) {
+        AWSDDLogError(@"Error unarchiving data into allowed classes `%@`: %@", allowableClasses, *error);
+        return nil;
     }
 
+    NSMutableDictionary *returnValue = [immutableDict mutableCopy];
     return returnValue;
 }
 
diff --git a/AWSDynamoDB.podspec b/AWSDynamoDB.podspec
index a1a315a8c4b..220e5dfcace 100644
--- a/AWSDynamoDB.podspec
+++ b/AWSDynamoDB.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSEC2.podspec b/AWSEC2.podspec
index 08fc93145e7..0b1306903a7 100644
--- a/AWSEC2.podspec
+++ b/AWSEC2.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSElasticLoadBalancing.podspec b/AWSElasticLoadBalancing.podspec
index da027702e18..301dbd18395 100644
--- a/AWSElasticLoadBalancing.podspec
+++ b/AWSElasticLoadBalancing.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSFacebookSignIn.podspec b/AWSFacebookSignIn.podspec
index 6c103234fb0..4769a454d9b 100644
--- a/AWSFacebookSignIn.podspec
+++ b/AWSFacebookSignIn.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSGoogleSignIn.podspec b/AWSGoogleSignIn.podspec
index 224a1c2f0bc..d8bbcfe9a6e 100644
--- a/AWSGoogleSignIn.podspec
+++ b/AWSGoogleSignIn.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSIoT.podspec b/AWSIoT.podspec
index 826644c719f..c2dbf49322d 100644
--- a/AWSIoT.podspec
+++ b/AWSIoT.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSIoT/AWSIoTKeyChainTypes.h b/AWSIoT/AWSIoTKeyChainTypes.h
index b2ddb27d4f2..81747eeb05e 100644
--- a/AWSIoT/AWSIoTKeyChainTypes.h
+++ b/AWSIoT/AWSIoTKeyChainTypes.h
@@ -22,11 +22,11 @@ NS_ASSUME_NONNULL_BEGIN
 typedef NS_ENUM(NSInteger, AWSIoTKeyChainAccessibility) {
     AWSIoTKeyChainAccessibilityWhenUnlocked = 1,
     AWSIoTKeyChainAccessibilityAfterFirstUnlock,
-    AWSIoTKeyChainAccessibilityAlways,
+    AWSIoTKeyChainAccessibilityAlways __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSIoTKeyChainAccessibilityAfterFirstUnlock"),
     AWSIoTKeyChainAccessibilityWhenPasscodeSetThisDeviceOnly,
     AWSIoTKeyChainAccessibilityWhenUnlockedThisDeviceOnly,
     AWSIoTKeyChainAccessibilityAfterFirstUnlockThisDeviceOnly,
-    AWSIoTKeyChainAccessibilityAlwaysThisDeviceOnly,
+    AWSIoTKeyChainAccessibilityAlwaysThisDeviceOnly __deprecated_enum_msg("Use an accessibility level that provides some user protection, such as AWSIoTKeyChainAccessibilityAfterFirstUnlockThisDeviceOnly"),
 };
 
 NS_ASSUME_NONNULL_END
diff --git a/AWSIoT/Internal/AWSIoTKeychain.m b/AWSIoT/Internal/AWSIoTKeychain.m
index e62ffcf3f06..a8871fb470d 100644
--- a/AWSIoT/Internal/AWSIoTKeychain.m
+++ b/AWSIoT/Internal/AWSIoTKeychain.m
@@ -522,6 +522,11 @@ + (void)setKeyChainAccessibility:(AWSIoTKeyChainAccessibility)accessibility {
     _accessibility = accessibility;
 }
 
+// The following keys are deprecated, but they still need to be supported:
+// - AWSIoTKeyChainAccessibilityAlways, kSecAttrAccessibleAlways,
+// - AWSIoTKeyChainAccessibilityAlwaysThisDeviceOnly, kSecAttrAccessibleAlwaysThisDeviceOnly
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
 + (CFTypeRef)accessibilityType {
     switch (_accessibility) {
         case AWSIoTKeyChainAccessibilityWhenUnlocked:
@@ -542,5 +547,6 @@ + (CFTypeRef)accessibilityType {
             return nil;
     }
 }
+#pragma clang diagnostic pop
 
 @end
diff --git a/AWSKMS.podspec b/AWSKMS.podspec
index 95f8a10b727..35393f03369 100644
--- a/AWSKMS.podspec
+++ b/AWSKMS.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSKinesis.podspec b/AWSKinesis.podspec
index 15792b6f228..ae7281745a7 100644
--- a/AWSKinesis.podspec
+++ b/AWSKinesis.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSKinesisVideo.podspec b/AWSKinesisVideo.podspec
index b6b218b63da..e6448acbfc4 100644
--- a/AWSKinesisVideo.podspec
+++ b/AWSKinesisVideo.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSKinesisVideoArchivedMedia.podspec b/AWSKinesisVideoArchivedMedia.podspec
index aaf30f318cd..499cbca0f13 100644
--- a/AWSKinesisVideoArchivedMedia.podspec
+++ b/AWSKinesisVideoArchivedMedia.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSKinesisVideoSignaling.podspec b/AWSKinesisVideoSignaling.podspec
index 2b055b92a2a..ebc12f11915 100644
--- a/AWSKinesisVideoSignaling.podspec
+++ b/AWSKinesisVideoSignaling.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSKinesisVideoWebRTCStorage.podspec b/AWSKinesisVideoWebRTCStorage.podspec
index e8a2fcfce7b..5a8c3be47c3 100644
--- a/AWSKinesisVideoWebRTCStorage.podspec
+++ b/AWSKinesisVideoWebRTCStorage.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSLambda.podspec b/AWSLambda.podspec
index 870f79b5c47..b2d3a813b01 100644
--- a/AWSLambda.podspec
+++ b/AWSLambda.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSLex.podspec b/AWSLex.podspec
index 1ba59d1ae63..5cff6c53e49 100644
--- a/AWSLex.podspec
+++ b/AWSLex.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache 2.0 AND AWS Customer Agreement'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSLex/AWSLexSignature.m b/AWSLex/AWSLexSignature.m
index c2bdbab78a9..59f5a6ab95d 100644
--- a/AWSLex/AWSLexSignature.m
+++ b/AWSLex/AWSLexSignature.m
@@ -89,7 +89,7 @@ - (NSString *)signRequest:(NSMutableURLRequest *)request credentials:(AWSCredent
         contentSha256 = @"UNSIGNED-PAYLOAD";
         [request setValue:contentSha256 forHTTPHeaderField:@"x-amz-content-sha256"];
     }else{
-        contentSha256 = [AWSSignatureSignerUtility hexEncode:[[NSString alloc] initWithData:[AWSSignatureSignerUtility hash:request.HTTPBody] encoding:NSASCIIStringEncoding]];
+        contentSha256 = [AWSSignatureSignerUtility hexEncode:[[NSString alloc] initWithData:[AWSSignatureSignerUtility hashData:request.HTTPBody] encoding:NSASCIIStringEncoding]];
     }
     
     NSString *canonicalRequest = [AWSSignatureV4Signer getCanonicalizedRequest:request.HTTPMethod
diff --git a/AWSLocation.podspec b/AWSLocation.podspec
index cf17b2b5b39..93e87134844 100644
--- a/AWSLocation.podspec
+++ b/AWSLocation.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSLogs.podspec b/AWSLogs.podspec
index 6b94a4b4fb5..4f6627f21ea 100644
--- a/AWSLogs.podspec
+++ b/AWSLogs.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSMachineLearning.podspec b/AWSMachineLearning.podspec
index fd15fd9a034..8353eec66df 100644
--- a/AWSMachineLearning.podspec
+++ b/AWSMachineLearning.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSMobileClient.podspec b/AWSMobileClient.podspec
index c31f1977cd2..245ab8d888e 100644
--- a/AWSMobileClient.podspec
+++ b/AWSMobileClient.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'https://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSPinpoint.podspec b/AWSPinpoint.podspec
index 5d554d1d60f..7c4894a96f4 100644
--- a/AWSPinpoint.podspec
+++ b/AWSPinpoint.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSPinpoint/AWSPinpointEvent.m b/AWSPinpoint/AWSPinpointEvent.m
index e7660fe69df..cc159c2ed85 100644
--- a/AWSPinpoint/AWSPinpointEvent.m
+++ b/AWSPinpoint/AWSPinpointEvent.m
@@ -188,7 +188,7 @@ + (NSString*)trimKey:(NSString*)theKey
     NSString* trimmedKey = [AWSPinpointStringUtils clipString:theKey
                                                    toMaxChars:AWSPinpointEventMaxAttributeAndMetricKeyLength andAppendEllipses:NO];
     if(trimmedKey.length < theKey.length) {
-        AWSDDLogWarn(@"The %@ key has been trimmed to a length of %0d characters", theType, AWSPinpointEventMaxAttributeAndMetricKeyLength);
+        AWSDDLogWarn(@"The %@ key has been trimmed to a length of %0ld characters", theType, (long)AWSPinpointEventMaxAttributeAndMetricKeyLength);
     }
     
     return trimmedKey;
@@ -198,7 +198,7 @@ + (NSString*)trimValue:(NSString*)theValue {
     NSString* trimmedValue = [AWSPinpointStringUtils clipString:theValue
                                                      toMaxChars:AWSPinpointEventMaxAttributeValueLength andAppendEllipses:NO];
     if(trimmedValue.length < theValue.length) {
-        AWSDDLogWarn( @"The attribute value has been trimmed to a length of %0d characters", AWSPinpointEventMaxAttributeValueLength);
+        AWSDDLogWarn( @"The attribute value has been trimmed to a length of %0ld characters", (long)AWSPinpointEventMaxAttributeValueLength);
     }
     
     return trimmedValue;
diff --git a/AWSPinpoint/AWSPinpointNotificationManager.m b/AWSPinpoint/AWSPinpointNotificationManager.m
index e4229ca64a8..6774f63a167 100644
--- a/AWSPinpoint/AWSPinpointNotificationManager.m
+++ b/AWSPinpoint/AWSPinpointNotificationManager.m
@@ -174,7 +174,10 @@ - (void)handleNotificationDeepLinkForNotification:(NSDictionary*) userInfo {
         NSURL *deepLinkURL = [NSURL URLWithString:amaDict[AWSCampaignDeepLinkKey]];
         if ([[UIApplication sharedApplication] canOpenURL:deepLinkURL]) {
             dispatch_async(dispatch_get_main_queue(), ^{
-                [[UIApplication sharedApplication] openURL:deepLinkURL];
+                [[UIApplication sharedApplication] openURL:deepLinkURL
+                                                   options:@{}
+                                         completionHandler:nil
+                ];
             });
         }
     }
diff --git a/AWSPinpointTests/AWSPinpointTargetingClientTests.m b/AWSPinpointTests/AWSPinpointTargetingClientTests.m
index 0ad6bd3d3e4..12793ed4c4b 100644
--- a/AWSPinpointTests/AWSPinpointTargetingClientTests.m
+++ b/AWSPinpointTests/AWSPinpointTargetingClientTests.m
@@ -33,7 +33,7 @@
 @interface AWSPinpointTargetingClientTests : XCTestCase
 @property (nonatomic, strong) AWSPinpoint *pinpoint;
 @property (nonatomic, strong) AWSPinpointConfiguration *configuration;
-@property (nonatomic, strong) UIApplication *application;
+@property (nonatomic, strong) id mockApplication;
 @property (nonatomic, strong) NSUserDefaults *userDefaults;
 @property (nonatomic, strong) AWSUICKeyChainStore *keychain;
 
@@ -72,6 +72,7 @@ - (void)setUp {
 }
 
 - (void)tearDown {
+    [self.mockApplication stopMocking];
     [super tearDown];
 }
 
@@ -122,6 +123,7 @@ - (void)initializeMockApplicationWithRemoteNotifications:(BOOL)withRemoteNotific
     UIUserNotificationSettings *notificationSettings = [UIUserNotificationSettings settingsForTypes:notificationType categories:nil];
     OCMStub([mockApplication currentUserNotificationSettings]).andReturn(notificationSettings);
     OCMStub([mockApplication isRegisteredForRemoteNotifications]).andReturn(withRemoteNotifications);
+    self.mockApplication = mockApplication;
 }
 
 - (void)testConstructors {
diff --git a/AWSPolly.podspec b/AWSPolly.podspec
index 7541a8656f3..10468624907 100644
--- a/AWSPolly.podspec
+++ b/AWSPolly.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSRekognition.podspec b/AWSRekognition.podspec
index d44253efc14..0c2625f668a 100644
--- a/AWSRekognition.podspec
+++ b/AWSRekognition.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSS3.podspec b/AWSS3.podspec
index fcd149da3ae..c87353abda2 100644
--- a/AWSS3.podspec
+++ b/AWSS3.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSS3UnitTests/AWSS3TransferUtilityCreatePartialFileTests.swift b/AWSS3UnitTests/AWSS3TransferUtilityCreatePartialFileTests.swift
index a4ec01c1f36..39ba61d657b 100644
--- a/AWSS3UnitTests/AWSS3TransferUtilityCreatePartialFileTests.swift
+++ b/AWSS3UnitTests/AWSS3TransferUtilityCreatePartialFileTests.swift
@@ -33,7 +33,7 @@ class AWSS3TransferUtilityCreatePartialFileTests: XCTestCase {
         self.transferUtility = transferUtility
 
         AWSDDLog.sharedInstance.logLevel = .verbose
-        AWSDDLog.sharedInstance.add(AWSDDTTYLogger())
+        AWSDDLog.sharedInstance.add(AWSDDTTYLogger.sharedInstance)
     }
 
     func testCreatingPartialFile() throws {
diff --git a/AWSSES.podspec b/AWSSES.podspec
index 5b30e9cdab9..f941820e496 100644
--- a/AWSSES.podspec
+++ b/AWSSES.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSSNS.podspec b/AWSSNS.podspec
index 531b3652b3c..8df925cdc94 100644
--- a/AWSSNS.podspec
+++ b/AWSSNS.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSSQS.podspec b/AWSSQS.podspec
index 1c2b52a1f62..32e1a91d71c 100644
--- a/AWSSQS.podspec
+++ b/AWSSQS.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSSageMakerRuntime.podspec b/AWSSageMakerRuntime.podspec
index 1c15b24dcb8..d762df5766a 100644
--- a/AWSSageMakerRuntime.podspec
+++ b/AWSSageMakerRuntime.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSSimpleDB.podspec b/AWSSimpleDB.podspec
index 4d6f4c25f80..b1c8addc710 100644
--- a/AWSSimpleDB.podspec
+++ b/AWSSimpleDB.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSTextract.podspec b/AWSTextract.podspec
index 72c35137360..00773e3befd 100644
--- a/AWSTextract.podspec
+++ b/AWSTextract.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSTranscribe.podspec b/AWSTranscribe.podspec
index 071db921cba..30f35b2cb2c 100644
--- a/AWSTranscribe.podspec
+++ b/AWSTranscribe.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSTranscribeStreaming.podspec b/AWSTranscribeStreaming.podspec
index f1706d1f0f3..42971bc3df1 100644
--- a/AWSTranscribeStreaming.podspec
+++ b/AWSTranscribeStreaming.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSTranslate.podspec b/AWSTranslate.podspec
index 989482dab7f..ec428c65acb 100644
--- a/AWSTranslate.podspec
+++ b/AWSTranslate.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSUserPoolsSignIn.podspec b/AWSUserPoolsSignIn.podspec
index 20fd11beb4b..35792d63ae2 100644
--- a/AWSUserPoolsSignIn.podspec
+++ b/AWSUserPoolsSignIn.podspec
@@ -8,7 +8,7 @@ Pod::Spec.new do |s|
    s.homepage     = 'http://aws.amazon.com/mobile/sdk'
    s.license      = 'Apache License, Version 2.0'
    s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-   s.platform     = :ios, '9.0'
+   s.platform     = :ios, '12.0'
    s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                       :tag => s.version}
    s.requires_arc = true
diff --git a/AWSiOSSDKv2.podspec b/AWSiOSSDKv2.podspec
index de4b85d3ced..8d7487888d8 100644
--- a/AWSiOSSDKv2.podspec
+++ b/AWSiOSSDKv2.podspec
@@ -11,7 +11,7 @@ Pod::Spec.new do |s|
   s.homepage     = 'http://aws.amazon.com/mobile/sdk'
   s.license      = 'Apache License, Version 2.0'
   s.author       = { 'Amazon Web Services' => 'amazonwebservices' }
-  s.platform     = :ios, '9.0'
+  s.platform     = :ios, '12.0'
   s.source       = { :git => 'https://github.com/aws-amplify/aws-sdk-ios.git',
                      :tag => s.version}
   s.requires_arc = true
diff --git a/AWSiOSSDKv2.xcodeproj/project.pbxproj b/AWSiOSSDKv2.xcodeproj/project.pbxproj
index ed04798d207..43697da4691 100644
--- a/AWSiOSSDKv2.xcodeproj/project.pbxproj
+++ b/AWSiOSSDKv2.xcodeproj/project.pbxproj
@@ -283,30 +283,6 @@
 		183BD93E1D8A4076004B2659 /* AWSTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB8EF2E1C6A69A00098B15B /* AWSTestUtility.m */; };
 		183BD9471D8B0030004B2659 /* AWSTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB8EF2E1C6A69A00098B15B /* AWSTestUtility.m */; };
 		183BD9481D8B0040004B2659 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CEB8EF551C6A6A2E0098B15B /* libOCMock.a */; };
-		184F430F1E930A2D004F3FE2 /* AWSCocoaLumberjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F42FE1E930A2D004F3FE2 /* AWSCocoaLumberjack.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F43101E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F42FF1E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h */; };
-		184F43111E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43001E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m */; };
-		184F43121E930A2D004F3FE2 /* AWSDDASLLogCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43011E930A2D004F3FE2 /* AWSDDASLLogCapture.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F43131E930A2D004F3FE2 /* AWSDDASLLogCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43021E930A2D004F3FE2 /* AWSDDASLLogCapture.m */; };
-		184F43141E930A2D004F3FE2 /* AWSDDASLLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43031E930A2D004F3FE2 /* AWSDDASLLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F43151E930A2D004F3FE2 /* AWSDDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43041E930A2D004F3FE2 /* AWSDDASLLogger.m */; };
-		184F43161E930A2D004F3FE2 /* AWSDDAssertMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43051E930A2D004F3FE2 /* AWSDDAssertMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F43171E930A2D004F3FE2 /* AWSDDFileLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43061E930A2D004F3FE2 /* AWSDDFileLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F43181E930A2D004F3FE2 /* AWSDDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43071E930A2D004F3FE2 /* AWSDDFileLogger.m */; };
-		184F431A1E930A2D004F3FE2 /* AWSDDLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43091E930A2D004F3FE2 /* AWSDDLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F431B1E930A2D004F3FE2 /* AWSDDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F430A1E930A2D004F3FE2 /* AWSDDLog.m */; };
-		184F431C1E930A2D004F3FE2 /* AWSDDLog+LOGV.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F430B1E930A2D004F3FE2 /* AWSDDLog+LOGV.h */; };
-		184F431D1E930A2D004F3FE2 /* AWSDDLogMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F430C1E930A2D004F3FE2 /* AWSDDLogMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F431E1E930A2D004F3FE2 /* AWSDDTTYLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F430D1E930A2D004F3FE2 /* AWSDDTTYLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F431F1E930A2D004F3FE2 /* AWSDDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F430E1E930A2D004F3FE2 /* AWSDDTTYLogger.m */; };
-		184F43261E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43201E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.h */; };
-		184F43271E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43211E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.m */; };
-		184F43281E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43221E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.h */; };
-		184F43291E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F43231E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.m */; };
-		184F432A1E930A34004F3FE2 /* AWSDDMultiFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43241E930A34004F3FE2 /* AWSDDMultiFormatter.h */; };
-		184F432E1E930E05004F3FE2 /* AWSDDOSLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F432C1E930E05004F3FE2 /* AWSDDOSLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
-		184F432F1E930E05004F3FE2 /* AWSDDOSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F432D1E930E05004F3FE2 /* AWSDDOSLogger.m */; };
-		184F43311E9336BD004F3FE2 /* AWSDDLegacyMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 184F43301E9336BD004F3FE2 /* AWSDDLegacyMacros.h */; };
 		185251351DED4F9800AF47F6 /* AWSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; };
 		1868C0261E207E33001CDA82 /* AWSGeneric.h in Headers */ = {isa = PBXBuildFile; fileRef = 1868C0251E207E33001CDA82 /* AWSGeneric.h */; settings = {ATTRIBUTES = (Public, ); }; };
 		186ABB031D9CADBC00AB8980 /* libBlueAudioSourceiOS.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 186ABB021D9CADBC00AB8980 /* libBlueAudioSourceiOS.a */; };
@@ -622,8 +598,43 @@
 		5C1590172755727C00F88085 /* AWSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; };
 		5C1978DD2702364800F9C11E /* AWSLocationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5C1978DC2702364800F9C11E /* AWSLocationTests.swift */; };
 		5C71F33F295672B8001183A4 /* guten_tag.wav in Resources */ = {isa = PBXBuildFile; fileRef = 5C71F33E295672B8001183A4 /* guten_tag.wav */; };
+		687952932B8FE2C5001E8990 /* AWSDDLog+Optional.swift in Sources */ = {isa = PBXBuildFile; fileRef = 687952922B8FE2C5001E8990 /* AWSDDLog+Optional.swift */; };
 		6883619E2B72D1C200D74FF4 /* AWSS3PreSignedURLBuilderUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6883619D2B72D1C200D74FF4 /* AWSS3PreSignedURLBuilderUnitTests.swift */; };
 		688361A12B73D25B00D74FF4 /* AWSIoTStreamThreadTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 688361A02B73D25B00D74FF4 /* AWSIoTStreamThreadTests.m */; };
+		68A45B792B8D5F7D00A0851E /* AWSCocoaLumberjack.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B542B8D5F7C00A0851E /* AWSCocoaLumberjack.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45B7B2B8D5F7D00A0851E /* AWSDDASLLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B572B8D5F7C00A0851E /* AWSDDASLLogger.m */; };
+		68A45B7C2B8D5F7D00A0851E /* AWSDDFileLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B582B8D5F7C00A0851E /* AWSDDFileLogger.m */; };
+		68A45B7D2B8D5F7D00A0851E /* AWSDDFileLogger+Internal.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B592B8D5F7C00A0851E /* AWSDDFileLogger+Internal.h */; };
+		68A45B7E2B8D5F7D00A0851E /* AWSDDTTYLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B5A2B8D5F7C00A0851E /* AWSDDTTYLogger.m */; };
+		68A45B7F2B8D5F7D00A0851E /* AWSDDContextFilterLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B5C2B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter.m */; };
+		68A45B802B8D5F7D00A0851E /* AWSDDDispatchQueueLogFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B5D2B8D5F7C00A0851E /* AWSDDDispatchQueueLogFormatter.m */; };
+		68A45B812B8D5F7D00A0851E /* AWSDDFileLogger+Buffering.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B5E2B8D5F7C00A0851E /* AWSDDFileLogger+Buffering.m */; };
+		68A45B822B8D5F7D00A0851E /* AWSDDMultiFormatter.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B5F2B8D5F7C00A0851E /* AWSDDMultiFormatter.m */; };
+		68A45B832B8D5F7D00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B602B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.m */; };
+		68A45B842B8D5F7D00A0851E /* AWSDDOSLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B612B8D5F7C00A0851E /* AWSDDOSLogger.m */; };
+		68A45B852B8D5F7D00A0851E /* AWSDDLegacyMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B622B8D5F7C00A0851E /* AWSDDLegacyMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45B862B8D5F7D00A0851E /* AWSDDLoggerNames.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B632B8D5F7C00A0851E /* AWSDDLoggerNames.m */; };
+		68A45B982B8D5F7D00A0851E /* AWSDDLog.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B762B8D5F7D00A0851E /* AWSDDLog.m */; };
+		68A45B992B8D5F7D00A0851E /* AWSDDASLLogCapture.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B772B8D5F7D00A0851E /* AWSDDASLLogCapture.m */; };
+		68A45B9A2B8D5F7D00A0851E /* AWSDDAbstractDatabaseLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45B782B8D5F7D00A0851E /* AWSDDAbstractDatabaseLogger.m */; };
+		68A45BAC2B8D6ADE00A0851E /* AWSDDASLLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B9B2B8D6ADD00A0851E /* AWSDDASLLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BAD2B8D6ADE00A0851E /* AWSDDTTYLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B9C2B8D6ADD00A0851E /* AWSDDTTYLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BAE2B8D6ADE00A0851E /* AWSDDAbstractDatabaseLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B9D2B8D6ADD00A0851E /* AWSDDAbstractDatabaseLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BAF2B8D6ADE00A0851E /* AWSDDFileLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B9E2B8D6ADD00A0851E /* AWSDDFileLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB02B8D6ADE00A0851E /* AWSDDLog+LOGV.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45B9F2B8D6ADD00A0851E /* AWSDDLog+LOGV.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB12B8D6ADE00A0851E /* AWSDDLogMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA02B8D6ADD00A0851E /* AWSDDLogMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB22B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA12B8D6ADD00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB32B8D6ADE00A0851E /* AWSDDASLLogCapture.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA22B8D6ADD00A0851E /* AWSDDASLLogCapture.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB42B8D6ADE00A0851E /* AWSDDDispatchQueueLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA32B8D6ADD00A0851E /* AWSDDDispatchQueueLogFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB62B8D6ADE00A0851E /* AWSDDLog.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA52B8D6ADE00A0851E /* AWSDDLog.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB72B8D6ADE00A0851E /* AWSDDLoggerNames.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA62B8D6ADE00A0851E /* AWSDDLoggerNames.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB82B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA72B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BB92B8D6ADE00A0851E /* AWSDDFileLogger+Buffering.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA82B8D6ADE00A0851E /* AWSDDFileLogger+Buffering.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BBA2B8D6ADE00A0851E /* AWSDDOSLogger.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BA92B8D6ADE00A0851E /* AWSDDOSLogger.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BBB2B8D6ADE00A0851E /* AWSDDAssertMacros.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BAA2B8D6ADE00A0851E /* AWSDDAssertMacros.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BBC2B8D6ADE00A0851E /* AWSDDMultiFormatter.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BAB2B8D6ADE00A0851E /* AWSDDMultiFormatter.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BBF2B8E74F900A0851E /* AWSCLIColor.h in Headers */ = {isa = PBXBuildFile; fileRef = 68A45BBD2B8E74F800A0851E /* AWSCLIColor.h */; settings = {ATTRIBUTES = (Public, ); }; };
+		68A45BC02B8E74F900A0851E /* AWSCLIColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 68A45BBE2B8E74F900A0851E /* AWSCLIColor.m */; };
 		68EE1A6C2B713D8100B7CF41 /* AWSIoTStreamThread.h in Headers */ = {isa = PBXBuildFile; fileRef = 68EE1A6B2B713D8100B7CF41 /* AWSIoTStreamThread.h */; };
 		68EE1A6E2B713D8900B7CF41 /* AWSIoTStreamThread.m in Sources */ = {isa = PBXBuildFile; fileRef = 68EE1A6D2B713D8900B7CF41 /* AWSIoTStreamThread.m */; };
 		6BE9D6AA25A54EBA00AB5C9A /* AWSIotDataManagerRetainTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6BE9D6A925A54EBA00AB5C9A /* AWSIotDataManagerRetainTests.swift */; };
@@ -2925,30 +2936,6 @@
 		181270E31E8EB78900174785 /* AWSLogsService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSLogsService.h; sourceTree = "<group>"; };
 		181270E41E8EB78900174785 /* AWSLogsService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSLogsService.m; sourceTree = "<group>"; };
 		181270EB1E8EB7D300174785 /* AWSGeneralLogsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSGeneralLogsTests.m; sourceTree = "<group>"; };
-		184F42FE1E930A2D004F3FE2 /* AWSCocoaLumberjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSCocoaLumberjack.h; sourceTree = "<group>"; };
-		184F42FF1E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDAbstractDatabaseLogger.h; sourceTree = "<group>"; };
-		184F43001E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDAbstractDatabaseLogger.m; sourceTree = "<group>"; };
-		184F43011E930A2D004F3FE2 /* AWSDDASLLogCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDASLLogCapture.h; sourceTree = "<group>"; };
-		184F43021E930A2D004F3FE2 /* AWSDDASLLogCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDASLLogCapture.m; sourceTree = "<group>"; };
-		184F43031E930A2D004F3FE2 /* AWSDDASLLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDASLLogger.h; sourceTree = "<group>"; };
-		184F43041E930A2D004F3FE2 /* AWSDDASLLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDASLLogger.m; sourceTree = "<group>"; };
-		184F43051E930A2D004F3FE2 /* AWSDDAssertMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDAssertMacros.h; sourceTree = "<group>"; };
-		184F43061E930A2D004F3FE2 /* AWSDDFileLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDFileLogger.h; sourceTree = "<group>"; };
-		184F43071E930A2D004F3FE2 /* AWSDDFileLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDFileLogger.m; sourceTree = "<group>"; };
-		184F43091E930A2D004F3FE2 /* AWSDDLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLog.h; sourceTree = "<group>"; };
-		184F430A1E930A2D004F3FE2 /* AWSDDLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDLog.m; sourceTree = "<group>"; };
-		184F430B1E930A2D004F3FE2 /* AWSDDLog+LOGV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AWSDDLog+LOGV.h"; sourceTree = "<group>"; };
-		184F430C1E930A2D004F3FE2 /* AWSDDLogMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLogMacros.h; sourceTree = "<group>"; };
-		184F430D1E930A2D004F3FE2 /* AWSDDTTYLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDTTYLogger.h; sourceTree = "<group>"; };
-		184F430E1E930A2D004F3FE2 /* AWSDDTTYLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDTTYLogger.m; sourceTree = "<group>"; };
-		184F43201E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDContextFilterLogFormatter.h; sourceTree = "<group>"; };
-		184F43211E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDContextFilterLogFormatter.m; sourceTree = "<group>"; };
-		184F43221E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDDispatchQueueLogFormatter.h; sourceTree = "<group>"; };
-		184F43231E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDDispatchQueueLogFormatter.m; sourceTree = "<group>"; };
-		184F43241E930A34004F3FE2 /* AWSDDMultiFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDMultiFormatter.h; sourceTree = "<group>"; };
-		184F432C1E930E05004F3FE2 /* AWSDDOSLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDOSLogger.h; sourceTree = "<group>"; };
-		184F432D1E930E05004F3FE2 /* AWSDDOSLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDOSLogger.m; sourceTree = "<group>"; };
-		184F43301E9336BD004F3FE2 /* AWSDDLegacyMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLegacyMacros.h; sourceTree = "<group>"; };
 		185111CB1D78F03B0009F5C3 /* AWSLex.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AWSLex.framework; sourceTree = BUILT_PRODUCTS_DIR; };
 		185111CF1D78F03B0009F5C3 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
 		185111D41D78F03B0009F5C3 /* AWSLexTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AWSLexTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -3226,8 +3213,43 @@
 		5C1978DB2702364800F9C11E /* AWSLocationTests-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "AWSLocationTests-Bridging-Header.h"; sourceTree = "<group>"; };
 		5C1978DC2702364800F9C11E /* AWSLocationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSLocationTests.swift; sourceTree = "<group>"; };
 		5C71F33E295672B8001183A4 /* guten_tag.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = guten_tag.wav; sourceTree = "<group>"; };
+		687952922B8FE2C5001E8990 /* AWSDDLog+Optional.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "AWSDDLog+Optional.swift"; sourceTree = "<group>"; };
 		6883619D2B72D1C200D74FF4 /* AWSS3PreSignedURLBuilderUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSS3PreSignedURLBuilderUnitTests.swift; sourceTree = "<group>"; };
 		688361A02B73D25B00D74FF4 /* AWSIoTStreamThreadTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AWSIoTStreamThreadTests.m; sourceTree = "<group>"; };
+		68A45B542B8D5F7C00A0851E /* AWSCocoaLumberjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSCocoaLumberjack.h; sourceTree = "<group>"; };
+		68A45B572B8D5F7C00A0851E /* AWSDDASLLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDASLLogger.m; sourceTree = "<group>"; };
+		68A45B582B8D5F7C00A0851E /* AWSDDFileLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDFileLogger.m; sourceTree = "<group>"; };
+		68A45B592B8D5F7C00A0851E /* AWSDDFileLogger+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AWSDDFileLogger+Internal.h"; sourceTree = "<group>"; };
+		68A45B5A2B8D5F7C00A0851E /* AWSDDTTYLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDTTYLogger.m; sourceTree = "<group>"; };
+		68A45B5C2B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDContextFilterLogFormatter.m; sourceTree = "<group>"; };
+		68A45B5D2B8D5F7C00A0851E /* AWSDDDispatchQueueLogFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDDispatchQueueLogFormatter.m; sourceTree = "<group>"; };
+		68A45B5E2B8D5F7C00A0851E /* AWSDDFileLogger+Buffering.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AWSDDFileLogger+Buffering.m"; sourceTree = "<group>"; };
+		68A45B5F2B8D5F7C00A0851E /* AWSDDMultiFormatter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDMultiFormatter.m; sourceTree = "<group>"; };
+		68A45B602B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "AWSDDContextFilterLogFormatter+Deprecated.m"; sourceTree = "<group>"; };
+		68A45B612B8D5F7C00A0851E /* AWSDDOSLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDOSLogger.m; sourceTree = "<group>"; };
+		68A45B622B8D5F7C00A0851E /* AWSDDLegacyMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLegacyMacros.h; sourceTree = "<group>"; };
+		68A45B632B8D5F7C00A0851E /* AWSDDLoggerNames.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDLoggerNames.m; sourceTree = "<group>"; };
+		68A45B762B8D5F7D00A0851E /* AWSDDLog.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDLog.m; sourceTree = "<group>"; };
+		68A45B772B8D5F7D00A0851E /* AWSDDASLLogCapture.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDASLLogCapture.m; sourceTree = "<group>"; };
+		68A45B782B8D5F7D00A0851E /* AWSDDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDAbstractDatabaseLogger.m; sourceTree = "<group>"; };
+		68A45B9B2B8D6ADD00A0851E /* AWSDDASLLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDASLLogger.h; sourceTree = "<group>"; };
+		68A45B9C2B8D6ADD00A0851E /* AWSDDTTYLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDTTYLogger.h; sourceTree = "<group>"; };
+		68A45B9D2B8D6ADD00A0851E /* AWSDDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDAbstractDatabaseLogger.h; sourceTree = "<group>"; };
+		68A45B9E2B8D6ADD00A0851E /* AWSDDFileLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDFileLogger.h; sourceTree = "<group>"; };
+		68A45B9F2B8D6ADD00A0851E /* AWSDDLog+LOGV.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AWSDDLog+LOGV.h"; sourceTree = "<group>"; };
+		68A45BA02B8D6ADD00A0851E /* AWSDDLogMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLogMacros.h; sourceTree = "<group>"; };
+		68A45BA12B8D6ADD00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AWSDDContextFilterLogFormatter+Deprecated.h"; sourceTree = "<group>"; };
+		68A45BA22B8D6ADD00A0851E /* AWSDDASLLogCapture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDASLLogCapture.h; sourceTree = "<group>"; };
+		68A45BA32B8D6ADD00A0851E /* AWSDDDispatchQueueLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDDispatchQueueLogFormatter.h; sourceTree = "<group>"; };
+		68A45BA52B8D6ADE00A0851E /* AWSDDLog.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLog.h; sourceTree = "<group>"; };
+		68A45BA62B8D6ADE00A0851E /* AWSDDLoggerNames.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDLoggerNames.h; sourceTree = "<group>"; };
+		68A45BA72B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDContextFilterLogFormatter.h; sourceTree = "<group>"; };
+		68A45BA82B8D6ADE00A0851E /* AWSDDFileLogger+Buffering.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "AWSDDFileLogger+Buffering.h"; sourceTree = "<group>"; };
+		68A45BA92B8D6ADE00A0851E /* AWSDDOSLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDOSLogger.h; sourceTree = "<group>"; };
+		68A45BAA2B8D6ADE00A0851E /* AWSDDAssertMacros.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDAssertMacros.h; sourceTree = "<group>"; };
+		68A45BAB2B8D6ADE00A0851E /* AWSDDMultiFormatter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDMultiFormatter.h; sourceTree = "<group>"; };
+		68A45BBD2B8E74F800A0851E /* AWSCLIColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSCLIColor.h; sourceTree = "<group>"; };
+		68A45BBE2B8E74F900A0851E /* AWSCLIColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSCLIColor.m; sourceTree = "<group>"; };
 		68EE1A6B2B713D8100B7CF41 /* AWSIoTStreamThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSIoTStreamThread.h; sourceTree = "<group>"; };
 		68EE1A6D2B713D8900B7CF41 /* AWSIoTStreamThread.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSIoTStreamThread.m; sourceTree = "<group>"; };
 		6BE9D6A925A54EBA00AB5C9A /* AWSIotDataManagerRetainTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AWSIotDataManagerRetainTests.swift; sourceTree = "<group>"; };
@@ -5492,42 +5514,35 @@
 		184F42CE1E930839004F3FE2 /* Logging */ = {
 			isa = PBXGroup;
 			children = (
-				184F42FE1E930A2D004F3FE2 /* AWSCocoaLumberjack.h */,
-				184F43301E9336BD004F3FE2 /* AWSDDLegacyMacros.h */,
-				184F432C1E930E05004F3FE2 /* AWSDDOSLogger.h */,
-				184F432D1E930E05004F3FE2 /* AWSDDOSLogger.m */,
-				184F42FF1E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h */,
-				184F43001E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m */,
-				184F43011E930A2D004F3FE2 /* AWSDDASLLogCapture.h */,
-				184F43021E930A2D004F3FE2 /* AWSDDASLLogCapture.m */,
-				184F43031E930A2D004F3FE2 /* AWSDDASLLogger.h */,
-				184F43041E930A2D004F3FE2 /* AWSDDASLLogger.m */,
-				184F43051E930A2D004F3FE2 /* AWSDDAssertMacros.h */,
-				184F43061E930A2D004F3FE2 /* AWSDDFileLogger.h */,
-				184F43071E930A2D004F3FE2 /* AWSDDFileLogger.m */,
-				184F43091E930A2D004F3FE2 /* AWSDDLog.h */,
-				184F430A1E930A2D004F3FE2 /* AWSDDLog.m */,
-				184F430B1E930A2D004F3FE2 /* AWSDDLog+LOGV.h */,
-				184F430C1E930A2D004F3FE2 /* AWSDDLogMacros.h */,
-				184F430D1E930A2D004F3FE2 /* AWSDDTTYLogger.h */,
-				184F430E1E930A2D004F3FE2 /* AWSDDTTYLogger.m */,
-				184F42F11E930925004F3FE2 /* Extensions */,
+				68A45BBD2B8E74F800A0851E /* AWSCLIColor.h */,
+				68A45BBE2B8E74F900A0851E /* AWSCLIColor.m */,
+				68A45B542B8D5F7C00A0851E /* AWSCocoaLumberjack.h */,
+				68A45B9D2B8D6ADD00A0851E /* AWSDDAbstractDatabaseLogger.h */,
+				68A45B782B8D5F7D00A0851E /* AWSDDAbstractDatabaseLogger.m */,
+				68A45BA22B8D6ADD00A0851E /* AWSDDASLLogCapture.h */,
+				68A45B772B8D5F7D00A0851E /* AWSDDASLLogCapture.m */,
+				68A45B9B2B8D6ADD00A0851E /* AWSDDASLLogger.h */,
+				68A45B572B8D5F7C00A0851E /* AWSDDASLLogger.m */,
+				68A45BAA2B8D6ADE00A0851E /* AWSDDAssertMacros.h */,
+				68A45B9E2B8D6ADD00A0851E /* AWSDDFileLogger.h */,
+				68A45B582B8D5F7C00A0851E /* AWSDDFileLogger.m */,
+				68A45B622B8D5F7C00A0851E /* AWSDDLegacyMacros.h */,
+				68A45BA52B8D6ADE00A0851E /* AWSDDLog.h */,
+				68A45B762B8D5F7D00A0851E /* AWSDDLog.m */,
+				68A45B9F2B8D6ADD00A0851E /* AWSDDLog+LOGV.h */,
+				68A45BA62B8D6ADE00A0851E /* AWSDDLoggerNames.h */,
+				68A45B632B8D5F7C00A0851E /* AWSDDLoggerNames.m */,
+				68A45BA02B8D6ADD00A0851E /* AWSDDLogMacros.h */,
+				68A45B5F2B8D5F7C00A0851E /* AWSDDMultiFormatter.m */,
+				68A45BA92B8D6ADE00A0851E /* AWSDDOSLogger.h */,
+				68A45B612B8D5F7C00A0851E /* AWSDDOSLogger.m */,
+				68A45B9C2B8D6ADD00A0851E /* AWSDDTTYLogger.h */,
+				68A45B5A2B8D5F7C00A0851E /* AWSDDTTYLogger.m */,
+				68A45B5B2B8D5F7C00A0851E /* Extensions */,
 			);
 			path = Logging;
 			sourceTree = "<group>";
 		};
-		184F42F11E930925004F3FE2 /* Extensions */ = {
-			isa = PBXGroup;
-			children = (
-				184F43201E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.h */,
-				184F43211E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.m */,
-				184F43221E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.h */,
-				184F43231E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.m */,
-				184F43241E930A34004F3FE2 /* AWSDDMultiFormatter.h */,
-			);
-			path = Extensions;
-			sourceTree = "<group>";
-		};
 		185111CC1D78F03B0009F5C3 /* AWSLex */ = {
 			isa = PBXGroup;
 			children = (
@@ -6020,6 +6035,24 @@
 			path = AWSKinesisVideoWebRTCStorage;
 			sourceTree = "<group>";
 		};
+		68A45B5B2B8D5F7C00A0851E /* Extensions */ = {
+			isa = PBXGroup;
+			children = (
+				68A45BA72B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter.h */,
+				68A45B5C2B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter.m */,
+				68A45BA12B8D6ADD00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.h */,
+				68A45B602B8D5F7C00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.m */,
+				68A45BA32B8D6ADD00A0851E /* AWSDDDispatchQueueLogFormatter.h */,
+				68A45B5D2B8D5F7C00A0851E /* AWSDDDispatchQueueLogFormatter.m */,
+				68A45BA82B8D6ADE00A0851E /* AWSDDFileLogger+Buffering.h */,
+				68A45B5E2B8D5F7C00A0851E /* AWSDDFileLogger+Buffering.m */,
+				68A45B592B8D5F7C00A0851E /* AWSDDFileLogger+Internal.h */,
+				687952922B8FE2C5001E8990 /* AWSDDLog+Optional.swift */,
+				68A45BAB2B8D6ADE00A0851E /* AWSDDMultiFormatter.h */,
+			);
+			path = Extensions;
+			sourceTree = "<group>";
+		};
 		9A7ACC2120B0E85000DDBEC1 /* AWSTranslate */ = {
 			isa = PBXGroup;
 			children = (
@@ -8277,14 +8310,17 @@
 				CE0D42A51C6A673E006B91B5 /* AWSModel.h in Headers */,
 				CE0D42251C6A673E006B91B5 /* AWSIdentityProvider.h in Headers */,
 				CE0D422C1C6A673E006B91B5 /* AWSCancellationToken.h in Headers */,
+				68A45BBB2B8D6ADE00A0851E /* AWSDDAssertMacros.h in Headers */,
 				CE0D42A71C6A673E006B91B5 /* AWSSynchronizedMutableDictionary.h in Headers */,
 				CE0D42441C6A673E006B91B5 /* AWSFMDatabase.h in Headers */,
 				CE0D42511C6A673E006B91B5 /* AWSGZIP.h in Headers */,
+				68A45BB12B8D6ADE00A0851E /* AWSDDLogMacros.h in Headers */,
 				CE0D42921C6A673E006B91B5 /* AWSSTSService.h in Headers */,
 				CE0D42801C6A673E006B91B5 /* AWSURLRequestRetryHandler.h in Headers */,
 				CE0D424D1C6A673E006B91B5 /* AWSFMResultSet.h in Headers */,
 				CE0D423B1C6A673E006B91B5 /* AWSCognitoIdentityResources.h in Headers */,
 				CE0D426B1C6A673E006B91B5 /* NSDictionary+AWSMTLManipulationAdditions.h in Headers */,
+				68A45BB22B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.h in Headers */,
 				CE0D42381C6A673E006B91B5 /* AWSCognitoIdentity.h in Headers */,
 				CE0D426F1C6A673E006B91B5 /* NSObject+AWSMTLComparisonAdditions.h in Headers */,
 				CE0D428D1C6A673E006B91B5 /* AWSSTS.h in Headers */,
@@ -8293,16 +8329,21 @@
 				CE0D42301C6A673E006B91B5 /* AWSCancellationTokenSource.h in Headers */,
 				CE0D428E1C6A673E006B91B5 /* AWSSTSModel.h in Headers */,
 				CE0D424C1C6A673E006B91B5 /* AWSFMDB.h in Headers */,
+				68A45BB42B8D6ADE00A0851E /* AWSDDDispatchQueueLogFormatter.h in Headers */,
 				CE0D42271C6A673E006B91B5 /* AWSSignature.h in Headers */,
 				CE0D428A1C6A673E006B91B5 /* AWSService.h in Headers */,
 				CE0D42A31C6A673E006B91B5 /* AWSLogging.h in Headers */,
+				68A45B852B8D5F7D00A0851E /* AWSDDLegacyMacros.h in Headers */,
 				CE0D422E1C6A673E006B91B5 /* AWSCancellationTokenRegistration.h in Headers */,
+				68A45BAD2B8D6ADE00A0851E /* AWSDDTTYLogger.h in Headers */,
+				68A45BB32B8D6ADE00A0851E /* AWSDDASLLogCapture.h in Headers */,
 				18DF08DB1D34866E004C7D19 /* AWSCognitoIdentity+Fabric.h in Headers */,
 				CE0D423D1C6A673E006B91B5 /* AWSCognitoIdentityService.h in Headers */,
 				CE0D425C1C6A673E006B91B5 /* AWSMTLModel.h in Headers */,
 				CE0D42861C6A673E006B91B5 /* AWSValidation.h in Headers */,
+				68A45BB82B8D6ADE00A0851E /* AWSDDContextFilterLogFormatter.h in Headers */,
+				68A45BB02B8D6ADE00A0851E /* AWSDDLog+LOGV.h in Headers */,
 				FA7A44C62305D09C00F55D7A /* AWSNetworkingHelpers.h in Headers */,
-				184F43261E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.h in Headers */,
 				CEA33FB61C8A37230083D6BC /* Fabric+FABKits.h in Headers */,
 				CE0D42481C6A673E006B91B5 /* AWSFMDatabasePool.h in Headers */,
 				CE0D428C1C6A673E006B91B5 /* AWSServiceEnum.h in Headers */,
@@ -8310,46 +8351,43 @@
 				CE0D42551C6A673E006B91B5 /* AWSMantle.h in Headers */,
 				CE0D42231C6A673E006B91B5 /* AWSCredentialsProvider.h in Headers */,
 				CE0D425A1C6A673E006B91B5 /* AWSMTLModel+NSCoding.h in Headers */,
+				68A45BBF2B8E74F900A0851E /* AWSCLIColor.h in Headers */,
 				CE0D42821C6A673E006B91B5 /* AWSURLRequestSerialization.h in Headers */,
+				68A45BB92B8D6ADE00A0851E /* AWSDDFileLogger+Buffering.h in Headers */,
+				68A45BAF2B8D6ADE00A0851E /* AWSDDFileLogger.h in Headers */,
 				CE0D42881C6A673E006B91B5 /* AWSClientContext.h in Headers */,
 				CE0D429D1C6A673E006B91B5 /* AWSUICKeyChainStore.h in Headers */,
 				CE0D42781C6A673E006B91B5 /* AWSURLSessionManager.h in Headers */,
+				68A45BAC2B8D6ADE00A0851E /* AWSDDASLLogger.h in Headers */,
 				CE0D42761C6A673E006B91B5 /* AWSNetworking.h in Headers */,
 				CE0D42391C6A673E006B91B5 /* AWSCognitoIdentityModel.h in Headers */,
 				CE0D42581C6A673E006B91B5 /* AWSMTLManagedObjectAdapter.h in Headers */,
 				CE0D42601C6A673E006B91B5 /* AWSMTLValueTransformer.h in Headers */,
+				68A45BB62B8D6ADE00A0851E /* AWSDDLog.h in Headers */,
 				CEA33FB41C8A37230083D6BC /* FABAttributes.h in Headers */,
 				CE0D42A11C6A673E006B91B5 /* AWSCategory.h in Headers */,
-				184F431D1E930A2D004F3FE2 /* AWSDDLogMacros.h in Headers */,
-				184F43141E930A2D004F3FE2 /* AWSDDASLLogger.h in Headers */,
+				68A45BBC2B8D6ADE00A0851E /* AWSDDMultiFormatter.h in Headers */,
 				FA5D34FC250C0D77007AA030 /* AWSNSCodingUtilities.h in Headers */,
 				CE0D42291C6A673E006B91B5 /* AWSBolts.h in Headers */,
 				CE0D42561C6A673E006B91B5 /* AWSMTLJSONAdapter.h in Headers */,
-				184F43121E930A2D004F3FE2 /* AWSDDASLLogCapture.h in Headers */,
 				1868C0261E207E33001CDA82 /* AWSGeneric.h in Headers */,
 				EFE40B7C1CC5BDCA0045D710 /* AWSInfo.h in Headers */,
-				184F432E1E930E05004F3FE2 /* AWSDDOSLogger.h in Headers */,
-				184F431E1E930A2D004F3FE2 /* AWSDDTTYLogger.h in Headers */,
-				184F430F1E930A2D004F3FE2 /* AWSCocoaLumberjack.h in Headers */,
 				2171EBE0254C725C00FAB22F /* AWSTimestampSerialization.h in Headers */,
-				184F431A1E930A2D004F3FE2 /* AWSDDLog.h in Headers */,
-				184F43161E930A2D004F3FE2 /* AWSDDAssertMacros.h in Headers */,
 				CE0D42341C6A673E006B91B5 /* AWSTask.h in Headers */,
-				184F43171E930A2D004F3FE2 /* AWSDDFileLogger.h in Headers */,
-				184F43311E9336BD004F3FE2 /* AWSDDLegacyMacros.h in Headers */,
-				184F432A1E930A34004F3FE2 /* AWSDDMultiFormatter.h in Headers */,
-				184F431C1E930A2D004F3FE2 /* AWSDDLog+LOGV.h in Headers */,
-				184F43281E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.h in Headers */,
-				184F43101E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h in Headers */,
+				68A45BBA2B8D6ADE00A0851E /* AWSDDOSLogger.h in Headers */,
 				CE0D42731C6A673E006B91B5 /* NSValueTransformer+AWSMTLPredefinedTransformerAdditions.h in Headers */,
 				CE0D42461C6A673E006B91B5 /* AWSFMDatabaseAdditions.h in Headers */,
 				CE0D41701C6A66E5006B91B5 /* AWSCore.h in Headers */,
 				CE0D42901C6A673E006B91B5 /* AWSSTSResources.h in Headers */,
 				CE0D426D1C6A673E006B91B5 /* NSError+AWSMTLModelException.h in Headers */,
+				68A45B7D2B8D5F7D00A0851E /* AWSDDFileLogger+Internal.h in Headers */,
 				CE0D425E1C6A673E006B91B5 /* AWSMTLReflection.h in Headers */,
 				CEA33FB51C8A37230083D6BC /* FABKitProtocol.h in Headers */,
 				CE0D42AD1C6A673E006B91B5 /* AWSXMLWriter.h in Headers */,
+				68A45B792B8D5F7D00A0851E /* AWSCocoaLumberjack.h in Headers */,
 				CE0D42A91C6A673E006B91B5 /* AWSXMLDictionary.h in Headers */,
+				68A45BAE2B8D6ADE00A0851E /* AWSDDAbstractDatabaseLogger.h in Headers */,
+				68A45BB72B8D6ADE00A0851E /* AWSDDLoggerNames.h in Headers */,
 				CE0D42671C6A673E006B91B5 /* AWSmetamacros.h in Headers */,
 				CE3627CE1CEBA92B003E85B9 /* AWSKSReachability.h in Headers */,
 				CE0D42621C6A673E006B91B5 /* AWSEXTKeyPathCoding.h in Headers */,
@@ -12977,65 +13015,71 @@
 				CE0D42351C6A673E006B91B5 /* AWSTask.m in Sources */,
 				CE0D42741C6A673E006B91B5 /* NSValueTransformer+AWSMTLPredefinedTransformerAdditions.m in Sources */,
 				CE0D42911C6A673E006B91B5 /* AWSSTSResources.m in Sources */,
-				184F43181E930A2D004F3FE2 /* AWSDDFileLogger.m in Sources */,
 				CE0D42371C6A673E006B91B5 /* AWSTaskCompletionSource.m in Sources */,
+				68A45B7B2B8D5F7D00A0851E /* AWSDDASLLogger.m in Sources */,
+				68A45B7E2B8D5F7D00A0851E /* AWSDDTTYLogger.m in Sources */,
 				CE0D422D1C6A673E006B91B5 /* AWSCancellationToken.m in Sources */,
 				CE0D42451C6A673E006B91B5 /* AWSFMDatabase.m in Sources */,
 				CE0D42311C6A673E006B91B5 /* AWSCancellationTokenSource.m in Sources */,
+				68A45B9A2B8D5F7D00A0851E /* AWSDDAbstractDatabaseLogger.m in Sources */,
 				CE0D42331C6A673E006B91B5 /* AWSExecutor.m in Sources */,
+				68A45BC02B8E74F900A0851E /* AWSCLIColor.m in Sources */,
 				CE0D42661C6A673E006B91B5 /* AWSEXTScope.m in Sources */,
 				CE0D42831C6A673E006B91B5 /* AWSURLRequestSerialization.m in Sources */,
 				CE0D42811C6A673E006B91B5 /* AWSURLRequestRetryHandler.m in Sources */,
-				184F43111E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m in Sources */,
 				CE0D422A1C6A673E006B91B5 /* AWSBolts.m in Sources */,
 				CE0D42791C6A673E006B91B5 /* AWSURLSessionManager.m in Sources */,
+				68A45B842B8D5F7D00A0851E /* AWSDDOSLogger.m in Sources */,
 				CE0D42A61C6A673E006B91B5 /* AWSModel.m in Sources */,
 				CE0D425F1C6A673E006B91B5 /* AWSMTLReflection.m in Sources */,
-				184F43291E930A34004F3FE2 /* AWSDDDispatchQueueLogFormatter.m in Sources */,
+				687952932B8FE2C5001E8990 /* AWSDDLog+Optional.swift in Sources */,
 				CE0D42A41C6A673E006B91B5 /* AWSLogging.m in Sources */,
+				68A45B822B8D5F7D00A0851E /* AWSDDMultiFormatter.m in Sources */,
 				CE0D42AE1C6A673E006B91B5 /* AWSXMLWriter.m in Sources */,
 				CE0D42261C6A673E006B91B5 /* AWSIdentityProvider.m in Sources */,
+				68A45B802B8D5F7D00A0851E /* AWSDDDispatchQueueLogFormatter.m in Sources */,
 				FAC3E7022208B0D60037813E /* AWSFMDB+AWSHelpers.m in Sources */,
 				CE0D42471C6A673E006B91B5 /* AWSFMDatabaseAdditions.m in Sources */,
 				CE0D423E1C6A673E006B91B5 /* AWSCognitoIdentityService.m in Sources */,
-				184F43131E930A2D004F3FE2 /* AWSDDASLLogCapture.m in Sources */,
 				CE0D425D1C6A673E006B91B5 /* AWSMTLModel.m in Sources */,
 				CE0D42A21C6A673E006B91B5 /* AWSCategory.m in Sources */,
 				CE0D42591C6A673E006B91B5 /* AWSMTLManagedObjectAdapter.m in Sources */,
-				184F432F1E930E05004F3FE2 /* AWSDDOSLogger.m in Sources */,
+				68A45B7F2B8D5F7D00A0851E /* AWSDDContextFilterLogFormatter.m in Sources */,
 				CE0D422F1C6A673E006B91B5 /* AWSCancellationTokenRegistration.m in Sources */,
 				CE0D426A1C6A673E006B91B5 /* NSArray+AWSMTLManipulationAdditions.m in Sources */,
 				18DF08D51D347633004C7D19 /* AWSCognitoIdentity+Fabric.m in Sources */,
-				184F43271E930A34004F3FE2 /* AWSDDContextFilterLogFormatter.m in Sources */,
 				2171EB6A254C721E00FAB22F /* AWSTimestampSerialization.m in Sources */,
 				CE0D42491C6A673E006B91B5 /* AWSFMDatabasePool.m in Sources */,
+				68A45B812B8D5F7D00A0851E /* AWSDDFileLogger+Buffering.m in Sources */,
 				CE0D424E1C6A673E006B91B5 /* AWSFMResultSet.m in Sources */,
 				CE0D426E1C6A673E006B91B5 /* NSError+AWSMTLModelException.m in Sources */,
 				CE0D42851C6A673E006B91B5 /* AWSURLResponseSerialization.m in Sources */,
 				CE0D429E1C6A673E006B91B5 /* AWSUICKeyChainStore.m in Sources */,
-				184F43151E930A2D004F3FE2 /* AWSDDASLLogger.m in Sources */,
 				FA7A44C72305D09C00F55D7A /* AWSNetworkingHelpers.m in Sources */,
 				CE0D42571C6A673E006B91B5 /* AWSMTLJSONAdapter.m in Sources */,
+				68A45B832B8D5F7D00A0851E /* AWSDDContextFilterLogFormatter+Deprecated.m in Sources */,
 				CE0D42281C6A673E006B91B5 /* AWSSignature.m in Sources */,
 				FA5D34FD250C0D77007AA030 /* AWSNSCodingUtilities.m in Sources */,
 				CE0D42701C6A673E006B91B5 /* NSObject+AWSMTLComparisonAdditions.m in Sources */,
 				CE0D42241C6A673E006B91B5 /* AWSCredentialsProvider.m in Sources */,
-				184F431B1E930A2D004F3FE2 /* AWSDDLog.m in Sources */,
+				68A45B862B8D5F7D00A0851E /* AWSDDLoggerNames.m in Sources */,
 				CE0D42721C6A673E006B91B5 /* NSValueTransformer+AWSMTLInversionAdditions.m in Sources */,
 				CE0D424B1C6A673E006B91B5 /* AWSFMDatabaseQueue.m in Sources */,
 				CE0D42611C6A673E006B91B5 /* AWSMTLValueTransformer.m in Sources */,
 				CE3627CF1CEBA92B003E85B9 /* AWSKSReachability.m in Sources */,
+				68A45B7C2B8D5F7D00A0851E /* AWSDDFileLogger.m in Sources */,
 				CE0D428B1C6A673E006B91B5 /* AWSService.m in Sources */,
 				CE0D42521C6A673E006B91B5 /* AWSGZIP.m in Sources */,
 				CE0D428F1C6A673E006B91B5 /* AWSSTSModel.m in Sources */,
 				CE0D423A1C6A673E006B91B5 /* AWSCognitoIdentityModel.m in Sources */,
 				CE0D42771C6A673E006B91B5 /* AWSNetworking.m in Sources */,
 				CE0D42871C6A673E006B91B5 /* AWSValidation.m in Sources */,
+				68A45B992B8D5F7D00A0851E /* AWSDDASLLogCapture.m in Sources */,
+				68A45B982B8D5F7D00A0851E /* AWSDDLog.m in Sources */,
 				CE0D42891C6A673E006B91B5 /* AWSClientContext.m in Sources */,
 				CE0D42931C6A673E006B91B5 /* AWSSTSService.m in Sources */,
 				CE0D42641C6A673E006B91B5 /* AWSEXTRuntimeExtensions.m in Sources */,
 				CE0D423C1C6A673E006B91B5 /* AWSCognitoIdentityResources.m in Sources */,
-				184F431F1E930A2D004F3FE2 /* AWSDDTTYLogger.m in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};
@@ -14680,7 +14724,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideo/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideo;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -14704,7 +14748,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideo/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideo;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -14729,7 +14773,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMedia/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoArchivedMedia;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -14755,7 +14799,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMedia/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoArchivedMedia;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				PROVISIONING_PROFILE_SPECIFIER = "";
@@ -14776,7 +14820,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMediaTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoArchivedMediaTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "AWSKinesisVideoArchivedMediaTests/AWSKinesisVideoArchivedMediaTests-Bridging-Header.h";
@@ -14799,7 +14843,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMediaTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoArchivedMediaTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "AWSKinesisVideoArchivedMediaTests/AWSKinesisVideoArchivedMediaTests-Bridging-Header.h";
@@ -14820,7 +14864,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -14843,7 +14887,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -14866,7 +14910,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMediaUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -14889,7 +14933,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoArchivedMediaUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -14912,7 +14956,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
@@ -14934,7 +14978,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 11.2;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SWIFT_OBJC_BRIDGING_HEADER = "AWSKinesisVideoTests/AWSKinesisVideoTests-Bridging-Header.h";
@@ -14960,7 +15004,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreaming/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreaming;
@@ -14987,7 +15031,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreaming/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreaming;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -15010,7 +15054,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreamingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreamingTests;
@@ -15036,7 +15080,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreamingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreamingTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -15057,7 +15101,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15084,7 +15128,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15115,7 +15159,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribe/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribe;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -15140,7 +15184,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribe/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribe;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -15159,7 +15203,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15182,7 +15226,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15204,7 +15248,7 @@
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				INFOPLIST_FILE = AWSAllTestsHost/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAllTestsHost;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -15222,7 +15266,7 @@
 				CLANG_WARN_SUSPICIOUS_MOVE = YES;
 				CODE_SIGN_IDENTITY = "iPhone Developer";
 				INFOPLIST_FILE = AWSAllTestsHost/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAllTestsHost;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -15240,7 +15284,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSLogs/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSLogs;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15258,7 +15302,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSLogs/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSLogs;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15270,7 +15314,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSLogsUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15286,7 +15330,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSLogsUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15310,7 +15354,7 @@
 				HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/AWSLex/Bluefront/include";
 				INFOPLIST_FILE = "$(SRCROOT)/AWSLex/Info.plist";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSLex/Bluefront",
@@ -15336,7 +15380,7 @@
 				HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/AWSLex/Bluefront/include";
 				INFOPLIST_FILE = "$(SRCROOT)/AWSLex/Info.plist";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSLex/Bluefront",
@@ -15354,7 +15398,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSLexTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15369,7 +15413,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSLexTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15390,7 +15434,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSPinpoint/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSPinpoint;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15408,7 +15452,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSPinpoint/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSPinpoint;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15420,7 +15464,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPinpointTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15437,7 +15481,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPinpointTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15454,7 +15498,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPinpointUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15470,7 +15514,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPinpointUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15492,7 +15536,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSRekognition/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSRekognition;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15510,7 +15554,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSRekognition/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSRekognition;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15522,7 +15566,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSRekognitionUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15538,7 +15582,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSRekognitionUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15562,7 +15606,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSPolly/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSPolly;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15582,7 +15626,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSPolly/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSPolly;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -15594,7 +15638,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPollyTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15610,7 +15654,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPollyTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15626,7 +15670,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPollyUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15642,7 +15686,7 @@
 			buildSettings = {
 				CLANG_ANALYZER_NONNULL = YES;
 				INFOPLIST_FILE = AWSPollyUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15657,7 +15701,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLexUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15672,7 +15716,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLexUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15703,7 +15747,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocation/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
@@ -15736,7 +15780,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocation/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSLocation;
@@ -15761,7 +15805,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocationTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -15794,7 +15838,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocationTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -15824,7 +15868,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocationUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -15853,7 +15897,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocationUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -15886,7 +15930,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignaling/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MARKETING_VERSION = 2.12.2;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
@@ -15914,7 +15958,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignaling/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MARKETING_VERSION = 2.12.2;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSKinesisVideoSignaling;
@@ -15937,7 +15981,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignalingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15968,7 +16012,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignalingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -15996,7 +16040,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignalingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16022,7 +16066,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSKinesisVideoSignalingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16053,7 +16097,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentity/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 2.24.4;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
@@ -16084,7 +16128,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentity/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 2.24.4;
 				MTL_FAST_MATH = YES;
@@ -16108,7 +16152,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentityTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16137,7 +16181,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentityTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16171,7 +16215,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessaging/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 2.24.4;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
@@ -16203,7 +16247,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessaging/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 2.24.4;
 				MTL_FAST_MATH = YES;
@@ -16228,7 +16272,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessagingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16257,7 +16301,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessagingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16285,7 +16329,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessagingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16313,7 +16357,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKMessagingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16340,7 +16384,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentityUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16368,7 +16412,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSChimeSDKIdentityUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
@@ -16402,7 +16446,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocation/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
@@ -16435,7 +16479,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSLocation/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSLocation;
@@ -16470,7 +16514,7 @@
 				INFOPLIST_FILE = AWSKinesisVideoWebRTCStorage/Info.plist;
 				INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Amazon Web Services. All rights reserved.";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 1.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
@@ -16510,7 +16554,7 @@
 				INFOPLIST_FILE = AWSKinesisVideoWebRTCStorage/Info.plist;
 				INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 Amazon Web Services. All rights reserved.";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				MARKETING_VERSION = 1.0;
 				MTL_FAST_MATH = YES;
@@ -16539,7 +16583,7 @@
 				DEVELOPMENT_TEAM = 94KV3E626L;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GENERATE_INFOPLIST_FILE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16573,7 +16617,7 @@
 				DEVELOPMENT_TEAM = 94KV3E626L;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				GENERATE_INFOPLIST_FILE = YES;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16606,7 +16650,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslate/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranslate;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -16630,7 +16674,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslate/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranslate;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -16649,7 +16693,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslateUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16672,7 +16716,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslateUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16700,7 +16744,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehend/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AWSComprehend;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -16724,7 +16768,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehend/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AWSComprehend;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
 				SKIP_INSTALL = YES;
@@ -16743,7 +16787,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehendUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16766,7 +16810,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehendUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16789,7 +16833,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehendTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16816,7 +16860,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSComprehendTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16841,7 +16885,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslateTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16868,7 +16912,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranslateTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -16893,7 +16937,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSRekognitionTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/AWSCoreTests/OCMock";
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AWSRekognitionTests;
@@ -16917,7 +16961,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSRekognitionTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = "$(PROJECT_DIR)/AWSCoreTests/OCMock";
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazon.AWSRekognitionTests;
@@ -16945,7 +16989,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSSageMakerRuntime/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSSageMakerRuntime;
@@ -16972,7 +17016,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSSageMakerRuntime/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSSageMakerRuntime;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -16993,7 +17037,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSSageMakerRuntimeUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17019,7 +17063,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSSageMakerRuntimeUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17049,7 +17093,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipant/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSConnectParticipant;
@@ -17076,7 +17120,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipant/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSConnectParticipant;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -17097,7 +17141,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipantUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17123,7 +17167,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipantUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17148,7 +17192,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipantTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17179,7 +17223,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectParticipantTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"${inherited}",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17207,7 +17251,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextractUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17233,7 +17277,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextractUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17263,7 +17307,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextract/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTextract;
@@ -17290,7 +17334,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextract/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTextract;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -17311,7 +17355,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextractTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTextractTests;
@@ -17334,7 +17378,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTextractTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTextractTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -17361,7 +17405,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnect/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "";
@@ -17389,7 +17433,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnect/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSConnect;
@@ -17412,7 +17456,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
@@ -17439,7 +17483,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				OTHER_LDFLAGS = "-ObjC";
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSConnectTests;
@@ -17463,7 +17507,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17489,7 +17533,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSConnectUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17638,10 +17682,11 @@
 				GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
 				INFOPLIST_FILE = AWSCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSCore;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 4.2;
 			};
 			name = Debug;
 		};
@@ -17656,10 +17701,11 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCore/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSCore;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
+				SWIFT_VERSION = 4.2;
 			};
 			name = Release;
 		};
@@ -17667,7 +17713,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCoreTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -17684,7 +17730,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCoreTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -17702,7 +17748,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSCoreUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -17722,7 +17768,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSCoreUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -17740,7 +17786,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAPIGatewayUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17755,7 +17801,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAPIGatewayUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17770,7 +17816,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAutoScalingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17785,7 +17831,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAutoScalingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17800,7 +17846,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCloudWatchUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17815,7 +17861,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCloudWatchUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17830,7 +17876,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSDynamoDBUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17845,7 +17891,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSDynamoDBUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17860,7 +17906,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSEC2UnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17875,7 +17921,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSEC2UnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17890,7 +17936,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSElasticLoadBalancingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17905,7 +17951,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSElasticLoadBalancingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17920,7 +17966,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSIoTUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17935,7 +17981,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSIoTUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17950,7 +17996,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSKinesisUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17965,7 +18011,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSKinesisUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17980,7 +18026,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLambdaUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -17995,7 +18041,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLambdaUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18010,7 +18056,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSMachineLearningUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18025,7 +18071,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSMachineLearningUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18041,7 +18087,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSS3UnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -18061,7 +18107,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSS3UnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
@@ -18079,7 +18125,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSESUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18094,7 +18140,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSESUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18109,7 +18155,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSimpleDBUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18124,7 +18170,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSimpleDBUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18139,7 +18185,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSNSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18154,7 +18200,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSNSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18169,7 +18215,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSQSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18184,7 +18230,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSQSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18206,7 +18252,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSAutoScaling/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAutoScaling;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18224,7 +18270,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSAutoScaling/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAutoScaling;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18235,7 +18281,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAutoScalingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18250,7 +18296,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSAutoScalingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18272,7 +18318,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSDynamoDB/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSDynamoDB;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18290,7 +18336,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSDynamoDB/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSDynamoDB;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18302,7 +18348,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSDynamoDBTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18321,7 +18367,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSDynamoDBTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18345,7 +18391,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSEC2/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSEC2;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18363,7 +18409,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSEC2/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSEC2;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18374,7 +18420,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSEC2Tests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18389,7 +18435,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSEC2Tests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18411,7 +18457,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSElasticLoadBalancing/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSElasticLoadBalancing;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18429,7 +18475,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSElasticLoadBalancing/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSElasticLoadBalancing;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18440,7 +18486,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSElasticLoadBalancingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18455,7 +18501,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSElasticLoadBalancingTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18477,7 +18523,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSIoT/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSIoT;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18495,7 +18541,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSIoT/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSIoT;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18507,7 +18553,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSIoTTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18527,7 +18573,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSIoTTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18552,7 +18598,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSKinesis/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSKinesis;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18570,7 +18616,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSKinesis/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSKinesis;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18581,7 +18627,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSKinesisTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18596,7 +18642,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSKinesisTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18618,7 +18664,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSLambda/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSLambda;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18636,7 +18682,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSLambda/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSLambda;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18647,7 +18693,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLambdaTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18662,7 +18708,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSLambdaTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18684,7 +18730,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSMachineLearning/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSMachineLearning;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18702,7 +18748,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSMachineLearning/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSMachineLearning;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18722,7 +18768,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSS3/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSS3;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18741,7 +18787,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSS3/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSS3;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18754,7 +18800,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				DEVELOPMENT_TEAM = "";
 				INFOPLIST_FILE = AWSS3Tests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18775,7 +18821,7 @@
 				CLANG_ENABLE_MODULES = YES;
 				DEVELOPMENT_TEAM = "";
 				INFOPLIST_FILE = AWSS3Tests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18800,7 +18846,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSES/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSES;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18818,7 +18864,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSES/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSES;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18829,7 +18875,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSESTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18844,7 +18890,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSESTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18866,7 +18912,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSimpleDB/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSimpleDB;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18884,7 +18930,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSimpleDB/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSimpleDB;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18895,7 +18941,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSimpleDBTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18910,7 +18956,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSimpleDBTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18932,7 +18978,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSNS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSNS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18950,7 +18996,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSNS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSNS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -18961,7 +19007,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSNSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18976,7 +19022,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSNSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -18998,7 +19044,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSQS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSQS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19016,7 +19062,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSSQS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSSQS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19027,7 +19073,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSQSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19042,7 +19088,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSSQSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19064,7 +19110,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSAPIGateway/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAPIGateway;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19082,7 +19128,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSAPIGateway/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSAPIGateway;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19094,7 +19140,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSAPIGatewayTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19114,7 +19160,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSAPIGatewayTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19139,7 +19185,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCloudWatch/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSCloudWatch;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19157,7 +19203,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCloudWatch/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSCloudWatch;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19168,7 +19214,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCloudWatchTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19183,7 +19229,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCloudWatchTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19206,7 +19252,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = "$(SRCROOT)/AWSCognitoIdentityProvider/Info.plist";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoIdentityProvider/Internal",
@@ -19230,7 +19276,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = "$(SRCROOT)/AWSCognitoIdentityProvider/Info.plist";
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoIdentityProvider/Internal",
@@ -19246,7 +19292,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoIdentityProviderTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19261,7 +19307,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoIdentityProviderTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19277,7 +19323,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSCognitoIdentityProviderUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19296,7 +19342,7 @@
 			buildSettings = {
 				CLANG_ENABLE_MODULES = YES;
 				INFOPLIST_FILE = AWSCognitoIdentityProviderUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19313,7 +19359,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CODE_SIGN_IDENTITY = "iPhone Developer";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Debug;
@@ -19322,7 +19368,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CODE_SIGN_IDENTITY = "iPhone Developer";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Release;
@@ -19340,7 +19386,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSKMS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSKMS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19360,7 +19406,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSKMS/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.sdk.ios.AWSKMS;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 				SKIP_INSTALL = YES;
@@ -19373,7 +19419,7 @@
 				CLANG_ANALYZER_NONNULL = YES_NONAGGRESSIVE;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
 				INFOPLIST_FILE = AWSKMSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19390,7 +19436,7 @@
 				CLANG_ANALYZER_NONNULL = YES_NONAGGRESSIVE;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
 				INFOPLIST_FILE = AWSKMSUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19407,7 +19453,7 @@
 				CLANG_ANALYZER_NONNULL = YES_NONAGGRESSIVE;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
 				INFOPLIST_FILE = AWSKMSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19424,7 +19470,7 @@
 				CLANG_ANALYZER_NONNULL = YES_NONAGGRESSIVE;
 				CLANG_WARN_DOCUMENTATION_COMMENTS = NO;
 				INFOPLIST_FILE = AWSKMSTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19447,7 +19493,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCognitoIdentityProviderASF/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoIdentityProviderASF",
@@ -19471,7 +19517,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCognitoIdentityProviderASF/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoIdentityProviderASF",
@@ -19495,7 +19541,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCognitoAuth/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoAuth/Internal",
@@ -19519,7 +19565,7 @@
 				DYLIB_INSTALL_NAME_BASE = "@rpath";
 				INFOPLIST_FILE = AWSCognitoAuth/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCognitoAuth/Internal",
@@ -19535,7 +19581,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoAuthTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19549,7 +19595,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoAuthTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19563,7 +19609,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoAuthUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19578,7 +19624,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				INFOPLIST_FILE = AWSCognitoAuthUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LIBRARY_SEARCH_PATHS = (
 					"$(inherited)",
 					"$(PROJECT_DIR)/AWSCoreTests/OCMock",
@@ -19659,7 +19705,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreamingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreamingUnitTests;
@@ -19684,7 +19730,7 @@
 				CODE_SIGN_STYLE = Automatic;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTranscribeStreamingUnitTests/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTranscribeStreamingUnitTests;
 				PRODUCT_NAME = "$(TARGET_NAME)";
@@ -19697,6 +19743,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CODE_SIGN_STYLE = Automatic;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Debug;
@@ -19705,6 +19752,7 @@
 			isa = XCBuildConfiguration;
 			buildSettings = {
 				CODE_SIGN_STYLE = Automatic;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				PRODUCT_NAME = "$(TARGET_NAME)";
 			};
 			name = Release;
@@ -19728,7 +19776,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTestResources/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTestResources;
@@ -19756,7 +19804,7 @@
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSTestResources/Info.plist;
 				INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSTestResources;
 				PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
@@ -19874,7 +19922,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSCoreServiceConfigurationTest/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
 				MTL_FAST_MATH = YES;
@@ -19897,7 +19945,7 @@
 				DEVELOPMENT_TEAM = W3DRXD72QU;
 				GCC_C_LANGUAGE_STANDARD = gnu11;
 				INFOPLIST_FILE = AWSCoreServiceConfigurationTest/Info.plist;
-				IPHONEOS_DEPLOYMENT_TARGET = 9.0;
+				IPHONEOS_DEPLOYMENT_TARGET = 12.0;
 				LD_RUNPATH_SEARCH_PATHS = "$(FRAMEWORK_SEARCH_PATHS)";
 				MTL_FAST_MATH = YES;
 				PRODUCT_BUNDLE_IDENTIFIER = com.amazonaws.AWSCoreServiceConfigurationTest;
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b638262adc3..960b3454ef7 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,6 +2,61 @@
 
 ## Unreleased
 
+### New features
+
+- Updating the iOS deployment target to 12.0 for the following services:
+  - AWSAPIGateway
+  - AWSAuth
+  - AWSAuthCore
+  - AWSAuthUI
+  - AWSAutoScaling
+  - AWSChimeSDKIdentity
+  - AWSChimeSDKMessaging
+  - AWSCloudWatch
+  - AWSCognitoAuth
+  - AWSCognitoIdentityProvider
+  - AWSCognitoIdentityProviderASF
+  - AWSComprehend
+  - AWSConnect
+  - AWSConnectParticipant
+  - AWSCore
+  - AWSDynamoDB
+  - AWSEC2
+  - AWSElasticLoadBalancing
+  - AWSFacebookSignIn
+  - AWSGoogleSignIn
+  - AWSiOSSDKv2
+  - AWSIoT
+  - AWSKinesis
+  - AWSKinesisVideo
+  - AWSKinesisVideoArchivedMedia
+  - AWSKinesisVideoSignaling
+  - AWSKinesisVideoWebRTCStorage
+  - AWSKMS
+  - AWSLambda
+  - AWSLex
+  - AWSLocation
+  - AWSLogs
+  - AWSMachineLearning
+  - AWSMobileClient
+  - AWSPinpoint
+  - AWSPolly
+  - AWSRekognition
+  - AWSS3
+  - AWSSageMakerRuntime
+  - AWSSES
+  - AWSSimpleDB
+  - AWSSNS
+  - AWSSQS
+  - AWSTextract
+  - AWSTranscribe
+  - AWSTranscribeStreaming
+  - AWSTranslate
+  - AWSUserPoolsSignIn
+
+- **AWSCore**
+  - Updating CocoaLumberjack to version 3.4.8
+
 ### Misc. Updates
 - **AWSIoT**
   - Updating `AWSIoTMQTTConfiguration.keepAliveTimeInterval`'s default value in its attribute comment.
diff --git a/README.md b/README.md
index 06671db818e..a7cc7a0eef0 100644
--- a/README.md
+++ b/README.md
@@ -24,7 +24,7 @@ To get started with the AWS SDK for iOS, check out the [Developer Guide for iOS]
 To use the AWS SDK for iOS, you will need the following installed on your development machine:
 
 * Xcode 11.0 or later
-* iOS 9 or later
+* iOS 12 or later
 
 ## Include the SDK for iOS in an Existing Application
 
@@ -413,13 +413,13 @@ To initialize logging to your Xcode console, use the following code:
 **Swift**
 
 ```swift
-AWSDDLog.add(AWSDDTTYLogger.sharedInstance) // TTY = Xcode console
+AWSDDLog.add(AWSDDOSLogger.sharedInstance) // Apple's unified logging
 ```
 
 **Objective-C**
 
 ```objective-c
-[AWSDDLog addLogger:[AWSDDTTYLogger sharedInstance]]; // TTY = Xcode console
+[AWSDDLog addLogger:[AWSDDOSLogger sharedInstance]]; // Apple's unified logging
 ```
 
 ## Open Source Contributions