From fc46a3e7ec81f3508010dbe1a370f63be43ed6a9 Mon Sep 17 00:00:00 2001 From: AWS Date: Fri, 14 Jul 2017 21:50:06 +0000 Subject: [PATCH] The AWS Mobile SDK for iOS 2.5.9. --- AWSAPIGateway.podspec | 4 +- AWSAPIGateway/AWSAPIGatewayClient.m | 2 +- AWSAPIGateway/Info.plist | 2 +- AWSAutoScaling.podspec | 4 +- AWSAutoScaling/AWSAutoScalingService.m | 2 +- AWSAutoScaling/Info.plist | 2 +- AWSCloudWatch.podspec | 4 +- AWSCloudWatch/AWSCloudWatchService.m | 2 +- AWSCloudWatch/Info.plist | 2 +- AWSCognito.podspec | 4 +- AWSCognito/AWSCognitoService.m | 2 +- .../CognitoSync/AWSCognitoSyncService.m | 2 +- AWSCognito/Info.plist | 2 +- AWSCognitoAuth.podspec | 2 +- AWSCognitoAuth/AWSCognitoAuth.m | 2 +- AWSCognitoAuth/Info.plist | 2 +- AWSCognitoIdentityProvider.podspec | 4 +- .../AWSCognitoIdentityProviderService.m | 2 +- AWSCognitoIdentityProvider/Info.plist | 2 +- AWSCognitoSync.podspec | 4 +- AWSCore.podspec | 2 +- AWSCore/Info.plist | 2 +- AWSCore/Service/AWSService.m | 2 +- AWSDynamoDB.podspec | 4 +- AWSDynamoDB/AWSDynamoDBService.m | 2 +- AWSDynamoDB/Info.plist | 2 +- AWSEC2.podspec | 4 +- AWSEC2/AWSEC2Service.m | 2 +- AWSEC2/Info.plist | 2 +- AWSElasticLoadBalancing.podspec | 4 +- .../AWSElasticLoadBalancingService.m | 2 +- AWSElasticLoadBalancing/Info.plist | 2 +- AWSIoT.podspec | 4 +- AWSIoT/AWSIoTDataManager.m | 2 +- AWSIoT/AWSIoTDataService.m | 2 +- AWSIoT/AWSIoTService.m | 2 +- AWSIoT/Info.plist | 2 +- AWSIoT/Internal/AWSIoTMQTTClient.m | 76 ++-- AWSIoT/Internal/MQTTSDK/MQTTDecoder.m | 11 +- AWSIoT/Internal/MQTTSDK/MQTTEncoder.m | 10 +- AWSIoT/Internal/MQTTSDK/MQTTMessage.m | 9 +- AWSIoT/Internal/MQTTSDK/MQTTSession.m | 18 +- AWSIoT/Internal/SocketRocket/AWSSRWebSocket.m | 7 +- AWSIoTTests/AWSIoTDataTests.m | 2 +- AWSKMS.podspec | 4 +- AWSKMS/AWSKMSService.m | 2 +- AWSKMS/Info.plist | 2 +- AWSKinesis.podspec | 4 +- AWSKinesis/AWSFirehoseService.m | 2 +- AWSKinesis/AWSKinesisService.m | 2 +- AWSKinesis/Info.plist | 2 +- AWSLambda.podspec | 4 +- AWSLambda/AWSLambdaService.m | 4 +- AWSLambda/Info.plist | 2 +- AWSLex.podspec | 6 +- AWSLex/AWSLexInteractionKit.m | 2 +- AWSLex/AWSLexService.m | 2 +- AWSLex/AWSLexVoiceButton.m | 9 +- AWSLex/Info.plist | 2 +- .../Media.xcassets/Contents.json | 0 .../LexSpeak.imageset/Contents.json | 0 .../LexSpeak.imageset/lex_speak@1x.png | Bin .../LexSpeak.imageset/lex_speak@2x.png | Bin .../LexSpeak.imageset/lex_speak@3x.png | Bin .../Microphone.imageset/Contents.json | 0 .../Microphone.imageset/microphone@1x.png | Bin .../Microphone.imageset/microphone@2x.png | Bin .../Microphone.imageset/microphone@3x.png | Bin AWSLogs.podspec | 4 +- AWSLogs/AWSLogsService.m | 2 +- AWSLogs/Info.plist | 2 +- AWSMachineLearning.podspec | 4 +- .../AWSMachineLearningService.m | 2 +- AWSMachineLearning/Info.plist | 2 +- AWSMobileAnalytics.podspec | 4 +- .../AWSMobileAnalyticsERSService.m | 4 +- AWSMobileAnalytics/Info.plist | 2 +- AWSPinpoint.podspec | 4 +- .../AWSPinpointAnalyticsService.m | 4 +- AWSPinpoint/AWSPinpointConfiguration.h | 1 + AWSPinpoint/AWSPinpointEventRecorder.h | 18 +- AWSPinpoint/AWSPinpointEventRecorder.m | 363 +++++++++++------- AWSPinpoint/AWSPinpointSessionClient.h | 2 +- AWSPinpoint/AWSPinpointSessionClient.m | 215 ++++++----- .../AWSPinpointTargetingService.m | 4 +- AWSPinpoint/Info.plist | 2 +- AWSPinpoint/Internal/AWSPinpointContext.m | 1 + .../AWSPinpointEventRecorderTests.m | 141 ++++--- .../AWSPinpointSessionClientTests.m | 146 ++++++- AWSPolly.podspec | 4 +- AWSPolly/AWSPollyService.m | 2 +- AWSPolly/AWSPollySynthesizeSpeechURLBuilder.m | 2 +- AWSPolly/Info.plist | 2 +- AWSRekognition.podspec | 4 +- AWSRekognition/AWSRekognitionService.m | 2 +- AWSRekognition/Info.plist | 2 +- AWSResources/Info.plist | 28 -- AWSS3.podspec | 4 +- AWSS3/AWSS3PreSignedURL.m | 2 +- AWSS3/AWSS3Service.m | 2 +- AWSS3/Info.plist | 2 +- AWSSES.podspec | 4 +- AWSSES/AWSSESService.m | 2 +- AWSSES/Info.plist | 2 +- AWSSNS.podspec | 4 +- AWSSNS/AWSSNSService.m | 2 +- AWSSNS/Info.plist | 2 +- AWSSQS.podspec | 4 +- AWSSQS/AWSSQSService.m | 2 +- AWSSQS/Info.plist | 2 +- AWSSimpleDB.podspec | 4 +- AWSSimpleDB/AWSSimpleDBService.m | 2 +- AWSSimpleDB/Info.plist | 2 +- AWSiOSSDKv2.podspec | 52 +-- AWSiOSSDKv2.xcodeproj/project.pbxproj | 35 +- CHANGELOG.md | 17 + Scripts/GenerateAppleDocs.sh | 2 +- 117 files changed, 872 insertions(+), 525 deletions(-) rename {AWSResources => AWSLex}/Media.xcassets/Contents.json (100%) rename {AWSResources => AWSLex}/Media.xcassets/LexSpeak.imageset/Contents.json (100%) rename {AWSResources => AWSLex}/Media.xcassets/LexSpeak.imageset/lex_speak@1x.png (100%) rename {AWSResources => AWSLex}/Media.xcassets/LexSpeak.imageset/lex_speak@2x.png (100%) rename {AWSResources => AWSLex}/Media.xcassets/LexSpeak.imageset/lex_speak@3x.png (100%) rename {AWSResources => AWSLex}/Media.xcassets/Microphone.imageset/Contents.json (100%) rename {AWSResources => AWSLex}/Media.xcassets/Microphone.imageset/microphone@1x.png (100%) rename {AWSResources => AWSLex}/Media.xcassets/Microphone.imageset/microphone@2x.png (100%) rename {AWSResources => AWSLex}/Media.xcassets/Microphone.imageset/microphone@3x.png (100%) delete mode 100644 AWSResources/Info.plist diff --git a/AWSAPIGateway.podspec b/AWSAPIGateway.podspec index 2b21745d0cf..852919247ef 100644 --- a/AWSAPIGateway.podspec +++ b/AWSAPIGateway.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'AWSAPIGateway' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -13,7 +13,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSAPIGateway/*.{h,m}' end diff --git a/AWSAPIGateway/AWSAPIGatewayClient.m b/AWSAPIGateway/AWSAPIGatewayClient.m index a7bba741deb..ff9b568b0f8 100644 --- a/AWSAPIGateway/AWSAPIGatewayClient.m +++ b/AWSAPIGateway/AWSAPIGatewayClient.m @@ -23,7 +23,7 @@ static NSString *const AWSAPIGatewayAPIKeyHeader = @"x-api-key"; -static NSString *const AWSAPIGatewaySDKVersion = @"2.5.8"; +static NSString *const AWSAPIGatewaySDKVersion = @"2.5.9"; static int defaultChunkSize = 1024; diff --git a/AWSAPIGateway/Info.plist b/AWSAPIGateway/Info.plist index 18d5c3de538..e7ee27cf561 100644 --- a/AWSAPIGateway/Info.plist +++ b/AWSAPIGateway/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSAutoScaling.podspec b/AWSAutoScaling.podspec index a7bfd2d1085..9fe45c1df21 100644 --- a/AWSAutoScaling.podspec +++ b/AWSAutoScaling.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSAutoScaling' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSAutoScaling/*.{h,m}' end diff --git a/AWSAutoScaling/AWSAutoScalingService.m b/AWSAutoScaling/AWSAutoScalingService.m index 053100dbac1..eb243bc6e24 100644 --- a/AWSAutoScaling/AWSAutoScalingService.m +++ b/AWSAutoScaling/AWSAutoScalingService.m @@ -26,7 +26,7 @@ #import "AWSAutoScalingResources.h" static NSString *const AWSInfoAutoScaling = @"AutoScaling"; -static NSString *const AWSAutoScalingSDKVersion = @"2.5.8"; +static NSString *const AWSAutoScalingSDKVersion = @"2.5.9"; @interface AWSAutoScalingResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSAutoScaling/Info.plist b/AWSAutoScaling/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSAutoScaling/Info.plist +++ b/AWSAutoScaling/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCloudWatch.podspec b/AWSCloudWatch.podspec index d18b764e300..1bf3459498f 100644 --- a/AWSCloudWatch.podspec +++ b/AWSCloudWatch.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSCloudWatch' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSCloudWatch/*.{h,m}' end diff --git a/AWSCloudWatch/AWSCloudWatchService.m b/AWSCloudWatch/AWSCloudWatchService.m index d9b621537da..f068dccfbf2 100644 --- a/AWSCloudWatch/AWSCloudWatchService.m +++ b/AWSCloudWatch/AWSCloudWatchService.m @@ -26,7 +26,7 @@ #import "AWSCloudWatchResources.h" static NSString *const AWSInfoCloudWatch = @"CloudWatch"; -static NSString *const AWSCloudWatchSDKVersion = @"2.5.8"; +static NSString *const AWSCloudWatchSDKVersion = @"2.5.9"; @interface AWSCloudWatchResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSCloudWatch/Info.plist b/AWSCloudWatch/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSCloudWatch/Info.plist +++ b/AWSCloudWatch/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCognito.podspec b/AWSCognito.podspec index 16fd605d561..af233084b00 100644 --- a/AWSCognito.podspec +++ b/AWSCognito.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSCognito' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Cognito SDK for iOS' s.description = 'Amazon Cognito offers multi device data synchronization with offline access' @@ -13,7 +13,7 @@ Pod::Spec.new do |s| :tag => s.version} s.requires_arc = true s.library = 'sqlite3' - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSCognito/*.{h,m}', 'AWSCognito/**/*.{h,m}' s.public_header_files = 'AWSCognito/*.h', 'AWSCognito/CognitoSync/*.h' s.private_header_files = 'AWSCognito/Fabric/*.h', 'AWSCognito/Internal/*.h' diff --git a/AWSCognito/AWSCognitoService.m b/AWSCognito/AWSCognitoService.m index f1b9a877525..b4d1e2e6c8e 100644 --- a/AWSCognito/AWSCognitoService.m +++ b/AWSCognito/AWSCognitoService.m @@ -34,7 +34,7 @@ #import "Fabric+FABKits.h" static NSString *const AWSInfoCognito = @"Cognito"; -static NSString *const AWSCognitoSDKVersion = @"2.5.8"; +static NSString *const AWSCognitoSDKVersion = @"2.5.9"; NSString *const AWSCognitoDidStartSynchronizeNotification = @"com.amazon.cognito.AWSCognitoDidStartSynchronizeNotification"; NSString *const AWSCognitoDidEndSynchronizeNotification = @"com.amazon.cognito.AWSCognitoDidEndSynchronizeNotification"; diff --git a/AWSCognito/CognitoSync/AWSCognitoSyncService.m b/AWSCognito/CognitoSync/AWSCognitoSyncService.m index 396d2a74f4c..6a8abae6bba 100644 --- a/AWSCognito/CognitoSync/AWSCognitoSyncService.m +++ b/AWSCognito/CognitoSync/AWSCognitoSyncService.m @@ -26,7 +26,7 @@ #import "AWSCognitoSyncResources.h" static NSString *const AWSInfoCognitoSync = @"CognitoSync"; -static NSString *const AWSCognitoSyncSDKVersion = @"2.5.8"; +static NSString *const AWSCognitoSyncSDKVersion = @"2.5.9"; @interface AWSCognitoSyncResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSCognito/Info.plist b/AWSCognito/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSCognito/Info.plist +++ b/AWSCognito/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCognitoAuth.podspec b/AWSCognitoAuth.podspec index bf667978e8c..b80a0310cc6 100644 --- a/AWSCognitoAuth.podspec +++ b/AWSCognitoAuth.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSCognitoAuth' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Cognito Auth SDK for iOS (Beta)' s.description = 'Amazon Cognito Auth enables sign up and authentication of your end users via a hosted UI' diff --git a/AWSCognitoAuth/AWSCognitoAuth.m b/AWSCognitoAuth/AWSCognitoAuth.m index f16fabe5751..4e56da744ab 100644 --- a/AWSCognitoAuth/AWSCognitoAuth.m +++ b/AWSCognitoAuth/AWSCognitoAuth.m @@ -41,7 +41,7 @@ @interface AWSCognitoAuth()CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCognitoIdentityProvider.podspec b/AWSCognitoIdentityProvider.podspec index bfc88ece660..0238c03913a 100644 --- a/AWSCognitoIdentityProvider.podspec +++ b/AWSCognitoIdentityProvider.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSCognitoIdentityProvider' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Cognito Identity Provider SDK for iOS (Beta)' s.description = 'Amazon Cognito Identity Provider enables sign up and authentication of your end users' @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSCognitoIdentityProvider/**/*.{h,m,c}' s.public_header_files = 'AWSCognitoIdentityProvider/*.h', 'AWSCognitoIdentityProvider/CognitoIdentityProvider/*.h' s.private_header_files = 'AWSCognitoIdentityProvider/Internal/*.h' diff --git a/AWSCognitoIdentityProvider/CognitoIdentityProvider/AWSCognitoIdentityProviderService.m b/AWSCognitoIdentityProvider/CognitoIdentityProvider/AWSCognitoIdentityProviderService.m index ac5bb668a3a..5c35a2759dd 100644 --- a/AWSCognitoIdentityProvider/CognitoIdentityProvider/AWSCognitoIdentityProviderService.m +++ b/AWSCognitoIdentityProvider/CognitoIdentityProvider/AWSCognitoIdentityProviderService.m @@ -26,7 +26,7 @@ #import "AWSCognitoIdentityProviderResources.h" static NSString *const AWSInfoCognitoIdentityProvider = @"CognitoIdentityProvider"; -static NSString *const AWSCognitoIdentityProviderSDKVersion = @"2.5.8"; +static NSString *const AWSCognitoIdentityProviderSDKVersion = @"2.5.9"; @interface AWSCognitoIdentityProviderResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSCognitoIdentityProvider/Info.plist b/AWSCognitoIdentityProvider/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSCognitoIdentityProvider/Info.plist +++ b/AWSCognitoIdentityProvider/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCognitoSync.podspec b/AWSCognitoSync.podspec index 56c9e1dd0fd..65fc369cec4 100644 --- a/AWSCognitoSync.podspec +++ b/AWSCognitoSync.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'AWSCognitoSync' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Cognito SDK for iOS' s.description = 'Amazon Cognito offers multi device data synchronization with offline access' @@ -14,7 +14,7 @@ Pod::Spec.new do |s| :tag => s.version} s.requires_arc = true s.library = 'sqlite3' - s.dependency 'AWSCognito', '2.5.8' + s.dependency 'AWSCognito', '2.5.9' s.deprecated = true s.deprecated_in_favor_of = 'AWSCognito' diff --git a/AWSCore.podspec b/AWSCore.podspec index b1d85176878..318d59d9fc9 100644 --- a/AWSCore.podspec +++ b/AWSCore.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'AWSCore' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' diff --git a/AWSCore/Info.plist b/AWSCore/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSCore/Info.plist +++ b/AWSCore/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSCore/Service/AWSService.m b/AWSCore/Service/AWSService.m index 57e26494fe8..c1139bc3b9c 100644 --- a/AWSCore/Service/AWSService.m +++ b/AWSCore/Service/AWSService.m @@ -21,7 +21,7 @@ #import "AWSCocoaLumberjack.h" #import "AWSCategory.h" -NSString *const AWSiOSSDKVersion = @"2.5.8"; +NSString *const AWSiOSSDKVersion = @"2.5.9"; NSString *const AWSServiceErrorDomain = @"com.amazonaws.AWSServiceErrorDomain"; static NSString *const AWSServiceConfigurationUnknown = @"Unknown"; diff --git a/AWSDynamoDB.podspec b/AWSDynamoDB.podspec index 8ee08584543..a2a128f2a69 100644 --- a/AWSDynamoDB.podspec +++ b/AWSDynamoDB.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSDynamoDB' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSDynamoDB/*.{h,m}' end diff --git a/AWSDynamoDB/AWSDynamoDBService.m b/AWSDynamoDB/AWSDynamoDBService.m index 07b4f1d77d4..9c89faebd2a 100644 --- a/AWSDynamoDB/AWSDynamoDBService.m +++ b/AWSDynamoDB/AWSDynamoDBService.m @@ -27,7 +27,7 @@ #import "AWSDynamoDBRequestRetryHandler.h" static NSString *const AWSInfoDynamoDB = @"DynamoDB"; -static NSString *const AWSDynamoDBSDKVersion = @"2.5.8"; +static NSString *const AWSDynamoDBSDKVersion = @"2.5.9"; @interface AWSDynamoDBResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSDynamoDB/Info.plist b/AWSDynamoDB/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSDynamoDB/Info.plist +++ b/AWSDynamoDB/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSEC2.podspec b/AWSEC2.podspec index 19f1910856f..bc15a8f2a76 100644 --- a/AWSEC2.podspec +++ b/AWSEC2.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSEC2' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSEC2/*.{h,m}' end diff --git a/AWSEC2/AWSEC2Service.m b/AWSEC2/AWSEC2Service.m index c736025e80f..2bcc907919f 100644 --- a/AWSEC2/AWSEC2Service.m +++ b/AWSEC2/AWSEC2Service.m @@ -27,7 +27,7 @@ #import "AWSEC2Serializer.h" static NSString *const AWSInfoEC2 = @"EC2"; -static NSString *const AWSEC2SDKVersion = @"2.5.8"; +static NSString *const AWSEC2SDKVersion = @"2.5.9"; @interface AWSEC2ResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSEC2/Info.plist b/AWSEC2/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSEC2/Info.plist +++ b/AWSEC2/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSElasticLoadBalancing.podspec b/AWSElasticLoadBalancing.podspec index b164085d699..32ba53a2643 100644 --- a/AWSElasticLoadBalancing.podspec +++ b/AWSElasticLoadBalancing.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSElasticLoadBalancing' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSElasticLoadBalancing/*.{h,m}' end diff --git a/AWSElasticLoadBalancing/AWSElasticLoadBalancingService.m b/AWSElasticLoadBalancing/AWSElasticLoadBalancingService.m index 2715f25910b..706b927aa48 100644 --- a/AWSElasticLoadBalancing/AWSElasticLoadBalancingService.m +++ b/AWSElasticLoadBalancing/AWSElasticLoadBalancingService.m @@ -26,7 +26,7 @@ #import "AWSElasticLoadBalancingResources.h" static NSString *const AWSInfoElasticLoadBalancing = @"ElasticLoadBalancing"; -static NSString *const AWSElasticLoadBalancingSDKVersion = @"2.5.8"; +static NSString *const AWSElasticLoadBalancingSDKVersion = @"2.5.9"; @interface AWSElasticLoadBalancingResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSElasticLoadBalancing/Info.plist b/AWSElasticLoadBalancing/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSElasticLoadBalancing/Info.plist +++ b/AWSElasticLoadBalancing/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSIoT.podspec b/AWSIoT.podspec index 109b882845d..651d8e02b66 100644 --- a/AWSIoT.podspec +++ b/AWSIoT.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSIoT' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSIoT/*.{h,m}', 'AWSIoT/**/*.{h,m}' s.private_header_files = 'AWSIoT/Internal/*.h' end diff --git a/AWSIoT/AWSIoTDataManager.m b/AWSIoT/AWSIoTDataManager.m index d941e319065..ef23dd5cd3b 100644 --- a/AWSIoT/AWSIoTDataManager.m +++ b/AWSIoT/AWSIoTDataManager.m @@ -289,7 +289,7 @@ - (BOOL)connectUsingWebSocketWithClientId:(NSString *)clientId if (clientId == nil || [clientId isEqualToString: @""]) { return false; } - AWSDDLogInfo(@"Connecting to IoT using websocket, client id: %@", clientId); + AWSDDLogInfo(@"IOTDataManager: Connecting to IoT using websocket, client id: %@", clientId); [self.mqttClient setBaseReconnectTime:self.mqttConfiguration.baseReconnectTimeInterval]; [self.mqttClient setMinimumConnectionTime:self.mqttConfiguration.minimumConnectionTimeInterval]; [self.mqttClient setMaximumReconnectTime:self.mqttConfiguration.maximumReconnectTimeInterval]; diff --git a/AWSIoT/AWSIoTDataService.m b/AWSIoT/AWSIoTDataService.m index 026f2dede53..ff752a81f94 100644 --- a/AWSIoT/AWSIoTDataService.m +++ b/AWSIoT/AWSIoTDataService.m @@ -26,7 +26,7 @@ #import "AWSIoTDataResources.h" static NSString *const AWSInfoIoTData = @"IoTData"; -static NSString *const AWSIoTDataSDKVersion = @"2.5.8"; +static NSString *const AWSIoTDataSDKVersion = @"2.5.9"; @interface AWSIoTDataResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSIoT/AWSIoTService.m b/AWSIoT/AWSIoTService.m index 88c9cc9110e..ff49442b6c2 100644 --- a/AWSIoT/AWSIoTService.m +++ b/AWSIoT/AWSIoTService.m @@ -26,7 +26,7 @@ #import "AWSIoTResources.h" static NSString *const AWSInfoIoT = @"IoT"; -static NSString *const AWSIoTSDKVersion = @"2.5.8"; +static NSString *const AWSIoTSDKVersion = @"2.5.9"; @interface AWSIoTResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSIoT/Info.plist b/AWSIoT/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSIoT/Info.plist +++ b/AWSIoT/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSIoT/Internal/AWSIoTMQTTClient.m b/AWSIoT/Internal/AWSIoTMQTTClient.m index 9ef3bc75191..dc2c7c1f42c 100644 --- a/AWSIoT/Internal/AWSIoTMQTTClient.m +++ b/AWSIoT/Internal/AWSIoTMQTTClient.m @@ -264,6 +264,7 @@ - (BOOL)connectWithClientId:(NSString *)clientId // // no client certificate specified, connect via WebSocket // + AWSDDLogInfo(@"AWSIoTMQTTClient: connecting via websocket. "); if ((configuration != nil) && (clientId != nil)) { [[configuration.credentialsProvider credentials] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { @@ -302,6 +303,7 @@ - (BOOL)connectWithClientId:(NSString *)clientId // the use of an asynchronous credentials provider (e.g. Cognito), it will // always return successfully. // + AWSDDLogDebug(@"%s [Line %d], Thread:%@ ", __PRETTY_FUNCTION__, __LINE__, [NSThread currentThread]); return YES; } else @@ -350,11 +352,14 @@ - (BOOL)webSocketConnectWithClientId:(NSString *)clientId // // Now that the WebSocket is created and opened, it will send us messages. // + AWSDDLogVerbose(@"Websocket is created and opened."); return YES; } - (void)disconnect { + AWSDDLogInfo(@"AWSIoTMQTTClient: Disconnecting"); self.userDisconnect = YES; + [self.reconnectTimer invalidate]; [self.encoderStream close]; [self.webSocket close]; [self.session close]; @@ -363,8 +368,8 @@ - (void)disconnect { } - (void)reconnectToSession { + AWSDDLogInfo(@"Trying to reconnect to session."); self.needReconnect = self.cleanSession; - // // Clear the existing reconnect timer; also, double the reconnect time which will // be used on the next reconnection if this one fails to connect for the minimum @@ -380,22 +385,34 @@ - (void)reconnectToSession { // // Connecting with a client certificate/TLS mutual authentication // - [self.session connectToHost:self.host port:self.port usingSSL:YES sslCertificated:self.clientCerts]; + [self.session connectToHost:self.host + port:self.port + usingSSL:YES + sslCertificated:self.clientCerts]; } else { [[self.configuration.credentialsProvider credentials] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { if (task.error) { if (self.reconnectTimer == nil) { - self.reconnectTimer =[NSTimer timerWithTimeInterval:self.currentReconnectTime target:self selector: @selector(reconnectToSession) userInfo:nil repeats:NO]; - [[NSRunLoop mainRunLoop] addTimer:self.reconnectTimer forMode:NSRunLoopCommonModes]; + self.reconnectTimer =[NSTimer timerWithTimeInterval:self.currentReconnectTime + target:self + selector: @selector(reconnectToSession) + userInfo:nil + repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.reconnectTimer + forMode:NSRunLoopCommonModes]; } AWSDDLogError(@"error fetching credentials"); } else { AWSCredentials *credentials = task.result; - NSString *urlString = [self prepareWebSocketUrlWithHostName:self.configuration.endpoint.hostName regionName:self.configuration.endpoint.regionName accessKey:credentials.accessKey secretKey:credentials.secretKey sessionKey:credentials.sessionKey ]; + NSString *urlString = [self prepareWebSocketUrlWithHostName:self.configuration.endpoint.hostName + regionName:self.configuration.endpoint.regionName + accessKey:credentials.accessKey + secretKey:credentials.secretKey + sessionKey:credentials.sessionKey ]; // // Connecting over a WebSocket with SigV4 authentication. Close and deallocate // WebSocket objects so that we can create another one. @@ -419,11 +436,12 @@ - (void)reconnectToSession { self.connectStatusCallback(AWSIoTMQTTStatusConnecting); } - self.webSocket = [[AWSSRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] protocols:[NSArray arrayWithObjects: @"mqttv3.1", nil] allowsUntrustedSSLCertificates:NO]; + self.webSocket = [[AWSSRWebSocket alloc] initWithURLRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:urlString]] + protocols:[NSArray arrayWithObjects: @"mqttv3.1", nil] + allowsUntrustedSSLCertificates:NO]; self.webSocket.delegate = self; [self.webSocket open]; - - + // // Now that the WebSocket is created and opened, it will send us messages. // @@ -507,6 +525,7 @@ - (void)publishData:(NSData*)data qos:(UInt8)qos onTopic:(NSString*)topic { } - (void)subscribeToTopic:(NSString*)topic qos:(UInt8)qos messageCallback:(AWSIoTMQTTNewMessageBlock)callback { + AWSDDLogInfo(@"Subscribing to topic %@ with messageCallback", topic); AWSIoTMQTTTopicModel *topicModel = [AWSIoTMQTTTopicModel new]; topicModel.topic = topic; topicModel.qos = qos; @@ -516,6 +535,7 @@ - (void)subscribeToTopic:(NSString*)topic qos:(UInt8)qos messageCallback:(AWSIoT } - (void)subscribeToTopic:(NSString*)topic qos:(UInt8)qos extendedCallback:(AWSIoTMQTTExtendedNewMessageBlock)callback { + AWSDDLogInfo(@"Subscribing to topic %@ with ExtendedmessageCallback", topic); AWSIoTMQTTTopicModel *topicModel = [AWSIoTMQTTTopicModel new]; topicModel.topic = topic; topicModel.qos = qos; @@ -590,8 +610,8 @@ - (void)session:(MQTTSession*)session handleEvent:(MQTTSessionEvent)eventCode { self.userDisconnect = NO; if (self.connectStatusCallback != nil) { self.connectStatusCallback(AWSIoTMQTTStatusDisconnected); + self.connectStatusCallback = nil; } - self.connectStatusCallback = nil; } [self.postConnectTimer invalidate]; [self.emptyQueueTimer invalidate]; @@ -604,6 +624,7 @@ - (void)session:(MQTTSession*)session handleEvent:(MQTTSessionEvent)eventCode { } if (!self.userDisconnect && self.session) { if (self.reconnectTimer == nil) { + AWSDDLogDebug(@"setting up reconnectTimer."); self.reconnectTimer =[NSTimer scheduledTimerWithTimeInterval:self.currentReconnectTime target:self selector: @selector(reconnectToSession) userInfo:nil repeats:NO]; } } @@ -627,7 +648,7 @@ - (void)session:(MQTTSession*)session handleEvent:(MQTTSessionEvent)eventCode { } - (void)session:(MQTTSession*)session newMessage:(NSData*)data onTopic:(NSString*)topic { - AWSDDLogVerbose(@"MQTTSessionDelegate newMessage: %@\n onTopic: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], topic); + AWSDDLogVerbose(@"MQTTSessionDelegate newMessage: %@ onTopic: %@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], topic); NSArray *topicParts = [topic componentsSeparatedByString: @"/"]; @@ -653,12 +674,15 @@ - (void)session:(MQTTSession*)session newMessage:(NSData*)data onTopic:(NSString } if (topicMatch) { + AWSDDLogInfo(@"Topic: %@ is matched.", topic); AWSIoTMQTTTopicModel *topicModel = [self.topicListeners objectForKey:topicKey]; if (topicModel) { if (topicModel.callback != nil) { + AWSDDLogVerbose(@"topicModel.callback."); topicModel.callback(data); } if (topicModel.extendedCallback != nil) { + AWSDDLogVerbose(@"topicModel.extendedcallback."); topicModel.extendedCallback(self, topic, data); } } @@ -670,7 +694,7 @@ - (void)session:(MQTTSession*)session newMessage:(NSData*)data onTopic:(NSString - (void)webSocketDidOpen:(AWSSRWebSocket *)webSocket; { - AWSDDLogInfo(@"Websocket Connected"); + AWSDDLogInfo(@"Websocket did open and is Connected."); // // The WebSocket is connected; at this point we need to create streams // for MQTT encode/decode and then instantiate the MQTT client. @@ -692,17 +716,19 @@ - (void)webSocketDidOpen:(AWSSRWebSocket *)webSocket; self.decoderStream = (__bridge_transfer NSInputStream *)_decoderReadStream; self.toDecoderStream = (__bridge_transfer NSOutputStream *)_decoderWriteStream; - [self.toDecoderStream setDelegate:self]; + [self.toDecoderStream setDelegate:self]; - dispatch_async( dispatch_get_main_queue(), ^ { - [self.encoderStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + dispatch_queue_t gqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); - [self.decoderStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; - [self.toDecoderStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + dispatch_async( gqueue, ^ { + AWSDDLogDebug(@"Scheduling MQTT streams on Thread: %@", [NSThread currentThread]); + [self.toDecoderStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; [self.toDecoderStream open]; [self.session connectToInputStream:self.decoderStream outputStream:self.encoderStream]; + // Must start the current loop associated with current thread to handle events on the MQTT streams + [[NSRunLoop currentRunLoop] run]; }); // @@ -734,8 +760,15 @@ - (void)webSocket:(AWSSRWebSocket *)webSocket didFailWithError:(NSError *)error; self.connectStatusCallback(AWSIoTMQTTStatusConnectionError); } if (!self.userDisconnect && self.session) { + AWSDDLogWarn(@"Unexpected disconnect, need to reconnect. "); if (self.reconnectTimer == nil) { - self.reconnectTimer =[NSTimer scheduledTimerWithTimeInterval:self.currentReconnectTime target:self selector: @selector(reconnectToSession) userInfo:nil repeats:NO]; + AWSDDLogDebug(@"setting up reconnect timer. "); + self.reconnectTimer =[NSTimer scheduledTimerWithTimeInterval:self.currentReconnectTime + target:self + selector: @selector(reconnectToSession) + userInfo:nil + repeats:NO]; + [[NSRunLoop currentRunLoop] run]; } } [self.postConnectTimer invalidate]; @@ -749,14 +782,13 @@ - (void)webSocket:(AWSSRWebSocket *)webSocket didReceiveMessage:(id)message; { NSData *messageData = (NSData *)message; - AWSDDLogVerbose(@"Received %lu bytes", (unsigned long)messageData.length); - + AWSDDLogVerbose(@"Websocket didReceiveMessage: Received %lu bytes", (unsigned long)messageData.length); // // When a message is received, send it to the MQTT client's decoder // stream. // - [self.toDecoderStream write:[messageData bytes] maxLength:messageData.length]; + } else { @@ -766,13 +798,12 @@ - (void)webSocket:(AWSSRWebSocket *)webSocket didReceiveMessage:(id)message; - (void)webSocket:(AWSSRWebSocket *)webSocket didCloseWithCode:(NSInteger)code reason:(NSString *)reason wasClean:(BOOL)wasClean; { - AWSDDLogVerbose(@"WebSocket closed"); - if (self.connectStatusCallback != nil) { // // Let the application know it has been disconnected. // self.connectStatusCallback(AWSIoTMQTTStatusDisconnected); + self.connectStatusCallback = nil; } // // The WebSocket is closed, and the MQTT client can be deleted at this point. @@ -782,6 +813,7 @@ - (void)webSocket:(AWSSRWebSocket *)webSocket didCloseWithCode:(NSInteger)code r [self.encoderStream close]; self.webSocket = nil; + AWSDDLogInfo(@"WebSocket closed with code:%ld with reason:%@", (long)code, reason); } - (void)webSocket:(AWSSRWebSocket *)webSocket didReceivePong:(NSData *)pongPayload; diff --git a/AWSIoT/Internal/MQTTSDK/MQTTDecoder.m b/AWSIoT/Internal/MQTTSDK/MQTTDecoder.m index 52c38c07024..c189ad44ab1 100644 --- a/AWSIoT/Internal/MQTTSDK/MQTTDecoder.m +++ b/AWSIoT/Internal/MQTTSDK/MQTTDecoder.m @@ -45,19 +45,24 @@ - (id)initWithStream:(NSInputStream*)aStream } - (void)open { + AWSDDLogDebug(@"opening decoder stream."); [stream setDelegate:self]; - [stream scheduleInRunLoop:runLoop forMode:runLoopMode]; + runLoop = [NSRunLoop currentRunLoop]; + [stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode]; [stream open]; } - (void)close { + AWSDDLogDebug(@"closing decoder stream."); [stream setDelegate:nil]; [stream close]; - [stream removeFromRunLoop:runLoop forMode:runLoopMode]; + [stream removeFromRunLoop:runLoop forMode:NSDefaultRunLoopMode]; stream = nil; } - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { + AWSDDLogVerbose(@"%s [Line %d] EventCode:%lu, stream: %@, Thread: %@", __PRETTY_FUNCTION__, __LINE__, (unsigned long)eventCode, sender, [NSThread currentThread]); + if(stream == nil) return; switch (eventCode) { @@ -135,7 +140,7 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { dupFlag:isDuplicate data:dataBuffer]; [_delegate decoder:self newMessage:msg]; - dataBuffer = NULL; + dataBuffer = nil; _status = MQTTDecoderStatusDecodingHeader; } } diff --git a/AWSIoT/Internal/MQTTSDK/MQTTEncoder.m b/AWSIoT/Internal/MQTTSDK/MQTTEncoder.m index aceb53105d4..8613fa00fe1 100644 --- a/AWSIoT/Internal/MQTTSDK/MQTTEncoder.m +++ b/AWSIoT/Internal/MQTTSDK/MQTTEncoder.m @@ -42,15 +42,18 @@ - (id)initWithStream:(NSOutputStream*)aStream } - (void)open { + AWSDDLogDebug(@"opening encoder stream."); [stream setDelegate:self]; - [stream scheduleInRunLoop:runLoop forMode:runLoopMode]; + runLoop = [NSRunLoop currentRunLoop]; + [stream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode]; [stream open]; } - (void)close { + AWSDDLogDebug(@"closing encoder stream."); [stream close]; [stream setDelegate:nil]; - [stream removeFromRunLoop:runLoop forMode:runLoopMode]; + [stream removeFromRunLoop:runLoop forMode:NSDefaultRunLoopMode]; stream = nil; } @@ -65,10 +68,12 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { // // assert(sender == stream); // + AWSDDLogVerbose(@"%s [Line %d] EventCode:%lu, Thread: %@", __PRETTY_FUNCTION__, __LINE__, (unsigned long)eventCode, [NSThread currentThread]); switch (eventCode) { case NSStreamEventOpenCompleted: break; case NSStreamEventHasSpaceAvailable: + AWSDDLogDebug(@"MQTTEncoderStatus = %d", _status); if (_status == MQTTEncoderStatusInitializing) { _status = MQTTEncoderStatusReady; [_delegate encoder:self handleEvent:MQTTEncoderEventReady]; @@ -112,6 +117,7 @@ - (void)stream:(NSStream*)sender handleEvent:(NSStreamEvent)eventCode { } - (void)encodeMessage:(MQTTMessage*)msg { + AWSDDLogVerbose(@"%s [Line %d], Thread:%@", __PRETTY_FUNCTION__, __LINE__, [NSThread currentThread]); UInt8 header; NSInteger n, length; diff --git a/AWSIoT/Internal/MQTTSDK/MQTTMessage.m b/AWSIoT/Internal/MQTTSDK/MQTTMessage.m index ac6fd2ab000..64353f5a762 100644 --- a/AWSIoT/Internal/MQTTSDK/MQTTMessage.m +++ b/AWSIoT/Internal/MQTTSDK/MQTTMessage.m @@ -25,6 +25,7 @@ + (id)connectMessageWithClientId:(NSString*)clientId password:(NSString*)password keepAlive:(NSInteger)keepAlive cleanSession:(BOOL)cleanSessionFlag { + AWSDDLogDebug(@"%s [Line %d], Thread:%@ ", __PRETTY_FUNCTION__, __LINE__, [NSThread currentThread]); MQTTMessage* msg; UInt8 flags = 0x00; @@ -50,7 +51,7 @@ + (id)connectMessageWithClientId:(NSString*)clientId [data appendMQTTString:password]; } } - AWSDDLogInfo(@"%@",data); + AWSDDLogDebug(@"Creating MQTTMessage with raw data >>>>> %@ <<<<<",data); msg = [[MQTTMessage alloc] initWithType:MQTTConnect data:data]; return msg; } @@ -64,6 +65,7 @@ + (id)connectMessageWithClientId:(NSString*)clientId willMsg:(NSData*)willMsg willQoS:(UInt8)willQoS willRetain:(BOOL)willRetainFlag { + AWSDDLogDebug(@"%s [Line %d], Thread:%@ ", __PRETTY_FUNCTION__, __LINE__, [NSThread currentThread]); UInt8 flags = 0x00; if (cleanSessionFlag) { @@ -101,7 +103,7 @@ + (id)connectMessageWithClientId:(NSString*)clientId [data appendMQTTString:password]; } } - AWSDDLogInfo(@"%@",data); + AWSDDLogDebug(@"Creating MQTTMessage with raw data >>>>> %@ <<<<<",data); MQTTMessage *msg = [[MQTTMessage alloc] initWithType:MQTTConnect data:data]; @@ -139,6 +141,7 @@ + (id)unsubscribeMessageWithMessageId:(UInt16)msgId + (id)publishMessageWithData:(NSData*)payload onTopic:(NSString*)topic retainFlag:(BOOL)retain { + AWSDDLogVerbose(@"Publish message on topic: %@, retain flag: %@", topic, retain ? @"true":@"false"); NSMutableData* data = [NSMutableData data]; [data appendMQTTString:topic]; [data appendData:payload]; @@ -156,6 +159,8 @@ + (id)publishMessageWithData:(NSData*)payload msgId:(UInt16)msgId retainFlag:(BOOL)retain dupFlag:(BOOL)dup { + AWSDDLogVerbose(@"Publish message on topic: %@, qos: %d, mssgId: %d, retain flag: %@, dup flag: %@", + topic, qosLevel, msgId, retain ? @"ture":@"false", dup ? @"ture":@"false"); NSMutableData* data = [NSMutableData data]; [data appendMQTTString:topic]; [data appendUInt16BigEndian:msgId]; diff --git a/AWSIoT/Internal/MQTTSDK/MQTTSession.m b/AWSIoT/Internal/MQTTSDK/MQTTSession.m index 58d4a7ab4f7..b8f42170fa3 100644 --- a/AWSIoT/Internal/MQTTSDK/MQTTSession.m +++ b/AWSIoT/Internal/MQTTSDK/MQTTSession.m @@ -166,6 +166,7 @@ - (id)initWithClientId:(NSString*)theClientId willRetainFlag:(BOOL)willRetainFlag runLoop:(NSRunLoop*)theRunLoop forMode:(NSString*)theRunLoopMode { + AWSDDLogInfo(@"%s [Line %d], Thread:%@ ", __PRETTY_FUNCTION__, __LINE__, [NSThread currentThread]); MQTTMessage *msg = [MQTTMessage connectMessageWithClientId:theClientId userName:theUserName password:thePassword @@ -303,6 +304,7 @@ - (void)connectToHost:(NSString*)ip port:(UInt32)port usingSSL:(BOOL)usingSSL ss - (id)connectToInputStream:(NSInputStream *)readStream outputStream:(NSOutputStream *)writeStream; { + AWSDDLogInfo(@"Initializing MQTTEncoder and MQTTDecoder streams"); status = MQTTSessionStatusCreated; encoder = [[MQTTEncoder alloc] initWithStream:writeStream @@ -415,7 +417,7 @@ - (void)timerHandler:(NSTimer*)theTimer { idleTimer++; if (idleTimer >= keepAliveInterval) { if ([encoder status] == MQTTEncoderStatusReady) { - AWSDDLogInfo(@"sending PINGREQ"); + AWSDDLogVerbose(@"sending PINGREQ"); [encoder encodeMessage:[MQTTMessage pingreqMessage]]; idleTimer = 0; } @@ -434,10 +436,11 @@ - (void)timerHandler:(NSTimer*)theTimer { } - (void)encoder:(MQTTEncoder*)sender handleEvent:(MQTTEncoderEvent) eventCode { - // AWSDDLogInfo(@"encoder:(MQTTEncoder*)sender handleEvent:(MQTTEncoderEvent) eventCode "); + AWSDDLogVerbose(@"%s [Line %d], eventCode: %d", __PRETTY_FUNCTION__, __LINE__, eventCode); if(sender == encoder) { switch (eventCode) { case MQTTEncoderEventReady: + AWSDDLogDebug(@"MQTTSessionStatus = %d", status); switch (status) { case MQTTSessionStatusCreated: //AWSDDLogInfo(@"Encoder has been created. Sending Auth Message"); @@ -465,7 +468,7 @@ - (void)encoder:(MQTTEncoder*)sender handleEvent:(MQTTEncoderEvent) eventCode { } - (void)decoder:(MQTTDecoder*)sender handleEvent:(MQTTDecoderEvent)eventCode { - //AWSDDLogInfo(@"decoder:(MQTTDecoder*)sender handleEvent:(MQTTDecoderEvent)eventCode"); + AWSDDLogVerbose(@"%s [Line %d] eventCode:%d", __PRETTY_FUNCTION__, __LINE__, eventCode); if(sender == decoder) { MQTTSessionEvent event; switch (eventCode) { @@ -484,9 +487,8 @@ - (void)decoder:(MQTTDecoder*)sender handleEvent:(MQTTDecoderEvent)eventCode { } - (void)decoder:(MQTTDecoder*)sender newMessage:(MQTTMessage*)msg { - //AWSDDLogInfo(@"decoder:(MQTTDecoder*)sender newMessage:(MQTTMessage*)msg "); + AWSDDLogVerbose(@"%s [Line %d] ", __PRETTY_FUNCTION__, __LINE__); MQTTMessageType messageType = [msg type]; - if(sender == decoder){ switch (status) { case MQTTSessionStatusConnecting: @@ -510,7 +512,7 @@ - (void)decoder:(MQTTDecoder*)sender newMessage:(MQTTMessage*)msg { } [_delegate session:self handleEvent:MQTTSessionEventConnected]; - AWSDDLogInfo(@"Adding timer for runLoop"); + AWSDDLogInfo(@"Adding timer for runLoop, timer interval: %f minute", timer.timeInterval); //the runloop that we want to attach the timer to may not be the same runloop //when AWSIoTMQTTConfiguration was created, instead, it needs to be the current //runloop at the time when the timer is created. Hence, we explicitly add timer @@ -537,6 +539,7 @@ - (void)decoder:(MQTTDecoder*)sender newMessage:(MQTTMessage*)msg { } - (void)newMessage:(MQTTMessage*)msg { + AWSDDLogInfo(@"MQTTSession- newMessage msg type is %d", [msg type]); switch ([msg type]) { case MQTTPublish: [self handlePublish:msg]; @@ -559,7 +562,7 @@ - (void)newMessage:(MQTTMessage*)msg { } - (void)handlePublish:(MQTTMessage*)msg { - + AWSDDLogVerbose(@"%s [Line %d] ", __PRETTY_FUNCTION__, __LINE__); NSData *data = [msg data]; if ([data length] < 2) { return; @@ -723,6 +726,7 @@ - (void)error:(MQTTSessionEvent)eventCode { } - (void)send:(MQTTMessage*)msg { + AWSDDLogVerbose(@"%s [Line %d] ", __PRETTY_FUNCTION__, __LINE__); if ([encoder status] == MQTTEncoderStatusReady) { [encoder encodeMessage:msg]; } diff --git a/AWSIoT/Internal/SocketRocket/AWSSRWebSocket.m b/AWSIoT/Internal/SocketRocket/AWSSRWebSocket.m index 50fc2f51bcf..3a1efa4990d 100644 --- a/AWSIoT/Internal/SocketRocket/AWSSRWebSocket.m +++ b/AWSIoT/Internal/SocketRocket/AWSSRWebSocket.m @@ -328,8 +328,9 @@ - (void)_SR_commonInit; // Going to set a specific on the queue so we can validate we're on the work queue dispatch_queue_set_specific(_workQueue, (__bridge void *)self, maybe_bridge(_workQueue), NULL); - - _delegateDispatchQueue = dispatch_get_main_queue(); + + //Changing it to be dispatched on global queue. This triggers didReceiveMessage , which should be running in background thread. + _delegateDispatchQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0); sr_dispatch_retain(_delegateDispatchQueue); _readBuffer = [[NSMutableData alloc] init]; @@ -403,8 +404,10 @@ - (void)open; - (void)_performDelegateBlock:(dispatch_block_t)block; { if (_delegateOperationQueue) { + SRFastLog(@"using _delegateOperationQueue."); [_delegateOperationQueue addOperationWithBlock:block]; } else { + SRFastLog(@"using _delegateDispatchQueue."); assert(_delegateDispatchQueue); dispatch_async(_delegateDispatchQueue, block); } diff --git a/AWSIoTTests/AWSIoTDataTests.m b/AWSIoTTests/AWSIoTDataTests.m index 1ca25b51f8d..fda0a858965 100644 --- a/AWSIoTTests/AWSIoTDataTests.m +++ b/AWSIoTTests/AWSIoTDataTests.m @@ -215,7 +215,7 @@ - (void) testWebsocketConnectStateTransition { void (^updateConnectionStatus)(AWSIoTMQTTStatus) = ^(AWSIoTMQTTStatus status) { ++timesTriggered; currentStatus = status; - + AWSDDLogInfo(@"status = %d", status); //timesTriggered is incremented before the following checks, so it's value should be at least 1. if (1 == timesTriggered) XCTAssertEqual(currentStatus, AWSIoTMQTTStatusConnecting); diff --git a/AWSKMS.podspec b/AWSKMS.podspec index ee2f0d47b59..3c7d1c80f10 100644 --- a/AWSKMS.podspec +++ b/AWSKMS.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSKMS' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSKMS/*.{h,m}' end diff --git a/AWSKMS/AWSKMSService.m b/AWSKMS/AWSKMSService.m index 9ab391153b8..a40090c0eb2 100644 --- a/AWSKMS/AWSKMSService.m +++ b/AWSKMS/AWSKMSService.m @@ -26,7 +26,7 @@ #import "AWSKMSResources.h" static NSString *const AWSInfoKMS = @"KMS"; -static NSString *const AWSKMSSDKVersion = @"2.5.8"; +static NSString *const AWSKMSSDKVersion = @"2.5.9"; @interface AWSKMSResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSKMS/Info.plist b/AWSKMS/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSKMS/Info.plist +++ b/AWSKMS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSKinesis.podspec b/AWSKinesis.podspec index 06ab0004326..83042d2b225 100644 --- a/AWSKinesis.podspec +++ b/AWSKinesis.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSKinesis' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSKinesis/*.{h,m}' end diff --git a/AWSKinesis/AWSFirehoseService.m b/AWSKinesis/AWSFirehoseService.m index 9d792d1684f..c7e6fbcc403 100644 --- a/AWSKinesis/AWSFirehoseService.m +++ b/AWSKinesis/AWSFirehoseService.m @@ -26,7 +26,7 @@ #import "AWSFirehoseResources.h" static NSString *const AWSInfoFirehose = @"Firehose"; -static NSString *const AWSFirehoseSDKVersion = @"2.5.8"; +static NSString *const AWSFirehoseSDKVersion = @"2.5.9"; @interface AWSFirehoseResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSKinesis/AWSKinesisService.m b/AWSKinesis/AWSKinesisService.m index 1c1867ae31e..360ca8b9e34 100644 --- a/AWSKinesis/AWSKinesisService.m +++ b/AWSKinesis/AWSKinesisService.m @@ -27,7 +27,7 @@ #import "AWSKinesisRequestRetryHandler.h" static NSString *const AWSInfoKinesis = @"Kinesis"; -static NSString *const AWSKinesisSDKVersion = @"2.5.8"; +static NSString *const AWSKinesisSDKVersion = @"2.5.9"; @interface AWSKinesisResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSKinesis/Info.plist b/AWSKinesis/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSKinesis/Info.plist +++ b/AWSKinesis/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSLambda.podspec b/AWSLambda.podspec index b36cfd68030..f3646bb80e2 100644 --- a/AWSLambda.podspec +++ b/AWSLambda.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSLambda' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSLambda/*.{h,m}' end diff --git a/AWSLambda/AWSLambdaService.m b/AWSLambda/AWSLambdaService.m index 925d374c830..e20e05132f8 100644 --- a/AWSLambda/AWSLambdaService.m +++ b/AWSLambda/AWSLambdaService.m @@ -27,7 +27,7 @@ #import "AWSLambdaRequestRetryHandler.h" static NSString *const AWSInfoLambda = @"Lambda"; -static NSString *const AWSLambdaSDKVersion = @"2.5.8"; +static NSString *const AWSLambdaSDKVersion = @"2.5.9"; @interface AWSLambdaResponseSerializer : AWSJSONResponseSerializer @@ -128,7 +128,7 @@ - (id)responseObjectForResponse:(NSHTTPURLResponse *)response *error = [NSError errorWithDomain:AWSLambdaErrorDomain code:AWSLambdaErrorUnknown userInfo:responseObject]; - } + } return responseObject; } diff --git a/AWSLambda/Info.plist b/AWSLambda/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSLambda/Info.plist +++ b/AWSLambda/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSLex.podspec b/AWSLex.podspec index 5222adf8787..4e8d699de0d 100644 --- a/AWSLex.podspec +++ b/AWSLex.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSLex' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,11 +12,11 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSLex/*.{h,m}', 'AWSLex/Bluefront/include/*.h' s.public_header_files = 'AWSLex/*.h' s.private_header_files = 'AWSLex/Bluefront/include/*.h' s.preserve_paths = 'AWSLex/Bluefront/include/*' s.vendored_libraries = 'AWSLex/Bluefront/libBlueAudioSourceiOS.a' - s.resource_bundle = { 'AWSResources' => 'AWSResources/*' } + s.resource_bundle = { 'AWSLex' => 'AWSLex/Media.xcassets/*' } end diff --git a/AWSLex/AWSLexInteractionKit.m b/AWSLex/AWSLexInteractionKit.m index 7a9a1f84ed6..eb0489e939b 100644 --- a/AWSLex/AWSLexInteractionKit.m +++ b/AWSLex/AWSLexInteractionKit.m @@ -22,7 +22,7 @@ #import NSString *const AWSInfoInteractionKit = @"LexInteractionKit"; -NSString *const AWSInteractionKitSDKVersion = @"2.5.8"; +NSString *const AWSInteractionKitSDKVersion = @"2.5.9"; NSString *const AWSInternalLexInteractionKit = @"LexInteractionKitClient"; NSString *const AWSLexInteractionKitUserAgent = @"interactionkit"; NSString *const AWSLexInteractionKitErrorDomain = @"com.amazonaws.AWSLexInteractionKitErrorDomain"; diff --git a/AWSLex/AWSLexService.m b/AWSLex/AWSLexService.m index b9ba7e8a968..788a14331e2 100644 --- a/AWSLex/AWSLexService.m +++ b/AWSLex/AWSLexService.m @@ -28,7 +28,7 @@ #import "AWSLexSignature.h" static NSString *const AWSInfoLex = @"Lex"; -static NSString *const AWSLexSDKVersion = @"2.5.8"; +static NSString *const AWSLexSDKVersion = @"2.5.9"; @interface AWSLexResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSLex/AWSLexVoiceButton.m b/AWSLex/AWSLexVoiceButton.m index d5cfce06bbd..957d503d7b1 100644 --- a/AWSLex/AWSLexVoiceButton.m +++ b/AWSLex/AWSLexVoiceButton.m @@ -26,8 +26,6 @@ NSString *const AWSLexVoiceButtonKey = @"AWSLexVoiceButton"; static NSString *ProgressAnimationKey = @"progressanimation.rotation"; -static NSString *ResourceBundle = @"AWSResources"; -static NSString *BundleExtension = @"bundle"; static NSString *MicrophoneImageKey = @"Microphone"; static NSString *LexSpeakImageKey = @"LexSpeak"; static NSString *VoiceButtonUserAgent = @"LexVoiceButton"; @@ -202,12 +200,9 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder{ if(self = [super initWithCoder:aDecoder]) { imageButton = [[UIButton alloc]initWithFrame:CGRectMake(0, 0, SIZE, SIZE)]; NSBundle *currentBundle = [NSBundle bundleForClass:[self class]]; - NSURL *bundleUrl = [currentBundle URLForResource:ResourceBundle withExtension:BundleExtension]; - - NSBundle *imageBundle = [NSBundle bundleWithURL:bundleUrl]; // Use microphone image when the user speaks. - UIImage *temp = [UIImage imageNamed:MicrophoneImageKey inBundle:imageBundle compatibleWithTraitCollection:nil]; + UIImage *temp = [UIImage imageNamed:MicrophoneImageKey inBundle:currentBundle compatibleWithTraitCollection:nil]; self.microphoneImage = [temp imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; [self setButtonImage:self.microphoneImage imageTintColor:self.microphoneImageColor animated:NO]; [imageButton addTarget:self action:@selector(startMonitoring:) forControlEvents:UIControlEventTouchDown]; @@ -215,7 +210,7 @@ - (instancetype)initWithCoder:(NSCoder *)aDecoder{ imageButton.imageView.tintColor = self.microphoneImageColor; // Use listen image when Lex speaks. - temp = [UIImage imageNamed:LexSpeakImageKey inBundle:imageBundle compatibleWithTraitCollection:nil]; + temp = [UIImage imageNamed:LexSpeakImageKey inBundle:currentBundle compatibleWithTraitCollection:nil]; self.listenImage = [temp imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; lightGrey = [UIColor colorWithWhite:0 alpha:0.2]; diff --git a/AWSLex/Info.plist b/AWSLex/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSLex/Info.plist +++ b/AWSLex/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSResources/Media.xcassets/Contents.json b/AWSLex/Media.xcassets/Contents.json similarity index 100% rename from AWSResources/Media.xcassets/Contents.json rename to AWSLex/Media.xcassets/Contents.json diff --git a/AWSResources/Media.xcassets/LexSpeak.imageset/Contents.json b/AWSLex/Media.xcassets/LexSpeak.imageset/Contents.json similarity index 100% rename from AWSResources/Media.xcassets/LexSpeak.imageset/Contents.json rename to AWSLex/Media.xcassets/LexSpeak.imageset/Contents.json diff --git a/AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@1x.png b/AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@1x.png similarity index 100% rename from AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@1x.png rename to AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@1x.png diff --git a/AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@2x.png b/AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@2x.png similarity index 100% rename from AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@2x.png rename to AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@2x.png diff --git a/AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@3x.png b/AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@3x.png similarity index 100% rename from AWSResources/Media.xcassets/LexSpeak.imageset/lex_speak@3x.png rename to AWSLex/Media.xcassets/LexSpeak.imageset/lex_speak@3x.png diff --git a/AWSResources/Media.xcassets/Microphone.imageset/Contents.json b/AWSLex/Media.xcassets/Microphone.imageset/Contents.json similarity index 100% rename from AWSResources/Media.xcassets/Microphone.imageset/Contents.json rename to AWSLex/Media.xcassets/Microphone.imageset/Contents.json diff --git a/AWSResources/Media.xcassets/Microphone.imageset/microphone@1x.png b/AWSLex/Media.xcassets/Microphone.imageset/microphone@1x.png similarity index 100% rename from AWSResources/Media.xcassets/Microphone.imageset/microphone@1x.png rename to AWSLex/Media.xcassets/Microphone.imageset/microphone@1x.png diff --git a/AWSResources/Media.xcassets/Microphone.imageset/microphone@2x.png b/AWSLex/Media.xcassets/Microphone.imageset/microphone@2x.png similarity index 100% rename from AWSResources/Media.xcassets/Microphone.imageset/microphone@2x.png rename to AWSLex/Media.xcassets/Microphone.imageset/microphone@2x.png diff --git a/AWSResources/Media.xcassets/Microphone.imageset/microphone@3x.png b/AWSLex/Media.xcassets/Microphone.imageset/microphone@3x.png similarity index 100% rename from AWSResources/Media.xcassets/Microphone.imageset/microphone@3x.png rename to AWSLex/Media.xcassets/Microphone.imageset/microphone@3x.png diff --git a/AWSLogs.podspec b/AWSLogs.podspec index d3ded77ad16..bdeeac17fa8 100644 --- a/AWSLogs.podspec +++ b/AWSLogs.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSLogs' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSLogs/*.{h,m}' end diff --git a/AWSLogs/AWSLogsService.m b/AWSLogs/AWSLogsService.m index 6a82f24c66b..55e234618f6 100644 --- a/AWSLogs/AWSLogsService.m +++ b/AWSLogs/AWSLogsService.m @@ -26,7 +26,7 @@ #import "AWSLogsResources.h" static NSString *const AWSInfoLogs = @"Logs"; -static NSString *const AWSLogsSDKVersion = @"2.5.8"; +static NSString *const AWSLogsSDKVersion = @"2.5.9"; @interface AWSLogsResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSLogs/Info.plist b/AWSLogs/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSLogs/Info.plist +++ b/AWSLogs/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSMachineLearning.podspec b/AWSMachineLearning.podspec index c9949679e7f..88911aabb8b 100644 --- a/AWSMachineLearning.podspec +++ b/AWSMachineLearning.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSMachineLearning' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSMachineLearning/*.{h,m}' end diff --git a/AWSMachineLearning/AWSMachineLearningService.m b/AWSMachineLearning/AWSMachineLearningService.m index 272c0b69383..b4953db4e79 100644 --- a/AWSMachineLearning/AWSMachineLearningService.m +++ b/AWSMachineLearning/AWSMachineLearningService.m @@ -26,7 +26,7 @@ #import "AWSMachineLearningResources.h" static NSString *const AWSInfoMachineLearning = @"MachineLearning"; -static NSString *const AWSMachineLearningSDKVersion = @"2.5.8"; +static NSString *const AWSMachineLearningSDKVersion = @"2.5.9"; diff --git a/AWSMachineLearning/Info.plist b/AWSMachineLearning/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSMachineLearning/Info.plist +++ b/AWSMachineLearning/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSMobileAnalytics.podspec b/AWSMobileAnalytics.podspec index 1e5f5a8cc09..f988521a341 100644 --- a/AWSMobileAnalytics.podspec +++ b/AWSMobileAnalytics.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSMobileAnalytics' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSMobileAnalytics/*.{h,m}', 'AWSMobileAnalytics/**/*.{h,m}' s.private_header_files = 'AWSMobileAnalytics/Internal/*.h' end diff --git a/AWSMobileAnalytics/AWSMobileAnalyticsERS/AWSMobileAnalyticsERSService.m b/AWSMobileAnalytics/AWSMobileAnalyticsERS/AWSMobileAnalyticsERSService.m index d3b2c43a1bd..090de88e189 100644 --- a/AWSMobileAnalytics/AWSMobileAnalyticsERS/AWSMobileAnalyticsERSService.m +++ b/AWSMobileAnalytics/AWSMobileAnalyticsERS/AWSMobileAnalyticsERSService.m @@ -26,7 +26,7 @@ #import "AWSMobileAnalyticsERSResources.h" static NSString *const AWSInfoMobileAnalyticsERS = @"MobileAnalyticsERS"; -static NSString *const AWSMobileAnalyticsERSSDKVersion = @"2.5.8"; +static NSString *const AWSMobileAnalyticsERSSDKVersion = @"2.5.9"; @interface AWSMobileAnalyticsERSResponseSerializer : AWSJSONResponseSerializer @@ -110,7 +110,7 @@ - (id)responseObjectForResponse:(NSHTTPURLResponse *)response *error = [NSError errorWithDomain:AWSMobileAnalyticsERSErrorDomain code:AWSMobileAnalyticsERSErrorUnknown userInfo:responseObject]; - } + } return responseObject; } diff --git a/AWSMobileAnalytics/Info.plist b/AWSMobileAnalytics/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSMobileAnalytics/Info.plist +++ b/AWSMobileAnalytics/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSPinpoint.podspec b/AWSPinpoint.podspec index be8f47fa8dc..ef07f825691 100644 --- a/AWSPinpoint.podspec +++ b/AWSPinpoint.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSPinpoint' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,7 +12,7 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSPinpoint/*.{h,m}', 'AWSPinpoint/**/*.{h,m}' s.private_header_files = 'AWSPinpoint/Internal/*.h' end diff --git a/AWSPinpoint/AWSPinpointAnalytics/AWSPinpointAnalyticsService.m b/AWSPinpoint/AWSPinpointAnalytics/AWSPinpointAnalyticsService.m index 6af445f7479..193f53a67e2 100644 --- a/AWSPinpoint/AWSPinpointAnalytics/AWSPinpointAnalyticsService.m +++ b/AWSPinpoint/AWSPinpointAnalytics/AWSPinpointAnalyticsService.m @@ -26,7 +26,7 @@ #import "AWSPinpointAnalyticsResources.h" static NSString *const AWSInfoPinpointAnalytics = @"PinpointAnalytics"; -static NSString *const AWSPinpointAnalyticsSDKVersion = @"2.5.8"; +static NSString *const AWSPinpointAnalyticsSDKVersion = @"2.5.9"; @interface AWSPinpointAnalyticsResponseSerializer : AWSJSONResponseSerializer @@ -110,7 +110,7 @@ - (id)responseObjectForResponse:(NSHTTPURLResponse *)response *error = [NSError errorWithDomain:AWSPinpointAnalyticsErrorDomain code:AWSPinpointAnalyticsErrorUnknown userInfo:responseObject]; - } + } return responseObject; } diff --git a/AWSPinpoint/AWSPinpointConfiguration.h b/AWSPinpoint/AWSPinpointConfiguration.h index 7b82d6c5873..6bccd98c8a9 100644 --- a/AWSPinpoint/AWSPinpointConfiguration.h +++ b/AWSPinpoint/AWSPinpointConfiguration.h @@ -61,6 +61,7 @@ typedef void(^AWSInitializationCompletionBlock)(AWSPinpoint * _Nonnull pinpoint) */ @property (nonatomic, assign) BOOL enableTargeting; + /** Indicates whether or not analytics session events are automatically recorded. Defaults to YES. diff --git a/AWSPinpoint/AWSPinpointEventRecorder.h b/AWSPinpoint/AWSPinpointEventRecorder.h index d0250841dda..442a2c0eae1 100644 --- a/AWSPinpoint/AWSPinpointEventRecorder.h +++ b/AWSPinpoint/AWSPinpointEventRecorder.h @@ -75,19 +75,33 @@ FOUNDATION_EXPORT NSString *const AWSPinpointEventByteThresholdReachedNotificati - (AWSTask *) saveEvent:(AWSPinpointEvent *) event; /** - Retrieves events in local storage. + Retrieves events in local storage with a limit of 128 events. @return AWSTask - task.result contains an array of AWSPinpointEvent objects. */ - (AWSTask *> *) getEvents; /** - Retrieves dirty events in local storage. + Retrieves events in local storage with the specified limit. + + @return AWSTask - task.result contains an array of AWSPinpointEvent objects. + */ +- (AWSTask *> *) getEventsWithLimit:(NSNumber *) limit; + +/** + Retrieves dirty events in local storage with a limit of 128 events. @return AWSTask - task.result contains an array of AWSPinpointEvent objects. */ - (AWSTask *> *) getDirtyEvents; +/** + Retrieves dirty events in local storage with the specified limit. + + @return AWSTask - task.result contains an array of AWSPinpointEvent objects. + */ +- (AWSTask *> *) getDirtyEventsWithLimit:(NSNumber *) limit; + /** Submits all locally saved events to Amazon Pinpoint. Events that are successfully sent will be deleted from the device. Events that fail due to the device being offline will stop the submission process and be kept. Events that fail due to other reasons (such as the event being invalid) will be marked dirty and moved to a dirty table. diff --git a/AWSPinpoint/AWSPinpointEventRecorder.m b/AWSPinpoint/AWSPinpointEventRecorder.m index c23bf56a995..b8c68ae1969 100644 --- a/AWSPinpoint/AWSPinpointEventRecorder.m +++ b/AWSPinpoint/AWSPinpointEventRecorder.m @@ -27,7 +27,7 @@ // Pinpoint Abstract Client NSUInteger const AWSPinpointClientByteLimitDefault = 5 * 1024 * 1024; // 5MB NSTimeInterval const AWSPinpointClientAgeLimitDefault = 0.0; // Keeps the data indefinitely unless it hits the size limit. -NSUInteger const AWSPinpointClientBatchRecordByteLimitDefault = 512 * 1024 * 1024; +NSUInteger const AWSPinpointClientBatchRecordByteLimitDefault = 512 * 1024; NSString *const AWSPinpointClientRecorderDatabasePathPrefix = @"com/amazonaws/AWSPinpointRecorder"; // Constants @@ -322,10 +322,10 @@ - (AWSTask*) getCurrentSession: (AWSPinpointSession*) session { withStartTime:[NSDate aws_dateFromString:[rs stringForColumn:@"sessionStartTime"] format:AWSDateISO8601DateFormat3] withStopTime:[NSDate aws_dateFromString:[rs stringForColumn:@"sessionStopTime"] format:AWSDateISO8601DateFormat3]]; event = [[AWSPinpointEvent alloc] initWithEventType:[rs stringForColumn:@"eventType"] - eventTimestamp:[AWSPinpointDateUtils utcTimeMillisFromISO8061String:[rs stringForColumn:@"eventTimestamp"]] - session:session - attributes:attributes - metrics:metrics]; + eventTimestamp:[AWSPinpointDateUtils utcTimeMillisFromISO8061String:[rs stringForColumn:@"eventTimestamp"]] + session:session + attributes:attributes + metrics:metrics]; } }]; @@ -338,18 +338,23 @@ - (AWSTask*) getCurrentSession: (AWSPinpointSession*) session { } - (AWSTask *> *) getEvents { + return [self getEventsWithLimit:@128]; +} + +- (AWSTask *> *) getEventsWithLimit:(NSNumber *) limit { AWSFMDatabaseQueue *databaseQueue = self.databaseQueue; return [[AWSTask taskWithResult:nil] continueWithExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withSuccessBlock:^id _Nullable(AWSTask * _Nonnull task) { __block NSError *error = nil; __block NSMutableArray *events = [NSMutableArray new]; + NSString *selectQuery = @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount "; + NSString *fromQuery = @"FROM Event "; + NSString *orderQuery = @"ORDER BY timestamp ASC "; + NSString *limitQuery = [NSString stringWithFormat:@"LIMIT %@", limit]; + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { - AWSFMResultSet *rs = [db executeQuery: - @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount " - @"FROM Event " - @"ORDER BY timestamp ASC " - @"LIMIT 128"]; + AWSFMResultSet *rs = [db executeQuery:[NSString stringWithFormat:@"%@%@%@%@", selectQuery, fromQuery, orderQuery, limitQuery]]; if (!rs) { AWSDDLogError(@"SQLite error. Rolling back... [%@]", db.lastError); error = db.lastError; @@ -381,18 +386,23 @@ - (AWSTask*) getCurrentSession: (AWSPinpointSession*) session { } - (AWSTask *> *) getDirtyEvents { + return [self getDirtyEventsWithLimit:@128]; +} + +- (AWSTask *> *) getDirtyEventsWithLimit:(NSNumber *) limit { AWSFMDatabaseQueue *databaseQueue = self.databaseQueue; return [[AWSTask taskWithResult:nil] continueWithExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withSuccessBlock:^id _Nullable(AWSTask * _Nonnull task) { __block NSError *error = nil; __block NSMutableArray *events = [NSMutableArray new]; + NSString *selectQuery = @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount "; + NSString *fromQuery = @"FROM DirtyEvent "; + NSString *orderQuery = @"ORDER BY timestamp ASC "; + NSString *limitQuery = [NSString stringWithFormat:@"LIMIT %@", limit]; + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { - AWSFMResultSet *rs = [db executeQuery: - @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount " - @"FROM DirtyEvent " - @"ORDER BY timestamp ASC " - @"LIMIT 128"]; + AWSFMResultSet *rs = [db executeQuery:[NSString stringWithFormat:@"%@%@%@%@", selectQuery, fromQuery, orderQuery, limitQuery]]; if (!rs) { AWSDDLogError(@"SQLite error. Rolling back... [%@]", db.lastError); error = db.lastError; @@ -425,104 +435,176 @@ - (AWSTask*) getCurrentSession: (AWSPinpointSession*) session { - (AWSTask *> *)submitAllEvents { + __block NSMutableArray *result = [NSMutableArray new]; + __block AWSTask *returnTask; + + [self getBatchRecords:^(NSArray *events, NSArray *eventIds, NSError *error) { + returnTask = [self submitEvents:&result events:events eventIds:eventIds error:error]; + }]; + + return returnTask; +} + +- (AWSTask *> *)submitEvents:(NSMutableArray**) resultEvents + events:(NSArray *)events + eventIds:(NSArray *)eventIds + error:(NSError *)error { + __block AWSTask *returnTask; + __block NSMutableArray *result = *resultEvents; + + AWSDDLogVerbose(@"Submitting Batch with %lu events ", (unsigned long)[events count]); + + if (error) { + returnTask = [AWSTask taskWithError:error]; + } else { + returnTask = [[self submitBatchEvents:events withEventIds:eventIds] continueWithBlock:^id _Nullable(AWSTask *> * _Nonnull t) { + __block AWSTask *nextTask; + + if (t.error) { + nextTask = [AWSTask taskWithError:t.error]; + } else { + [result addObjectsFromArray:t.result]; //Aggregate results + + [self getBatchRecords:^(NSArray *events, NSArray *eventIds, NSError *error) { + if (error) { + nextTask = [AWSTask taskWithError:t.error]; + } else if ([events count] > 0) { + nextTask = [self submitEvents:&result events:events eventIds:eventIds error:error]; + } else { + nextTask = [AWSTask taskWithResult:result]; + } + + }]; + } + + return nextTask; + }]; + } + + + return returnTask; +} + +- (void) getBatchRecords:(void (^)(NSArray *events, NSArray *eventIds, NSError *error))result { + AWSFMDatabaseQueue *databaseQueue = self.databaseQueue; + __block NSError *error = nil; + + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + NSMutableArray *eventIds = nil; + AWSFMResultSet *rs = [db executeQuery: + @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount " + @"FROM Event " + @"ORDER BY timestamp ASC " + @"LIMIT 1000"]; + if (!rs) { + AWSDDLogError(@"SQLite error. Rolling back... [%@]", db.lastError); + error = db.lastError; + *rollback = YES; + return; + } + + NSMutableArray *temporaryEvents = [NSMutableArray new]; + eventIds = [NSMutableArray new]; + while ([rs next]) { + [temporaryEvents addObject:@{ + @"id": [rs stringForColumn:@"id"], + @"attributes": [rs dataForColumn:@"attributes"], + @"eventType": [rs stringForColumn:@"eventType"], + @"metrics": [rs dataForColumn:@"metrics"], + @"eventTimestamp": [rs stringForColumn:@"eventTimestamp"], + @"sessionId": [rs stringForColumn:@"sessionId"], + @"sessionStartTime": [rs stringForColumn:@"sessionStartTime"], + @"sessionStopTime": [rs stringForColumn:@"sessionStopTime"] + }]; + + [eventIds addObject:[rs stringForColumn:@"id"]]; + + NSData *batchData = [NSKeyedArchiver archivedDataWithRootObject:temporaryEvents]; + if ([batchData length] > self.batchRecordsByteLimit) { // if the batch size exceeds `batchRecordsByteLimit`, stop there. + break; + } + } + rs = nil; + + result(temporaryEvents, eventIds, error); + }]; +} + +- (AWSTask *> *)submitBatchEvents:(NSArray*) events + withEventIds:(NSArray*) eventIds { AWSFMDatabaseQueue *databaseQueue = self.databaseQueue; + NSArray *temporaryEvents = [events copy]; return [[AWSTask taskWithResult:nil] continueWithExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withSuccessBlock:^id _Nullable(AWSTask * _Nonnull task) { __block NSError *error = nil; - __block NSUInteger batchSize = 0; __block BOOL stop = NO; __block NSMutableArray *events = [NSMutableArray new]; - do { - [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { - NSMutableArray *eventIDs = nil; - - AWSFMResultSet *rs = [db executeQuery: - @"SELECT id, attributes, eventType, metrics, eventTimestamp, sessionId, sessionStartTime, sessionStopTime, timestamp, retryCount " - @"FROM Event " - @"ORDER BY timestamp ASC " - @"LIMIT 128"]; - if (!rs) { - AWSDDLogError(@"SQLite error. Rolling back... [%@]", db.lastError); - error = db.lastError; - *rollback = YES; - return; - } - - NSMutableArray *temporaryEvents = [NSMutableArray new]; - eventIDs = [NSMutableArray new]; - while ([rs next]) { - [temporaryEvents addObject:@{ - @"id": [rs stringForColumn:@"id"], - @"attributes": [rs dataForColumn:@"attributes"], - @"eventType": [rs stringForColumn:@"eventType"], - @"metrics": [rs dataForColumn:@"metrics"], - @"eventTimestamp": [rs stringForColumn:@"eventTimestamp"], - @"sessionId": [rs stringForColumn:@"sessionId"], - @"sessionStartTime": [rs stringForColumn:@"sessionStartTime"], - @"sessionStopTime": [rs stringForColumn:@"sessionStopTime"] - }]; - - [eventIDs addObject:[rs stringForColumn:@"id"]]; - - NSData *batchData = [NSKeyedArchiver archivedDataWithRootObject:temporaryEvents]; - if ([batchData length] > self.batchRecordsByteLimit) { // if the batch size exceeds `batchRecordsByteLimit`, stop there. - break; - } - } - rs = nil; - batchSize = [temporaryEvents count]; - - if (batchSize > 0) { - [[[self submitEvents:temporaryEvents - db:db - error:&error - eventIDs:eventIDs - stop:&stop] - continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { - events = task.result; - error = task.error; - return nil; - }] waitUntilFinished]; - } - + AWSTask *submitTask = [[self submitEvents:temporaryEvents + error:&error + eventIDs:eventIds + stop:&stop] + continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + if (task.error) { + error = task.error; + return [AWSTask taskWithError:task.error]; + } + [events addObjectsFromArray:task.result]; + return [AWSTask taskWithResult:events]; + }]; + + return [[AWSTask taskForCompletionOfAllTasksWithResults:@[submitTask]] continueWithBlock:^id _Nullable(AWSTask * _Nonnull t) { + AWSTask *failTask = [AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ // If an event failed three times, mark even as dirty - BOOL result = [db executeUpdate: - @"UPDATE Event " - @"SET dirty = 1 " - @"WHERE retryCount > 3"]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - error = db.lastError; - } - + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate: + @"UPDATE Event " + @"SET dirty = 1 " + @"WHERE retryCount > 3"]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + error = db.lastError; + } + }]; + return [AWSTask taskWithResult:nil]; + }]; + + AWSTask *moveTask = [AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ //Move dirty events into DirtyEvent table - result = [db executeUpdate: - @"INSERT INTO DirtyEvent " - @"SELECT * FROM Event " - @"WHERE dirty = 1"]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - error = db.lastError; - } - + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate: + @"INSERT INTO DirtyEvent " + @"SELECT * FROM Event " + @"WHERE dirty = 1"]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + error = db.lastError; + } + }]; + return [AWSTask taskWithResult:nil]; + }]; + + AWSTask *deleteTask = [AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ //Delete dirty events - result = [db executeUpdate: - @"DELETE FROM Event " - @"WHERE dirty = 1"]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - error = db.lastError; + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate: + @"DELETE FROM Event " + @"WHERE dirty = 1"]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + error = db.lastError; + } + }]; + return [AWSTask taskWithResult:nil]; + }]; + + return [[AWSTask taskForCompletionOfAllTasksWithResults:@[failTask, moveTask, deleteTask]] continueWithBlock:^id _Nullable(AWSTask * _Nonnull t) { + if (error) { + return [AWSTask taskWithError:error]; } - + return [AWSTask taskWithResult:events]; }]; - } while (!stop && !error && batchSize > 0); - - if (error) { - return [AWSTask taskWithError:error]; - } - - return [AWSTask taskWithResult:events]; + }]; }]; } @@ -599,10 +681,11 @@ - (void)checkByteThresholdForNotification:(NSUInteger)notificationByteThreshold } - (AWSTask *)submitEvents:(NSArray *)temporaryEvents - db:(AWSFMDatabase *) db error:(NSError**) error eventIDs:(NSArray *)eventIDs stop:(BOOL *)stop { + AWSFMDatabaseQueue *databaseQueue = self.databaseQueue; + NSMutableArray *events = [NSMutableArray new]; for (NSDictionary *eventDictionary in temporaryEvents) { @@ -634,31 +717,38 @@ - (AWSTask *)submitEvents:(NSArray *)temporaryEvents NSInteger responseCode = [task.error.userInfo[@"responseStatusCode"] integerValue]; AWSDDLogError(@"Server rejected submission of %lu events. (Events will be marked dirty.) Response code:%ld, Error Message:%@", (unsigned long)[events count], (long)responseCode, task.error); - for (NSString *eventID in eventIDs) { - BOOL result = [db executeUpdate:@"UPDATE Event SET dirty = 1 WHERE id = :id" - withParameterDictionary:@{ - @"id" : eventID - }]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - *error = db.lastError; + return [AWSTask taskForCompletionOfAllTasksWithResults:@[[AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ + for (NSString *eventID in eventIDs) { + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate:@"UPDATE Event SET dirty = 1 WHERE id = :id" + withParameterDictionary:@{ + @"id" : eventID + }]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + *error = db.lastError; + } + }]; } - } - return task; - + return task; + }]]]; } else { AWSDDLogError(@"Unable to successfully deliver events to server. Events will be retried. Error Message:%@", task.error); - for (NSString *eventID in eventIDs) { - BOOL result = [db executeUpdate:@"UPDATE Event SET retryCount = retryCount + 1 WHERE id = :id" - withParameterDictionary:@{ - @"id" : eventID - }]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - *error = db.lastError; + return [AWSTask taskForCompletionOfAllTasksWithResults:@[[AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ + for (NSString *eventID in eventIDs) { + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate:@"UPDATE Event SET retryCount = retryCount + 1 WHERE id = :id" + withParameterDictionary:@{ + @"id" : eventID + }]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + *error = db.lastError; + } + }]; } - } - return task; + return task; + }]]]; } } @@ -666,18 +756,23 @@ - (AWSTask *)submitEvents:(NSArray *)temporaryEvents NSInteger responseCode = [task.result[@"responseStatusCode"] integerValue]; AWSDDLogVerbose(@"The http response code is %ld", (long)responseCode); AWSDDLogInfo(@"Successful submission of %lu events. Response code:%ld", (unsigned long)[events count], (long)responseCode); - for (NSString *eventID in eventIDs) { - BOOL result = [db executeUpdate:@"DELETE FROM Event WHERE id = :id" - withParameterDictionary:@{ - @"id" : eventID - }]; - if (!result) { - AWSDDLogError(@"SQLite error. [%@]", db.lastError); - *error = db.lastError; + return [[AWSTask taskForCompletionOfAllTasksWithResults:@[[AWSTask taskFromExecutor:[AWSExecutor executorWithDispatchQueue:[AWSPinpointEventRecorder sharedQueue]] withBlock:^id _Nonnull{ + for (NSString *eventID in eventIDs) { + [databaseQueue inTransaction:^(AWSFMDatabase *db, BOOL *rollback) { + BOOL result = [db executeUpdate:@"DELETE FROM Event WHERE id = :id" + withParameterDictionary:@{ + @"id" : eventID + }]; + if (!result) { + AWSDDLogError(@"SQLite error. [%@]", db.lastError); + *error = db.lastError; + } + }]; } - } - - return [AWSTask taskWithResult:events]; + return task; + }]]] continueWithBlock:^id _Nullable(AWSTask * _Nonnull t) { + return [AWSTask taskWithResult:events]; + }]; } return task; diff --git a/AWSPinpoint/AWSPinpointSessionClient.h b/AWSPinpoint/AWSPinpointSessionClient.h index 960af404303..3de8996f7f9 100644 --- a/AWSPinpoint/AWSPinpointSessionClient.h +++ b/AWSPinpoint/AWSPinpointSessionClient.h @@ -26,7 +26,7 @@ typedef __nullable id(^AWSPinpointTimeoutBlock)(AWSTask *task); /** The session object needs that the session client keeps track of, the session information is added to each event recorded. */ -@interface AWSPinpointSession : NSObject +@interface AWSPinpointSession : NSObject /** The start timestamp is populated when the client start the session. diff --git a/AWSPinpoint/AWSPinpointSessionClient.m b/AWSPinpoint/AWSPinpointSessionClient.m index 5d7412d3d32..c55c1541cdc 100644 --- a/AWSPinpoint/AWSPinpointSessionClient.m +++ b/AWSPinpoint/AWSPinpointSessionClient.m @@ -112,10 +112,18 @@ - (instancetype)initWithContext:(AWSPinpointContext *)context { } - (void)saveSession { - NSData *sessionData = [NSKeyedArchiver archivedDataWithRootObject:_session]; - [[NSUserDefaults standardUserDefaults] setObject:sessionData forKey:AWSPinpointSessionKey]; - [[NSUserDefaults standardUserDefaults] synchronize]; -} + @try { + @synchronized (_session) { + AWSPinpointSession *session = [_session copy]; + NSData *sessionData = [NSKeyedArchiver archivedDataWithRootObject:session]; + [[NSUserDefaults standardUserDefaults] setObject:sessionData forKey:AWSPinpointSessionKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + + } + } + @catch (NSException *e) { + AWSDDLogError(@"Unable to save session to user defaults: %@", e.reason); + }} - (void)applicationDidEnterBackground:(NSNotification*)notification { [self pauseSessionWithTimeoutEnabled:YES @@ -138,76 +146,86 @@ - (void)dealloc { } - (AWSPinpointSession*)session { - if (!_session) { - //Start a session if one is not active - [[self startNewSession] waitUntilFinished]; + @synchronized(_session) { + if (!_session) { + //Start a session if one is not active + [self startNewSession]; + } + + return _session; } - - return _session; } - (AWSTask*)startSession { - if (!self.context.analyticsClient) { - AWSDDLogError(@"Pinpoint Analytics is disabled."); - return nil; - } - if (_session) { - [self endCurrentSession]; - return [self startNewSession]; - } else { - return [self startNewSession]; + @synchronized(_session) { + if (!self.context.analyticsClient) { + AWSDDLogError(@"Pinpoint Analytics is disabled."); + return nil; + } + if (_session) { + [self endCurrentSession]; + return [self startNewSession]; + } else { + return [self startNewSession]; + } } } - (AWSTask*)stopSession { - if (!self.context.analyticsClient) { - AWSDDLogError(@"Pinpoint Analytics is disabled."); - return nil; - } - if (_session) { - return [self endCurrentSession]; - } else { - AWSDDLogDebug(@"Session Stop Failed: No session is running."); - return nil; + @synchronized(_session) { + if (!self.context.analyticsClient) { + AWSDDLogError(@"Pinpoint Analytics is disabled."); + return nil; + } + if (_session) { + return [self endCurrentSession]; + } else { + AWSDDLogDebug(@"Session Stop Failed: No session is running."); + return nil; + } } } - (AWSTask*)pauseSessionWithTimeoutEnabled:(BOOL) timeoutEnabled timeoutCompletionBlock:(AWSPinpointTimeoutBlock) block { - if (!self.context.analyticsClient) { - AWSDDLogError(@"Pinpoint Analytics is disabled."); - return nil; - } - if (_session) { - return [self pauseCurrentSessionWithTimeoutEnabled:timeoutEnabled - timeoutCompletionBlock:block]; - } else { - AWSDDLogDebug(@"Session Pause Failed: No session is running."); - return nil; + @synchronized(_session) { + if (!self.context.analyticsClient) { + AWSDDLogError(@"Pinpoint Analytics is disabled."); + return nil; + } + if (_session) { + return [self pauseCurrentSessionWithTimeoutEnabled:timeoutEnabled + timeoutCompletionBlock:block]; + } else { + AWSDDLogDebug(@"Session Pause Failed: No session is running."); + return nil; + } } } - (AWSTask*)resumeSession { - if (!self.context.analyticsClient) { - AWSDDLogError(@"Pinpoint Analytics is disabled."); - return nil; - } - if (_session) { - if ([_session stopTime]) { - UTCTimeMillis now = [AWSPinpointDateUtils utcTimeMillisNow]; - if (now - [AWSPinpointDateUtils utcTimeMillisFromDate:[_session stopTime]] < self.context.configuration.sessionTimeout){ - return [self resumeCurrentSession]; + @synchronized(_session) { + if (!self.context.analyticsClient) { + AWSDDLogError(@"Pinpoint Analytics is disabled."); + return nil; + } + if (_session) { + if ([_session stopTime]) { + UTCTimeMillis now = [AWSPinpointDateUtils utcTimeMillisNow]; + if (now - [AWSPinpointDateUtils utcTimeMillisFromDate:[_session stopTime]] < self.context.configuration.sessionTimeout){ + return [self resumeCurrentSession]; + } else { + AWSDDLogVerbose(@"Session has expired. Starting a fresh one..."); + [self endCurrentSession]; + return [self startNewSession]; + } } else { - AWSDDLogVerbose(@"Session has expired. Starting a fresh one..."); - [self endCurrentSession]; - return [self startNewSession]; + AWSDDLogVerbose(@"Session Resume Failed: Session is already running."); + return nil; } } else { - AWSDDLogVerbose(@"Session Resume Failed: Session is already running."); - return nil; + return [self startNewSession]; } - } else { - return [self startNewSession]; } } @@ -215,7 +233,9 @@ - (AWSTask*)startNewSession { [self.bgTimer invalidate]; //Generate new session object - _session = [[AWSPinpointSession alloc] initWithContext:self.context]; + @synchronized(_session) { + _session = [[AWSPinpointSession alloc] initWithContext:self.context]; + } [self saveSession]; AWSDDLogVerbose(@"Firing Session Event: Start"); @@ -240,15 +260,18 @@ - (AWSTask*)endCurrentSession { AWSPinpointEvent *stopEvent = [self.context.analyticsClient createEventWithEventType:SESSION_STOP_EVENT_TYPE]; //Kill current session object - _session = nil; + @synchronized(_session) { + _session = nil; + + //Remove current session + [[NSUserDefaults standardUserDefaults] setObject:nil forKey:AWSPinpointSessionKey]; + [[NSUserDefaults standardUserDefaults] removeObjectForKey:AWSPinpointSessionKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + } //Remove campaign global attributes [self.context.analyticsClient removeAllGlobalCampaignAttributes]; - //Remove current session - [[NSUserDefaults standardUserDefaults] removeObjectForKey:AWSPinpointSessionKey]; - [[NSUserDefaults standardUserDefaults] synchronize]; - AWSDDLogInfo(@"Session Stopped."); return [self.context.analyticsClient recordEvent:stopEvent]; } @@ -263,20 +286,20 @@ - (void) endCurrentSessionTimeoutWithTimer:(NSTimer*) timer { } - (void) endCurrentSessionWithBlock:(AWSPinpointTimeoutBlock) block { - [self endCurrentSession]; - if (block) { - //Add to background queue so its in different thread and not blocking. - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ - [[[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [self endCurrentSession]; + if (block) { + //Add to background queue so its in different thread and not blocking. + [[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { block(task); [[UIApplication sharedApplication] endBackgroundTask:self.bgTask]; self.bgTask = UIBackgroundTaskInvalid; return nil; - }] waitUntilFinished]; - }); - } else { - [[self.context.analyticsClient submitEvents] waitUntilFinished]; - } + }]; + } else { + [self.context.analyticsClient submitEvents]; + } + }); } - (AWSTask*)pauseCurrentSessionWithTimeoutEnabled:(BOOL) timeoutEnabled @@ -304,7 +327,7 @@ - (AWSTask*)resumeCurrentSession { } - (void)waitForSessionTimeoutWithCompletionBlock:(AWSPinpointTimeoutBlock) block { - dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ if (self.context.configuration.sessionTimeout > 0) { self.bgTask = [[UIApplication sharedApplication] beginBackgroundTaskWithName:AWSPinpointSessionBackgroundTask expirationHandler:^{ // If background task expires before timeout then stop the session and submit events. @@ -316,28 +339,28 @@ - (void)waitForSessionTimeoutWithCompletionBlock:(AWSPinpointTimeoutBlock) block if (block) { userInfo = @{@"completionBlock":block}; } - - self.bgTimer = [NSTimer scheduledTimerWithTimeInterval:(self.context.configuration.sessionTimeout / 1000) - target:self - selector:@selector(endCurrentSessionTimeoutWithTimer:) - userInfo:userInfo - repeats:NO]; - [[NSRunLoop mainRunLoop] addTimer:self.bgTimer forMode:NSDefaultRunLoopMode]; + dispatch_async(dispatch_get_main_queue(), ^(){ + self.bgTimer = [NSTimer scheduledTimerWithTimeInterval:(self.context.configuration.sessionTimeout / 1000) + target:self + selector:@selector(endCurrentSessionTimeoutWithTimer:) + userInfo:userInfo + repeats:NO]; + }); } else { [self endCurrentSession]; if (block) { - [[[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + [[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { block(task); [[UIApplication sharedApplication] endBackgroundTask:self.bgTask]; self.bgTask = UIBackgroundTaskInvalid; return nil; - }] waitUntilFinished]; + }]; } else { - [[[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + [[self.context.analyticsClient submitEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { [[UIApplication sharedApplication] endBackgroundTask:self.bgTask]; self.bgTask = UIBackgroundTaskInvalid; return nil; - }] waitUntilFinished]; + }]; } } }); @@ -392,23 +415,31 @@ - (UTCTimeMillis)timeDurationInMillis { } - (void)stop { - if(!self.stopTime) { - self.stopTime = [NSDate date]; + @synchronized(self) { + if(!self.stopTime) { + self.stopTime = [NSDate date]; + } } } - (BOOL)isPaused { - return (self.stopTime != nil); + @synchronized(self) { + return (self.stopTime != nil); + } } - (void) pause { - if(![self isPaused]) { - self.stopTime = [NSDate date]; + @synchronized(self) { + if(![self isPaused]) { + self.stopTime = [NSDate date]; + } } } - (void)resume { - self.stopTime = nil; + @synchronized(self) { + self.stopTime = nil; + } } + (NSString *)generateSessionIdWithContext:(AWSPinpointContext *) context { @@ -440,4 +471,14 @@ + (NSString *)generateSessionIdWithContext:(AWSPinpointContext *) context { return [NSString stringWithFormat:@"%@%c%@%c%@%c%@", appKey, AWSPinpointSessionIDDelimiter, uniqID, AWSPinpointSessionIDDelimiter, timestamp_day, AWSPinpointSessionIDDelimiter, timestamp_time]; }; +- (id)copyWithZone:(nullable NSZone *)zone { + @synchronized(self) { + id copy = [[AWSPinpointSession alloc] initWithSessionId:[_sessionId copyWithZone:zone] + withStartTime:[_startTime copyWithZone:zone] + withStopTime:[_stopTime copyWithZone:zone]]; + + return copy; + } +} + @end diff --git a/AWSPinpoint/AWSPinpointTargeting/AWSPinpointTargetingService.m b/AWSPinpoint/AWSPinpointTargeting/AWSPinpointTargetingService.m index 7de7ff51304..f2774e529af 100644 --- a/AWSPinpoint/AWSPinpointTargeting/AWSPinpointTargetingService.m +++ b/AWSPinpoint/AWSPinpointTargeting/AWSPinpointTargetingService.m @@ -26,7 +26,7 @@ #import "AWSPinpointTargetingResources.h" static NSString *const AWSInfoPinpointTargeting = @"PinpointTargeting"; -static NSString *const AWSPinpointTargetingSDKVersion = @"2.5.8"; +static NSString *const AWSPinpointTargetingSDKVersion = @"2.5.9"; @interface AWSPinpointTargetingResponseSerializer : AWSJSONResponseSerializer @@ -115,7 +115,7 @@ - (id)responseObjectForResponse:(NSHTTPURLResponse *)response *error = [NSError errorWithDomain:AWSPinpointTargetingErrorDomain code:AWSPinpointTargetingErrorUnknown userInfo:responseObject]; - } + } return responseObject; } diff --git a/AWSPinpoint/Info.plist b/AWSPinpoint/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSPinpoint/Info.plist +++ b/AWSPinpoint/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSPinpoint/Internal/AWSPinpointContext.m b/AWSPinpoint/Internal/AWSPinpointContext.m index 48808e7bcb7..b9118204a17 100644 --- a/AWSPinpoint/Internal/AWSPinpointContext.m +++ b/AWSPinpoint/Internal/AWSPinpointContext.m @@ -129,6 +129,7 @@ - (NSString *) retrieveUniqueId { if ([self.keychain stringForKey:AWSPinpointContextKeychainUniqueIdKey]) { AWSDDLogVerbose(@"Merged Pinpoint UniqueId to Keychain: %@", deviceUniqueId); //Successful save to keychain, delete from UserDefaults + [[NSUserDefaults standardUserDefaults] setObject:nil forKey:AWSPinpointContextKeychainUniqueIdKey]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:AWSPinpointContextKeychainUniqueIdKey]; [[NSUserDefaults standardUserDefaults] synchronize]; } diff --git a/AWSPinpointTests/AWSPinpointEventRecorderTests.m b/AWSPinpointTests/AWSPinpointEventRecorderTests.m index e8797140b7b..b1e06ec86df 100644 --- a/AWSPinpointTests/AWSPinpointEventRecorderTests.m +++ b/AWSPinpointTests/AWSPinpointEventRecorderTests.m @@ -59,7 +59,7 @@ @implementation AWSPinpointEventRecorderTests - (void)setUp { [super setUp]; - + [AWSTestUtility setupCognitoCredentialsProvider]; NSString *filePath = [[NSBundle bundleForClass:[self class]] pathForResource:@"credentials" ofType:@"json"]; @@ -70,6 +70,7 @@ - (void)setUp { AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:credentialsJson[@"pinpointAppId"] launchOptions:@{}]; self.pinpoint = [AWSPinpoint pinpointWithConfiguration:config]; [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; + [[AWSDDLog sharedInstance] setLogLevel:AWSDDLogLevelVerbose]; } - (void)tearDown { @@ -87,7 +88,7 @@ - (void)testConstructors { } - (void) testDeleteAllEvents { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; @@ -106,7 +107,7 @@ - (void) testDeleteAllEvents { } - (void) testDeleteAllDirtyEvents { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; [[self.pinpoint.analyticsClient.eventRecorder removeAllDirtyEvents] waitUntilFinished]; @@ -154,18 +155,18 @@ - (void) testUpdateSessionCampaignAttributes { return nil; }]; - + } - (void) testSaveAndGetEvent { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; XCTAssertNotNil(self.pinpoint.analyticsClient.eventRecorder); AWSPinpointEvent *event = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT" ]; [event addAttribute:@"Attr1" forKey:@"Attr1"]; [event addMetric:@(1) forKey:@"Mettr1"]; - + [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { @@ -197,7 +198,7 @@ - (void) testSaveAndGetEvent { [expectation fulfill]; return nil; }]; - + [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { XCTAssertNil(error); }]; @@ -205,7 +206,7 @@ - (void) testSaveAndGetEvent { - (void) testSaveGetDeleteGetEvent { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; XCTAssertNotNil(self.pinpoint.analyticsClient.eventRecorder); AWSPinpointEvent *event = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT"]; @@ -259,8 +260,8 @@ - (void) testSaveGetDeleteGetEvent { } - (void)testFullEventCycle { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; - + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + XCTAssertNotNil(self.pinpoint.analyticsClient.eventRecorder); AWSPinpointEvent *event = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT"]; [event addAttribute:@"Attr1" forKey:@"Attr1"]; @@ -283,9 +284,9 @@ - (void)testFullEventCycle { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNil(task.error); XCTAssertNotNil(task.result); - + XCTAssertEqual([task.result count], 1); - + //Extract Event and compare event type and timestamp AWSPinpointEvent *resultEvent = [task.result firstObject]; XCTAssertNotNil(resultEvent); @@ -306,7 +307,7 @@ - (void)testFullEventCycle { XCTAssertEqual(resultEvent.eventTimestamp, event.eventTimestamp); XCTAssertEqual([[resultEvent.allMetrics objectForKey:@"Mettr1"] intValue], @(1).intValue); XCTAssertTrue([[resultEvent.allAttributes objectForKey:@"Attr1"] isEqualToString:@"Attr1"]); - + return nil; }] waitUntilFinished]; @@ -325,8 +326,8 @@ - (void)testFullEventCycle { - (void) testMultipleEvents { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; - + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + AWSPinpointEvent *event1 = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT1"]; [event1 addAttribute:@"Attr1" forKey:@"Attr1"]; [event1 addMetric:@(1) forKey:@"Mettr1"]; @@ -336,7 +337,7 @@ - (void) testMultipleEvents { [event2 addMetric:@(2) forKey:@"Mettr2"]; [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; - + [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); //Should contain no events after removal @@ -356,7 +357,6 @@ - (void) testMultipleEvents { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 2); return nil; }] waitUntilFinished]; @@ -366,7 +366,7 @@ - (void) testMultipleEvents { XCTAssertNotNil(task.result); XCTAssertEqual([task.result count], 2); - + AWSPinpointEvent *resultEvent1 = [task.result firstObject]; XCTAssertNotNil(resultEvent1); XCTAssertTrue([resultEvent1.eventType isEqualToString:event1.eventType]); @@ -397,9 +397,69 @@ - (void) testMultipleEvents { }]; } -- (void) testRecordDirtyEventWithTooManyAttributes { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; +- (void) testForMultipleBatches { + //This tests should take a little over 1m to complete. + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + + AWSPinpointEvent *event1 = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT1"]; + [event1 addAttribute:@"Attr1" forKey:@"Attr1"]; + [event1 addMetric:@(1) forKey:@"Mettr1"]; + + [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; + + [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + XCTAssertNotNil(task.result); + //Should contain no events after removal + XCTAssertEqual([task.result count], 0); + return nil; + }] waitUntilFinished]; + + for (int i=0; i < 5000; i++) { + [[[self.pinpoint.analyticsClient.eventRecorder saveEvent:event1] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + XCTAssertNil(task.error); + return nil; + }] waitUntilFinished]; + } + + [[[self.pinpoint.analyticsClient.eventRecorder getEventsWithLimit:@5000] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + XCTAssertNotNil(task.result); + XCTAssertEqual([task.result count], 5000); + return nil; + }] waitUntilFinished]; + + [[[self.pinpoint.analyticsClient.eventRecorder submitAllEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + XCTAssertNil(task.error); + XCTAssertNotNil(task.result); + + XCTAssertEqual([task.result count], 5000); + + AWSPinpointEvent *resultEvent1 = [task.result firstObject]; + XCTAssertNotNil(resultEvent1); + XCTAssertTrue([resultEvent1.eventType isEqualToString:event1.eventType]); + XCTAssertEqual(resultEvent1.eventTimestamp, event1.eventTimestamp); + XCTAssertEqual([[resultEvent1.allMetrics objectForKey:@"Mettr1"] intValue], @(1).intValue); + XCTAssertTrue([[resultEvent1.allAttributes objectForKey:@"Attr1"] isEqualToString:@"Attr1"]); + + return nil; + }] waitUntilFinished]; + + [[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { + XCTAssertNotNil(task.result); + //Should contain no events after successful submission + XCTAssertEqual([task.result count], 0); + [expectation fulfill]; + return nil; + }]; + + [self waitForExpectationsWithTimeout:5 handler:^(NSError * _Nullable error) { + XCTAssertNil(error); + }]; +} + +- (void) testRecordDirtyEventWithTooManyAttributes { + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + NSMutableDictionary *tooManyAttributes = [NSMutableDictionary dictionaryWithCapacity:51]; for (int i = 0; i < 51; i++) { @@ -414,7 +474,7 @@ - (void) testRecordDirtyEventWithTooManyAttributes { [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; [[self.pinpoint.analyticsClient.eventRecorder removeAllDirtyEvents] waitUntilFinished]; - + [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); //Should contain no events after removal @@ -437,7 +497,6 @@ - (void) testRecordDirtyEventWithTooManyAttributes { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 1); return nil; }] waitUntilFinished]; @@ -454,13 +513,13 @@ - (void) testRecordDirtyEventWithTooManyAttributes { XCTAssertEqual([task.result count], 0); return nil; }] waitUntilFinished]; - + [[self.pinpoint.analyticsClient.eventRecorder getDirtyEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); //Should contain one dirty event after failed submission XCTAssertEqual([task.result count], 1); [expectation fulfill]; - + return nil; }]; @@ -470,7 +529,7 @@ - (void) testRecordDirtyEventWithTooManyAttributes { } - (void) testRecordDirtyEventWithTooManyMetrics { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; NSMutableDictionary *tooManyMetrics = [NSMutableDictionary dictionaryWithCapacity:51]; @@ -509,7 +568,6 @@ - (void) testRecordDirtyEventWithTooManyMetrics { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 1); return nil; }] waitUntilFinished]; @@ -542,7 +600,7 @@ - (void) testRecordDirtyEventWithTooManyMetrics { } - (void) testRecordDirtyEventWithLongAttributeValue { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; NSMutableString *longAttributeValue = [NSMutableString stringWithCapacity:1001]; for (int i = 0; i < 1001; i++) { @@ -579,7 +637,6 @@ - (void) testRecordDirtyEventWithLongAttributeValue { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 1); return nil; }] waitUntilFinished]; @@ -612,7 +669,7 @@ - (void) testRecordDirtyEventWithLongAttributeValue { } - (void) testRecordDirtyEventWithLongAttributeKey { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; NSMutableString *longAttributeKey = [NSMutableString stringWithCapacity:51]; for (int i = 0; i < 51; i++) { @@ -649,7 +706,6 @@ - (void) testRecordDirtyEventWithLongAttributeKey { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 1); return nil; }] waitUntilFinished]; @@ -683,7 +739,7 @@ - (void) testRecordDirtyEventWithLongAttributeKey { - (void) testRecordDirtyEventWithLongMetricKey { - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; NSMutableString *longMetricKey = [NSMutableString stringWithCapacity:51]; for (int i = 0; i < 51; i++) { @@ -720,7 +776,6 @@ - (void) testRecordDirtyEventWithLongMetricKey { [[[self.pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); - //Should contain no events after successful submission XCTAssertEqual([task.result count], 1); return nil; }] waitUntilFinished]; @@ -755,7 +810,7 @@ - (void) testRecordDirtyEventWithLongMetricKey { - (void)testDiskByteLimit { [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; [[self.pinpoint.analyticsClient.eventRecorder removeAllDirtyEvents] waitUntilFinished]; - + uint64_t baseline = self.pinpoint.analyticsClient.eventRecorder.diskBytesUsed; __block BOOL byteThresholdReached = NO; @@ -778,7 +833,7 @@ - (void)testDiskByteLimit { for (int i = 0; i < 248; i++) { [value appendString:@"Y"]; } - + self.pinpoint.analyticsClient.eventRecorder.diskByteLimit = 1 * 1024 * 1024; // 1MB self.pinpoint.analyticsClient.eventRecorder.notificationByteThreshold = 500 * 1024; // 500KB @@ -786,14 +841,14 @@ - (void)testDiskByteLimit { for (int i = 0; i < 40; i++) { [event addAttribute:[NSString stringWithFormat:@"%@%d",value, i] forKey:[NSString stringWithFormat:@"%@%d",key, i]]; } - + AWSTask *task = [AWSTask taskWithResult:nil]; for (int i = 0; i < 100; i++) { task = [task continueWithBlock:^id(AWSTask *task) { return [self.pinpoint.analyticsClient.eventRecorder saveEvent:event]; }]; } - + [[[task continueWithBlock:^id(AWSTask *task) { uint64_t newSize = self.pinpoint.analyticsClient.eventRecorder.diskBytesUsed; XCTAssertLessThan(newSize, 1.2 * 1024 * 1024); // Less than 1.2MB @@ -803,12 +858,12 @@ - (void)testDiskByteLimit { XCTAssertLessThanOrEqual(self.pinpoint.analyticsClient.eventRecorder.diskBytesUsed, baseline); return nil; }] waitUntilFinished]; - + XCTAssertTrue(byteThresholdReached); - + [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; [[self.pinpoint.analyticsClient.eventRecorder removeAllDirtyEvents] waitUntilFinished]; - + self.pinpoint.analyticsClient.eventRecorder.diskByteLimit = 5 * 1024 * 1024; self.pinpoint.analyticsClient.eventRecorder.notificationByteThreshold = 0; @@ -820,13 +875,13 @@ - (void)testDiskByteLimit { - (void)testDiskAgeLimit { [[self.pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; [[self.pinpoint.analyticsClient.eventRecorder removeAllDirtyEvents] waitUntilFinished]; - + uint64_t baseline = self.pinpoint.analyticsClient.eventRecorder.diskBytesUsed; - + AWSPinpointEvent *event = [self.pinpoint.analyticsClient createEventWithEventType:@"TEST_EVENT"]; - + self.pinpoint.analyticsClient.eventRecorder.diskAgeLimit = 1; - + AWSTask *task = [AWSTask taskWithResult:nil]; for (int i = 0; i < 10; i++) { task = [task continueWithBlock:^id(AWSTask *task) { diff --git a/AWSPinpointTests/AWSPinpointSessionClientTests.m b/AWSPinpointTests/AWSPinpointSessionClientTests.m index da04f200b4c..267e350f00b 100644 --- a/AWSPinpointTests/AWSPinpointSessionClientTests.m +++ b/AWSPinpointTests/AWSPinpointSessionClientTests.m @@ -26,6 +26,9 @@ @interface AWSPinpointSessionClient() @property (nonatomic, readwrite) AWSPinpointSession *session; + +-(void) saveSession; + @end @interface AWSPinpointSessionClientTests : XCTestCase @@ -44,8 +47,15 @@ - (void)tearDown { } - (void) clearSession { + [[NSUserDefaults standardUserDefaults] setObject:nil forKey:AWSPinpointSessionKey]; [[NSUserDefaults standardUserDefaults] removeObjectForKey:AWSPinpointSessionKey]; [[NSUserDefaults standardUserDefaults] synchronize]; + + NSData *data = [[NSUserDefaults standardUserDefaults] dataForKey:AWSPinpointSessionKey]; + AWSPinpointSession *session = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + + NSLog(@"Session Object Should be Empty: %@",session.description); + XCTAssertNil([[NSUserDefaults standardUserDefaults] dataForKey:AWSPinpointSessionKey]); } @@ -60,13 +70,13 @@ - (void)testConstructors { } - (void) cleanupForPinpoint:(AWSPinpoint*) pinpoint { - [[pinpoint.analyticsClient.eventRecorder removeAllEvents] waitUntilFinished]; + [pinpoint.analyticsClient.eventRecorder removeAllEvents]; } - (void)testSessionStart { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionStart" launchOptions:nil @@ -102,6 +112,7 @@ - (void)testSessionStart { XCTAssertEqual([resultEvent.allMetrics count], 0); XCTAssertTrue([resultEvent.session.sessionId isEqualToString:event.session.sessionId]); [expectation fulfill]; + expectation = nil; return nil; }]; @@ -113,7 +124,7 @@ - (void)testSessionStart { - (void)testSessionPause { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionPause" launchOptions:nil @@ -174,6 +185,7 @@ - (void)testSessionPause { XCTAssertTrue([resultPauseEvent.session.sessionId isEqualToString:pauseEvent.session.sessionId]); [expectation fulfill]; + expectation = nil; return nil; }]; @@ -185,7 +197,7 @@ - (void)testSessionPause { - (void)testSessionResume { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionResume" launchOptions:nil @@ -269,6 +281,7 @@ - (void)testSessionResume { XCTAssertTrue([resultResumeEvent.session.sessionId isEqualToString:resumeEvent.session.sessionId]); [expectation fulfill]; + expectation = nil; return nil; }] waitUntilFinished]; @@ -280,7 +293,7 @@ - (void)testSessionResume { - (void)testSessionStop { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionStop" launchOptions:nil @@ -385,6 +398,7 @@ - (void)testSessionStop { XCTAssertTrue([resultStopEvent.session.sessionId isEqualToString:stopEvent.session.sessionId]); [expectation fulfill]; + expectation = nil; return nil; }]; @@ -396,7 +410,7 @@ - (void)testSessionStop { - (void)testSessionTimeout { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionTimeout" launchOptions:nil @@ -429,6 +443,7 @@ - (void)testSessionTimeout { //Should have submitted 3 events (Start,Pause,Stop) XCTAssertEqual([task.result count], 3); [expectation fulfill]; + expectation = nil; return nil; }] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); @@ -460,7 +475,7 @@ - (void)testSessionTimeout { - (void)testSessionTimeoutNoCompletion { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionTimeoutNoCompletion" launchOptions:nil @@ -507,6 +522,7 @@ - (void)testSessionTimeoutNoCompletion { //Since we dont use the completion timeout, wait some time for timeout to happen and events to submit successfully dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [expectation fulfill]; + expectation = nil; }); [self waitForExpectationsWithTimeout:15 handler:^(NSError * _Nullable error) { @@ -523,7 +539,7 @@ - (void)testSessionTimeoutNoCompletion { - (void)testSessionImmediateTimeout { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionImmediateTimeout" launchOptions:nil @@ -556,6 +572,7 @@ - (void)testSessionImmediateTimeout { //Should have submitted 3 events (Start,Pause,Stop) XCTAssertEqual([task.result count], 3); [expectation fulfill]; + expectation = nil; return nil; }] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); @@ -586,7 +603,7 @@ - (void)testSessionImmediateTimeout { - (void)testSessionImmediateTimeoutNoCompletion { [self clearSession]; - XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionImmediateTimeoutNoCompletion" launchOptions:nil @@ -633,6 +650,7 @@ - (void)testSessionImmediateTimeoutNoCompletion { //Since we dont use the completion timeout, wait some time for events to submit successfully dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ [expectation fulfill]; + expectation = nil; }); [self waitForExpectationsWithTimeout:15 handler:^(NSError * _Nullable error) { @@ -642,10 +660,118 @@ - (void)testSessionImmediateTimeoutNoCompletion { [[pinpoint.analyticsClient.eventRecorder getEvents] continueWithBlock:^id _Nullable(AWSTask * _Nonnull task) { XCTAssertNotNil(task.result); XCTAssertEqual([task.result count], 0); - [expectation fulfill]; return nil; }]; } +- (void) testSavingSessionFromMultipleThreads { + [self clearSession]; + + __block XCTestExpectation *expectation = [self expectationWithDescription:@"Test finished running."]; + + AWSPinpointConfiguration *config = [[AWSPinpointConfiguration alloc] initWithAppId:@"testSessionImmediateTimeoutNoCompletion" + launchOptions:nil + maxStorageSize:5*1024*1024 + sessionTimeout:0]; + config.enableAutoSessionRecording = NO; + AWSPinpoint *pinpoint = [AWSPinpoint pinpointWithConfiguration:config]; + [self cleanupForPinpoint:pinpoint]; + + XCTAssertNotNil(pinpoint.sessionClient.session); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INTERACTIVE, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UTILITY, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_BACKGROUND, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + dispatch_async(dispatch_get_global_queue(QOS_CLASS_UNSPECIFIED, 0), ^(void){ + [pinpoint.sessionClient saveSession]; + [pinpoint.sessionClient startSession]; + [pinpoint.sessionClient pauseSessionWithTimeoutEnabled:NO timeoutCompletionBlock:nil]; + [pinpoint.sessionClient resumeSession]; + [pinpoint.sessionClient stopSession]; + }); + + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [expectation fulfill]; + expectation = nil; + }); + + + [self waitForExpectationsWithTimeout:6 handler:^(NSError * _Nullable error) { + XCTAssertNil(error); + }]; + +} + + @end diff --git a/AWSPolly.podspec b/AWSPolly.podspec index ab2f04c1134..5e26b5f9bd5 100644 --- a/AWSPolly.podspec +++ b/AWSPolly.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSPolly' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSPolly/*.{h,m}' end diff --git a/AWSPolly/AWSPollyService.m b/AWSPolly/AWSPollyService.m index 679f2036547..07d735680bb 100644 --- a/AWSPolly/AWSPollyService.m +++ b/AWSPolly/AWSPollyService.m @@ -26,7 +26,7 @@ #import "AWSPollyResources.h" static NSString *const AWSInfoPolly = @"Polly"; -static NSString *const AWSPollySDKVersion = @"2.5.8"; +static NSString *const AWSPollySDKVersion = @"2.5.9"; @interface AWSPollyResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSPolly/AWSPollySynthesizeSpeechURLBuilder.m b/AWSPolly/AWSPollySynthesizeSpeechURLBuilder.m index 45655623cfb..1ee92ae7a27 100644 --- a/AWSPolly/AWSPollySynthesizeSpeechURLBuilder.m +++ b/AWSPolly/AWSPollySynthesizeSpeechURLBuilder.m @@ -16,7 +16,7 @@ #import "AWSPollySynthesizeSpeechURLBuilder.h" static NSString *const AWSInfoPollySynthesizeSpeechURLBuilder = @"PollySynthesizeSpeechUrlBuilder"; -static NSString *const AWSPollySDKVersion = @"2.5.8"; +static NSString *const AWSPollySDKVersion = @"2.5.9"; NSString *const AWSPollySynthesizeSpeechURLBuilderErrorDomain = @"com.amazonaws.AWSPollySynthesizeSpeechURLBuilderErrorDomain"; NSString *const AWSPollyPresignedUrlPath = @"v1/speech"; diff --git a/AWSPolly/Info.plist b/AWSPolly/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSPolly/Info.plist +++ b/AWSPolly/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSRekognition.podspec b/AWSRekognition.podspec index 34b3482ed05..417dc19ae89 100644 --- a/AWSRekognition.podspec +++ b/AWSRekognition.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSRekognition' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSRekognition/*.{h,m}' end diff --git a/AWSRekognition/AWSRekognitionService.m b/AWSRekognition/AWSRekognitionService.m index 728deaa4cea..10fe9aa85e1 100644 --- a/AWSRekognition/AWSRekognitionService.m +++ b/AWSRekognition/AWSRekognitionService.m @@ -26,7 +26,7 @@ #import "AWSRekognitionResources.h" static NSString *const AWSInfoRekognition = @"Rekognition"; -static NSString *const AWSRekognitionSDKVersion = @"2.5.8"; +static NSString *const AWSRekognitionSDKVersion = @"2.5.9"; @interface AWSRekognitionResponseSerializer : AWSJSONResponseSerializer diff --git a/AWSRekognition/Info.plist b/AWSRekognition/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSRekognition/Info.plist +++ b/AWSRekognition/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSResources/Info.plist b/AWSResources/Info.plist deleted file mode 100644 index 49e6a15544b..00000000000 --- a/AWSResources/Info.plist +++ /dev/null @@ -1,28 +0,0 @@ - - - - - CFBundleDevelopmentRegion - en - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - NSHumanReadableCopyright - Copyright © 2016 Amazon Web Services. All rights reserved. - NSPrincipalClass - - - diff --git a/AWSS3.podspec b/AWSS3.podspec index b1aa43ee296..fb55a1b5ce1 100644 --- a/AWSS3.podspec +++ b/AWSS3.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSS3' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSS3/*.{h,m}' end diff --git a/AWSS3/AWSS3PreSignedURL.m b/AWSS3/AWSS3PreSignedURL.m index fca5bd4a29f..13d4881fbac 100644 --- a/AWSS3/AWSS3PreSignedURL.m +++ b/AWSS3/AWSS3PreSignedURL.m @@ -26,7 +26,7 @@ static NSString *const AWSS3PreSignedURLBuilderAcceleratedEndpoint = @"s3-accelerate.amazonaws.com"; static NSString *const AWSInfoS3PreSignedURLBuilder = @"S3PreSignedURLBuilder"; -static NSString *const AWSS3PreSignedURLBuilderSDKVersion = @"2.5.8"; +static NSString *const AWSS3PreSignedURLBuilderSDKVersion = @"2.5.9"; @interface AWSS3PreSignedURLBuilder() diff --git a/AWSS3/AWSS3Service.m b/AWSS3/AWSS3Service.m index d14e68248c2..56cc14bc1a3 100644 --- a/AWSS3/AWSS3Service.m +++ b/AWSS3/AWSS3Service.m @@ -28,7 +28,7 @@ #import "AWSS3Serializer.h" static NSString *const AWSInfoS3 = @"S3"; -static NSString *const AWSS3SDKVersion = @"2.5.8"; +static NSString *const AWSS3SDKVersion = @"2.5.9"; diff --git a/AWSS3/Info.plist b/AWSS3/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSS3/Info.plist +++ b/AWSS3/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSSES.podspec b/AWSSES.podspec index 8f4128069c4..072393d44ca 100644 --- a/AWSSES.podspec +++ b/AWSSES.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSSES' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSSES/*.{h,m}' end diff --git a/AWSSES/AWSSESService.m b/AWSSES/AWSSESService.m index e07afcb6b6e..1c520b09626 100644 --- a/AWSSES/AWSSESService.m +++ b/AWSSES/AWSSESService.m @@ -26,7 +26,7 @@ #import "AWSSESResources.h" static NSString *const AWSInfoSES = @"SES"; -static NSString *const AWSSESSDKVersion = @"2.5.8"; +static NSString *const AWSSESSDKVersion = @"2.5.9"; @interface AWSSESResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSSES/Info.plist b/AWSSES/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSSES/Info.plist +++ b/AWSSES/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSSNS.podspec b/AWSSNS.podspec index 850cdbb077b..b8f74ae817c 100644 --- a/AWSSNS.podspec +++ b/AWSSNS.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSSNS' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSSNS/*.{h,m}' end diff --git a/AWSSNS/AWSSNSService.m b/AWSSNS/AWSSNSService.m index b113ac84bd0..fdd40bad1e3 100644 --- a/AWSSNS/AWSSNSService.m +++ b/AWSSNS/AWSSNSService.m @@ -26,7 +26,7 @@ #import "AWSSNSResources.h" static NSString *const AWSInfoSNS = @"SNS"; -static NSString *const AWSSNSSDKVersion = @"2.5.8"; +static NSString *const AWSSNSSDKVersion = @"2.5.9"; @interface AWSSNSResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSSNS/Info.plist b/AWSSNS/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSSNS/Info.plist +++ b/AWSSNS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSSQS.podspec b/AWSSQS.podspec index 1ee237da766..647bf7942b9 100644 --- a/AWSSQS.podspec +++ b/AWSSQS.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSSQS' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSSQS/*.{h,m}' end diff --git a/AWSSQS/AWSSQSService.m b/AWSSQS/AWSSQSService.m index 3f5981b6f2a..b4d7b031d4f 100644 --- a/AWSSQS/AWSSQSService.m +++ b/AWSSQS/AWSSQSService.m @@ -26,7 +26,7 @@ #import "AWSSQSResources.h" static NSString *const AWSInfoSQS = @"SQS"; -static NSString *const AWSSQSSDKVersion = @"2.5.8"; +static NSString *const AWSSQSSDKVersion = @"2.5.9"; @interface AWSSQSResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSSQS/Info.plist b/AWSSQS/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSSQS/Info.plist +++ b/AWSSQS/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSSimpleDB.podspec b/AWSSimpleDB.podspec index db486bcd71b..10fbda2ba1d 100644 --- a/AWSSimpleDB.podspec +++ b/AWSSimpleDB.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = 'AWSSimpleDB' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -12,6 +12,6 @@ Pod::Spec.new do |s| s.source = { :git => 'https://github.com/aws/aws-sdk-ios.git', :tag => s.version} s.requires_arc = true - s.dependency 'AWSCore', '2.5.8' + s.dependency 'AWSCore', '2.5.9' s.source_files = 'AWSSimpleDB/*.{h,m}' end diff --git a/AWSSimpleDB/AWSSimpleDBService.m b/AWSSimpleDB/AWSSimpleDBService.m index 738dadbe158..f10832b46c3 100644 --- a/AWSSimpleDB/AWSSimpleDBService.m +++ b/AWSSimpleDB/AWSSimpleDBService.m @@ -26,7 +26,7 @@ #import "AWSSimpleDBResources.h" static NSString *const AWSInfoSimpleDB = @"SimpleDB"; -static NSString *const AWSSimpleDBSDKVersion = @"2.5.8"; +static NSString *const AWSSimpleDBSDKVersion = @"2.5.9"; @interface AWSSimpleDBResponseSerializer : AWSXMLResponseSerializer diff --git a/AWSSimpleDB/Info.plist b/AWSSimpleDB/Info.plist index 999abdbbc83..cfb29c10027 100644 --- a/AWSSimpleDB/Info.plist +++ b/AWSSimpleDB/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 2.5.8 + 2.5.9 CFBundleSignature ???? CFBundleVersion diff --git a/AWSiOSSDKv2.podspec b/AWSiOSSDKv2.podspec index 3245e687142..646efa34cfe 100644 --- a/AWSiOSSDKv2.podspec +++ b/AWSiOSSDKv2.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'AWSiOSSDKv2' - s.version = '2.5.8' + s.version = '2.5.9' s.summary = 'Amazon Web Services SDK for iOS.' s.description = 'The AWS SDK for iOS provides a library, code samples, and documentation for developers to build connected mobile applications using AWS.' @@ -15,103 +15,103 @@ Pod::Spec.new do |s| s.requires_arc = true s.subspec 'AWSCore' do |aws| - aws.dependency 'AWSCore', '2.5.8' + aws.dependency 'AWSCore', '2.5.9' end s.subspec 'AWSAPIGateway' do |apigateway| - apigateway.dependency 'AWSAPIGateway', '2.5.8' + apigateway.dependency 'AWSAPIGateway', '2.5.9' end s.subspec 'AutoScaling' do |autoscaling| - autoscaling.dependency 'AWSAutoScaling', '2.5.8' + autoscaling.dependency 'AWSAutoScaling', '2.5.9' end s.subspec 'CloudWatch' do |cloudwatch| - cloudwatch.dependency 'AWSCloudWatch', '2.5.8' + cloudwatch.dependency 'AWSCloudWatch', '2.5.9' end s.subspec 'Pinpoint' do |pp| - pp.dependency 'AWSPinpoint', '2.5.8' + pp.dependency 'AWSPinpoint', '2.5.9' end s.subspec 'AWSCognito' do |cognito| - cognito.dependency 'AWSCognito', '2.5.8' + cognito.dependency 'AWSCognito', '2.5.9' end s.subspec 'AWSCognitoIdentityProvider' do |cognitoidentityprovider| - cognitoidentityprovider.dependency 'AWSCognitoIdentityProvider', '2.5.8' + cognitoidentityprovider.dependency 'AWSCognitoIdentityProvider', '2.5.9' end s.subspec 'DynamoDB' do |ddb| - ddb.dependency 'AWSDynamoDB', '2.5.8' + ddb.dependency 'AWSDynamoDB', '2.5.9' end s.subspec 'EC2' do |ec2| - ec2.dependency 'AWSEC2', '2.5.8' + ec2.dependency 'AWSEC2', '2.5.9' end s.subspec 'ElasticLoadBalancing' do |elasticloadbalancing| - elasticloadbalancing.dependency 'AWSElasticLoadBalancing', '2.5.8' + elasticloadbalancing.dependency 'AWSElasticLoadBalancing', '2.5.9' end s.subspec 'AWSIoT' do |iot| - iot.dependency 'AWSIoT', '2.5.8' + iot.dependency 'AWSIoT', '2.5.9' end s.subspec 'Kinesis' do |kinesis| - kinesis.dependency 'AWSKinesis', '2.5.8' + kinesis.dependency 'AWSKinesis', '2.5.9' end s.subspec 'AWSKMS' do |kms| - kms.dependency 'AWSKMS', '2.5.8' + kms.dependency 'AWSKMS', '2.5.9' end s.subspec 'AWSLambda' do |lambda| - lambda.dependency 'AWSLambda', '2.5.8' + lambda.dependency 'AWSLambda', '2.5.9' end s.subspec 'AWSLex' do |lex| - lex.dependency 'AWSLex', '2.5.8' + lex.dependency 'AWSLex', '2.5.9' end s.subspec 'AWSLogs' do |log| - log.dependency 'AWSLogs', '2.5.8' + log.dependency 'AWSLogs', '2.5.9' end s.subspec 'AWSMachineLearning' do |machinelearning| - machinelearning.dependency 'AWSMachineLearning', '2.5.8' + machinelearning.dependency 'AWSMachineLearning', '2.5.9' end s.subspec 'AWSPolly' do |polly| - polly.dependency 'AWSPolly', '2.5.8' + polly.dependency 'AWSPolly', '2.5.9' end s.subspec 'MobileAnalytics' do |mobileanalytics| - mobileanalytics.dependency 'AWSMobileAnalytics', '2.5.8' + mobileanalytics.dependency 'AWSMobileAnalytics', '2.5.9' end s.subspec 'AWSRekognition' do |rekognition| - rekognition.dependency 'AWSRekognition', '2.5.8' + rekognition.dependency 'AWSRekognition', '2.5.9' end s.subspec 'AWSS3' do |s3| - s3.dependency 'AWSS3', '2.5.8' + s3.dependency 'AWSS3', '2.5.9' end s.subspec 'AWSSES' do |ses| - ses.dependency 'AWSSES', '2.5.8' + ses.dependency 'AWSSES', '2.5.9' end s.subspec 'AWSSimpleDB' do |simpledb| - simpledb.dependency 'AWSSimpleDB', '2.5.8' + simpledb.dependency 'AWSSimpleDB', '2.5.9' end s.subspec 'AWSSNS' do |sns| - sns.dependency 'AWSSNS', '2.5.8' + sns.dependency 'AWSSNS', '2.5.9' end s.subspec 'AWSSQS' do |sqs| - sqs.dependency 'AWSSQS', '2.5.8' + sqs.dependency 'AWSSQS', '2.5.9' end diff --git a/AWSiOSSDKv2.xcodeproj/project.pbxproj b/AWSiOSSDKv2.xcodeproj/project.pbxproj index ed58049056d..3ab71b44484 100644 --- a/AWSiOSSDKv2.xcodeproj/project.pbxproj +++ b/AWSiOSSDKv2.xcodeproj/project.pbxproj @@ -100,7 +100,6 @@ 181270EF1E8EBFE400174785 /* AWSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; }; 181270F11E8F163100174785 /* AWSCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 181270F21E8F163200174785 /* AWSLogs.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 181270C11E8EB53900174785 /* AWSLogs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 1813F6621DB5A0DA009486D6 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 1813F6611DB5A0DA009486D6 /* Media.xcassets */; }; 182EA13A1D7F7D4E00BF3FDC /* AWSCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; }; 183BD93C1D8A4066004B2659 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CEB8EF551C6A6A2E0098B15B /* libOCMock.a */; }; 183BD93D1D8A406F004B2659 /* credentials.json in Resources */ = {isa = PBXBuildFile; fileRef = CEB8EF3E1C6A69AB0098B15B /* credentials.json */; }; @@ -245,7 +244,6 @@ 18E2F59F1DED371C00BD4608 /* libOCMock.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CEB8EF551C6A6A2E0098B15B /* libOCMock.a */; }; 18E2F5A21DED374C00BD4608 /* AWSCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18E2F5A31DED375200BD4608 /* AWSPolly.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 18E2F5611DED307400BD4608 /* AWSPolly.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 18EAC4B61DE0F3A000798E89 /* AWSResources.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1813F65B1DB5A0B8009486D6 /* AWSResources.bundle */; }; 18F455471DEFE875000D2F68 /* AWSTestUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = CEB8EF2E1C6A69A00098B15B /* AWSTestUtility.m */; }; 18F455491DF01D74000D2F68 /* AWSCore.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 18F4554A1DF01D81000D2F68 /* AWSPinpoint.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 18798F7E1DEF9EA900BC419B /* AWSPinpoint.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -268,6 +266,7 @@ 18F938D21DE5148E00034221 /* AWSLexVoiceButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F938C11DE5148E00034221 /* AWSLexVoiceButton.m */; }; 18F938D41DE5193F00034221 /* AWSGeneralLexTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F938D31DE5193F00034221 /* AWSGeneralLexTests.m */; }; 18F938D71DE520C500034221 /* AWSLexClientTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 18F938D61DE520C500034221 /* AWSLexClientTests.m */; }; + B52FBE921F17414A000F0C00 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B52FBE911F17414A000F0C00 /* Media.xcassets */; }; CE0D41701C6A66E5006B91B5 /* AWSCore.h in Headers */ = {isa = PBXBuildFile; fileRef = CE0D416F1C6A66E5006B91B5 /* AWSCore.h */; settings = {ATTRIBUTES = (Public, ); }; }; CE0D417C1C6A66E5006B91B5 /* AWSCoreTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CE0D417B1C6A66E5006B91B5 /* AWSCoreTests.m */; }; CE0D42231C6A673E006B91B5 /* AWSCredentialsProvider.h in Headers */ = {isa = PBXBuildFile; fileRef = CE0D41851C6A673E006B91B5 /* AWSCredentialsProvider.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -1383,13 +1382,6 @@ remoteGlobalIDString = CE0D416C1C6A66E5006B91B5; remoteInfo = AWSCore; }; - 187953A61DE17C2E00643D64 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = CE0D41541C6A66A9006B91B5 /* Project object */; - proxyType = 1; - remoteGlobalIDString = 1813F65A1DB5A0B8009486D6; - remoteInfo = AWSResources; - }; 18798F891DEF9EA900BC419B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = CE0D41541C6A66A9006B91B5 /* Project object */; @@ -2535,8 +2527,6 @@ 181270E41E8EB78900174785 /* AWSLogsService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSLogsService.m; sourceTree = ""; }; 181270EB1E8EB7D300174785 /* AWSGeneralLogsTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSGeneralLogsTests.m; sourceTree = ""; }; 1813F65B1DB5A0B8009486D6 /* AWSResources.bundle */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = AWSResources.bundle; sourceTree = BUILT_PRODUCTS_DIR; }; - 1813F65D1DB5A0B9009486D6 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 1813F6611DB5A0DA009486D6 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; 184F42FE1E930A2D004F3FE2 /* AWSCocoaLumberjack.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSCocoaLumberjack.h; sourceTree = ""; }; 184F42FF1E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSDDAbstractDatabaseLogger.h; sourceTree = ""; }; 184F43001E930A2D004F3FE2 /* AWSDDAbstractDatabaseLogger.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSDDAbstractDatabaseLogger.m; sourceTree = ""; }; @@ -2696,6 +2686,7 @@ 18F938C11DE5148E00034221 /* AWSLexVoiceButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSLexVoiceButton.m; sourceTree = ""; }; 18F938D31DE5193F00034221 /* AWSGeneralLexTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSGeneralLexTests.m; sourceTree = ""; }; 18F938D61DE520C500034221 /* AWSLexClientTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSLexClientTests.m; sourceTree = ""; }; + B52FBE911F17414A000F0C00 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = ""; }; CE0D416D1C6A66E5006B91B5 /* AWSCore.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = AWSCore.framework; sourceTree = BUILT_PRODUCTS_DIR; }; CE0D416F1C6A66E5006B91B5 /* AWSCore.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AWSCore.h; sourceTree = ""; }; CE0D41711C6A66E5006B91B5 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -2954,7 +2945,7 @@ CE9DE6291C6A78D70060793F /* AWSIoTDataResources.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSIoTDataResources.h; sourceTree = ""; }; CE9DE62A1C6A78D70060793F /* AWSIoTDataResources.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSIoTDataResources.m; sourceTree = ""; }; CE9DE62B1C6A78D70060793F /* AWSIoTDataService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSIoTDataService.h; sourceTree = ""; }; - CE9DE62C1C6A78D70060793F /* AWSIoTDataService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AWSIoTDataService.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; }; + CE9DE62C1C6A78D70060793F /* AWSIoTDataService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; path = AWSIoTDataService.m; sourceTree = ""; }; CE9DE62D1C6A78D70060793F /* AWSIoTManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSIoTManager.h; sourceTree = ""; }; CE9DE62E1C6A78D70060793F /* AWSIoTManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AWSIoTManager.m; sourceTree = ""; }; CE9DE62F1C6A78D70060793F /* AWSIoTModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AWSIoTModel.h; sourceTree = ""; }; @@ -4159,15 +4150,6 @@ path = AWSLogsUnitTests; sourceTree = ""; }; - 1813F65C1DB5A0B9009486D6 /* AWSResources */ = { - isa = PBXGroup; - children = ( - 1813F6611DB5A0DA009486D6 /* Media.xcassets */, - 1813F65D1DB5A0B9009486D6 /* Info.plist */, - ); - path = AWSResources; - sourceTree = ""; - }; 182EA1361D7F7BD200BF3FDC /* Bluefront */ = { isa = PBXGroup; children = ( @@ -4220,6 +4202,7 @@ 185111CC1D78F03B0009F5C3 /* AWSLex */ = { isa = PBXGroup; children = ( + B52FBE911F17414A000F0C00 /* Media.xcassets */, 18F938B11DE5148E00034221 /* AWSLex.h */, 18F938B21DE5148E00034221 /* AWSLexInteractionKit.h */, 18F938B31DE5148E00034221 /* AWSLexInteractionKit.m */, @@ -4504,7 +4487,6 @@ 18E2F58F1DED31D300BD4608 /* AWSPollyUnitTests */, 188321031DFF11B8003FBE9F /* AWSRekognition */, 1883210F1DFF11B9003FBE9F /* AWSRekognitionUnitTests */, - 1813F65C1DB5A0B9009486D6 /* AWSResources */, CE9DE9BE1C6A7C2D0060793F /* AWSS3 */, CE9DE9CA1C6A7C2E0060793F /* AWSS3Tests */, CE5604A01C6BC97600B4E00B /* AWSS3UnitTests */, @@ -6710,7 +6692,6 @@ buildRules = ( ); dependencies = ( - 187953A71DE17C2E00643D64 /* PBXTargetDependency */, 18B6E1FA1D831F2C009054B0 /* PBXTargetDependency */, ); name = AWSLex; @@ -8546,7 +8527,6 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 1813F6621DB5A0DA009486D6 /* Media.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -8554,7 +8534,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 18EAC4B61DE0F3A000798E89 /* AWSResources.bundle in Resources */, + B52FBE921F17414A000F0C00 /* Media.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -10374,11 +10354,6 @@ target = CE0D416C1C6A66E5006B91B5 /* AWSCore */; targetProxy = 185251331DED4F8700AF47F6 /* PBXContainerItemProxy */; }; - 187953A71DE17C2E00643D64 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 1813F65A1DB5A0B8009486D6 /* AWSResources */; - targetProxy = 187953A61DE17C2E00643D64 /* PBXContainerItemProxy */; - }; 18798F8A1DEF9EA900BC419B /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 18798F7D1DEF9EA900BC419B /* AWSPinpoint */; diff --git a/CHANGELOG.md b/CHANGELOG.md index 823f941285e..33720bb3ba7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,22 @@ # AWS Mobile SDK for iOS CHANGELOG +## 2.5.9 + +### Bug fixes + +* **Amazon Lex** + * Fixed bug where an application consuming `Lex` cannot be signed and distributed [Github Issue #704](https://github.com/aws/aws-sdk-ios/issues/704) + +* **Amazon Pinpoint** + * Fixed bug where saving a session cause a crash. [Github Issue #580] (https://github.com/aws/aws-sdk-ios/issues/580) + * Removed all calls that blocked the main thread [Github Issue #614] (https://github.com/aws/aws-sdk-ios/issues/614) + +* **AWS IoT** + * Moved encoding and decoding MQTT packet into background thread + * Moved websocket delegate methods (webSocketDidOpen:, webSocket:didFailWithError:, webSocket:didReceiveMessage:, webSocket:didCloseWithCode: ) into background thread + * Fixed bug where app receives duplicate "Disconnected" callback when previously connected to AWS IoT via websocket + * Fixed bug where reconnect timer incorrectly triggered after user disconnects + ## 2.5.8 ### New Features diff --git a/Scripts/GenerateAppleDocs.sh b/Scripts/GenerateAppleDocs.sh index 8806c5a84f9..f7562de8299 100644 --- a/Scripts/GenerateAppleDocs.sh +++ b/Scripts/GenerateAppleDocs.sh @@ -9,7 +9,7 @@ function cleanup } -VERSION="2.5.8" +VERSION="2.5.9" if [ -n $1 ] && [ "$1" == "clean" ]; then cleanup