summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Gluck <justin.gluck@livio.io>2019-07-23 16:48:14 -0400
committerJustin Gluck <justin.gluck@livio.io>2019-07-23 16:48:14 -0400
commit65d75f0310b82e12fc875a872bad6c66505f7888 (patch)
tree188d96f1b0eb3bf5b02e5e427d3904bfbf42b3a4
parent4288fcaad0f9c61c69e5eb42e9f26710bb32ebf3 (diff)
parent5f0190a9a7dd1196c0206fbccdc55a97b566bcaa (diff)
downloadsdl_ios-bugfix/issue-1352-Align-SDLSyncVersion.tar.gz
Merge branch 'develop' into bugfix/issue-1352-Align-SDLSyncVersionbugfix/issue-1352-Align-SDLSyncVersion
# Conflicts: # SmartDeviceLink/SDLLifecycleManager.m
-rw-r--r--CHANGELOG.md5
-rw-r--r--Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist2
-rw-r--r--Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist2
-rw-r--r--SmartDeviceLink-iOS.podspec2
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/project.pbxproj14
-rw-r--r--SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme2
-rw-r--r--SmartDeviceLink.podspec2
-rw-r--r--SmartDeviceLink/CVPixelBufferRef+SDLUtil.m2
-rw-r--r--SmartDeviceLink/Info.plist2
-rw-r--r--SmartDeviceLink/SDLAsynchronousOperation.m6
-rw-r--r--SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m23
-rwxr-xr-xSmartDeviceLink/SDLAudioStreamManager.m10
-rw-r--r--SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m4
-rw-r--r--SmartDeviceLink/SDLChoiceSetManager.m5
-rw-r--r--SmartDeviceLink/SDLDeleteChoicesOperation.m4
-rw-r--r--SmartDeviceLink/SDLDeleteFileOperation.h17
-rw-r--r--SmartDeviceLink/SDLDeleteFileOperation.m2
-rw-r--r--SmartDeviceLink/SDLFile.m4
-rw-r--r--SmartDeviceLink/SDLFileManager.m88
-rw-r--r--SmartDeviceLink/SDLFocusableItemLocator.m8
-rw-r--r--SmartDeviceLink/SDLGlobals.h3
-rw-r--r--SmartDeviceLink/SDLGlobals.m6
-rw-r--r--SmartDeviceLink/SDLIAPTransport.m2
-rw-r--r--SmartDeviceLink/SDLLifecycleManager.m123
-rw-r--r--SmartDeviceLink/SDLListFilesOperation.h10
-rw-r--r--SmartDeviceLink/SDLListFilesOperation.m4
-rw-r--r--SmartDeviceLink/SDLLogFileModuleMap.m2
-rw-r--r--SmartDeviceLink/SDLLogManager.m11
-rw-r--r--SmartDeviceLink/SDLMenuManager.m4
-rw-r--r--SmartDeviceLink/SDLPreloadChoicesOperation.m4
-rw-r--r--SmartDeviceLink/SDLPresentChoiceSetOperation.m4
-rw-r--r--SmartDeviceLink/SDLPresentKeyboardOperation.m4
-rw-r--r--SmartDeviceLink/SDLProtocol.m20
-rw-r--r--SmartDeviceLink/SDLProxy.m32
-rw-r--r--SmartDeviceLink/SDLRPCRequest.m4
-rw-r--r--SmartDeviceLink/SDLRPCResponse.m5
-rw-r--r--SmartDeviceLink/SDLResponseDispatcher.m6
-rw-r--r--SmartDeviceLink/SDLTouch.m4
-rw-r--r--SmartDeviceLink/SDLTouchManager.m176
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.h2
-rw-r--r--SmartDeviceLink/SDLUploadFileOperation.m17
-rw-r--r--SmartDeviceLink/dispatch_timer.h18
-rw-r--r--SmartDeviceLink/dispatch_timer.m38
-rw-r--r--SmartDeviceLinkSwift/Info.plist2
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m18
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m1963
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m9
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m27
-rw-r--r--SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m335
-rw-r--r--SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m2
-rwxr-xr-xSmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m2
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.pngbin29249 -> 38911 bytes
-rw-r--r--SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.pngbin65090 -> 65070 bytes
-rw-r--r--SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m9
-rw-r--r--SmartDeviceLinkTests/TestResponse.m4
-rw-r--r--SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m4
-rw-r--r--SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m47
-rw-r--r--SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m162
66 files changed, 1549 insertions, 1738 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3bcfbf9b8..b780fa9c4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,9 @@
# Changelog
+## 6.3.1
+### Bug Fixes
+* Fix unregistering for EATransport notifications can interfere with other apps' EATransport notifications (https://www.github.com/smartdevicelink/sdl_ios/issues/1329).
+* Fix issues related to the background task running when the device is in the process of making an IAP connection but is in the background (https://www.github.com/smartdevicelink/sdl_ios/issues/1326, https://www.github.com/smartdevicelink/sdl_ios/issues/1327).
+
## 6.3.0
### Versions
* Supports [SDL RPC Spec 5.1.0](https://github.com/smartdevicelink/rpc_spec/releases/tag/5.1.0) and [SDL Protocol Spec 5.2.0](https://github.com/smartdevicelink/protocol_spec/releases/tag/5.2.0).
diff --git a/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist b/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
index db70c2cae..ddf174213 100644
--- a/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
+++ b/Example Apps/Example ObjC/SmartDeviceLink-Example-ObjC-Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist b/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
index d3ab6c871..34a7b097a 100644
--- a/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
+++ b/Example Apps/Example Swift/SmartDeviceLink-Example-Swift-Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/SmartDeviceLink-iOS.podspec b/SmartDeviceLink-iOS.podspec
index 8acb3e016..787e346dd 100644
--- a/SmartDeviceLink-iOS.podspec
+++ b/SmartDeviceLink-iOS.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SmartDeviceLink-iOS"
-s.version = "6.3.0"
+s.version = "6.3.1"
s.summary = "Connect your app with cars!"
s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
diff --git a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
index 1aea15a88..a4b03eef6 100644
--- a/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
+++ b/SmartDeviceLink-iOS.xcodeproj/project.pbxproj
@@ -1449,7 +1449,6 @@
DA318C201DD0F06C00C035AC /* NSMutableDictionary+Store.m in Sources */ = {isa = PBXBuildFile; fileRef = DA318C1E1DD0F06C00C035AC /* NSMutableDictionary+Store.m */; };
DA4353DF1D271FD10099B8C4 /* CGPointUtilSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */; };
DA4353E31D2720A30099B8C4 /* SDLPinchGestureSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E21D2720A30099B8C4 /* SDLPinchGestureSpec.m */; };
- DA4353E91D2721680099B8C4 /* DispatchTimerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */; };
DA4353EA1D2721680099B8C4 /* SDLTouchManagerSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */; };
DA4353EB1D2721680099B8C4 /* SDLTouchSpec.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */; };
DA4F47961E771AA100FC809E /* SDLEnum.m in Sources */ = {isa = PBXBuildFile; fileRef = DA4F47951E771AA100FC809E /* SDLEnum.m */; };
@@ -1507,8 +1506,6 @@
DAC572631D10C5020004288B /* SDLPinchGesture.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572611D10C5020004288B /* SDLPinchGesture.h */; settings = {ATTRIBUTES = (Public, ); }; };
DAC572661D10C5640004288B /* CGPoint_Util.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572641D10C5640004288B /* CGPoint_Util.m */; };
DAC572671D10C5640004288B /* CGPoint_Util.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572651D10C5640004288B /* CGPoint_Util.h */; };
- DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */ = {isa = PBXBuildFile; fileRef = DAC572681D10D5FC0004288B /* dispatch_timer.m */; };
- DAC5726B1D10D5FC0004288B /* dispatch_timer.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC572691D10D5FC0004288B /* dispatch_timer.h */; };
DAC5726C1D11B4840004288B /* SDLTouchManagerDelegate.h in Headers */ = {isa = PBXBuildFile; fileRef = DAC5725F1D10BD690004288B /* SDLTouchManagerDelegate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4139D1D1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h in Headers */ = {isa = PBXBuildFile; fileRef = E4139D1B1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h */; settings = {ATTRIBUTES = (Public, ); }; };
E4139D1E1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m in Sources */ = {isa = PBXBuildFile; fileRef = E4139D1C1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m */; };
@@ -3109,7 +3106,6 @@
DA318C1E1DD0F06C00C035AC /* NSMutableDictionary+Store.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSMutableDictionary+Store.m"; sourceTree = "<group>"; };
DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CGPointUtilSpec.m; path = UtilitiesSpecs/Touches/CGPointUtilSpec.m; sourceTree = "<group>"; };
DA4353E21D2720A30099B8C4 /* SDLPinchGestureSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLPinchGestureSpec.m; path = UtilitiesSpecs/Touches/SDLPinchGestureSpec.m; sourceTree = "<group>"; };
- DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DispatchTimerSpec.m; path = UtilitiesSpecs/Touches/DispatchTimerSpec.m; sourceTree = "<group>"; };
DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchManagerSpec.m; path = UtilitiesSpecs/Touches/SDLTouchManagerSpec.m; sourceTree = "<group>"; };
DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SDLTouchSpec.m; path = UtilitiesSpecs/Touches/SDLTouchSpec.m; sourceTree = "<group>"; };
DA4F47951E771AA100FC809E /* SDLEnum.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLEnum.m; sourceTree = "<group>"; };
@@ -3170,8 +3166,6 @@
DAC572611D10C5020004288B /* SDLPinchGesture.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLPinchGesture.h; sourceTree = "<group>"; };
DAC572641D10C5640004288B /* CGPoint_Util.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CGPoint_Util.m; sourceTree = "<group>"; };
DAC572651D10C5640004288B /* CGPoint_Util.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CGPoint_Util.h; sourceTree = "<group>"; };
- DAC572681D10D5FC0004288B /* dispatch_timer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = dispatch_timer.m; sourceTree = "<group>"; };
- DAC572691D10D5FC0004288B /* dispatch_timer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dispatch_timer.h; sourceTree = "<group>"; };
E4139D1B1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLLifecycleConfigurationUpdate.h; sourceTree = "<group>"; };
E4139D1C1F6017770005B6EA /* SDLLifecycleConfigurationUpdate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDLLifecycleConfigurationUpdate.m; sourceTree = "<group>"; };
E9C32B891AB20BA200F283AF /* SDLIAPSession.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDLIAPSession.h; sourceTree = "<group>"; };
@@ -5646,9 +5640,9 @@
5D82041C1BCD8E6100D0A41B /* SDLConfiguration.h */,
5D82041D1BCD8E6100D0A41B /* SDLConfiguration.m */,
5D2F58071D0717D5001085CE /* SDLManagerDelegate.h */,
+ 5D82042A1BCEA91E00D0A41B /* Files */,
5D1654571D3E79CA00554D93 /* Lifecycle */,
5DBAE0A51D355EE700CE00BF /* Lock Screen */,
- 5D82042A1BCEA91E00D0A41B /* Files */,
5D8204291BCEA91400D0A41B /* Permissions */,
DA8966E71E56937100413EAB /* Streaming */,
5D0A736F203F0C450001595D /* Screen */,
@@ -6082,7 +6076,6 @@
DA1166D71D14601C00438CEA /* Touches */ = {
isa = PBXGroup;
children = (
- DA4353E61D2721680099B8C4 /* DispatchTimerSpec.m */,
DA4353E71D2721680099B8C4 /* SDLTouchManagerSpec.m */,
DA4353E81D2721680099B8C4 /* SDLTouchSpec.m */,
DA4353DE1D271FD10099B8C4 /* CGPointUtilSpec.m */,
@@ -6169,8 +6162,6 @@
DAC572601D10C5020004288B /* SDLPinchGesture.m */,
DAC572651D10C5640004288B /* CGPoint_Util.h */,
DAC572641D10C5640004288B /* CGPoint_Util.m */,
- DAC572691D10D5FC0004288B /* dispatch_timer.h */,
- DAC572681D10D5FC0004288B /* dispatch_timer.m */,
);
name = Touches;
sourceTree = "<group>";
@@ -6351,7 +6342,6 @@
5D92938020B70CD600FCC775 /* SDLCheckChoiceVROptionalOperation.h in Headers */,
5D339CEF207C08BA000CC364 /* SDLVoiceCommand.h in Headers */,
5D61FC4B1A84238C00846EE7 /* SDLBeltStatus.h in Headers */,
- DAC5726B1D10D5FC0004288B /* dispatch_timer.h in Headers */,
DA9F7E991DCC052C00ACAE48 /* SDLLocationCoordinate.h in Headers */,
5D0A7382203F23F30001595D /* SDLSoftButtonManager.h in Headers */,
5D61FC351A84238C00846EE7 /* SDLAirbagStatus.h in Headers */,
@@ -7441,7 +7431,6 @@
5D61FDC21A84238C00846EE7 /* SDLSystemRequestResponse.m in Sources */,
5D9FDA911F2A7D3400A495C8 /* bson_object.c in Sources */,
5D61FD001A84238C00846EE7 /* SDLOnAppInterfaceUnregistered.m in Sources */,
- DAC5726A1D10D5FC0004288B /* dispatch_timer.m in Sources */,
5D61FC6C1A84238C00846EE7 /* SDLCreateInteractionChoiceSet.m in Sources */,
5DCD7AF71FCCA8E400A0FC7F /* SDLScreenshotViewController.m in Sources */,
1EB59CA4202D92F600343A61 /* SDLMassageMode.m in Sources */,
@@ -7632,7 +7621,6 @@
88B848C91F462E3600DED768 /* TestFileProgressResponse.m in Sources */,
162E83231A9BDE8B00906325 /* SDLAddSubMenuSpec.m in Sources */,
5DCC458D221C9F6600036C2F /* SDLVersionSpec.m in Sources */,
- DA4353E91D2721680099B8C4 /* DispatchTimerSpec.m in Sources */,
1EE8C45D1F387D1C00FDC2CF /* SDLGetInteriorVehicleDataResponseSpec.m in Sources */,
162E82F21A9BDE8B00906325 /* SDLPredefinedLayoutSpec.m in Sources */,
162E83521A9BDE8B00906325 /* SDLDeleteSubMenuResponseSpec.m in Sources */,
diff --git a/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme b/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
index 4570e5a1a..6f8818b13 100644
--- a/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
+++ b/SmartDeviceLink-iOS.xcodeproj/xcshareddata/xcschemes/SmartDeviceLink.xcscheme
@@ -92,7 +92,7 @@
</AdditionalOptions>
</LaunchAction>
<ProfileAction
- buildConfiguration = "Release"
+ buildConfiguration = "Debug"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
diff --git a/SmartDeviceLink.podspec b/SmartDeviceLink.podspec
index 33a3c604e..fd9fc8478 100644
--- a/SmartDeviceLink.podspec
+++ b/SmartDeviceLink.podspec
@@ -1,7 +1,7 @@
Pod::Spec.new do |s|
s.name = "SmartDeviceLink"
-s.version = "6.3.0"
+s.version = "6.3.1"
s.summary = "Connect your app with cars!"
s.homepage = "https://github.com/smartdevicelink/SmartDeviceLink-iOS"
s.license = { :type => "New BSD", :file => "LICENSE" }
diff --git a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
index 4234f76f1..1a62ece10 100644
--- a/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
+++ b/SmartDeviceLink/CVPixelBufferRef+SDLUtil.m
@@ -28,7 +28,7 @@ UIFont * _Nullable sdl_findFontSizeToFitText(CGSize size, NSString *text) {
break;
}
- fontSize -= 1.0;
+ fontSize -= (CGFloat)1.0;
} while (fontSize > 0.0);
return (fontSize > 0) ? [UIFont systemFontOfSize:fontSize] : nil;
diff --git a/SmartDeviceLink/Info.plist b/SmartDeviceLink/Info.plist
index 8761e930d..0e0ef8021 100644
--- a/SmartDeviceLink/Info.plist
+++ b/SmartDeviceLink/Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
diff --git a/SmartDeviceLink/SDLAsynchronousOperation.m b/SmartDeviceLink/SDLAsynchronousOperation.m
index 49450f49b..d2e12384d 100644
--- a/SmartDeviceLink/SDLAsynchronousOperation.m
+++ b/SmartDeviceLink/SDLAsynchronousOperation.m
@@ -8,16 +8,21 @@
#import "SDLAsynchronousOperation.h"
+#import "SDLLogMacros.h"
+
@implementation SDLAsynchronousOperation {
BOOL executing;
BOOL finished;
}
- (void)start {
+ SDLLogV(@"Starting operation: %@", self);
+
if (self.isCancelled) {
[self willChangeValueForKey:@"isFinished"];
finished = YES;
[self didChangeValueForKey:@"isFinished"];
+ SDLLogV(@"Operation was cancelled: %@", self);
return;
}
@@ -28,6 +33,7 @@
}
- (void)finishOperation {
+ SDLLogV(@"Finishing Operation: %@", self);
[self willChangeValueForKey:@"isExecuting"];
executing = NO;
[self didChangeValueForKey:@"isExecuting"];
diff --git a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
index 5c67e3e8a..c77c80d52 100644
--- a/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
+++ b/SmartDeviceLink/SDLAsynchronousRPCRequestOperation.m
@@ -91,29 +91,30 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_sendRequest:(SDLRPCRequest *)request {
__weak typeof(self) weakSelf = self;
[self.connectionManager sendConnectionRequest:request withResponseHandler:^(__kindof SDLRPCRequest * _Nullable request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error) {
- __strong typeof(self) strongSelf = weakSelf;
+ if (weakSelf == nil) { return; }
- if (strongSelf.isCancelled) {
- [self sdl_abortOperationWithRequest:request];
+ if (weakSelf.isCancelled) {
+ [weakSelf sdl_abortOperationWithRequest:request];
BLOCK_RETURN;
}
- strongSelf.requestsComplete++;
+ weakSelf.requestsComplete++;
// If this request failed set our internal request failed to YES
if (error != nil) {
- strongSelf.requestFailed = YES;
+ weakSelf.requestFailed = YES;
}
- if (strongSelf.progressHandler != NULL) {
- strongSelf.progressHandler(request, response, error, strongSelf.percentComplete);
- } else if (strongSelf.responseHandler != NULL) {
- strongSelf.responseHandler(request, response, error);
+ if (weakSelf.progressHandler != NULL) {
+ float percentComplete = weakSelf.percentComplete;
+ weakSelf.progressHandler(request, response, error, percentComplete);
+ } else if (weakSelf.responseHandler != NULL) {
+ weakSelf.responseHandler(request, response, error);
}
// If we've received responses for all requests, call the completion handler.
- if (strongSelf.requestsComplete >= strongSelf.requests.count) {
- [strongSelf finishOperation];
+ if (weakSelf.requestsComplete >= weakSelf.requests.count) {
+ [weakSelf finishOperation];
}
}];
}
diff --git a/SmartDeviceLink/SDLAudioStreamManager.m b/SmartDeviceLink/SDLAudioStreamManager.m
index ff16f2b16..11d39812a 100755
--- a/SmartDeviceLink/SDLAudioStreamManager.m
+++ b/SmartDeviceLink/SDLAudioStreamManager.m
@@ -10,6 +10,7 @@
#import "SDLAudioFile.h"
#import "SDLFile.h"
+#import "SDLGlobals.h"
#import "SDLLogMacros.h"
#import "SDLManager.h"
#import "SDLPCMAudioConverter.h"
@@ -38,9 +39,14 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS
if (!self) { return nil; }
_mutableQueue = [NSMutableArray array];
- _audioQueue = dispatch_queue_create("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL);
_shouldPlayWhenReady = NO;
+ if (@available(iOS 10.0, *)) {
+ _audioQueue = dispatch_queue_create_with_target("com.sdl.audiomanager.transcode", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _audioQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
+
_streamManager = streamManager;
return self;
@@ -146,7 +152,7 @@ NSString *const SDLErrorDomainAudioStreamManager = @"com.sdl.extension.pcmAudioS
// Determine the length of the audio PCM data and perform a few items once the audio has finished playing
float audioLengthSecs = (float)audioData.length / (float)32000.0;
__weak typeof(self) weakself = self;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(audioLengthSecs * NSEC_PER_SEC)), [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
__strong typeof(weakself) strongSelf = weakself;
strongSelf.playing = NO;
diff --git a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
index f42144e67..abe323689 100644
--- a/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
+++ b/SmartDeviceLink/SDLCheckChoiceVROptionalOperation.m
@@ -18,6 +18,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLCheckChoiceVROptionalOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) NSError *internalError;
@@ -30,6 +31,7 @@ NS_ASSUME_NONNULL_BEGIN
if (!self) { return nil; }
_connectionManager = connectionManager;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -94,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.checkVROptional";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLChoiceSetManager.m b/SmartDeviceLink/SDLChoiceSetManager.m
index 037878fc5..7818dac24 100644
--- a/SmartDeviceLink/SDLChoiceSetManager.m
+++ b/SmartDeviceLink/SDLChoiceSetManager.m
@@ -21,6 +21,7 @@
#import "SDLDisplayCapabilities+ShowManagerExtensions.h"
#import "SDLError.h"
#import "SDLFileManager.h"
+#import "SDLGlobals.h"
#import "SDLHMILevel.h"
#import "SDLKeyboardProperties.h"
#import "SDLLogMacros.h"
@@ -127,9 +128,9 @@ UInt16 const ChoiceCellIdMin = 1;
- (NSOperationQueue *)sdl_newTransactionQueue {
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
- queue.name = @"SDLChoiceSetManager Transaction Queue";
+ queue.name = @"com.sdl.screenManager.choiceSetManager.transactionQueue";
queue.maxConcurrentOperationCount = 1;
- queue.qualityOfService = NSQualityOfServiceUserInitiated;
+ queue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue;
queue.suspended = YES;
return queue;
diff --git a/SmartDeviceLink/SDLDeleteChoicesOperation.m b/SmartDeviceLink/SDLDeleteChoicesOperation.m
index 46b7c0d6d..7fd42a491 100644
--- a/SmartDeviceLink/SDLDeleteChoicesOperation.m
+++ b/SmartDeviceLink/SDLDeleteChoicesOperation.m
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLDeleteChoicesOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (strong, nonatomic) NSSet<SDLChoiceCell *> *cellsToDelete;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) NSError *internalError;
@@ -37,6 +38,7 @@ NS_ASSUME_NONNULL_BEGIN
_connectionManager = connectionManager;
_cellsToDelete = cells;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -71,7 +73,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.deleteChoices";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLDeleteFileOperation.h b/SmartDeviceLink/SDLDeleteFileOperation.h
index 78563c58f..9252ae725 100644
--- a/SmartDeviceLink/SDLDeleteFileOperation.h
+++ b/SmartDeviceLink/SDLDeleteFileOperation.h
@@ -29,6 +29,21 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithFileName:(NSString *)fileName connectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerDeleteCompletionHandler)completionHandler;
+/**
+ The name of the file to be deleted on the remote system.
+ */
+@property (copy, nonatomic, readonly) NSString *fileName;
+
+/**
+ The connection manager which will handle transporting the request to the remote system.
+ */
+@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager;
+
+/**
+ A completion handler to be called when the delete finishes.
+ */
+@property (copy, nonatomic, nullable, readonly) SDLFileManagerDeleteCompletionHandler completionHandler;
+
@end
-NS_ASSUME_NONNULL_END \ No newline at end of file
+NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLDeleteFileOperation.m b/SmartDeviceLink/SDLDeleteFileOperation.m
index 4d974a2ad..fa1de55f6 100644
--- a/SmartDeviceLink/SDLDeleteFileOperation.m
+++ b/SmartDeviceLink/SDLDeleteFileOperation.m
@@ -69,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Property Overrides
- (nullable NSString *)name {
- return self.fileName;
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileName];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLFile.m b/SmartDeviceLink/SDLFile.m
index 3e69a943c..1efe7454b 100644
--- a/SmartDeviceLink/SDLFile.m
+++ b/SmartDeviceLink/SDLFile.m
@@ -166,6 +166,10 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - NSObject overrides
+- (NSString *)description {
+ return [NSString stringWithFormat:@"SDLFile: %@", self.name];
+}
+
- (NSUInteger)hash {
return self.name.hash ^ self.data.hash;
}
diff --git a/SmartDeviceLink/SDLFileManager.m b/SmartDeviceLink/SDLFileManager.m
index eef7e92ac..215c098d2 100644
--- a/SmartDeviceLink/SDLFileManager.m
+++ b/SmartDeviceLink/SDLFileManager.m
@@ -45,14 +45,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
// Local state
@property (strong, nonatomic) NSOperationQueue *transactionQueue;
-@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSOperation *> *uploadsInProgress;
@property (strong, nonatomic) NSMutableSet<SDLFileName *> *uploadedEphemeralFileNames;
@property (strong, nonatomic) SDLStateMachine *stateMachine;
@property (copy, nonatomic, nullable) SDLFileManagerStartupCompletionHandler startupCompletionHandler;
@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *failedFileUploadsCount;
-@property (assign, nonatomic) UInt8 maxFileUploadAttempts;
-@property (assign, nonatomic) UInt8 maxArtworkUploadAttempts;
+@property (assign, nonatomic) NSUInteger maxFileUploadAttempts;
+@property (assign, nonatomic) NSUInteger maxArtworkUploadAttempts;
@end
@@ -77,9 +76,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
_mutableRemoteFileNames = [NSMutableSet set];
_transactionQueue = [[NSOperationQueue alloc] init];
- _transactionQueue.name = @"SDLFileManager Transaction Queue";
+ _transactionQueue.name = @"com.sdl.fileManager.transactionQueue";
+ _transactionQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
_transactionQueue.maxConcurrentOperationCount = 1;
- _uploadsInProgress = [[NSMutableDictionary alloc] init];
_uploadedEphemeralFileNames = [[NSMutableSet<SDLFileName *> alloc] init];
_stateMachine = [[SDLStateMachine alloc] initWithTarget:self initialState:SDLFileManagerStateShutdown states:[self.class sdl_stateTransitionDictionary]];
@@ -105,11 +104,13 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
- (void)stop {
[self.stateMachine transitionToState:SDLFileManagerStateShutdown];
-
- // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core
- _failedFileUploadsCount = [NSMutableDictionary dictionary];
}
+- (void)dealloc {
+ if (self.currentState != SDLFileManagerStateShutdown) {
+ [self.stateMachine transitionToState:SDLFileManagerStateShutdown];
+ }
+}
#pragma mark - Getters
@@ -161,6 +162,9 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
[self.class sdl_clearTemporaryFileDirectory];
self.bytesAvailable = 0;
+ // Clear the failed uploads tracking so failed files can be uploaded again when a new connection has been established with Core
+ _failedFileUploadsCount = [NSMutableDictionary dictionary];
+
if (self.startupCompletionHandler != nil) {
self.startupCompletionHandler(NO, [NSError sdl_fileManager_unableToStartError]);
self.startupCompletionHandler = nil;
@@ -262,7 +266,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
dispatch_group_leave(deleteFilesTask);
// Wait for all files to be deleted
- dispatch_group_notify(deleteFilesTask, dispatch_get_main_queue(), ^{
+ dispatch_group_notify(deleteFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
if (completionHandler == nil) { return; }
if (failedDeletes.count > 0) {
return completionHandler([NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:failedDeletes]);
@@ -302,9 +306,20 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
dispatch_group_t uploadFilesTask = dispatch_group_create();
dispatch_group_enter(uploadFilesTask);
- for(SDLFile *file in files) {
- dispatch_group_enter(uploadFilesTask);
+ // Wait for all files to be uploaded
+ dispatch_group_notify(uploadFilesTask, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
+ if (completionHandler == nil) { return; }
+ if (failedUploads.count > 0) {
+ return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]);
+ }
+ return completionHandler(nil);
+ });
+
+ for(NSUInteger i = 0; i < files.count; i++) {
+ SDLFile *file = files[i];
+ dispatch_group_enter(uploadFilesTask);
+ __weak typeof(self) weakself = self;
[self uploadFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
if(!success) {
failedUploads[file.name] = error;
@@ -313,14 +328,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
// Send an update for each file sent to the remote
if (progressHandler != nil) {
totalBytesUploaded += file.fileSize;
- float uploadPercentage = [self sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded];
+ float uploadPercentage = [weakself sdl_uploadPercentage:totalBytesToUpload uploadedBytes:totalBytesUploaded];
BOOL continueWithRemainingUploads = progressHandler(file.name, uploadPercentage, error);
if (!continueWithRemainingUploads) {
// Cancel any remaining files waiting to be uploaded
- for(SDLFile *file in files) {
- NSOperation *fileUploadOperation = self.uploadsInProgress[file.name];
- if (fileUploadOperation) {
- [fileUploadOperation cancel];
+ for(NSUInteger j = i + 1; j < files.count; j++) {
+ SDLFile *cancelFile = files[j];
+ for (SDLUploadFileOperation *op in weakself.transactionQueue.operations) {
+ if ([op.fileWrapper.file isEqual:cancelFile]) {
+ [op cancel];
+ break;
+ }
}
}
@@ -332,15 +350,6 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}];
}
dispatch_group_leave(uploadFilesTask);
-
- // Wait for all files to be uploaded
- dispatch_group_notify(uploadFilesTask, dispatch_get_main_queue(), ^{
- if (completionHandler == nil) { return; }
- if (failedUploads.count > 0) {
- return completionHandler([NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:failedUploads]);
- }
- return completionHandler(nil);
- });
}
- (void)uploadFile:(SDLFile *)file completionHandler:(nullable SDLFileManagerUploadCompletionHandler)handler {
@@ -372,7 +381,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}
// Check our overwrite settings and error out if it would overwrite
- if (file.overwrite == NO && [self.remoteFileNames containsObject:file.name]) {
+ if (!file.overwrite && [self.remoteFileNames containsObject:file.name]) {
if (handler != nil) {
handler(NO, self.bytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
}
@@ -389,21 +398,17 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
__weak typeof(self) weakSelf = self;
SDLFileWrapper *fileWrapper = [SDLFileWrapper wrapperWithFile:file completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError *_Nullable error) {
- if (self.uploadsInProgress[file.name]) {
- [self.uploadsInProgress removeObjectForKey:file.name];
- }
-
if (success) {
weakSelf.bytesAvailable = bytesAvailable;
[weakSelf.mutableRemoteFileNames addObject:fileName];
[weakSelf.uploadedEphemeralFileNames addObject:fileName];
} else {
- self.failedFileUploadsCount = [self.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:self.failedFileUploadsCount];
+ weakSelf.failedFileUploadsCount = [weakSelf.class sdl_incrementFailedUploadCountForFileName:file.name failedFileUploadsCount:weakSelf.failedFileUploadsCount];
- UInt8 maxUploadCount = [file isKindOfClass:[SDLArtwork class]] ? self.maxArtworkUploadAttempts : self.maxFileUploadAttempts;
- if ([self sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:self.failedFileUploadsCount]) {
+ NSUInteger maxUploadCount = [file isMemberOfClass:[SDLArtwork class]] ? weakSelf.maxArtworkUploadAttempts : self.maxFileUploadAttempts;
+ if ([weakSelf sdl_canFileBeUploadedAgain:file maxUploadCount:maxUploadCount failedFileUploadsCount:weakSelf.failedFileUploadsCount]) {
SDLLogD(@"Attempting to resend file with name %@ after a failed upload attempt", file.name);
- return [self sdl_uploadFile:file completionHandler:handler];
+ return [weakSelf sdl_uploadFile:file completionHandler:handler];
}
}
@@ -414,18 +419,18 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
SDLUploadFileOperation *uploadOperation = [[SDLUploadFileOperation alloc] initWithFile:fileWrapper connectionManager:self.connectionManager];
- self.uploadsInProgress[file.name] = uploadOperation;
[self.transactionQueue addOperation:uploadOperation];
}
#pragma mark Artworks
- (void)uploadArtwork:(SDLArtwork *)artwork completionHandler:(nullable SDLFileManagerUploadArtworkCompletionHandler)completion {
+ __weak typeof(self) weakself = self;
[self uploadFile:artwork completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
if (completion == nil) { return; }
- if ([self sdl_isErrorCannotOverwriteError:error]) {
+ if ([weakself sdl_isErrorCannotOverwriteError:error]) {
// Artwork with same name already uploaded to remote
- return completion(true, artwork.name, bytesAvailable, nil);
+ return completion(YES, artwork.name, bytesAvailable, nil);
}
completion(success, artwork.name, bytesAvailable, error);
}];
@@ -440,9 +445,10 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@throw [NSException sdl_missingFilesException];
}
+ __weak typeof(self) weakself = self;
[self uploadFiles:artworks progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
if (progressHandler == nil) { return YES; }
- if ([self sdl_isErrorCannotOverwriteError:error]) {
+ if ([weakself sdl_isErrorCannotOverwriteError:error]) {
return progressHandler(fileName, uploadPercentage, nil);
}
return progressHandler(fileName, uploadPercentage, error);
@@ -457,7 +463,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
if (error != nil) {
for (NSString *erroredArtworkName in error.userInfo) {
- if (![self sdl_isErrorCannotOverwriteError:[error.userInfo objectForKey:erroredArtworkName]]) {
+ if (![weakself sdl_isErrorCannotOverwriteError:error.userInfo[erroredArtworkName]]) {
[successfulArtworkUploadNames removeObject:erroredArtworkName];
} else {
// An overwrite error means that an artwork with the same name is already uploaded to the remote
@@ -523,7 +529,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
* @param maxUploadCount The max number of times the file is allowed to be uploaded to Core
* @return True if the file still needs to be (re)sent to Core; false if not.
*/
-- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(UInt8)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount {
+- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(NSUInteger)maxUploadCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount {
if (![self.currentState isEqualToString:SDLFileManagerStateReady]) {
SDLLogW(@"File named %@ failed to upload. The file manager has shutdown so the file upload will not retry.", file.name);
return NO;
@@ -540,7 +546,7 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
}
NSNumber *failedUploadCount = failedFileUploadsCount[file.name];
- BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.integerValue < maxUploadCount);
+ BOOL canFileBeUploadedAgain = (failedUploadCount == nil) ? YES : (failedUploadCount.unsignedIntegerValue < maxUploadCount);
if (!canFileBeUploadedAgain) {
SDLLogE(@"File named %@ failed to upload. Max number of upload attempts reached.", file.name);
}
diff --git a/SmartDeviceLink/SDLFocusableItemLocator.m b/SmartDeviceLink/SDLFocusableItemLocator.m
index e3fb4d451..9ab7da07a 100644
--- a/SmartDeviceLink/SDLFocusableItemLocator.m
+++ b/SmartDeviceLink/SDLFocusableItemLocator.m
@@ -148,7 +148,13 @@ NS_ASSUME_NONNULL_BEGIN
@param notification object with notification data
*/
- (void)sdl_projectionViewUpdated:(NSNotification *)notification {
- [self updateInterfaceLayout];
+ if ([NSThread isMainThread]) {
+ [self updateInterfaceLayout];
+ } else {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self updateInterfaceLayout];
+ });
+ }
}
@end
diff --git a/SmartDeviceLink/SDLGlobals.h b/SmartDeviceLink/SDLGlobals.h
index cf34de68a..2d4edf017 100644
--- a/SmartDeviceLink/SDLGlobals.h
+++ b/SmartDeviceLink/SDLGlobals.h
@@ -32,6 +32,9 @@ extern NSUInteger const SDLV3MTUSize;
@property (strong, nonatomic) SDLVersion *rpcVersion;
@property (copy, nonatomic) SDLVersion *maxHeadUnitProtocolVersion;
+@property (copy, nonatomic) dispatch_queue_t sdlProcessingQueue;
+@property (copy, nonatomic) dispatch_queue_t sdlConcurrentQueue;
+
+ (instancetype)sharedGlobals;
- (void)setDynamicMTUSize:(NSUInteger)maxMTUSize forServiceType:(SDLServiceType)serviceType;
diff --git a/SmartDeviceLink/SDLGlobals.m b/SmartDeviceLink/SDLGlobals.m
index 874f58ed7..dfff3ca50 100644
--- a/SmartDeviceLink/SDLGlobals.m
+++ b/SmartDeviceLink/SDLGlobals.m
@@ -58,6 +58,12 @@ typedef NSNumber *MTUBox;
_rpcVersion = [[SDLVersion alloc] initWithString:@"1.0.0"];
_dynamicMTUDict = [NSMutableDictionary dictionary];
+ dispatch_queue_attr_t qosSerial = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, 0);
+ dispatch_queue_attr_t qosConcurrent = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_CONCURRENT, QOS_CLASS_USER_INITIATED, 0);
+
+ _sdlProcessingQueue = dispatch_queue_create("com.sdl.serialProcessing", qosSerial);
+ _sdlConcurrentQueue = dispatch_queue_create("com.sdl.concurrentProcessing", qosConcurrent);
+
return self;
}
diff --git a/SmartDeviceLink/SDLIAPTransport.m b/SmartDeviceLink/SDLIAPTransport.m
index d67b2f11e..e83e5aa3d 100644
--- a/SmartDeviceLink/SDLIAPTransport.m
+++ b/SmartDeviceLink/SDLIAPTransport.m
@@ -80,7 +80,7 @@ int const CreateSessionRetries = 3;
*/
- (void)sdl_stopEventListening {
SDLLogV(@"SDLIAPTransport stopped listening for events");
- [[EAAccessoryManager sharedAccessoryManager] unregisterForLocalNotifications];
+ [[NSNotificationCenter defaultCenter] removeObserver:self];
}
#pragma mark EAAccessory Notifications
diff --git a/SmartDeviceLink/SDLLifecycleManager.m b/SmartDeviceLink/SDLLifecycleManager.m
index 8c83f9da9..d59b1e4eb 100644
--- a/SmartDeviceLink/SDLLifecycleManager.m
+++ b/SmartDeviceLink/SDLLifecycleManager.m
@@ -127,8 +127,13 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
_rpcOperationQueue = [[NSOperationQueue alloc] init];
_rpcOperationQueue.name = @"com.sdl.lifecycle.rpcOperation.concurrent";
- _rpcOperationQueue.maxConcurrentOperationCount = 3;
- _lifecycleQueue = dispatch_queue_create("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL);
+ _rpcOperationQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlConcurrentQueue;
+
+ if (@available(iOS 10.0, *)) {
+ _lifecycleQueue = dispatch_queue_create_with_target("com.sdl.lifecycle", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _lifecycleQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
// Managers
_fileManager = [[SDLFileManager alloc] initWithConnectionManager:self configuration:_configuration.fileManagerConfig];
@@ -273,7 +278,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
// Due to a race condition internally with EAStream, we cannot immediately attempt to restart the proxy, as we will randomly crash.
// Apple Bug ID #30059457
__weak typeof(self) weakSelf = self;
- dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
+ dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), self.lifecycleQueue, ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
if (!strongSelf) { return; }
@@ -313,25 +318,23 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
__weak typeof(self) weakSelf = self;
[self sdl_sendRequest:regRequest
withResponseHandler:^(__kindof SDLRPCRequest *_Nullable request, __kindof SDLRPCResponse *_Nullable response, NSError *_Nullable error) {
- dispatch_async(weakSelf.lifecycleQueue, ^{
- // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
- if (error != nil || ![response.success boolValue]) {
- SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
- if (weakSelf.readyHandler) {
- weakSelf.readyHandler(NO, error);
- }
-
- if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
- [weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
- }
-
- return;
+ // If the success BOOL is NO or we received an error at this point, we failed. Call the ready handler and transition to the DISCONNECTED state.
+ if (error != nil || ![response.success boolValue]) {
+ SDLLogE(@"Failed to register the app. Error: %@, Response: %@", error, response);
+ if (weakSelf.readyHandler) {
+ weakSelf.readyHandler(NO, error);
}
- weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
- [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion];
- [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
- });
+ if (weakSelf.lifecycleState != SDLLifecycleStateReconnecting) {
+ [weakSelf sdl_transitionToState:SDLLifecycleStateStopped];
+ }
+
+ return;
+ }
+
+ weakSelf.registerResponse = (SDLRegisterAppInterfaceResponse *)response;
+ [SDLGlobals sharedGlobals].rpcVersion = [SDLVersion versionWithSDLMsgVersion:weakSelf.registerResponse.sdlMsgVersion];
+ [weakSelf sdl_transitionToState:SDLLifecycleStateRegistered];
}];
}
@@ -483,23 +486,19 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
}
// If we got to this point, we succeeded, send the error if there was a warning.
- dispatch_async(dispatch_get_main_queue(), ^{
- self.readyHandler(YES, startError);
- });
+ self.readyHandler(YES, startError);
[self.notificationDispatcher postNotificationName:SDLDidBecomeReady infoObject:nil];
// Send the hmi level going from NONE to whatever we're at now (could still be NONE)
- dispatch_async(dispatch_get_main_queue(), ^{
- [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel];
+ [self.delegate hmiLevel:SDLHMILevelNone didChangeToLevel:self.hmiLevel];
- // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE)
- if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
- [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState];
- }
- });
+ // Send the audio streaming state going from NOT_AUDIBLE to whatever we're at now (could still be NOT_AUDIBLE)
+ if ([self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
+ [self.delegate audioStreamingState:SDLAudioStreamingStateNotAudible didChangeToState:self.audioStreamingState];
+ }
- // Stop the background task now that setup has completed
+ // Stop the background task now that setup has completed
[self.backgroundTaskManager endBackgroundTask];
}
@@ -607,33 +606,25 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
return;
}
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:rpc withResponseHandler:nil];
- });
+ [self sdl_sendRequest:rpc withResponseHandler:nil];
}
- (void)sendConnectionRequest:(__kindof SDLRPCRequest *)request withResponseHandler:(nullable SDLResponseHandler)handler {
if (![self.lifecycleStateMachine isCurrentState:SDLLifecycleStateReady]) {
SDLLogW(@"Manager not ready, request not sent (%@)", request);
if (handler) {
- dispatch_async(dispatch_get_main_queue(), ^{
- handler(request, nil, [NSError sdl_lifecycle_notReadyError]);
- });
+ handler(request, nil, [NSError sdl_lifecycle_notReadyError]);
}
return;
}
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:request withResponseHandler:handler];
- });
+ [self sdl_sendRequest:request withResponseHandler:handler];
}
// Managers need to avoid state checking. Part of <SDLConnectionManagerType>.
- (void)sendConnectionManagerRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler {
- dispatch_async(_lifecycleQueue, ^{
- [self sdl_sendRequest:request withResponseHandler:handler];
- });
+ [self sdl_sendRequest:request withResponseHandler:handler];
}
- (void)sdl_sendRequest:(__kindof SDLRPCMessage *)request withResponseHandler:(nullable SDLResponseHandler)handler {
@@ -645,9 +636,7 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
NSError *error = [NSError sdl_lifecycle_rpcErrorWithDescription:@"Nil Request Sent" andReason:@"A nil RPC request was passed and cannot be sent."];
SDLLogW(@"%@", error);
if (handler) {
- dispatch_async(dispatch_get_main_queue(), ^{
- handler(nil, nil, error);
- });
+ handler(nil, nil, error);
}
return;
}
@@ -686,8 +675,18 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
}
// this is to make sure that the transition happens on the dedicated queue
+- (void)sdl_runOnProcessingQueue:(void (^)(void))block {
+ if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0
+ || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) {
+ block();
+ } else {
+ dispatch_sync(self.lifecycleQueue, block);
+ }
+}
+
- (void)sdl_transitionToState:(SDLState *)state {
- if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0) {
+ if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(self.lifecycleQueue)) == 0
+ || strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label([SDLGlobals sharedGlobals].sdlProcessingQueue)) == 0) {
[self.lifecycleStateMachine transitionToState:state];
} else {
// once this method returns, the transition is completed
@@ -769,24 +768,22 @@ NSString *const BackgroundTaskTransportName = @"com.sdl.transport.backgroundTask
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if (![oldHMILevel isEqualToEnum:self.hmiLevel]
- && !(oldHMILevel == nil && self.hmiLevel == nil)) {
- [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel];
- }
+ if (![oldHMILevel isEqualToEnum:self.hmiLevel]
+ && !(oldHMILevel == nil && self.hmiLevel == nil)) {
+ [self.delegate hmiLevel:oldHMILevel didChangeToLevel:self.hmiLevel];
+ }
- if (![oldStreamingState isEqualToEnum:self.audioStreamingState]
- && !(oldStreamingState == nil && self.audioStreamingState == nil)
- && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
- [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState];
- }
+ if (![oldStreamingState isEqualToEnum:self.audioStreamingState]
+ && !(oldStreamingState == nil && self.audioStreamingState == nil)
+ && [self.delegate respondsToSelector:@selector(audioStreamingState:didChangeToState:)]) {
+ [self.delegate audioStreamingState:oldStreamingState didChangeToState:self.audioStreamingState];
+ }
- if (![oldSystemContext isEqualToEnum:self.systemContext]
- && !(oldSystemContext == nil && self.systemContext == nil)
- && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) {
- [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext];
- }
- });
+ if (![oldSystemContext isEqualToEnum:self.systemContext]
+ && !(oldSystemContext == nil && self.systemContext == nil)
+ && [self.delegate respondsToSelector:@selector(systemContext:didChangeToContext:)]) {
+ [self.delegate systemContext:oldSystemContext didChangeToContext:self.systemContext];
+ }
}
- (void)remoteHardwareDidUnregister:(SDLRPCNotificationNotification *)notification {
diff --git a/SmartDeviceLink/SDLListFilesOperation.h b/SmartDeviceLink/SDLListFilesOperation.h
index 9107ef758..fc8453820 100644
--- a/SmartDeviceLink/SDLListFilesOperation.h
+++ b/SmartDeviceLink/SDLListFilesOperation.h
@@ -28,6 +28,16 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithConnectionManager:(id<SDLConnectionManagerType>)connectionManager completionHandler:(nullable SDLFileManagerListFilesCompletionHandler)completionHandler;
+/**
+ The connection manager which will handle transporting the request to the remote system.
+ */
+@property (weak, nonatomic, readonly) id<SDLConnectionManagerType> connectionManager;
+
+/**
+ A completion handler for when the response returns.
+ */
+@property (copy, nonatomic, nullable, readonly) SDLFileManagerListFilesCompletionHandler completionHandler;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLListFilesOperation.m b/SmartDeviceLink/SDLListFilesOperation.m
index ca45ac928..5e6ace166 100644
--- a/SmartDeviceLink/SDLListFilesOperation.m
+++ b/SmartDeviceLink/SDLListFilesOperation.m
@@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLListFilesOperation ()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (copy, nonatomic, nullable) SDLFileManagerListFilesCompletionHandler completionHandler;
@@ -31,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
return nil;
}
+ _operationId = [NSUUID UUID];
_connectionManager = connectionManager;
_completionHandler = completionHandler;
@@ -67,7 +69,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark Property Overrides
- (nullable NSString *)name {
- return @"List Files";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLLogFileModuleMap.m b/SmartDeviceLink/SDLLogFileModuleMap.m
index 11e7466e7..e9e2a56ba 100644
--- a/SmartDeviceLink/SDLLogFileModuleMap.m
+++ b/SmartDeviceLink/SDLLogFileModuleMap.m
@@ -60,7 +60,7 @@
}
+ (SDLLogFileModule *)sdl_lifecycleManagerModule {
- return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager"]]];
+ return [SDLLogFileModule moduleWithName:@"Lifecycle" files:[NSSet setWithArray:@[@"SDLLifecycleManager", @"SDLManager", @"SDLAsynchronousOperation"]]];
}
+ (SDLLogFileModule *)sdl_systemCapabilityModule {
diff --git a/SmartDeviceLink/SDLLogManager.m b/SmartDeviceLink/SDLLogManager.m
index 22918ed9c..ae0fa317f 100644
--- a/SmartDeviceLink/SDLLogManager.m
+++ b/SmartDeviceLink/SDLLogManager.m
@@ -8,6 +8,7 @@
#import "SDLLogManager.h"
+#import "SDLGlobals.h"
#import "SDLHexUtility.h"
#import "SDLLogConfiguration.h"
#import "SDLLogFileModule.h"
@@ -189,9 +190,7 @@ static dispatch_queue_t _logQueue = NULL;
}
- (void)sdl_syncLog:(SDLLogModel *)log {
- dispatch_sync(self.class.logQueue, ^{
- [self sdl_log:log];
- });
+ [self sdl_log:log];
}
- (void)sdl_log:(SDLLogModel *)log {
@@ -341,7 +340,11 @@ static dispatch_queue_t _logQueue = NULL;
+ (dispatch_queue_t)logQueue {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
- _logQueue = dispatch_queue_create("com.sdl.log", DISPATCH_QUEUE_SERIAL);
+ if (@available(iOS 10.0, *)) {
+ _logQueue = dispatch_queue_create_with_target("com.sdl.log", DISPATCH_QUEUE_SERIAL, [SDLGlobals sharedGlobals].sdlProcessingQueue);
+ } else {
+ _logQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
+ }
});
return _logQueue;
diff --git a/SmartDeviceLink/SDLMenuManager.m b/SmartDeviceLink/SDLMenuManager.m
index 734e1fc00..3f95a5353 100644
--- a/SmartDeviceLink/SDLMenuManager.m
+++ b/SmartDeviceLink/SDLMenuManager.m
@@ -382,10 +382,10 @@ UInt32 const MenuCellIdMin = 1;
}
self.inProgressUpdate = [mainMenuCommands arrayByAddingObjectsFromArray:subMenuCommands];
-
+
__block NSMutableDictionary<SDLRPCRequest *, NSError *> *errors = [NSMutableDictionary dictionary];
__weak typeof(self) weakSelf = self;
- [self.connectionManager sendRequests:mainMenuCommands progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
+ [self.connectionManager sendRequests:mainMenuCommands progressHandler:^void(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
if (error != nil) {
errors[request] = error;
}
diff --git a/SmartDeviceLink/SDLPreloadChoicesOperation.m b/SmartDeviceLink/SDLPreloadChoicesOperation.m
index caedc168b..a2f83b5b7 100644
--- a/SmartDeviceLink/SDLPreloadChoicesOperation.m
+++ b/SmartDeviceLink/SDLPreloadChoicesOperation.m
@@ -30,6 +30,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPreloadChoicesOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (strong, nonatomic) NSMutableSet<SDLChoiceCell *> *cellsToUpload;
@property (strong, nonatomic) SDLDisplayCapabilities *displayCapabilities;
@property (assign, nonatomic, getter=isVROptional) BOOL vrOptional;
@@ -51,6 +52,7 @@ NS_ASSUME_NONNULL_BEGIN
_displayCapabilities = displayCapabilities;
_vrOptional = isVROptional;
_cellsToUpload = [cells mutableCopy];
+ _operationId = [NSUUID UUID];
_currentState = SDLPreloadChoicesOperationStateWaitingToStart;
@@ -191,7 +193,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.preloadChoices";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLPresentChoiceSetOperation.m b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
index 4e923b8e1..a1644fd2e 100644
--- a/SmartDeviceLink/SDLPresentChoiceSetOperation.m
+++ b/SmartDeviceLink/SDLPresentChoiceSetOperation.m
@@ -32,6 +32,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentChoiceSetOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (strong, nonatomic, readwrite) SDLChoiceSet *choiceSet;
@property (strong, nonatomic) SDLInteractionMode presentationMode;
@@ -60,6 +61,7 @@ NS_ASSUME_NONNULL_BEGIN
_connectionManager = connectionManager;
_choiceSet = choiceSet;
_presentationMode = mode;
+ _operationId = [NSUUID UUID];
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
@@ -254,7 +256,7 @@ NS_ASSUME_NONNULL_BEGIN
}
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.presentChoiceSet";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLPresentKeyboardOperation.m b/SmartDeviceLink/SDLPresentKeyboardOperation.m
index b81284ebe..4899f8f46 100644
--- a/SmartDeviceLink/SDLPresentKeyboardOperation.m
+++ b/SmartDeviceLink/SDLPresentKeyboardOperation.m
@@ -23,6 +23,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLPresentKeyboardOperation()
+@property (strong, nonatomic) NSUUID *operationId;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (weak, nonatomic) id<SDLKeyboardDelegate> keyboardDelegate;
@property (copy, nonatomic) NSString *initialText;
@@ -46,6 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
_keyboardDelegate = keyboardDelegate;
_originalKeyboardProperties = originalKeyboardProperties;
_keyboardProperties = originalKeyboardProperties;
+ _operationId = [NSUUID UUID];
return self;
}
@@ -163,7 +165,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return @"com.sdl.choicesetmanager.presentKeyboard";
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.operationId];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/SDLProtocol.m b/SmartDeviceLink/SDLProtocol.m
index 3f1996e92..5adfd5b88 100644
--- a/SmartDeviceLink/SDLProtocol.m
+++ b/SmartDeviceLink/SDLProtocol.m
@@ -39,8 +39,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLProtocol () {
UInt32 _messageID;
- dispatch_queue_t _receiveQueue;
- dispatch_queue_t _sendQueue;
SDLPrioritizedObjectCollection *_prioritizedCollection;
}
@@ -65,8 +63,6 @@ NS_ASSUME_NONNULL_BEGIN
if (self = [super init]) {
_messageID = 0;
_hashId = SDLControlFrameInt32NotFound;
- _receiveQueue = dispatch_queue_create("com.sdl.protocol.receive", DISPATCH_QUEUE_SERIAL);
- _sendQueue = dispatch_queue_create("com.sdl.protocol.transmit", DISPATCH_QUEUE_SERIAL);
_prioritizedCollection = [[SDLPrioritizedObjectCollection alloc] init];
_protocolDelegateTable = [NSHashTable weakObjectsHashTable];
_serviceHeaders = [[NSMutableDictionary alloc] init];
@@ -357,13 +353,10 @@ NS_ASSUME_NONNULL_BEGIN
- (void)sdl_sendDataToTransport:(NSData *)data onService:(NSInteger)priority {
[_prioritizedCollection addObject:data withPriority:priority];
- // TODO: (Joel F.)[2016-02-11] Autoreleasepool?
- dispatch_async(_sendQueue, ^{
- NSData *dataToTransmit = nil;
- while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) {
- [self.transport sendData:dataToTransmit];
- };
- });
+ NSData *dataToTransmit = nil;
+ while (dataToTransmit = (NSData *)[self->_prioritizedCollection nextObject]) {
+ [self.transport sendData:dataToTransmit];
+ }
}
- (void)sendRawData:(NSData *)data withServiceType:(SDLServiceType)serviceType {
@@ -465,9 +458,7 @@ NS_ASSUME_NONNULL_BEGIN
self.receiveBuffer = [[self.receiveBuffer subdataWithRange:NSMakeRange(messageSize, self.receiveBuffer.length - messageSize)] mutableCopy];
// Pass on the message to the message router.
- dispatch_async(_receiveQueue, ^{
- [self.messageRouter handleReceivedMessage:message];
- });
+ [self.messageRouter handleReceivedMessage:message];
// Call recursively until the buffer is empty or incomplete message is encountered
if (self.receiveBuffer.length > 0) {
@@ -475,7 +466,6 @@ NS_ASSUME_NONNULL_BEGIN
}
}
-// TODO: This is a v4 packet (create new delegate methods)
- (void)handleProtocolStartServiceACKMessage:(SDLProtocolMessage *)startServiceACK {
// V5 Packet
if (startServiceACK.header.version >= 5) {
diff --git a/SmartDeviceLink/SDLProxy.m b/SmartDeviceLink/SDLProxy.m
index 6ab2006c8..f32b3de94 100644
--- a/SmartDeviceLink/SDLProxy.m
+++ b/SmartDeviceLink/SDLProxy.m
@@ -50,7 +50,7 @@ typedef NSString SDLVehicleMake;
typedef void (^URLSessionTaskCompletionHandler)(NSData *data, NSURLResponse *response, NSError *error);
typedef void (^URLSessionDownloadTaskCompletionHandler)(NSURL *location, NSURLResponse *response, NSError *error);
-NSString *const SDLProxyVersion = @"6.3.0";
+NSString *const SDLProxyVersion = @"6.3.1";
const float StartSessionTime = 10.0;
const float NotifyProxyClosedDelay = (float)0.1;
const int PoliciesCorrelationId = 65535;
@@ -65,7 +65,6 @@ static float DefaultConnectionTimeout = 45.0;
@property (nullable, nonatomic, strong) SDLDisplayCapabilities *displayCapabilities;
@property (nonatomic, strong) NSMutableDictionary<SDLVehicleMake *, Class> *securityManagers;
@property (nonatomic, strong) NSURLSession* urlSession;
-@property (strong, nonatomic) dispatch_queue_t rpcProcessingQueue;
@end
@@ -77,7 +76,6 @@ static float DefaultConnectionTimeout = 45.0;
if (self = [super init]) {
SDLLogD(@"Framework Version: %@", self.proxyVersion);
_lsm = [[SDLLockScreenStatusManager alloc] init];
- _rpcProcessingQueue = dispatch_queue_create("com.sdl.rpcProcessingQueue", DISPATCH_QUEUE_SERIAL);
_mutableProxyListeners = [NSMutableSet setWithObject:delegate];
_securityManagers = [NSMutableDictionary dictionary];
@@ -150,13 +148,15 @@ static float DefaultConnectionTimeout = 45.0;
#pragma mark - Application Lifecycle
- (void)sendMobileHMIState {
- dispatch_async(dispatch_get_main_queue(), ^{
- [self sdl_sendMobileHMIState];
- });
-}
+ __block UIApplicationState appState = UIApplicationStateInactive;
+ if ([NSThread isMainThread]) {
+ appState = [UIApplication sharedApplication].applicationState;
+ } else {
+ dispatch_sync(dispatch_get_main_queue(), ^{
+ appState = [UIApplication sharedApplication].applicationState;
+ });
+ }
-- (void)sdl_sendMobileHMIState {
- UIApplicationState appState = [UIApplication sharedApplication].applicationState;
SDLOnHMIStatus *HMIStatusRPC = [[SDLOnHMIStatus alloc] init];
HMIStatusRPC.audioStreamingState = SDLAudioStreamingStateNotAudible;
@@ -898,15 +898,13 @@ static float DefaultConnectionTimeout = 45.0;
}
- (void)invokeMethodOnDelegates:(SEL)aSelector withObject:(nullable id)object {
- // Occurs on the protocol receive serial queue
- dispatch_async(_rpcProcessingQueue, ^{
- for (id<SDLProxyListener> listener in self.proxyListeners) {
- if ([listener respondsToSelector:aSelector]) {
- // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown
- ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object);
- }
+ // Occurs on the processing serial queue
+ for (id<SDLProxyListener> listener in self.proxyListeners) {
+ if ([listener respondsToSelector:aSelector]) {
+ // HAX: http://stackoverflow.com/questions/7017281/performselector-may-cause-a-leak-because-its-selector-is-unknown
+ ((void (*)(id, SEL, id))[(NSObject *)listener methodForSelector:aSelector])(listener, aSelector, object);
}
- });
+ }
}
diff --git a/SmartDeviceLink/SDLRPCRequest.m b/SmartDeviceLink/SDLRPCRequest.m
index 1ce2186c1..445bace56 100644
--- a/SmartDeviceLink/SDLRPCRequest.m
+++ b/SmartDeviceLink/SDLRPCRequest.m
@@ -26,6 +26,10 @@ NS_ASSUME_NONNULL_BEGIN
[self.function sdl_setObject:corrID forName:SDLRPCParameterNameCorrelationId];
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLRPCResponse.m b/SmartDeviceLink/SDLRPCResponse.m
index c996473e9..c0ad88b74 100644
--- a/SmartDeviceLink/SDLRPCResponse.m
+++ b/SmartDeviceLink/SDLRPCResponse.m
@@ -44,8 +44,13 @@ NS_ASSUME_NONNULL_BEGIN
return self;
}
+
#pragma clang diagnostic pop
+- (NSString *)description {
+ return [NSString stringWithFormat:@"%@ (%@), id: %@\n%@", self.name, self.messageType, self.correlationID, self.parameters];
+}
+
- (NSNumber<SDLInt> *)correlationID {
NSError *error = nil;
return [self.function sdl_objectForName:SDLRPCParameterNameCorrelationId ofClass:NSNumber.class error:&error];
diff --git a/SmartDeviceLink/SDLResponseDispatcher.m b/SmartDeviceLink/SDLResponseDispatcher.m
index 6851a1575..4ac79c8bf 100644
--- a/SmartDeviceLink/SDLResponseDispatcher.m
+++ b/SmartDeviceLink/SDLResponseDispatcher.m
@@ -132,8 +132,12 @@ NS_ASSUME_NONNULL_BEGIN
// When we get disconnected we have to delete all existing responseHandlers as they are not valid anymore
for (SDLRPCCorrelationId *correlationID in self.rpcResponseHandlerMap.dictionaryRepresentation) {
SDLResponseHandler responseHandler = self.rpcResponseHandlerMap[correlationID];
- responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]);
+
+ if (responseHandler != NULL) {
+ responseHandler(self.rpcRequestDictionary[correlationID], nil, [NSError sdl_lifecycle_notConnectedError]);
+ }
}
+
[self.rpcRequestDictionary removeAllObjects];
[self.rpcResponseHandlerMap removeAllObjects];
[self.commandHandlerMap removeAllObjects];
diff --git a/SmartDeviceLink/SDLTouch.m b/SmartDeviceLink/SDLTouch.m
index e4007471f..d9fa83c7a 100644
--- a/SmartDeviceLink/SDLTouch.m
+++ b/SmartDeviceLink/SDLTouch.m
@@ -58,6 +58,10 @@ NS_ASSUME_NONNULL_BEGIN
return self.identifier == SDLTouchIdentifierSecondFinger;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"SDLTouch: ID: %ld, Location: %@, Timestamp: %lu, firstFinger? %@, secondFinger? %@", (long)_identifier, NSStringFromCGPoint(_location), (unsigned long)_timeStamp, (self.isFirstFinger ? @"YES" : @"NO"), (self.isSecondFinger ? @"YES" : @"NO")];
+}
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLTouchManager.m b/SmartDeviceLink/SDLTouchManager.m
index 9a66d81e4..1f4f4adea 100644
--- a/SmartDeviceLink/SDLTouchManager.m
+++ b/SmartDeviceLink/SDLTouchManager.m
@@ -9,8 +9,8 @@
#import "SDLTouchManager.h"
#import "CGPoint_Util.h"
-#import "dispatch_timer.h"
+#import "SDLGlobals.h"
#import "SDLFocusableItemHitTester.h"
#import "SDLLogMacros.h"
#import "SDLNotificationConstants.h"
@@ -75,7 +75,7 @@ static NSUInteger const MaximumNumberOfTouches = 2;
* @abstract
* Timer used for distinguishing between single & double taps.
*/
-@property (nonatomic, strong, nullable) dispatch_source_t singleTapTimer;
+@property (nonatomic, strong, nullable) NSTimer *singleTapTimer;
/*!
* @abstract
@@ -131,39 +131,43 @@ static NSUInteger const MaximumNumberOfTouches = 2;
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) {
- CGPoint storedTouchLocation = self.lastStoredTouchLocation;
- CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation;
+ if (self.performingTouchType == SDLPerformingTouchTypePanningTouch) {
+ CGPoint storedTouchLocation = self.lastStoredTouchLocation;
+ CGPoint notifiedTouchLocation = self.lastNotifiedTouchLocation;
- if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) ||
- CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) ||
- CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) {
- return;
- }
+ if (CGPointEqualToPoint(storedTouchLocation, CGPointZero) ||
+ CGPointEqualToPoint(notifiedTouchLocation, CGPointZero) ||
+ CGPointEqualToPoint(storedTouchLocation, notifiedTouchLocation)) {
+ return;
+ }
- if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) {
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePanningFromPoint:toPoint:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
[self.touchEventDelegate touchManager:self
didReceivePanningFromPoint:notifiedTouchLocation
toPoint:storedTouchLocation];
self.lastNotifiedTouchLocation = storedTouchLocation;
- }
- } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) {
- if (self.previousPinchDistance == self.currentPinchGesture.distance) {
- return;
- }
+ });
+ }
+ } else if (self.performingTouchType == SDLPerformingTouchTypeMultiTouch) {
+ if (self.previousPinchDistance == self.currentPinchGesture.distance) {
+ return;
+ }
- if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) {
- CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance;
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceivePinchAtCenterPoint:withScale:)]) {
+
+ CGFloat scale = self.currentPinchGesture.distance / self.previousPinchDistance;
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
[self.touchEventDelegate touchManager:self
- didReceivePinchAtCenterPoint:self.currentPinchGesture.center
+ didReceivePinchAtCenterPoint:center
withScale:scale];
- }
-
- self.previousPinchDistance = self.currentPinchGesture.distance;
+ });
}
- });
+
+ self.previousPinchDistance = self.currentPinchGesture.distance;
+ }
}
#pragma mark - SDLDidReceiveTouchEventNotification
@@ -186,25 +190,25 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[onTouchEvent.event enumerateObjectsUsingBlock:^(SDLTouchEvent *touchEvent, NSUInteger idx, BOOL *stop) {
SDLTouch *touch = [[SDLTouch alloc] initWithTouchEvent:touchEvent];
- if (self.touchEventHandler) {
- self.touchEventHandler(touch, touchType);
+ if (self.touchEventHandler != NULL) {
+ dispatch_async(dispatch_get_main_queue(), ^{
+ self.touchEventHandler(touch, touchType);
+ });
}
if (!self.touchEventDelegate || (touch.identifier > MaximumNumberOfTouches)) {
return;
}
- dispatch_async(dispatch_get_main_queue(), ^{
- if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) {
- [self sdl_handleTouchBegan:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) {
- [self sdl_handleTouchMoved:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) {
- [self sdl_handleTouchEnded:touch];
- } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) {
- [self sdl_handleTouchCanceled:touch];
- }
- });
+ if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeBegin]) {
+ [self sdl_handleTouchBegan:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeMove]) {
+ [self sdl_handleTouchMoved:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeEnd]) {
+ [self sdl_handleTouchEnded:touch];
+ } else if ([onTouchEvent.type isEqualToEnum:SDLTouchTypeCancel]) {
+ [self sdl_handleTouchCanceled:touch];
+ }
}];
}
@@ -227,8 +231,11 @@ static NSUInteger const MaximumNumberOfTouches = 2;
self.currentPinchGesture = [[SDLPinchGesture alloc] initWithFirstTouch:self.previousTouch secondTouch:touch];
self.previousPinchDistance = self.currentPinchGesture.distance;
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidStartInView:atCenterPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
- [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:self.currentPinchGesture.center];
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:center] : nil;
+ [self.touchEventDelegate touchManager:self pinchDidStartInView:hitView atCenterPoint:center];
+ });
}
} break;
}
@@ -275,8 +282,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
_performingTouchType = SDLPerformingTouchTypePanningTouch;
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidStartInView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
- [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
+ [self.touchEventDelegate touchManager:self panningDidStartInView:hitView atPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypePanningTouch: {
@@ -302,9 +311,11 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[self sdl_setMultiTouchFingerTouchForTouch:touch];
if (self.currentPinchGesture.isValid) {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchDidEndInView:atCenterPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
- [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center];
- self.currentPinchGesture = nil;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:self.currentPinchGesture.center] : nil;
+ [self.touchEventDelegate touchManager:self pinchDidEndInView:hitView atCenterPoint:self.currentPinchGesture.center];
+ self.currentPinchGesture = nil;
+ });
} else {
self.currentPinchGesture = nil;
}
@@ -312,8 +323,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
} break;
case SDLPerformingTouchTypePanningTouch: {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningDidEndInView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
- [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:touch.location] : nil;
+ [self.touchEventDelegate touchManager:self panningDidEndInView:hitView atPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypeSingleTouch: {
@@ -333,8 +346,10 @@ static NSUInteger const MaximumNumberOfTouches = 2;
CGPoint centerPoint = CGPointCenterOfPoints(touch.location,
self.singleTapTouch.location);
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveDoubleTapForView:atPoint:)]) {
- UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil;
- [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ UIView *hitView = (self.hitTester != nil) ? [self.hitTester viewForPoint:centerPoint] : nil;
+ [self.touchEventDelegate touchManager:self didReceiveDoubleTapForView:hitView atPoint:centerPoint];
+ });
}
}
@@ -368,16 +383,21 @@ static NSUInteger const MaximumNumberOfTouches = 2;
[self sdl_setMultiTouchFingerTouchForTouch:touch];
if (self.currentPinchGesture.isValid) {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:pinchCanceledAtCenterPoint:)]) {
- [self.touchEventDelegate touchManager:self
- pinchCanceledAtCenterPoint:self.currentPinchGesture.center];
+ CGPoint center = self.currentPinchGesture.center;
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.touchEventDelegate touchManager:self
+ pinchCanceledAtCenterPoint:center];
+ });
}
self.currentPinchGesture = nil;
}
} break;
case SDLPerformingTouchTypePanningTouch: {
if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:panningCanceledAtPoint:)]) {
- [self.touchEventDelegate touchManager:self
- panningCanceledAtPoint:touch.location];
+ dispatch_async(dispatch_get_main_queue(), ^{
+ [self.touchEventDelegate touchManager:self
+ panningCanceledAtPoint:touch.location];
+ });
}
} break;
case SDLPerformingTouchTypeSingleTouch: // fallthrough
@@ -413,18 +433,32 @@ static NSUInteger const MaximumNumberOfTouches = 2;
* @param point Screen coordinates of the tap gesture
*/
- (void)sdl_initializeSingleTapTimerAtPoint:(CGPoint)point {
- __weak typeof(self) weakSelf = self;
- self.singleTapTimer = dispatch_create_timer(self.tapTimeThreshold, NO, ^{
- // If timer was not canceled by a second tap then only one tap detected
- typeof(weakSelf) strongSelf = weakSelf;
- strongSelf.singleTapTouch = nil;
- [strongSelf sdl_cancelSingleTapTimer];
- if ([strongSelf.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) {
+ if (self.singleTapTimer != nil) {
+ [self sdl_cancelSingleTapTimer];
+ }
+
+ self.singleTapTimer = [NSTimer timerWithTimeInterval:self.tapTimeThreshold target:self selector:@selector(sdl_singleTapTimerCallback:) userInfo:@{@"point": [NSValue valueWithCGPoint:point]} repeats:NO];
+ [[NSRunLoop mainRunLoop] addTimer:self.singleTapTimer forMode:NSRunLoopCommonModes];
+}
+
+/**
+ The method that will be called when the timer fires that was started in `sdl_initializeSingleTapTimerAtPoint:`.
+
+ This is called on the main thread based on `sdl_initializeSingleTapTimerAtPoint:`
+
+ @param timer The timer that was fired
+ */
+- (void)sdl_singleTapTimerCallback:(NSTimer *)timer {
+ CGPoint point = ((NSValue *)timer.userInfo[@"point"]).CGPointValue;
+ self.singleTapTouch = nil;
+ [self sdl_cancelSingleTapTimer];
+ if ([self.touchEventDelegate respondsToSelector:@selector(touchManager:didReceiveSingleTapForView:atPoint:)]) {
+ dispatch_async(dispatch_get_main_queue(), ^{
[self sdl_getSingleTapHitView:point hitViewHandler:^(UIView * _Nullable selectedView) {
- [strongSelf.touchEventDelegate touchManager:strongSelf didReceiveSingleTapForView:selectedView atPoint:point];
+ [self.touchEventDelegate touchManager:self didReceiveSingleTapForView:selectedView atPoint:point];
}];
- }
- });
+ });
+ }
}
/**
@@ -441,24 +475,22 @@ static NSUInteger const MaximumNumberOfTouches = 2;
return hitViewHandler(nil);
}
- dispatch_async(dispatch_get_main_queue(), ^{
- UIView *hitView = [self.hitTester viewForPoint:point];
- dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
- if (!hitViewHandler) { return; }
- return hitViewHandler(hitView);
- });
- });
+ UIView *hitView = [self.hitTester viewForPoint:point];
+ if (!hitViewHandler) { return; }
+
+ return hitViewHandler(hitView);
}
/**
* Cancels a tap gesture timer
*/
- (void)sdl_cancelSingleTapTimer {
- if (self.singleTapTimer == NULL) {
+ if (self.singleTapTimer == nil) {
return;
}
- dispatch_stop_timer(self.singleTapTimer);
- self.singleTapTimer = NULL;
+
+ [self.singleTapTimer invalidate];
+ self.singleTapTimer = nil;
}
@end
diff --git a/SmartDeviceLink/SDLUploadFileOperation.h b/SmartDeviceLink/SDLUploadFileOperation.h
index 40c4b36c4..cd3eaa4af 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.h
+++ b/SmartDeviceLink/SDLUploadFileOperation.h
@@ -31,6 +31,8 @@ NS_ASSUME_NONNULL_BEGIN
*/
- (instancetype)initWithFile:(SDLFileWrapper *)file connectionManager:(id<SDLConnectionManagerType>)connectionManager;
+@property (nonatomic, strong, readonly) SDLFileWrapper *fileWrapper;
+
@end
NS_ASSUME_NONNULL_END
diff --git a/SmartDeviceLink/SDLUploadFileOperation.m b/SmartDeviceLink/SDLUploadFileOperation.m
index 620d0f833..f9edfe2f5 100644
--- a/SmartDeviceLink/SDLUploadFileOperation.m
+++ b/SmartDeviceLink/SDLUploadFileOperation.m
@@ -24,7 +24,7 @@ NS_ASSUME_NONNULL_BEGIN
@interface SDLUploadFileOperation ()
-@property (strong, nonatomic) SDLFileWrapper *fileWrapper;
+@property (strong, nonatomic, readwrite) SDLFileWrapper *fileWrapper;
@property (weak, nonatomic) id<SDLConnectionManagerType> connectionManager;
@property (strong, nonatomic) NSInputStream *inputStream;
@@ -70,21 +70,25 @@ NS_ASSUME_NONNULL_BEGIN
__block NSInteger highestCorrelationIDReceived = -1;
if (self.isCancelled) {
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ return;
}
if (file == nil) {
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
+ return;
}
self.inputStream = [self sdl_openInputStreamWithFile:file];
if (self.inputStream == nil || ![self.inputStream hasBytesAvailable]) {
// If the file does not exist or the passed data is nil, return an error
[self sdl_closeInputStream];
+
+ completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
[self finishOperation];
- return completion(NO, bytesAvailable, [NSError sdl_fileManager_fileDoesNotExistError]);
+ return;
}
dispatch_group_t putFileGroup = dispatch_group_create();
@@ -92,7 +96,7 @@ NS_ASSUME_NONNULL_BEGIN
// Wait for all packets be sent before returning whether or not the upload was a success
__weak typeof(self) weakself = self;
- dispatch_group_notify(putFileGroup, dispatch_get_main_queue(), ^{
+ dispatch_group_notify(putFileGroup, [SDLGlobals sharedGlobals].sdlProcessingQueue, ^{
typeof(weakself) strongself = weakself;
[weakself sdl_closeInputStream];
@@ -101,6 +105,7 @@ NS_ASSUME_NONNULL_BEGIN
} else {
completion(YES, bytesAvailable, nil);
}
+
[weakself finishOperation];
});
@@ -259,7 +264,7 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Property Overrides
- (nullable NSString *)name {
- return self.fileWrapper.file.name;
+ return [NSString stringWithFormat:@"%@ - %@", self.class, self.fileWrapper.file.name];
}
- (NSOperationQueuePriority)queuePriority {
diff --git a/SmartDeviceLink/dispatch_timer.h b/SmartDeviceLink/dispatch_timer.h
deleted file mode 100644
index 1dd8bb9f2..000000000
--- a/SmartDeviceLink/dispatch_timer.h
+++ /dev/null
@@ -1,18 +0,0 @@
-//
-// dispatch_timer.h
-// MobileNav
-//
-// Created by Muller, Alexander (A.) on 5/12/16.
-// Copyright © 2016 Alex Muller. All rights reserved.
-//
-
-#ifndef dispatch_timer_h
-#define dispatch_timer_h
-
-#include <dispatch/dispatch.h>
-#include <stdio.h>
-
-dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block);
-void dispatch_stop_timer(dispatch_source_t timer);
-
-#endif /* dispatch_timer_h */
diff --git a/SmartDeviceLink/dispatch_timer.m b/SmartDeviceLink/dispatch_timer.m
deleted file mode 100644
index 445095eb6..000000000
--- a/SmartDeviceLink/dispatch_timer.m
+++ /dev/null
@@ -1,38 +0,0 @@
-//
-// dispatch_timer.c
-// MobileNav
-//
-// Created by Muller, Alexander (A.) on 5/12/16.
-// Copyright © 2016 Alex Muller. All rights reserved.
-//
-
-#include "dispatch_timer.h"
-
-dispatch_source_t dispatch_create_timer(double afterInterval, bool repeating, dispatch_block_t block) {
- dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,
- 0);
- dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
- 0,
- 0,
- queue);
- dispatch_source_set_timer(timer,
- dispatch_time(DISPATCH_TIME_NOW, (int64_t)(afterInterval * NSEC_PER_SEC)),
- (uint64_t)(afterInterval * NSEC_PER_SEC),
- (1ull * NSEC_PER_SEC) / 10);
- dispatch_source_set_event_handler(timer, ^{
- if (!repeating) {
- dispatch_stop_timer(timer);
- }
- if (block) {
- block();
- }
- });
- dispatch_resume(timer);
-
- return timer;
-}
-
-void dispatch_stop_timer(dispatch_source_t timer) {
- dispatch_source_set_event_handler(timer, NULL);
- dispatch_source_cancel(timer);
-}
diff --git a/SmartDeviceLinkSwift/Info.plist b/SmartDeviceLinkSwift/Info.plist
index 93c3f315c..5286dd4de 100644
--- a/SmartDeviceLinkSwift/Info.plist
+++ b/SmartDeviceLinkSwift/Info.plist
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
- <string>6.3.0</string>
+ <string>6.3.1</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
index 7cec8f3e5..9a80d5fd4 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLAsynchronousRPCRequestOperationSpec.m
@@ -45,21 +45,21 @@ describe(@"sending asynchronous requests", ^{
});
it(@"should correctly send all requests", ^{
- testOperation = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:testConnectionManager requests:sendRequests.copy progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
- TestRequestProgressResponse *progressResponse = testProgressResponses[request.correlationID];
-
- expect(progressResponse.percentComplete).to(beCloseTo(percentComplete));
- expect(response).toNot(beNil());
- expect(error).to(beNil());
+ __block NSError *testError = nil;
+ __block BOOL testSuccess = NO;
- [resultResponses addObject:response];
+ testOperation = [[SDLAsynchronousRPCRequestOperation alloc] initWithConnectionManager:testConnectionManager requests:sendRequests.copy progressHandler:^(__kindof SDLRPCRequest * _Nonnull request, __kindof SDLRPCResponse * _Nullable response, NSError * _Nullable error, float percentComplete) {
+ if (testError == nil) { testError = error; }
+ if (response != nil) { [resultResponses addObject:response]; }
} completionHandler:^(BOOL success) {
- expect(resultResponses).to(haveCount(3));
- expect(success).to(beTruthy());
+ testSuccess = success;
}];
[testOperationQueue addOperation:testOperation];
[NSThread sleepForTimeInterval:0.5];
+
+ expect(testSuccess).toEventually(beTruthy());
+ expect(testError).toEventually(beNil());
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
index c7dd86483..5cb8377f4 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLFileManagerSpec.m
@@ -3,11 +3,13 @@
#import <OCMock/OCMock.h>
#import "SDLDeleteFileResponse.h"
+#import "SDLDeleteFileOperation.h"
#import "SDLError.h"
#import "SDLFile.h"
#import "SDLFileManager.h"
#import "SDLFileManagerConfiguration.h"
#import "SDLFileType.h"
+#import "SDLFileWrapper.h"
#import "SDLListFiles.h"
#import "SDLListFilesOperation.h"
#import "SDLListFilesResponse.h"
@@ -16,6 +18,7 @@
#import "SDLPutFileResponse.h"
#import "SDLRPCResponse.h"
#import "SDLStateMachine.h"
+#import "SDLUploadFileOperation.h"
#import "TestConnectionManager.h"
#import "TestMultipleFilesConnectionManager.h"
#import "TestFileProgressResponse.h"
@@ -28,6 +31,10 @@ SDLFileManagerState *const SDLFileManagerStateReady = @"Ready";
SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@interface SDLFileManager ()
+
+@property (strong, nonatomic) NSMutableSet<SDLFileName *> *mutableRemoteFileNames;
+@property (assign, nonatomic, readwrite) NSUInteger bytesAvailable;
+
@property (strong, nonatomic) NSOperationQueue *transactionQueue;
@property (strong, nonatomic) NSMutableSet<SDLFileName *> *uploadedEphemeralFileNames;
@property (strong, nonatomic) NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *failedFileUploadsCount;
@@ -35,44 +42,68 @@ SDLFileManagerState *const SDLFileManagerStateStartupError = @"StartupError";
@property (assign, nonatomic) UInt8 maxArtworkUploadAttempts;
@property (strong, nonatomic) SDLStateMachine *stateMachine;
+// List files helper
+- (void)sdl_listRemoteFilesWithCompletionHandler:(SDLFileManagerListFilesCompletionHandler)handler;
+
- (BOOL)sdl_canFileBeUploadedAgain:(nullable SDLFile *)file maxUploadCount:(int)maxRetryCount failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount;
+ (NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)sdl_incrementFailedUploadCountForFileName:(SDLFileName *)fileName failedFileUploadsCount:(NSMutableDictionary<SDLFileName *, NSNumber<SDLUInt> *> *)failedFileUploadsCount;
@end
+@interface FileManagerSpecHelper : NSObject
+
+@end
+
+@implementation FileManagerSpecHelper
+
++ (NSArray<UIImage *> *)imagesForCount:(NSUInteger)count {
+ NSMutableArray<UIImage *> *images = [NSMutableArray arrayWithCapacity:count];
+ for (NSUInteger i = 0; i < count; i++) {
+ UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
+ CGContextRef context = UIGraphicsGetCurrentContext();
+ CGFloat grey = (i % 255) / 255.0;
+ [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
+ CGContextFillRect(context, CGRectMake(0, 0, i + 1, i + 1));
+ UIImage *graySquareImage = UIGraphicsGetImageFromCurrentImageContext();
+ UIGraphicsEndImageContext();
+
+ [images addObject:graySquareImage];
+ }
+
+ return [images copy];
+}
+
+@end
+
QuickSpecBegin(SDLFileManagerSpec)
-describe(@"SDLFileManager", ^{
+describe(@"uploading / deleting single files with the file manager", ^{
__block TestConnectionManager *testConnectionManager = nil;
__block SDLFileManager *testFileManager = nil;
__block SDLFileManagerConfiguration *testFileManagerConfiguration = nil;
- __block NSUInteger initialSpaceAvailable = 250;
+ NSUInteger initialSpaceAvailable = 250;
+ NSUInteger failureSpaceAvailabe = 2000000000;
+ NSUInteger newBytesAvailable = 750;
+ NSArray<NSString *> *testInitialFileNames = @[@"testFile1", @"testFile2", @"testFile3"];
beforeEach(^{
testConnectionManager = [[TestConnectionManager alloc] init];
testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
testFileManager.suspended = YES;
+ testFileManager.bytesAvailable = initialSpaceAvailable;
+ });
+
+ afterEach(^{
+ [testFileManager stop];
});
describe(@"before starting", ^{
it(@"should be in the shutdown state", ^{
expect(testFileManager.currentState).to(match(SDLFileManagerStateShutdown));
- });
-
- it(@"bytesAvailable should be 0", ^{
- expect(@(testFileManager.bytesAvailable)).to(equal(@0));
- });
-
- it(@"remoteFileNames should be empty", ^{
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
expect(testFileManager.remoteFileNames).to(beEmpty());
- });
-
- it(@"should have no pending operations", ^{
expect(testFileManager.pendingTransactions).to(beEmpty());
- });
-
- it(@"should set the maximum number of upload attempts to 1", ^{
expect(testFileManager.maxFileUploadAttempts).to(equal(1));
expect(testFileManager.maxArtworkUploadAttempts).to(equal(1));
});
@@ -91,718 +122,421 @@ describe(@"SDLFileManager", ^{
completionHandlerCalled = YES;
}];
- testFileManager.suspended = NO;
-
[NSThread sleepForTimeInterval:0.1];
});
it(@"should have queued a ListFiles request", ^{
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateFetchingInitialList));
expect(testFileManager.pendingTransactions).to(haveCount(@1));
expect(testFileManager.pendingTransactions.firstObject).to(beAnInstanceOf([SDLListFilesOperation class]));
});
- it(@"should be in the fetching initial list state", ^{
- expect(testFileManager.currentState).to(match(SDLFileManagerStateFetchingInitialList));
- });
-
describe(@"after going to the shutdown state and receiving a ListFiles response", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [NSArray arrayWithArray:[testInitialFileNames allObjects]];
-
[testFileManager stop];
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, initialSpaceAvailable, testInitialFileNames, nil);
});
it(@"should remain in the stopped state after receiving the response if disconnected", ^{
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateShutdown));
- expect(@(completionHandlerCalled)).toEventually(equal(@YES));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateShutdown));
+ expect(completionHandlerCalled).to(beTrue());
});
});
describe(@"after receiving a ListFiles error", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
- __block NSUInteger initialBytesAvailable = 0;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
- initialBytesAvailable = testFileManager.bytesAvailable;
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @NO;
- testListFilesResponse.spaceAvailable = nil;
- testListFilesResponse.filenames = nil;
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(NO, initialSpaceAvailable, testInitialFileNames, [NSError sdl_fileManager_unableToStartError]);
});
it(@"should handle the error properly", ^{
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
-
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateStartupError));
- expect(testFileManager.remoteFileNames).toEventually(beEmpty());
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(initialBytesAvailable));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateStartupError));
+ expect(testFileManager.remoteFileNames).to(beEmpty());
+ expect(@(testFileManager.bytesAvailable)).to(equal(initialSpaceAvailable));
});
});
describe(@"after receiving a ListFiles response", ^{
- __block SDLListFilesResponse *testListFilesResponse = nil;
- __block NSSet<NSString *> *testInitialFileNames = nil;
-
beforeEach(^{
- testInitialFileNames = [NSSet setWithArray:@[@"testFile1", @"testFile2", @"testFile3"]];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [NSArray arrayWithArray:[testInitialFileNames allObjects]];
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
+ SDLListFilesOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, initialSpaceAvailable, testInitialFileNames, nil);
});
it(@"the file manager should be in the correct state", ^{
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
-
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.remoteFileNames).toEventually(equal(testInitialFileNames));
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.remoteFileNames).to(equal([NSSet setWithArray:testInitialFileNames]));
+ expect(@(testFileManager.bytesAvailable)).to(equal(@(initialSpaceAvailable)));
});
+ });
+ });
- describe(@"deleting a file", ^{
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
-
- context(@"when the file is unknown", ^{
- beforeEach(^{
- NSString *someUnknownFileName = @"Some Unknown File Name";
- [testFileManager deleteRemoteFileWithName:someUnknownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
-
- [NSThread sleepForTimeInterval:0.1];
- });
-
- it(@"should return the correct data", ^{
- expect(@(completionSuccess)).toEventually(equal(@NO));
- expect(@(completionBytesAvailable)).toEventually(equal(@250));
- expect(completionError).toEventually(equal([NSError sdl_fileManager_noKnownFileError]));
- });
-
- it(@"should not have deleted any files in the file manager", ^{
- expect(testFileManager.remoteFileNames).toEventually(haveCount(@(testInitialFileNames.count)));
- });
- });
-
- context(@"when the file is known", ^{
- __block NSUInteger newSpaceAvailable = 600;
- __block NSString *someKnownFileName = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ describe(@"deleting a file", ^{
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- beforeEach(^{
- someKnownFileName = [testInitialFileNames anyObject];
- [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ beforeEach(^{
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- SDLDeleteFileResponse *deleteResponse = [[SDLDeleteFileResponse alloc] init];
- deleteResponse.success = @YES;
- deleteResponse.spaceAvailable = @(newSpaceAvailable);
+ context(@"when the file is unknown", ^{
+ beforeEach(^{
+ NSString *someUnknownFileName = @"Some Unknown File Name";
+ [testFileManager deleteRemoteFileWithName:someUnknownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
- [NSThread sleepForTimeInterval:0.1];
+ expect(testFileManager.pendingTransactions).to(beEmpty());
+ });
- [testConnectionManager respondToLastRequestWithResponse:deleteResponse];
- });
+ it(@"should return the correct data", ^{
+ expect(completionSuccess).to(beFalse());
+ expect(completionBytesAvailable).to(equal(initialSpaceAvailable));
+ expect(completionError).to(equal([NSError sdl_fileManager_noKnownFileError]));
+ expect(testFileManager.remoteFileNames).to(haveCount(testInitialFileNames.count));
+ });
+ });
- it(@"should return the correct data", ^{
- expect(@(completionSuccess)).to(equal(@YES));
- expect(@(completionBytesAvailable)).to(equal(@(newSpaceAvailable)));
- expect(@(testFileManager.bytesAvailable)).to(equal(@(newSpaceAvailable)));
- expect(completionError).to(beNil());
- });
+ context(@"when the file is known", ^{
+ __block NSUInteger newSpaceAvailable = 600;
+ __block NSString *someKnownFileName = nil;
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- it(@"should have removed the file from the file manager", ^{
- expect(testFileManager.remoteFileNames).toNot(contain(someKnownFileName));
- });
- });
+ beforeEach(^{
+ someKnownFileName = [testInitialFileNames lastObject];
+ [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
- context(@"when the request returns an error", ^{
- __block NSUInteger initialSpaceAvailable = 0;
- __block NSString *someKnownFileName = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ SDLDeleteFileOperation *operation = testFileManager.pendingTransactions.firstObject;
+ operation.completionHandler(YES, newSpaceAvailable, nil);
+ });
- beforeEach(^{
- initialSpaceAvailable = testFileManager.bytesAvailable;
- someKnownFileName = [testInitialFileNames anyObject];
- [testFileManager deleteRemoteFileWithName:someKnownFileName completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ it(@"should return the correct data", ^{
+ expect(@(completionSuccess)).to(equal(@YES));
+ expect(@(completionBytesAvailable)).to(equal(@(newSpaceAvailable)));
+ expect(@(testFileManager.bytesAvailable)).to(equal(@(newSpaceAvailable)));
+ expect(completionError).to(beNil());
+ expect(testFileManager.remoteFileNames).toNot(contain(someKnownFileName));
+ });
+ });
+ });
- SDLDeleteFileResponse *deleteResponse = [[SDLDeleteFileResponse alloc] init];
- deleteResponse.success = @NO;
- deleteResponse.spaceAvailable = nil;
+ describe(@"uploading a new file", ^{
+ __block NSString *testFileName = nil;
+ __block SDLFile *testUploadFile = nil;
+ __block BOOL completionSuccess = NO;
+ __block NSUInteger completionBytesAvailable = 0;
+ __block NSError *completionError = nil;
- [NSThread sleepForTimeInterval:0.1];
+ __block NSData *testFileData = nil;
- [testConnectionManager respondToLastRequestWithResponse:deleteResponse];;
- });
+ beforeEach(^{
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- it(@"should handle the error properly", ^{
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(completionSuccess).toEventually(beFalse());
- expect(completionBytesAvailable).toEventually(equal(2000000000));
- expect(completionError).toNot(beNil());
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- });
- });
+ context(@"when there is a remote file with the same file name", ^{
+ beforeEach(^{
+ testFileName = [testInitialFileNames lastObject];
+ testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
+ testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
});
- describe(@"uploading a new file", ^{
- __block NSString *testFileName = nil;
- __block SDLFile *testUploadFile = nil;
- __block BOOL completionSuccess = NO;
- __block NSUInteger completionBytesAvailable = 0;
- __block NSError *completionError = nil;
+ context(@"when the file's overwrite property is YES", ^{
+ beforeEach(^{
+ testUploadFile.overwrite = YES;
- __block SDLPutFile *sentPutFile = nil;
- __block NSData *testFileData = nil;
+ [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
+ });
- context(@"when there is a remote file with the same file name", ^{
+ context(@"when the connection returns a success", ^{
beforeEach(^{
- testFileName = [testInitialFileNames anyObject];
- testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
- testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
});
- context(@"when the file's overwrite property is YES", ^{
- beforeEach(^{
- testUploadFile.overwrite = YES;
-
- [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
-
- [NSThread sleepForTimeInterval:0.1];
-
- sentPutFile = testConnectionManager.receivedRequests.lastObject;
- });
-
- it(@"should set the file manager state to be waiting", ^{
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- });
-
- it(@"should create a putfile with the correct data", ^{
- expect(sentPutFile.length).to(equal(@(testFileData.length)));
- expect(sentPutFile.bulkData).to(equal(testFileData));
- expect(sentPutFile.fileType).to(match(SDLFileTypeBinary));
- });
-
- context(@"when the response returns without error", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseSuccess = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
-
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @YES;
-
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.success = testResponseSuccess;
- testResponse.spaceAvailable = testResponseBytesAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager data correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventually(contain(testFileName));
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).toEventually(equal(@YES));
- expect(completionError).to(beNil());
- });
- });
-
- context(@"when the connection returns failure", ^{
- __block SDLPutFileResponse *testResponse = nil;
-
- beforeEach(^{
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.spaceAvailable = nil;
- testResponse.success = @NO;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager data correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(completionBytesAvailable).to(equal(2000000000));
- expect(@(completionSuccess)).to(equal(@NO));
- expect(completionError).toEventuallyNot(beNil());
- });
-
- it(@"should increment the failure count for the artwork", ^{
- expect(testFileManager.failedFileUploadsCount[testFileName]).toEventually(equal(1));
- });
- });
-
- context(@"when the connection errors without a response", ^{
- beforeEach(^{
- [testConnectionManager respondToLastRequestWithResponse:nil error:[NSError sdl_lifecycle_notReadyError]];
- });
-
- it(@"should have the correct file manager state", ^{
- expect(testFileManager.remoteFileNames).to(contain(testFileName));
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- });
-
- it(@"should call the completion handler with correct data", ^{
- expect(completionError).toEventually(equal([NSError sdl_lifecycle_notReadyError]));
- });
- });
- });
+ it(@"should set the file manager state to be waiting and set correct data", ^{
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.uploadedEphemeralFileNames).toNot(beEmpty());
+
+ expect(completionBytesAvailable).to(equal(newBytesAvailable));
+ expect(completionSuccess).to(equal(YES));
+ expect(completionError).to(beNil());
- context(@"when allow overwrite is NO", ^{
- __block NSString *testUploadFileName = nil;
- __block Boolean testUploadOverwrite = NO;
-
- beforeEach(^{
- testUploadFileName = [testInitialFileNames anyObject];
- });
-
- it(@"should not upload the file if persistance is YES", ^{
- SDLFile *persistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:YES];
- persistantFile.overwrite = testUploadOverwrite;
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:persistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).toNot(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beFalse());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(equal([NSError sdl_fileManager_cannotOverwriteError]));
- done();
- }];
- });
- });
-
- it(@"should upload the file if persistance is NO", ^{
- SDLFile *unPersistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:NO];
- unPersistantFile.overwrite = testUploadOverwrite;
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:unPersistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).to(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beTrue());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(beNil());
- done();
- }];
-
- [NSThread sleepForTimeInterval:0.1];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
- });
+ expect(@(testFileManager.bytesAvailable)).to(equal(newBytesAvailable));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).to(contain(testFileName));
});
});
- context(@"when there is not a remote file named the same thing", ^{
+ context(@"when the connection returns failure", ^{
beforeEach(^{
- testFileName = @"not a test file";
- testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
- testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
-
- [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- completionSuccess = success;
- completionBytesAvailable = bytesAvailable;
- completionError = error;
- }];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureSpaceAvailabe, [NSError sdl_fileManager_fileUploadCanceled]);
+ });
- [NSThread sleepForTimeInterval:0.1];
+ it(@"should set the file manager data correctly", ^{
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
+ expect(testFileManager.uploadedEphemeralFileNames).to(beEmpty());
- sentPutFile = (SDLPutFile *)testConnectionManager.receivedRequests.lastObject;
- });
+ expect(completionBytesAvailable).to(equal(failureSpaceAvailabe));
+ expect(completionSuccess).to(equal(@NO));
+ expect(completionError).toNot(beNil());
- it(@"should not have testFileName in the files set", ^{
- expect(testInitialFileNames).toNot(contain(testFileName));
+ expect(testFileManager.failedFileUploadsCount[testFileName]).to(equal(1));
});
+ });
+ });
- context(@"when the connection returns without error", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseSuccess = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
-
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @YES;
-
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.success = testResponseSuccess;
- testResponse.spaceAvailable = testResponseBytesAvailable;
-
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
-
- it(@"should set the file manager state correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(testFileManager.remoteFileNames).toEventually(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventually(contain(testUploadFile.name));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- });
-
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).toEventually(equal(testResponseBytesAvailable));
- expect(@(completionSuccess)).toEventually(equal(@YES));
- expect(completionError).to(beNil());
- });
- });
+ context(@"when allow overwrite is NO", ^{
+ __block NSString *testUploadFileName = nil;
+ __block Boolean testUploadOverwrite = NO;
- context(@"when the connection returns failure", ^{
- __block SDLPutFileResponse *testResponse = nil;
- __block NSNumber *testResponseBytesAvailable = nil;
- __block NSNumber *testResponseSuccess = nil;
+ beforeEach(^{
+ testUploadFileName = [testInitialFileNames lastObject];
+ });
- beforeEach(^{
- testResponseBytesAvailable = @750;
- testResponseSuccess = @NO;
+ it(@"should not upload the file if persistance is YES", ^{
+ SDLFile *persistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:YES];
+ persistantFile.overwrite = testUploadOverwrite;
- testResponse = [[SDLPutFileResponse alloc] init];
- testResponse.spaceAvailable = testResponseBytesAvailable;
- testResponse.success = testResponseSuccess;
+ [testFileManager uploadFile:persistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(@(success)).to(beFalse());
+ expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
+ expect(error).to(equal([NSError sdl_fileManager_cannotOverwriteError]));
+ }];
- testFileManager.accessibilityHint = @"This doesn't matter";
+ expect(testFileManager.pendingTransactions.count).to(equal(0));
+ });
- [testConnectionManager respondToLastRequestWithResponse:testResponse];
- });
+ it(@"should upload the file if persistance is NO", ^{
+ SDLFile *unPersistantFile = [[SDLFile alloc] initWithData:testFileData name:testUploadFileName fileExtension:@"bin" persistent:NO];
+ unPersistantFile.overwrite = testUploadOverwrite;
- it(@"should set the file manager state correctly", ^{
- expect(@(testFileManager.bytesAvailable)).toEventually(equal(@(initialSpaceAvailable)));
- expect(testFileManager.remoteFileNames).toEventuallyNot(contain(testFileName));
- expect(testFileManager.uploadedEphemeralFileNames).toEventuallyNot(contain(testUploadFile.name));
- expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- });
+ [testFileManager uploadFile:unPersistantFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
- it(@"should call the completion handler with the correct data", ^{
- expect(@(completionBytesAvailable)).to(equal(@2000000000));
- expect(@(completionSuccess)).to(equal(testResponseSuccess));
- expect(completionError).toEventuallyNot(beNil());
- });
- });
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ });
+ });
+ });
- context(@"when the connection errors without a response", ^{
- beforeEach(^{
- [testConnectionManager respondToLastRequestWithResponse:nil error:[NSError sdl_lifecycle_notReadyError]];
- });
+ context(@"when there is not a remote file named the same thing", ^{
+ beforeEach(^{
+ testFileName = @"not a test file";
+ testFileData = [@"someData" dataUsingEncoding:NSUTF8StringEncoding];
+ testUploadFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+
+ [testFileManager uploadFile:testUploadFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ completionSuccess = success;
+ completionBytesAvailable = bytesAvailable;
+ completionError = error;
+ }];
+ });
- it(@"should set the file manager state correctly", ^{
- expect(testFileManager.remoteFileNames).toNot(contain(testFileName));
- expect(testFileManager.currentState).to(match(SDLFileManagerStateReady));
- });
+ it(@"should not have testFileName in the files set", ^{
+ expect(testInitialFileNames).toNot(contain(testFileName));
+ });
- it(@"should call the completion handler with nil error", ^{
- expect(completionError).toEventually(equal([NSError sdl_lifecycle_notReadyError]));
- });
- });
+ context(@"when the connection returns without error", ^{\
+ beforeEach(^{
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
});
- context(@"When the file data is nil", ^{
- it(@"should call the completion handler with an error", ^{
- SDLFile *emptyFile = [[SDLFile alloc] initWithData:[[NSData alloc] init] name:@"testFile" fileExtension:@"bin" persistent:YES];
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadFile:emptyFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(testConnectionManager.receivedRequests.lastObject).toNot(beAnInstanceOf([SDLPutFile class]));
- expect(@(success)).to(beFalse());
- expect(@(bytesAvailable)).to(equal(@(testFileManager.bytesAvailable)));
- expect(error).to(equal([NSError sdl_fileManager_dataMissingError]));
- done();
- }];
- });
- });
+ it(@"should set the file manager state correctly", ^{
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).to(contain(testUploadFile.name));
+ expect(testFileManager.currentState).to(equal(SDLFileManagerStateReady));
+
+ expect(@(completionBytesAvailable)).to(equal(newBytesAvailable));
+ expect(@(completionSuccess)).to(equal(@YES));
+ expect(completionError).to(beNil());
});
});
- describe(@"uploading artwork", ^{
- __block UIImage *testUIImage = nil;
- __block SDLArtwork *testArtwork = nil;
-
- __block NSString *expectedArtworkName = nil;
- __block Boolean expectedOverwrite = false;
- __block NSUInteger expectedRemoteFilesCount = 0;
- __block NSUInteger expectedBytesAvailable = 0;
-
- __block Boolean expectedToUploadArtwork = true;
- __block NSUInteger expectedRPCsSentCount = 1;
-
+ context(@"when the connection returns failure", ^{
beforeEach(^{
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- [[UIColor blackColor] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 5, 5));
- UIImage *blackSquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
- testUIImage = blackSquareImage;
-
- expectedRemoteFilesCount = testInitialFileNames.count;
- expect(testFileManager.remoteFileNames.count).to(equal(expectedRemoteFilesCount));
-
- expectedBytesAvailable = initialSpaceAvailable;
- expect(testFileManager.bytesAvailable).to(equal(expectedBytesAvailable));
-
- expectedRPCsSentCount = 1; // ListFiles RPC
- expect(testConnectionManager.receivedRequests.count).to(equal(expectedRPCsSentCount));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureSpaceAvailabe, [NSError sdl_fileManager_fileUploadCanceled]);
});
- it(@"should not upload the artwork again and simply return the artwork name when sending artwork that has already been uploaded", ^{
- expectedArtworkName = [testListFilesResponse.filenames firstObject];
- expectedOverwrite = false;
- expectedRemoteFilesCount = testInitialFileNames.count;
- expectedBytesAvailable = initialSpaceAvailable;
- expectedToUploadArtwork = false;
- });
+ it(@"should set the file manager state correctly", ^{
+ expect(testFileManager.bytesAvailable).toEventually(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).toEventuallyNot(contain(testFileName));
+ expect(testFileManager.uploadedEphemeralFileNames).toEventuallyNot(contain(testUploadFile.name));
+ expect(testFileManager.currentState).toEventually(match(SDLFileManagerStateReady));
- it(@"should upload the artwork and return the artwork name when done when sending artwork that has not yet been uploaded", ^{
- expectedArtworkName = @"uniqueArtworkName";
- expectedOverwrite = false;
- expectedRemoteFilesCount = testInitialFileNames.count + 1;
- expectedBytesAvailable = 22;
- expectedToUploadArtwork = true;
- expectedRPCsSentCount += 1;
+ expect(completionBytesAvailable).to(equal(failureSpaceAvailabe));
+ expect(completionSuccess).to(beFalse());
+ expect(completionError).toEventuallyNot(beNil());
});
+ });
+ });
+ });
- it(@"should upload the artwork and return the artwork name when done when sending arwork that is already been uploaded but overwrite is enabled", ^{
- expectedArtworkName = [testListFilesResponse.filenames firstObject];
- expectedOverwrite = true;
- expectedRemoteFilesCount = testInitialFileNames.count;
- expectedBytesAvailable = initialSpaceAvailable;
- expectedToUploadArtwork = true;
- expectedRPCsSentCount += 1;
- });
+ describe(@"uploading artwork", ^{
+ __block UIImage *testUIImage = nil;
+ __block NSString *expectedArtworkName = nil;
- afterEach(^{
- testArtwork = [[SDLArtwork alloc] initWithImage:testUIImage name:expectedArtworkName persistent:true asImageFormat:SDLArtworkImageFormatPNG];
- testArtwork.overwrite = expectedOverwrite;
+ beforeEach(^{
+ testUIImage = [FileManagerSpecHelper imagesForCount:1].firstObject;
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadArtwork:testArtwork completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
- expect(artworkName).to(equal(expectedArtworkName));
- expect(success).to(beTrue());
- expect(bytesAvailable).to(equal(expectedBytesAvailable));
- expect(error).to(beNil());
+ testFileManager.uploadedEphemeralFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithArray:testInitialFileNames];
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
+ });
- expect(testFileManager.remoteFileNames.count).to(equal(expectedRemoteFilesCount));
+ it(@"should not upload the artwork again and simply return the artwork name when sending artwork that has already been uploaded", ^{
+ expectedArtworkName = testInitialFileNames.firstObject;
- done();
- }];
+ SDLArtwork *art = [SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG];
+ [testFileManager uploadArtwork:art completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(error).to(beNil());
+ }];
- if (expectedToUploadArtwork) {
- [NSThread sleepForTimeInterval:0.1];
+ expect(testFileManager.pendingTransactions.count).to(equal(0));
+ });
- SDLPutFileResponse *successfulPutFileResponse = [[SDLPutFileResponse alloc] init];
- successfulPutFileResponse.success = @YES;
- successfulPutFileResponse.spaceAvailable = @(expectedBytesAvailable);
- [testConnectionManager respondToLastRequestWithResponse:successfulPutFileResponse];
- }
- });
+ it(@"should upload the artwork and return the artwork name when done when sending artwork that has not yet been uploaded", ^{
+ expectedArtworkName = @"uniqueArtworkName";
+ [testFileManager uploadArtwork:[SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG] completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
- expect(testConnectionManager.receivedRequests.count).to(equal(expectedRPCsSentCount));
- });
- });
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
});
- afterEach(^{
- expect(testFileManager.transactionQueue.maxConcurrentOperationCount).to(equal(@(1)));
+ it(@"should upload the artwork and return the artwork name when done when sending arwork that is already been uploaded but overwrite is enabled", ^{
+ expectedArtworkName = testInitialFileNames.firstObject;
+ SDLArtwork *testArt = [SDLArtwork artworkWithImage:testUIImage name:expectedArtworkName asImageFormat:SDLArtworkImageFormatPNG];
+ testArt.overwrite = YES;
+ [testFileManager uploadArtwork:testArt completionHandler:^(BOOL success, NSString * _Nonnull artworkName, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(newBytesAvailable));
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
});
});
});
-describe(@"SDLFileManager uploading/deleting multiple files", ^{
+describe(@"uploading/deleting multiple files in the file manager", ^{
__block TestMultipleFilesConnectionManager *testConnectionManager;
__block SDLFileManager *testFileManager;
- __block NSUInteger initialSpaceAvailable;
+ __block NSUInteger initialSpaceAvailable = 123;
+ NSUInteger newBytesAvailable = 750;
+ NSUInteger failureBytesAvailable = 2000000000;
beforeEach(^{
testConnectionManager = [[TestMultipleFilesConnectionManager alloc] init];
SDLFileManagerConfiguration *testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
- initialSpaceAvailable = 66666;
+ testFileManager.suspended = YES;
+ testFileManager.bytesAvailable = initialSpaceAvailable;
+ });
+
+ afterEach(^{
+ [testFileManager stop];
});
context(@"When the file manager is passed multiple files to upload", ^{
- __block SDLListFilesResponse *testListFilesResponse;
__block NSMutableArray<SDLFile *> *testSDLFiles;
- __block NSMutableArray *expectedSuccessfulFileNames;
- __block NSNumber *expectedSpaceLeft;
- __block SDLPutFileResponse *failedResponse;
- __block SDLPutFileResponse *successfulResponse;
beforeEach(^{
testSDLFiles = [NSMutableArray array];
- expectedSuccessfulFileNames = [NSMutableArray array];
- expectedSpaceLeft = @(initialSpaceAvailable);
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [[NSArray alloc] initWithObjects:@"A", @"B", @"C", nil];
-
- failedResponse = [[SDLPutFileResponse alloc] init];
- failedResponse.success = @NO;
- failedResponse.spaceAvailable = @(initialSpaceAvailable);
-
- successfulResponse = [[SDLPutFileResponse alloc] init];
- successfulResponse.success = @YES;
- successfulResponse.spaceAvailable = @(initialSpaceAvailable);
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ [testFileManager.stateMachine setToState:SDLFileManagerStateReady fromOldState:SDLFileManagerStateShutdown callEnterTransition:NO];
});
context(@"and all files are uploaded successfully", ^{
- __block NSError *successfulResponseError = nil;
- __block NSMutableDictionary *testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
-
- it(@"should not return an error when one small file is uploaded from memory", ^{
+ it(@"should upload 1 file successfully", ^{
NSString *testFileName = [NSString stringWithFormat:@"TestSmallFileMemory%d", 0];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- testConnectionManager.responses = testConnectionManagerResponses;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- it(@"should not return an error when one large file is uploaded from disk", ^{
- NSString *testFileName = [NSString stringWithFormat:@"TestLargeFileDisk%d", 0];
- SDLFile *testSDLFile = [SDLFile fileAtFileURL: [[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- testConnectionManager.responses = testConnectionManagerResponses;
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- it(@"should not return an error when multiple small files are uploaded from memory", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
+ it(@"should upload 5 files successfully", ^{
for(int i = 0; i < 5; i += 1) {
NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
+ }
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 5);
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 4));
});
- it(@"should not return an error when a large number of small files are uploaded from memory", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
+ it(@"should upload 500 files successfully", ^{
for(int i = 0; i < 500; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"Test500FilesMemory%d", i];
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
-
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 4);
-
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
- }
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
-
- it(@"should not return an error when multiple small files are uploaded from disk", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < 5; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"TestMultipleSmallFilesDisk%d", i];
- SDLFile *testSDLFile = [SDLFile fileAtFileURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
-
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 3);
-
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
-
- it(@"should not return an error when multiple files are uploaded from both memory and disk", ^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < 10; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"TestMultipleFilesDiskAndMemory%d", i];
- SDLFile *testSDLFile;
- if (i < 5) {
- testSDLFile = [SDLFile fileAtFileURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle bundleForClass:[self class]] pathForResource:@"testImagePNG" ofType:@"png"]] name:testFileName];
- } else {
- testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- }
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 2);
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- [expectedSuccessfulFileNames addObject:testFileName];
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:successfulResponseError];
+ expect(testFileManager.pendingTransactions.count).to(equal(500));
+ for (int i = 0; i < 500; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
- // TODO: This should use itBehavesLike
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 499));
});
});
@@ -818,336 +552,280 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
});
it(@"should upload one artwork successfully", ^{
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- [[UIColor blackColor] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 5, 5));
- UIImage *blackSquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:blackSquareImage asImageFormat:SDLArtworkImageFormatPNG];
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:1];
+
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:images.firstObject asImageFormat:SDLArtworkImageFormatPNG];
[testArtworks addObject:testArtwork];
[expectedArtworkNames addObject:testArtwork.name];
- successfulResponse.spaceAvailable = @22;
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- expectedSpaceLeft = @22;
- testConnectionManager.responses = testConnectionManagerResponses;
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
it(@"should upload multiple artworks successfully", ^{
- NSInteger spaceAvailable = 6000;
- for (NSUInteger i = 0; i < 200; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 10, 10));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:200];
+
+ for (UIImage *image in images) {
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:image asImageFormat:SDLArtworkImageFormatPNG];
[testArtworks addObject:testArtwork];
[expectedArtworkNames addObject:testArtwork.name];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- successfulResponse.spaceAvailable = @(spaceAvailable -= 1);
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(200));
+ for (int i = 0; i < 200; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
}
- expectedSpaceLeft = @(spaceAvailable);
- testConnectionManager.responses = testConnectionManagerResponses;
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- for (NSString *artworkName in expectedArtworkNames) {
- expect(artworkNames).to(contain(artworkName));
- }
- expect(expectedArtworkNames.count).to(equal(artworkNames.count));
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 199));
});
});
- context(@"and all files are not uploaded successfully", ^{
- __block NSMutableDictionary *testConnectionManagerResponses;
- __block NSMutableDictionary *expectedFailedUploads;
- __block NSError *expectedError;
- __block int testTotalFileCount;
- __block NSString *testFileNameBase;
- __block int testFailureIndexStart;
- __block int testFailureIndexEnd;
+ context(@"and file uploads fail", ^{
+ context(@"file upload failure", ^{
+ it(@"should return an error when all files fail", ^{
+ for(int i = 0; i < 5; i++) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- beforeEach(^{
- testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
- expectedFailedUploads = [[NSMutableDictionary alloc] init];
- expectedError = nil;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- context(@"When the file manager receives a notification from the remote that a file upload failed", ^{
- describe(@"The correct errors should be returned", ^{
- beforeEach(^{
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ });
- it(@"should return an error when all files fail", ^{
- testTotalFileCount = 5;
- testFileNameBase = @"TestAllFilesUnsuccessful";
- testFailureIndexStart = testTotalFileCount;
- });
+ it(@"should return an error when the first file fails to upload", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- it(@"should return an error when the first file fails to upload", ^{
- testTotalFileCount = 5;
- testFileNameBase = @"TestFirstFileUnsuccessful";
- testFailureIndexStart = 0;
- });
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- it(@"should return an error when the last file fails to upload", ^{
- testTotalFileCount = 100;
- testFileNameBase = @"TestLastFileUnsuccessful";
- testFailureIndexEnd = (testTotalFileCount - 1);
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
-
- SDLPutFileResponse *response = [[SDLPutFileResponse alloc] init];
- NSError *responseError = nil;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- // Failed response
- response = failedResponse;
- response.spaceAvailable = @(testSpaceAvailable);
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason:[NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedUploads[testFileName] = responseError;
- } else {
- // Successful response
- response = successfulResponse;
- response.spaceAvailable = @(testSpaceAvailable -= 1);
- responseError = nil;
- [expectedSuccessfulFileNames addObject:testFileName];
- }
-
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:response error:responseError];
- }
-
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:expectedFailedUploads];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ for (int i = 1; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(equal(expectedError));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should return an error when the last file fails to upload", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
+
+ [testFileManager uploadFiles:testSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 4; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.lastObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
});
- context(@"When the file manager receives a notification from the remote that an artwork upload failed", ^{
+ context(@"artwork upload failure", ^{
__block NSMutableArray<SDLArtwork *> *testArtworks = nil;
- __block NSSet<NSNumber *> *testOverwriteErrorIndices = nil;
- __block NSMutableArray<NSString *> *expectedSuccessfulArtworkNames = nil;
- __block NSInteger expectedSuccessfulArtworkNameCount = 0;
- __block NSInteger expectedErrorMessagesCount = 0;
beforeEach(^{
testArtworks = [NSMutableArray array];
- testOverwriteErrorIndices = [NSSet set];
- expectedSuccessfulArtworkNameCount = 0;
- expectedSuccessfulArtworkNames = [NSMutableArray array];
- expectedErrorMessagesCount = 0;
+ });
+
+ it(@"should return an empty artwork name array if all artwork uploads failed", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(beEmpty());
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
+ }
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
});
- describe(@"The correct errors should be returned", ^{
- it(@"should return an empty artwork name array if all artwork uploads failed", ^{
- testTotalFileCount = 20;
- testFailureIndexStart = testTotalFileCount;
- expectedSuccessfulArtworkNameCount = 0;
- expectedErrorMessagesCount = 20;
- });
+ it(@"should not include a single failed upload in the artwork names", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
- it(@"should not include the failed upload in the artwork names", ^{
- testTotalFileCount = 5;
- testFailureIndexStart = 1;
- testFailureIndexEnd = 3;
- expectedSuccessfulArtworkNameCount = 1;
- expectedErrorMessagesCount = 4;
- });
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count - 1));
+ expect(error).toNot(beNil());
+ }];
- it(@"should not return any errors that are overwrite errors", ^{
- testTotalFileCount = 12;
- testFailureIndexEnd = 5;
- testOverwriteErrorIndices = [[NSSet alloc] initWithArray:@[@6, @7]];
- expectedSuccessfulArtworkNameCount = 7;
- expectedErrorMessagesCount = 5;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count - 1; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.lastObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_dataMissingError]);
- it(@"should not return an error if all the errors are overwrite errors", ^{
- testTotalFileCount = 10;
- testFailureIndexEnd = 5;
- testOverwriteErrorIndices = [[NSSet alloc] initWithArray:@[@5, @6, @7, @8, @9]];
- expectedSuccessfulArtworkNameCount = 10;
- expectedErrorMessagesCount = 0;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, i + 1, i + 1));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
- [testArtworks addObject:testArtwork];
-
- SDLPutFileResponse *response = [[SDLPutFileResponse alloc] init];
- NSError *responseError = nil;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- // Failed response
- response = failedResponse;
- response.spaceAvailable = @(testSpaceAvailable);
- if ([testOverwriteErrorIndices containsObject:@(i)]) {
- // Overwrite error
- responseError = [NSError sdl_fileManager_cannotOverwriteError];
- [expectedSuccessfulArtworkNames addObject:testArtwork.name];
- } else {
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason:[NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedUploads[testArtwork.name] = responseError;
- }
- } else {
- // Successful response
- response = successfulResponse;
- response.spaceAvailable = @(testSpaceAvailable -= 1);
- responseError = nil;
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- [expectedSuccessfulArtworkNames addObject:testArtwork.name];
- }
- testConnectionManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:response error:responseError];
- }
-
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = expectedFailedUploads.count == 0 ? nil : [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:expectedFailedUploads];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ it(@"should not return any errors that are overwrite errors", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i++) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
+
+ for (int i = 1; i < images.count; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- expect(testFileManager.remoteFileNames.count).to(equal(testListFilesResponse.filenames.count));
-
- waitUntilTimeout(1, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- expect(artworkNames.count).to(equal(expectedSuccessfulArtworkNameCount));
- if (expectedSuccessfulArtworkNames == nil) {
- expect(artworkNames).to(beNil());
- } else {
- for (NSString *artworkName in expectedSuccessfulArtworkNames) {
- expect(artworkNames).to(contain(artworkName));
- }
- }
-
- if (expectedError == nil) {
- expect(error).to(beNil());
- } else {
- for (NSString *artworkName in expectedError.userInfo) {
- expect([error.userInfo objectForKey:artworkName]).toNot(beNil());
- }
- }
-
- expect(error.userInfo.count).to(equal(expectedErrorMessagesCount));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should not return an error if all the errors are overwrite errors", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:5];
+ for(int i = 0; i < images.count; i += 1) {
+ SDLArtwork *artwork = [SDLArtwork artworkWithImage:images[i] asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:artwork];
+ }
+
+ [testFileManager uploadArtworks:testArtworks completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(images.count));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < images.count; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_cannotOverwriteError]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
});
});
});
- context(@"and all files are uploaded successfully while expecting a progress response for each file", ^{
+ context(@"files succeed with progress block", ^{
__block NSMutableDictionary *testFileManagerResponses;
__block NSMutableDictionary *testFileManagerProgressResponses;
__block int testTotalFileCount;
- __block NSString *testFileNameBase;
beforeEach(^{
testFileManagerResponses = [[NSMutableDictionary alloc] init];
testFileManagerProgressResponses = [[NSMutableDictionary alloc] init];
});
- describe(@"When uploading files", ^{
- context(@"A progress handler should be returned for each file", ^{
- it(@"should upload 1 small file from memory without error", ^{
- testTotalFileCount = 1;
- testFileNameBase = @"TestProgressHandlerOneSmallFileMemory";
- });
-
- it(@"should upload a large number of small files from memory without error", ^{
- testTotalFileCount = 200;
- testFileNameBase = @"TestProgressHandlerMultipleSmallFileMemory";
- });
+ context(@"when uploading files", ^{
+ it(@"should upload 1 small file from memory without error", ^{
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFileMemory%d", 0];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
- afterEach(^{
- NSData *testFileData = [@"someTextData" dataUsingEncoding:NSUTF8StringEncoding];
- float testTotalBytesToUpload = testTotalFileCount * testFileData.length;
- float testTotalBytesUploaded = 0.0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ expect(fileName).to(equal(testFileName));
+ expect(uploadPercentage).to(beCloseTo(1.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testTotalFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
- [testSDLFiles addObject:testSDLFile];
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- successfulResponse.spaceAvailable = @(testSpaceAvailable -= 10);
- [expectedSuccessfulFileNames addObject:testFileName];
- testFileManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
- testTotalBytesUploaded += testSDLFile.fileSize;
- testFileManagerProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:testTotalBytesUploaded / testTotalBytesToUpload error:nil];
+ it(@"should upload a 5 small files from memory without error", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
}
- expectedSpaceLeft = @(testSpaceAvailable);
- testConnectionManager.responses = testFileManagerResponses;
- });
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
+ __block NSUInteger numberOfFilesDone = 0;
[testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- TestFileProgressResponse *testProgressResponse = testFileManagerProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
- expect(uploadPercentage).to(equal(testProgressResponse.testUploadPercentage));
- expect(error).to(testProgressResponse.testError == nil ? beNil() : equal(testProgressResponse.testError));
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+ expect(error).to(beNil());
return YES;
} completionHandler:^(NSError * _Nullable error) {
expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
}];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 4));
});
});
- });
- describe(@"When uploading artworks", ^{
+ context(@"when uploading artworks", ^{
__block NSMutableArray<SDLArtwork *> *testArtworks = nil;
__block NSMutableDictionary *testConnectionManagerResponses;
__block NSMutableArray<NSString*> *expectedArtworkNames = nil;
@@ -1159,76 +837,66 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
testTotalFileCount = 0;
});
- context(@"A progress handler should be returned for each artwork", ^{
- it(@"should upload 1 artwork without error", ^{
- testTotalFileCount = 1;
- });
+ it(@"should upload 1 artwork without error", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:1];
- it(@"should upload multiple artworks without error", ^{
- testTotalFileCount = 100;
- });
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:images.firstObject asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:testArtwork];
+ [expectedArtworkNames addObject:testArtwork.name];
- afterEach(^{
- NSInteger spaceAvailable = initialSpaceAvailable;
- float testTotalBytesToUpload = 0; // testTotalFileCount * testFileData.length;
- for (NSUInteger i = 0; i < testTotalFileCount; i += 1) {
- UIGraphicsBeginImageContextWithOptions(CGSizeMake(5, 5), YES, 0);
- CGContextRef context = UIGraphicsGetCurrentContext();
- CGFloat grey = (i % 255) / 255.0;
- [[UIColor colorWithRed:grey green:grey blue:grey alpha:1.0] setFill];
- CGContextFillRect(context, CGRectMake(0, 0, 10, 10));
- UIImage *greySquareImage = UIGraphicsGetImageFromCurrentImageContext();
- UIGraphicsEndImageContext();
-
- SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:greySquareImage asImageFormat:SDLArtworkImageFormatPNG];
- [testArtworks addObject:testArtwork];
- [expectedArtworkNames addObject:testArtwork.name];
- testTotalBytesToUpload += testArtwork.fileSize;
-
- successfulResponse.spaceAvailable = @(spaceAvailable -= 1);
- [expectedSuccessfulFileNames addObject:testArtwork.name];
- testFileManagerResponses[testArtwork.name] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
-
- testFileManagerProgressResponses[testArtwork.name] = [[TestFileProgressResponse alloc] initWithFileName:testArtwork.name testUploadPercentage:0 error:nil];
- }
-
- float testTotalBytesUploaded = 0.0;
- for (SDLArtwork *artwork in testArtworks) {
- testTotalBytesUploaded += artwork.fileSize;
- TestFileProgressResponse *response = testFileManagerProgressResponses[artwork.name];
- response.testUploadPercentage = testTotalBytesUploaded / testTotalBytesToUpload;
- }
-
- expectedSpaceLeft = @(spaceAvailable);
- testConnectionManager.responses = testFileManagerResponses;
- });
+ [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
+ expect(artworkName).to(equal(testArtwork.name));
+ expect(uploadPercentage).to(beCloseTo(1.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(1));
+ expect(artworkNames).to(contain(testArtwork.name));
+ expect(error).to(beNil());
+ }];
+
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
- TestFileProgressResponse *testProgressResponse = testFileManagerProgressResponses[artworkName];
- expect(artworkName).to(equal(testProgressResponse.testFileName));
- expect(uploadPercentage).to(equal(testProgressResponse.testUploadPercentage));
- expect(error).to(testProgressResponse.testError == nil ? beNil() : equal(testProgressResponse.testError));
- return YES;
- } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
- expect(error).to(beNil());
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
- }];
- });
+ it(@"should upload multiple artworks without error", ^{
+ NSArray<UIImage *> *images = [FileManagerSpecHelper imagesForCount:200];
+
+ for (UIImage *image in images) {
+ SDLArtwork *testArtwork = [SDLArtwork artworkWithImage:image asImageFormat:SDLArtworkImageFormatPNG];
+ [testArtworks addObject:testArtwork];
+ [expectedArtworkNames addObject:testArtwork.name];
+ }
+
+ __block NSUInteger artworksDone = 0;
+ [testFileManager uploadArtworks:testArtworks progressHandler:^BOOL(NSString * _Nonnull artworkName, float uploadPercentage, NSError * _Nullable error) {
+ artworksDone++;
+ expect(artworkName).to(equal(expectedArtworkNames[artworksDone - 1]));
+ expect(uploadPercentage).to(beCloseTo((float)artworksDone / 200.0));
+ expect(error).to(beNil());
+ return YES;
+ } completionHandler:^(NSArray<NSString *> * _Nonnull artworkNames, NSError * _Nullable error) {
+ expect(artworkNames).to(haveCount(200));
+ expect(error).to(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(200));
+ for (int i = 0; i < 200; i += 1) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable - i, nil);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable - 199));
});
});
});
- context(@"When an upload is canceled while in progress by the cancel parameter of the progress handler", ^{
+ context(@"when an upload is canceled while in progress by the cancel parameter of the progress handler", ^{
__block NSMutableDictionary *testResponses;
__block NSMutableDictionary *testProgressResponses;
- __block NSString *testFileNameBase;
- __block int testFileCount = 0;
- __block int testCancelIndex = 0;
- __block NSError *expectedError;
beforeEach(^{
testResponses = [[NSMutableDictionary alloc] init];
@@ -1236,339 +904,277 @@ describe(@"SDLFileManager uploading/deleting multiple files", ^{
});
it(@"should cancel the remaining files if cancel is triggered after first upload", ^{
- testFileCount = 11;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelAfterFirst";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
+
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+
+ if (numberOfFilesDone == 1) {
+ expect(error).to(beNil());
+ return NO;
+ } else {
+ expect(error).toNot(beNil());
+ return YES;
+ }
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+
+ for (int i = 1; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
it(@"should cancel the remaining files if cancel is triggered after half of the files are uploaded", ^{
- testFileCount = 30;
- testCancelIndex = testFileCount / 2;
- testFileNameBase = @"TestUploadFilesCancelInMiddle";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
- });
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
+ testSDLFile.overwrite = true;
+ [testSDLFiles addObject:testSDLFile];
+ }
- it(@"should not fail if there are no more files to cancel", ^{
- testFileCount = 20;
- testCancelIndex = (testFileCount - 1);
- testFileNameBase = @"TestUploadFilesCancelAtEnd";
- expectedError = nil;
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5.0));
+
+ if (numberOfFilesDone <= 3) {
+ expect(error).to(beNil());
+ } else {
+ expect(error).toNot(beNil());
+ }
+
+ if (numberOfFilesDone == 3) {
+ return NO;
+ } else {
+ return YES;
+ }
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
+
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 3; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+
+ for (int i = 3; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
- afterEach(^{
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
+ it(@"should not fail if there are no more files to cancel", ^{
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
+ }
- if (i <= testCancelIndex) {
- [expectedSuccessfulFileNames addObject:testFileName];
- }
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5));
+ expect(error).to(beNil());
+ return numberOfFilesDone == 5 ? NO : YES;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- testProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:0.0 error:nil];
+ expect(testFileManager.pendingTransactions.count).to(equal(5));
+ for (int i = 0; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
}
- testConnectionManager.responses = testResponses;
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles progressHandler:^(NSString * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- // Once operations are canceled, the order in which the operations complete is random, so the upload percentage and the error message can vary. This means we can not test the error message or upload percentage it will be different every test run.
- TestFileProgressResponse *testProgressResponse = testProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
-
- NSString *cancelFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, testCancelIndex];
- if ([fileName isEqual:cancelFileName]) {
- return NO;
- }
- return YES;
- } completionHandler:^(NSError * _Nullable error) {
- if (expectedError != nil) {
- expect(error.code).to(equal(SDLFileManagerMultipleFileUploadTasksFailed));
- } else {
- expect(error).to(beNil());
- }
- done();
- }];
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
});
});
context(@"When an upload is canceled it should only cancel files that were passed with the same file array", ^{
- // When canceled is called in this test group, the rest of the files should be canceled
- __block NSMutableDictionary *testResponses;
- __block NSMutableDictionary *testProgressResponses;
- __block NSString *testFileNameBase;
- __block int testFileCount = 0;
- __block int testCancelIndex = 0;
- __block NSError *expectedError;
-
- // Another group of uploads. These uploads should not be canceled when the other files are canceled
+ // Another group of uploads. These uploads should not be canceled when the other files are canceled.
__block NSMutableArray<SDLFile *> *testOtherSDLFiles;
- __block NSString *testOtherFileNameBase;
- __block int testOtherFileCount = 0;
- __block NSError *expectedOtherError;
beforeEach(^{
- testResponses = [[NSMutableDictionary alloc] init];
- testProgressResponses = [[NSMutableDictionary alloc] init];
-
testOtherSDLFiles = [[NSMutableArray alloc] init];
});
it(@"should only cancel the remaining files that were passed with the same file. Other files in the queue that were not passed in the same array should not be canceled", ^{
- testFileCount = 11;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelGroupOnly";
- expectedError = [NSError sdl_fileManager_unableToUpload_ErrorWithUserInfo:testResponses];
-
- testOtherFileNameBase = @"TestOtherUploadFilesCancelGroupOnly";
- testOtherFileCount = 22;
- expectedOtherError = nil;
- });
-
- it(@"should not fail if no files are canceled", ^{
- testFileCount = 1;
- testCancelIndex = 0;
- testFileNameBase = @"TestUploadFilesCancelGroupOnlyOneFile";
- expectedError = nil;
-
- testOtherFileNameBase = @"TestOtherUploadFilesCancelGroupOnlyOneFile";
- testOtherFileCount = 2;
- expectedOtherError = nil;
- });
-
- afterEach(^{
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, i];
+ // Files to be cancelled
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestSmallFilesMemory%d", i];
SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
[testSDLFiles addObject:testSDLFile];
-
- if (i <= testCancelIndex) {
- [expectedSuccessfulFileNames addObject:testFileName];
- }
-
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- testProgressResponses[testFileName] = [[TestFileProgressResponse alloc] initWithFileName:testFileName testUploadPercentage:0.0 error:nil];
}
- for(int i = 0; i < testOtherFileCount; i += 1) {
- NSString *testFileName = [NSString stringWithFormat:@"%@%d", testOtherFileNameBase, i];
- SDLFile *testSDLFile = [SDLFile fileWithData:[@"someOtherTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
- testSDLFile.overwrite = true;
+ // Files not to be cancelled
+ for(int i = 0; i < 5; i += 1) {
+ NSString *testFileName = [NSString stringWithFormat:@"TestOtherFilesMemory%d", i];
+ SDLFile *testSDLFile = [SDLFile fileWithData:[@"someTextData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin"];
[testOtherSDLFiles addObject:testSDLFile];
+ }
- [expectedSuccessfulFileNames addObject:testFileName];
+ __block NSUInteger numberOfFilesDone = 0;
+ [testFileManager uploadFiles:testSDLFiles progressHandler:^BOOL(SDLFileName * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
+ numberOfFilesDone++;
+ expect(fileName).to(equal([NSString stringWithFormat:@"TestSmallFilesMemory%ld", numberOfFilesDone-1]));
+ expect(uploadPercentage).to(beCloseTo((float)numberOfFilesDone / 5));
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulResponse error:nil];
- }
+ if (numberOfFilesDone == 1) {
+ expect(error).to(beNil());
+ } else {
+ expect(error).toNot(beNil());
+ }
- testConnectionManager.responses = testResponses;
+ return NO;
+ } completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager uploadFiles:testSDLFiles progressHandler:^(NSString * _Nonnull fileName, float uploadPercentage, NSError * _Nullable error) {
- // Once operations are canceled, the order in which the operations complete is random, so the upload percentage and the error message can vary. This means we can not test the error message or upload percentage it will be different every test run.
- TestFileProgressResponse *testProgressResponse = testProgressResponses[fileName];
- expect(fileName).to(equal(testProgressResponse.testFileName));
+ [testFileManager uploadFiles:testOtherSDLFiles completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- NSString *cancelFileName = [NSString stringWithFormat:@"%@%d", testFileNameBase, testCancelIndex];
- if ([fileName isEqual:cancelFileName]) {
- return NO;
- }
- return YES;
- } completionHandler:^(NSError * _Nullable error) {
- if (expectedError != nil) {
- expect(error.code).to(equal(SDLFileManagerMultipleFileUploadTasksFailed));
- } else {
- expect(error).to(beNil());
- }
- }];
+ expect(testFileManager.pendingTransactions.count).to(equal(10));
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions.firstObject;
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
- [testFileManager uploadFiles:testOtherSDLFiles completionHandler:^(NSError * _Nullable error) {
- expect(error).to(beNil());
- // Since the queue is serial, we know that these files will finish after the first uploadFiles() batch.
- done();
- }];
- });
- });
- });
+ for (int i = 1; i < 5; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beTrue());
+ sentOperation.fileWrapper.completionHandler(NO, failureBytesAvailable, [NSError sdl_fileManager_fileUploadCanceled]);
+ }
- afterEach(^{
- for(int i = 0; i < expectedSuccessfulFileNames.count; i += 1) {
- expect(testFileManager.remoteFileNames).to(contain(expectedSuccessfulFileNames[i]));
- }
+ for (int i = 5; i < 10; i++) {
+ SDLUploadFileOperation *sentOperation = testFileManager.pendingTransactions[i];
+ expect(sentOperation.cancelled).to(beFalse());
+ sentOperation.fileWrapper.completionHandler(YES, newBytesAvailable, nil);
+ }
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ });
});
});
context(@"When the file manager is passed multiple files to delete", ^{
- __block SDLListFilesResponse *testListFilesResponse;
- __block NSArray<NSString *> *testRemoteFileNames;
- __block NSMutableArray<NSString *> *expectedRemoteFileNames;
- __block NSNumber *expectedSpaceLeft;
- __block NSMutableArray *testDeleteFileNames;
- __block SDLDeleteFileResponse *failedDeleteResponse;
- __block SDLDeleteFileResponse *successfulDeleteResponse;
- __block NSError *expectedError = nil;
-
beforeEach(^{
- testRemoteFileNames = [[NSArray alloc] initWithObjects:@"AA", @"BB", @"CC", @"DD", @"EE", @"FF", nil];
- expectedRemoteFileNames = [[NSMutableArray alloc] init];
-
- testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = testRemoteFileNames;
-
- // Failed delete response
- failedDeleteResponse = [[SDLDeleteFileResponse alloc] init];
- failedDeleteResponse.spaceAvailable = @10;
- failedDeleteResponse.success = @NO;
-
- // Successful delete response
- successfulDeleteResponse = [[SDLDeleteFileResponse alloc] init];
- successfulDeleteResponse.spaceAvailable = @9;
- successfulDeleteResponse.success = @YES;
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithObjects:@"AA", @"BB", @"CC", @"DD", @"EE", @"FF", nil];
+ testFileManager.bytesAvailable = initialSpaceAvailable;
});
context(@"and all files are deleted successfully", ^{
- __block NSMutableDictionary *testResponses;
- __block int testFileCount = 0;
+ it(@"should not return an error when one remote file is deleted", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- beforeEach(^{
- testResponses = [[NSMutableDictionary alloc] init];
- testDeleteFileNames = [[NSMutableArray alloc] init];
+ expect(testFileManager.pendingTransactions.count).to(equal(1));
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.firstObject;
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).toNot(contain(@"AA"));
});
- context(@"When the file manager receives a successful notification for each deleted file", ^{
- it(@"should not return an error when one remote file is deleted", ^{
- testFileCount = 1;
- });
+ it(@"should not return an error when all remote files are deleted", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).to(beNil());
+ }];
- it(@"should not return an error when all remote files are deleted", ^{
- testFileCount = (int)testRemoteFileNames.count;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testFileCount; i += 1) {
- NSString *testFileName = [testRemoteFileNames objectAtIndex:i];
- successfulDeleteResponse.spaceAvailable = @(testSpaceAvailable += 91);
- testResponses[testFileName] = [[TestResponse alloc] initWithResponse:successfulDeleteResponse error:nil];
- [testDeleteFileNames addObject:testFileName];
- }
- expectedSpaceLeft = @(testSpaceAvailable);
- [expectedRemoteFileNames removeAllObjects];
- testConnectionManager.responses = testResponses;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(0));
});
});
context(@"and all files are not deleted successfully", ^{
- __block NSMutableDictionary *testConnectionManagerResponses;
- __block NSMutableDictionary *expectedFailedDeletes;
+ __block int testFailureIndexStart;
+ __block int testFailureIndexEnd;
beforeEach(^{
- testConnectionManagerResponses = [[NSMutableDictionary alloc] init];
- testDeleteFileNames = [[NSMutableArray alloc] init];
- expectedFailedDeletes = [[NSMutableDictionary alloc] init];
+ testFailureIndexStart = -1;
+ testFailureIndexEnd = INT8_MAX;
});
- context(@"When the file manager receives a unsuccessful notification for a deleted file", ^{
- __block int testFailureIndexStart;
- __block int testFailureIndexEnd;
+ it(@"should return an error if the first remote file fails to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- beforeEach(^{
- testFailureIndexStart = -1;
- testFailureIndexEnd = INT8_MAX;
- });
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.firstObject;
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
- it(@"should return an error if the first remote file fails to delete", ^{
- testFailureIndexStart = 0;
- });
+ for (int i = 1; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
- it(@"should return an error if the last remote file fails to delete", ^{
- testFailureIndexEnd = (int)testRemoteFileNames.count - 1;
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(1));
+ });
- it(@"should return an error if all files fail to delete", ^{
- testFailureIndexStart = (int)testRemoteFileNames.count;
- });
+ it(@"should return an error if the last remote file fails to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
+ }];
- afterEach(^{
- NSInteger testSpaceAvailable = initialSpaceAvailable;
- for(int i = 0; i < testRemoteFileNames.count; i += 1) {
- NSString *testFileName = [testRemoteFileNames objectAtIndex:i];
-
- SDLDeleteFileResponse *response;
- NSError *responseError;
- if (i <= testFailureIndexStart || i >= testFailureIndexEnd) {
- failedDeleteResponse.spaceAvailable = @(testSpaceAvailable);
- response = failedDeleteResponse;
- responseError = [NSError sdl_lifecycle_unknownRemoteErrorWithDescription:[NSString stringWithFormat:@"file upload failed: %d", i] andReason: [NSString stringWithFormat:@"some error reason: %d", i]];
- expectedFailedDeletes[testFileName] = responseError;
- [expectedRemoteFileNames addObject:testFileName];
- } else {
- successfulDeleteResponse.spaceAvailable = @(testSpaceAvailable += 891);
- response = successfulDeleteResponse;
- responseError = nil;
- }
-
- testConnectionManagerResponses[testFileName] = [[TestResponse alloc] initWithResponse:response error:responseError];
- [testDeleteFileNames addObject:testFileName];
- }
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 5; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(YES, newBytesAvailable, nil);
+ }
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions.lastObject;
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
- testConnectionManager.responses = testConnectionManagerResponses;
- expectedError = [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:expectedFailedDeletes];
- expectedSpaceLeft = @(testSpaceAvailable);
- });
+ expect(testFileManager.bytesAvailable).to(equal(newBytesAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(1));
});
- });
- afterEach(^{
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager deleteRemoteFilesWithNames:testDeleteFileNames completionHandler:^(NSError * _Nullable error) {
- expect(error).to(expectedError == nil ? beNil() : equal(expectedError));
- expect(testFileManager.bytesAvailable).to(equal(expectedSpaceLeft));
- done();
+ it(@"should return an error if all files fail to delete", ^{
+ [testFileManager deleteRemoteFilesWithNames:@[@"AA", @"BB", @"CC", @"DD", @"EE", @"FF"] completionHandler:^(NSError * _Nullable error) {
+ expect(error).toNot(beNil());
}];
- });
- for(int i = 0; i < expectedRemoteFileNames.count; i += 1) {
- expect(testFileManager.remoteFileNames).to(contain(expectedRemoteFileNames[i]));
- }
+ expect(testFileManager.pendingTransactions.count).to(equal(6));
+ for (int i = 0; i < 6; i++) {
+ SDLDeleteFileOperation *deleteOp = testFileManager.pendingTransactions[i];
+ deleteOp.completionHandler(NO, newBytesAvailable, [NSError sdl_fileManager_unableToDelete_ErrorWithUserInfo:@{}]);
+ }
+
+ expect(testFileManager.bytesAvailable).to(equal(initialSpaceAvailable));
+ expect(testFileManager.remoteFileNames).to(haveCount(6));
+ });
});
});
context(@"The file manager should handle exceptions correctly", ^{
beforeEach(^{
- SDLListFilesResponse *testListFilesResponse = [[SDLListFilesResponse alloc] init];
- testListFilesResponse.success = @YES;
- testListFilesResponse.spaceAvailable = @(initialSpaceAvailable);
- testListFilesResponse.filenames = [[NSArray alloc] initWithObjects:@"AA", nil];
-
- waitUntilTimeout(10, ^(void (^done)(void)){
- [testFileManager startWithCompletionHandler:^(BOOL success, NSError * _Nullable error) {
- done();
- }];
-
- // Need to wait state machine transitions to complete before sending testListFilesResponse
- [NSThread sleepForTimeInterval:0.3];
-
- [testConnectionManager respondToLastRequestWithResponse:testListFilesResponse];
- });
+ testFileManager.mutableRemoteFileNames = [NSMutableSet setWithObjects:@"AA", nil];
});
it(@"should throw an exception when the upload function is passed an empty array", ^{
@@ -1609,6 +1215,10 @@ describe(@"SDLFileManager reupload failed files", ^{
__block TestConnectionManager *testConnectionManager = nil;
__block SDLFileManagerConfiguration *testFileManagerConfiguration = nil;
+ afterEach(^{
+ [testFileManager stop];
+ });
+
it(@"should set the max upload attempts to 2 if the configuration properties are not set", ^{
testFileManagerConfiguration = [SDLFileManagerConfiguration defaultConfiguration];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
@@ -1672,10 +1282,15 @@ describe(@"SDLFileManager reupload failed files", ^{
testConnectionManager = [[TestConnectionManager alloc] init];
testFileManagerConfiguration = [[SDLFileManagerConfiguration alloc] initWithArtworkRetryCount:0 fileRetryCount:0];
testFileManager = [[SDLFileManager alloc] initWithConnectionManager:testConnectionManager configuration:testFileManagerConfiguration];
+ testFileManager.suspended = YES;
testFailedFileUploadsCount = [NSMutableDictionary dictionary];
testFile = [[SDLFile alloc] initWithData:[@"someData" dataUsingEncoding:NSUTF8StringEncoding] name:testFileName fileExtension:@"bin" persistent:false];
});
+ afterEach(^{
+ [testFileManager stop];
+ });
+
describe(@"the file cannot be uploaded again", ^{
it(@"should not upload a file that is nil", ^{
// Make sure we are in the ready state
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
index 83805292a..6d2fd0c79 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLLifecycleManagerSpec.m
@@ -136,7 +136,6 @@ describe(@"a lifecycle manager", ^{
expect(testManager.streamManager).toNot(beNil());
expect(testManager.systemCapabilityManager).toNot(beNil());
expect(testManager.rpcOperationQueue).toNot(beNil());
- expect(testManager.rpcOperationQueue.maxConcurrentOperationCount).to(equal(3));
expect(@([testManager conformsToProtocol:@protocol(SDLConnectionManagerType)])).to(equal(@YES));
expect(testManager.authToken).to(beNil());
});
@@ -255,12 +254,10 @@ describe(@"a lifecycle manager", ^{
});
describe(@"stopping the manager", ^{
- beforeEach(^{
- [testManager stop];
- });
-
it(@"should simply stop", ^{
- expect(testManager.lifecycleState).to(match(SDLLifecycleStateStopped));
+ [testManager stop];
+
+ expect(testManager.lifecycleState).toEventually(match(SDLLifecycleStateStopped));
});
});
});
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
index 2b96e74b0..6980fb02a 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLMenuManagerSpec.m
@@ -2,32 +2,9 @@
#import <Nimble/Nimble.h>
#import <OCMock/OCMock.h>
-#import "SDLAddCommand.h"
-#import "SDLAddSubMenu.h"
-#import "SDLDeleteCommand.h"
-#import "SDLDeleteSubMenu.h"
-#import "SDLDisplayCapabilities.h"
-#import "SDLDisplayType.h"
-#import "SDLFileManager.h"
-#import "SDLHMILevel.h"
-#import "SDLImage.h"
-#import "SDLImageField.h"
-#import "SDLImageFieldName.h"
-#import "SDLMediaClockFormat.h"
-#import "SDLMenuCell.h"
+#import <SmartDeviceLink/SmartDeviceLink.h>
+
#import "SDLMenuManager.h"
-#import "SDLMenuManagerConstants.h"
-#import "SDLOnCommand.h"
-#import "SDLOnHMIStatus.h"
-#import "SDLRegisterAppInterfaceResponse.h"
-#import "SDLRPCNotificationNotification.h"
-#import "SDLRPCParameterNames.h"
-#import "SDLRPCResponseNotification.h"
-#import "SDLSetDisplayLayoutResponse.h"
-#import "SDLScreenManager.h"
-#import "SDLScreenParams.h"
-#import "SDLSystemContext.h"
-#import "SDLTextField.h"
#import "TestConnectionManager.h"
diff --git a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
index e3fb6732f..93254ca78 100644
--- a/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
+++ b/SmartDeviceLinkTests/DevAPISpecs/SDLUploadFileOperationSpec.m
@@ -12,6 +12,45 @@
#import "TestConnectionManager.h"
#import <zlib.h>
+@interface UploadFileOperationSpecHelpers : NSObject
+
++ (void)testPutFiles:(NSArray<SDLPutFile *> *)putFiles data:(NSData *)testFileData file:(SDLFile *)testFile;
+
+@end
+
+@implementation UploadFileOperationSpecHelpers
+
++ (void)testPutFiles:(NSArray<SDLPutFile *> *)putFiles data:(NSData *)testFileData file:(SDLFile *)testFile {
+ // Test all packets for offset, length, and data
+ for (NSUInteger index = 0; index < putFiles.count; index++) {
+ SDLPutFile *putFile = putFiles[index];
+
+ NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
+ NSData *testBulkFileData = [testFileData subdataWithRange:NSMakeRange((index * mtuSize), MIN(putFile.length.unsignedIntegerValue, mtuSize))];
+ unsigned long testBulkFileDataCrc = crc32(0, testBulkFileData.bytes, (uInt)testBulkFileData.length);
+
+ expect(putFile.offset).to(equal(@(index * mtuSize)));
+ expect(putFile.persistentFile).to(equal(@NO));
+ expect(putFile.syncFileName).to(equal(testFile.name));
+ expect(putFile.bulkData).to(equal(testBulkFileData));
+ expect(putFile.crc).to(equal([NSNumber numberWithUnsignedLong:testBulkFileDataCrc]));
+
+ // Length is used to inform the SDL Core of the total incoming packet size
+ if (index == 0) {
+ // The first putfile sent should have the full file size
+ expect(putFile.length).to(equal(@([testFile fileSize])));
+ } else if (index == putFiles.count - 1) {
+ // The last pufile contains the remaining data size
+ expect(putFile.length).to(equal(@([testFile fileSize] - (index * mtuSize))));
+ } else {
+ // All other putfiles contain the max data size for a putfile packet
+ expect(putFile.length).to(equal(@(mtuSize)));
+ }
+ }
+}
+
+@end
+
QuickSpecBegin(SDLUploadFileOperationSpec)
describe(@"Streaming upload of data", ^{
@@ -19,7 +58,7 @@ describe(@"Streaming upload of data", ^{
__block NSData *testFileData = nil;
__block SDLFile *testFile = nil;
__block SDLFileWrapper *testFileWrapper = nil;
- __block NSInteger numberOfPutFiles = 0;
+ __block NSUInteger numberOfPutFiles = 0;
__block TestConnectionManager *testConnectionManager = nil;
__block SDLUploadFileOperation *testOperation = nil;
@@ -38,121 +77,171 @@ describe(@"Streaming upload of data", ^{
numberOfPutFiles = 0;
testOperation = nil;
- testConnectionManager = nil;
+ testConnectionManager = [[TestConnectionManager alloc] init];
successResult = NO;
bytesAvailableResult = NO;
errorResult = nil;
});
- context(@"When uploading data", ^{
+ describe(@"When uploading data", ^{
context(@"data should be split into smaller packets if too large to send all at once", ^{
- context(@"both data in memory and on disk can be uploaded", ^{
- it(@"should split the data from a short chunk of text in memory correctly", ^{
- testFileName = @"TestSmallMemory";
- testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
- testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- });
-
- it(@"should split the data from a large image in memory correctly", ^{
- testFileName = @"TestLargeMemory";
- UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
- testFileData = UIImageJPEGRepresentation(testImage, 1.0);
- testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
- });
-
- it(@"should split the data from a small text file correctly", ^{
- NSString *fileName = @"testFileJSON";
- testFileName = fileName;
- NSString *textFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"];
- NSURL *textFileURL = [[NSURL alloc] initFileURLWithPath:textFilePath];
- testFile = [SDLFile fileAtFileURL:textFileURL name:fileName];
- testFileData = [[NSData alloc] initWithContentsOfURL:textFileURL];
- });
-
- it(@"should split the data from a large image file correctly", ^{
- NSString *fileName = @"testImagePNG";
- testFileName = fileName;
- NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
- NSURL *imageFileURL = [[NSURL alloc] initFileURLWithPath:imageFilePath];
- testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
-
- // For testing: get data to check if data chunks are being created correctly
- testFileData = [[NSData alloc] initWithContentsOfURL:imageFileURL];
- });
-
- afterEach(^{
- testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
- }];
-
- numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
-
- testConnectionManager = [[TestConnectionManager alloc] init];
- testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
- [testOperation start];
- });
+ it(@"should split the data from a short chunk of text in memory correctly", ^{
+ testFileName = @"TestSmallMemory";
+ testFileData = [@"test1234" dataUsingEncoding:NSUTF8StringEncoding];
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
- afterEach(^{
- expect(@(testOperation.queuePriority)).to(equal(@(NSOperationQueuePriorityNormal)));
+ it(@"should split the data from a large image in memory correctly", ^{
+ testFileName = @"TestLargeMemory";
+ UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
+ testFileData = UIImageJPEGRepresentation(testImage, 1.0);
+ testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
- // Test all packets for offset, length, and data
- for (NSUInteger index = 0; index < numberOfPutFiles; index++) {
- SDLPutFile *putFile = putFiles[index];
-
- NSUInteger mtuSize = [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData];
- NSData *testBulkFileData = [testFileData subdataWithRange:NSMakeRange((index * mtuSize), MIN(putFile.length.unsignedIntegerValue, mtuSize))];
- unsigned long testBulkFileDataCrc = crc32(0, testBulkFileData.bytes, (uInt)testBulkFileData.length);
-
- expect(putFile.offset).to(equal(@(index * mtuSize)));
- expect(putFile.persistentFile).to(equal(@NO));
- expect(putFile.syncFileName).to(equal(testFileName));
- expect(putFile.bulkData).to(equal(testBulkFileData));
- expect(putFile.crc).to(equal([NSNumber numberWithUnsignedLong:testBulkFileDataCrc]));
-
- // Length is used to inform the SDL Core of the total incoming packet size
- if (index == 0) {
- // The first putfile sent should have the full file size
- expect(putFile.length).to(equal(@([testFile fileSize])));
- } else if (index == numberOfPutFiles - 1) {
- // The last pufile contains the remaining data size
- expect(putFile.length).to(equal(@([testFile fileSize] - (index * mtuSize))));
- } else {
- // All other putfiles contain the max data size for a putfile packet
- expect(putFile.length).to(equal(@(mtuSize)));
- }
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
}
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
- });
- afterEach(^{
- __block SDLPutFileResponse *goodResponse = nil;
+ it(@"should split the data from a small text file correctly", ^{
+ NSString *fileName = @"testFileJSON";
+ testFileName = fileName;
+ NSString *textFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"json"];
+ NSURL *textFileURL = [[NSURL alloc] initFileURLWithPath:textFilePath];
+ testFile = [SDLFile fileAtFileURL:textFileURL name:fileName];
+ testFileData = [[NSData alloc] initWithContentsOfURL:textFileURL];
+ __block NSInteger spaceLeft = 11212512;
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
+ });
+
+ it(@"should split the data from a large image file correctly", ^{
+ NSString *fileName = @"testImagePNG";
+ testFileName = fileName;
+ NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
+ NSURL *imageFileURL = [[NSURL alloc] initFileURLWithPath:imageFilePath];
+ testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
+ __block NSInteger spaceLeft = 11212512;
- // We must do some cleanup here otherwise the unit test cases will crash
- NSInteger spaceLeft = 11212512;
- for (int i = 0; i < numberOfPutFiles; i++) {
- spaceLeft -= 1024;
- goodResponse = [[SDLPutFileResponse alloc] init];
- goodResponse.success = @YES;
- goodResponse.spaceAvailable = @(spaceLeft);
- [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
- }
-
- expect(@(successResult)).toEventually(equal(@YES));
- expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
- expect(errorResult).toEventually(beNil());
- expect(@(testOperation.finished)).toEventually(equal(@YES));
- expect(@(testOperation.executing)).toEventually(equal(@NO));
+ // For testing: get data to check if data chunks are being created correctly
+ testFileData = [[NSData alloc] initWithContentsOfURL:imageFileURL];
+
+ testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
+ expect(success).to(beTrue());
+ expect(bytesAvailable).to(equal(spaceLeft));
+ expect(error).to(beNil());
+ }];
+
+ numberOfPutFiles = ((([testFile fileSize] - 1) / [[SDLGlobals sharedGlobals] mtuSizeForServiceType:SDLServiceTypeBulkData]) + 1);
+
+ testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
+ [testOperation start];
+
+ NSArray<SDLPutFile *> *putFiles = testConnectionManager.receivedRequests;
+ expect(@(putFiles.count)).to(equal(@(numberOfPutFiles)));
+ [UploadFileOperationSpecHelpers testPutFiles:putFiles data:testFileData file:testFile];
+
+ __block SDLPutFileResponse *goodResponse = nil;
+
+ // We must do some cleanup here otherwise the unit test cases will crash
+ for (int i = 0; i < numberOfPutFiles; i++) {
+ spaceLeft -= 1024;
+ goodResponse = [[SDLPutFileResponse alloc] init];
+ goodResponse.success = @YES;
+ goodResponse.spaceAvailable = @(spaceLeft);
+ [testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
+ }
+
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
+ });
});
});
- context(@"When a response to the data upload comes back", ^{
+ describe(@"When a response to the data upload comes back", ^{
beforeEach(^{
testFileName = @"TestLargeMemory";
UIImage *testImage = [UIImage imageNamed:@"testImagePNG" inBundle:[NSBundle bundleForClass:[self class]] compatibleWithTraitCollection:nil];
@@ -174,8 +263,8 @@ describe(@"Streaming upload of data", ^{
});
context(@"If data was sent successfully", ^{
- __block SDLPutFileResponse *goodResponse = nil;
- __block NSInteger spaceLeft = 0;
+ __block SDLPutFileResponse *goodResponse = nil;
+ __block NSInteger spaceLeft = 0;
beforeEach(^{
goodResponse = nil;
@@ -190,15 +279,13 @@ describe(@"Streaming upload of data", ^{
goodResponse.spaceAvailable = @(spaceLeft);
[testConnectionManager respondToRequestWithResponse:goodResponse requestNumber:i error:nil];
}
- });
- afterEach(^{
- expect(@(successResult)).toEventually(equal(@YES));
- expect(@(bytesAvailableResult)).toEventually(equal(spaceLeft));
+ expect(successResult).toEventually(beTrue());
+ expect(bytesAvailableResult).toEventually(equal(spaceLeft));
expect(errorResult).toEventually(beNil());
- expect(@(testOperation.finished)).toEventually(equal(@YES));
- expect(@(testOperation.executing)).toEventually(equal(@NO));
+ expect(testOperation.finished).toEventually(beTrue());
+ expect(testOperation.executing).toEventually(beFalse());
});
});
@@ -234,6 +321,10 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
}
+
+ expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
+ expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
+ expect(successResult).toEventually(beFalse());
});
it(@"should have called the completion handler with error if the last packet was not sent successfully", ^{
@@ -255,6 +346,10 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:error];
}
+
+ expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
+ expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
+ expect(successResult).toEventually(beFalse());
});
it(@"should have called the completion handler with error if all packets were not sent successfully", ^{
@@ -269,18 +364,16 @@ describe(@"Streaming upload of data", ^{
[testConnectionManager respondToRequestWithResponse:response requestNumber:i error:[NSError sdl_lifecycle_unknownRemoteErrorWithDescription:responseErrorDescription andReason:responseErrorReason]];
}
- });
- afterEach(^{
expect(errorResult.localizedDescription).toEventually(match(responseErrorDescription));
expect(errorResult.localizedFailureReason).toEventually(match(responseErrorReason));
- expect(@(successResult)).toEventually(equal(@NO));
+ expect(successResult).toEventually(beFalse());
});
});
});
- context(@"When an incorrect file url is passed", ^{
- beforeEach(^{
+ describe(@"when an incorrect file url is passed", ^{
+ it(@"should have called the completion handler with an error", ^{
NSString *fileName = @"testImagePNG";
testFileName = fileName;
NSString *imageFilePath = [[NSBundle bundleForClass:[self class]] pathForResource:fileName ofType:@"png"];
@@ -288,43 +381,31 @@ describe(@"Streaming upload of data", ^{
testFile = [SDLFile fileAtFileURL:imageFileURL name:fileName];
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
+ expect(success).to(beFalse());
+ expect(error).to(equal([NSError sdl_fileManager_fileDoesNotExistError]));
}];
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
[testOperation start];
});
-
- it(@"should have called the completion handler with an error", ^{
- expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
- expect(@(successResult)).toEventually(equal(@NO));
- });
});
- context(@"When empty data is passed", ^{
- beforeEach(^{
+ describe(@"when empty data is passed", ^{
+ it(@"should have called the completion handler with an error", ^{
testFileName = @"TestEmptyMemory";
testFileData = [@"" dataUsingEncoding:NSUTF8StringEncoding];
testFile = [SDLFile fileWithData:testFileData name:testFileName fileExtension:@"bin"];
testFileWrapper = [SDLFileWrapper wrapperWithFile:testFile completionHandler:^(BOOL success, NSUInteger bytesAvailable, NSError * _Nullable error) {
- successResult = success;
- bytesAvailableResult = bytesAvailable;
- errorResult = error;
+ expect(error).to(equal([NSError sdl_fileManager_fileDoesNotExistError]));
+ expect(success).to(beFalse());
}];
testConnectionManager = [[TestConnectionManager alloc] init];
testOperation = [[SDLUploadFileOperation alloc] initWithFile:testFileWrapper connectionManager:testConnectionManager];
[testOperation start];
});
-
- it(@"should have called the completion handler with an error", ^{
- expect(errorResult).toEventually(equal([NSError sdl_fileManager_fileDoesNotExistError]));
- expect(@(successResult)).toEventually(equal(@NO));
- });
});
});
diff --git a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
index 497870b9d..b1adaa135 100644
--- a/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
+++ b/SmartDeviceLinkTests/ProxySpecs/SDLHapticManagerSpec.m
@@ -311,7 +311,7 @@ describe(@"the haptic manager", ^{
OCMVerify(sdlLifecycleManager);
int expectedCount = 2;
- expect(sentHapticRequest.hapticRectData.count).to(equal(expectedCount));
+ expect(sentHapticRequest.hapticRectData.count).toEventually(equal(expectedCount));
if(sentHapticRequest.hapticRectData.count == expectedCount) {
NSArray<SDLHapticRect *> *hapticRectData = sentHapticRequest.hapticRectData;
diff --git a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
index ea41d0163..42286b97b 100755
--- a/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
+++ b/SmartDeviceLinkTests/RPCSpecs/StructSpecs/SDLSystemCapabilitySpec.m
@@ -127,7 +127,7 @@ describe(@"Getter/Setter Tests", ^ {
resolution.resolutionHeight = @500;
int32_t maxBitrate = 100;
- NSNumber *hapticDataSupported = @YES;
+ BOOL hapticDataSupported = YES;
SDLVideoStreamingFormat *format1 = [[SDLVideoStreamingFormat alloc] init];
format1.codec = SDLVideoStreamingCodecH264;
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testAppAndVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testLightBackgroundNoAppNoVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testNoAppNoVehicleIcons@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyAppIcon@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
index 3648c2bce..935e31a1b 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@2x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
index 3b7684a62..f1b99e2c5 100644
--- a/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
+++ b/SmartDeviceLinkTests/ReferenceImages_64/SDLLockScreenViewControllerSnapshotTests/testOnlyVehicleIcon@3x.png
Binary files differ
diff --git a/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m b/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
index 40fff1d7a..917756334 100644
--- a/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
+++ b/SmartDeviceLinkTests/SDLAsynchronousRPCOperationSpec.m
@@ -10,8 +10,9 @@
#import <Nimble/Nimble.h>
#import "SDLAppServiceData.h"
-#import "SDLGetAppServiceDataResponse.h"
#import "SDLAsynchronousRPCOperation.h"
+#import "SDLGetAppServiceDataResponse.h"
+#import "SDLGlobals.h"
#import "TestConnectionManager.h"
QuickSpecBegin(SDLAsynchronousRPCOperationSpec)
@@ -27,7 +28,7 @@ describe(@"sending responses and notifications", ^{
testOperationQueue = [[NSOperationQueue alloc] init];
testOperationQueue.name = @"com.sdl.RPCResponse.testqueue";
- testOperationQueue.maxConcurrentOperationCount = 3;
+ testOperationQueue.underlyingQueue = [SDLGlobals sharedGlobals].sdlProcessingQueue;
});
context(@"when a single request succeeds", ^{
@@ -49,7 +50,7 @@ describe(@"sending responses and notifications", ^{
context(@"when multiple request succeed", ^{
__block NSMutableArray< __kindof SDLRPCMessage *> *sendRPCs = nil;
- __block int rpcCount = (int)testOperationQueue.maxConcurrentOperationCount + 3;
+ int rpcCount = 9;
beforeEach(^{
sendRPCs = [NSMutableArray array];
@@ -64,8 +65,6 @@ describe(@"sending responses and notifications", ^{
[testOperationQueue addOperation:testOperation];
}
- [NSThread sleepForTimeInterval:0.5];
-
expect(testConnectionManager.receivedRequests.count).toEventually(equal(rpcCount));
expect(testConnectionManager.receivedRequests).toEventually(equal(sendRPCs));
});
diff --git a/SmartDeviceLinkTests/TestResponse.m b/SmartDeviceLinkTests/TestResponse.m
index f949f3b1b..0af400104 100644
--- a/SmartDeviceLinkTests/TestResponse.m
+++ b/SmartDeviceLinkTests/TestResponse.m
@@ -22,4 +22,8 @@
return self;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"Test response: %@, error: %@", _testResponse, _testError];
+}
+
@end
diff --git a/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m b/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
index 64afa7107..c40081063 100644
--- a/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
+++ b/SmartDeviceLinkTests/TestUtilities/TestRequestProgressResponse.m
@@ -21,4 +21,8 @@
return self;
}
+- (NSString *)description {
+ return [NSString stringWithFormat:@"Progress Response: correlation id: %@, percent complete: %0.03f, error: %@", _correlationId, _percentComplete, _error];
+}
+
@end
diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m
deleted file mode 100644
index 771d2c4bb..000000000
--- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/DispatchTimerSpec.m
+++ /dev/null
@@ -1,47 +0,0 @@
-//
-// DispatchTimerSpec.m
-// SmartDeviceLink-iOS
-//
-// Created by Muller, Alexander (A.) on 7/1/16.
-// Copyright © 2016 smartdevicelink. All rights reserved.
-//
-
-#import <Foundation/Foundation.h>
-
-#import <Quick/Quick.h>
-#import <Nimble/Nimble.h>
-#import <OCMock/OCMock.h>
-
-#import "dispatch_timer.h"
-
-QuickSpecBegin(DispatchTimerSpec)
-
-describe(@"dispatch_timer Tests", ^{
- context(@"Creating", ^{
- it(@"should be successful within specified time", ^{
- waitUntilTimeout(4, ^(void (^done)(void)) {
- __block double currentTime = [[NSDate date] timeIntervalSince1970];
- dispatch_create_timer(2.5, false, ^{
- double difference = [[NSDate date] timeIntervalSince1970] - currentTime;
- expect(@(difference)).to(beCloseTo(@2.5).within(0.1));
- done();
- });
- });
- });
-
- it(@"should be cancellable and not fire", ^{
- __block dispatch_source_t timer;
- waitUntilTimeout(2, ^(void (^done)(void)) {
- timer = dispatch_create_timer(2.5, false, ^{
- fail();
- });
- [NSThread sleepForTimeInterval:0.5];
- dispatch_stop_timer(timer);
- done();
- });
- expect(@(dispatch_source_testcancel(timer))).to(beGreaterThan(@0));
- });
- });
-});
-
-QuickSpecEnd \ No newline at end of file
diff --git a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
index 25fad6316..24a06dcb0 100644
--- a/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
+++ b/SmartDeviceLinkTests/UtilitiesSpecs/Touches/SDLTouchManagerSpec.m
@@ -31,6 +31,55 @@
@property (nonatomic, assign) CGFloat previousPinchDistance;
@property (nonatomic, strong, nullable) SDLPinchGesture *currentPinchGesture;
@property (nonatomic, strong, nullable) dispatch_source_t singleTapTimer;
+
+@end
+
+@interface TestGroup : NSObject
+
++ (void)testTouchesWithTimeout:(CGFloat)timeoutTime
+ numTimesCalled:(NSUInteger)numTimesHandlerCalled expected:(NSUInteger)expectedNumTimesHandlerCalled
+ singleTap:(BOOL)didCallSingleTap expected:(BOOL)expectedDidCallSingleTap
+ doubleTap:(BOOL)didCallDoubleTap expected:(BOOL)expectedDidCallDoubleTap
+ beginPan:(BOOL)didCallBeginPan expected:(BOOL)expectedDidCallBeginPan
+ movePan:(BOOL)didCallMovePan expected:(BOOL)expectedDidCallMovePan
+ endPan:(BOOL)didCallEndPan expected:(BOOL)expectedDidCallEndPan
+ cancelPan:(BOOL)didCallCancelPan expected:(BOOL)expectedDidCallCancelPan
+ beginPinch:(BOOL)didCallBeginPinch expected:(BOOL)expectedDidCallBeginPinch
+ movePinch:(BOOL)didCallMovePinch expected:(BOOL)expectedDidCallMovePinch
+ endPinch:(BOOL)didCallEndPinch expected:(BOOL)expectedDidCallEndPinch
+ cancelPinch:(BOOL)didCallCancelPinch expected:(BOOL)expectedDidCallCancelPinch;
+
+@end
+
+@implementation TestGroup
+
++ (void)testTouchesWithTimeout:(CGFloat)timeoutTime
+ numTimesCalled:(NSUInteger)numTimesHandlerCalled expected:(NSUInteger)expectedNumTimesHandlerCalled
+ singleTap:(BOOL)didCallSingleTap expected:(BOOL)expectedDidCallSingleTap
+ doubleTap:(BOOL)didCallDoubleTap expected:(BOOL)expectedDidCallDoubleTap
+ beginPan:(BOOL)didCallBeginPan expected:(BOOL)expectedDidCallBeginPan
+ movePan:(BOOL)didCallMovePan expected:(BOOL)expectedDidCallMovePan
+ endPan:(BOOL)didCallEndPan expected:(BOOL)expectedDidCallEndPan
+ cancelPan:(BOOL)didCallCancelPan expected:(BOOL)expectedDidCallCancelPan
+ beginPinch:(BOOL)didCallBeginPinch expected:(BOOL)expectedDidCallBeginPinch
+ movePinch:(BOOL)didCallMovePinch expected:(BOOL)expectedDidCallMovePinch
+ endPinch:(BOOL)didCallEndPinch expected:(BOOL)expectedDidCallEndPinch
+ cancelPinch:(BOOL)didCallCancelPinch expected:(BOOL)expectedDidCallCancelPinch
+{
+ expect(didCallSingleTap).withTimeout(timeoutTime).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+ expect(didCallDoubleTap).withTimeout(timeoutTime).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+ expect(didCallBeginPan).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout(timeoutTime).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout(timeoutTime).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+ expect(didCallBeginPinch).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout(timeoutTime).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout(timeoutTime).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
+}
+
@end
QuickSpecBegin(SDLTouchManagerSpec)
@@ -255,6 +304,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = YES;
expectedNumTimesHandlerCalled = 2;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -302,6 +355,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -356,6 +413,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -376,6 +437,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
});
@@ -410,6 +475,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallSingleTap = NO;
expectedNumTimesHandlerCalled = 2;
+
+ expect(didCallSingleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallSingleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -441,6 +510,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue delegate callbacks when a double tap is canceled before the start of the second tap", ^{
@@ -452,6 +525,10 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallDoubleTap = NO;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallDoubleTap).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallDoubleTap ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -604,6 +681,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = YES;
expectedDidCallCancelPan = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -638,6 +722,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should issue a cancel pan delegate callback when a pan is canceled right after second move detected", ^{
@@ -685,6 +776,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue a cancel pan delegate callback if the cancel onTouchEvent is received while a pan gesture is not in progress", ^{
@@ -695,6 +793,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPan = NO;
expectedDidCallCancelPan = NO;
expectedNumTimesHandlerCalled = 1;
+
+ expect(didCallBeginPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPan ? beTrue() : beFalse());
+ expect(didCallMovePan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePan ? beTrue() : beFalse());
+ expect(didCallEndPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPan ? beTrue() : beFalse());
+ expect(didCallCancelPan).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPan ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
afterEach(^{
@@ -815,7 +920,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&point atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchStartCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchStartCenter))).to(beTrue());
};
pinchMoveTests = ^(NSInvocation* invocation) {
@@ -828,7 +933,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&scale atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchMoveCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchMoveCenter))).to(beTrue());
expect(@(scale)).to(beCloseTo(@(pinchMoveScale)).within(0.0001));
};
@@ -840,7 +945,7 @@ describe(@"SDLTouchManager Tests", ^{
[invocation getArgument:&point atIndex:4];
expect(touchManagerCallback).to(equal(touchManager));
- expect(@(CGPointEqualToPoint(point, pinchEndCenter))).to(beTruthy());
+ expect(@(CGPointEqualToPoint(point, pinchEndCenter))).to(beTrue());
};
performTouchEvent(touchManager, pinchStartFirstFingerOnTouchEvent);
@@ -854,6 +959,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = YES;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -905,6 +1017,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = YES;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
});
@@ -939,6 +1058,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = YES;
expectedNumTimesHandlerCalled = 3;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should notify delegates if pinch is canceled while it is in progress", ^{
@@ -986,6 +1112,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = YES;
expectedNumTimesHandlerCalled = 4;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
it(@"should not issue a cancel pinch delegate callback if the cancel onTouchEvent is received while a pinch gesture is not in progress", ^{
@@ -996,6 +1129,13 @@ describe(@"SDLTouchManager Tests", ^{
expectedDidCallEndPinch = NO;
expectedDidCallCancelPinch = NO;
expectedNumTimesHandlerCalled = 1;
+
+ expect(didCallBeginPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallBeginPinch ? beTrue() : beFalse());
+ expect(didCallMovePinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallMovePinch ? beTrue() : beFalse());
+ expect(didCallEndPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallEndPinch ? beTrue() : beFalse());
+ expect(didCallCancelPinch).withTimeout((touchManager.tapTimeThreshold + additionalWaitTime)).toEventually(expectedDidCallCancelPinch ? beTrue() : beFalse());
+
+ expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
});
afterEach(^{
@@ -1003,22 +1143,6 @@ describe(@"SDLTouchManager Tests", ^{
});
});
});
-
- afterEach(^{
- CGFloat timeoutTime = touchManager.tapTimeThreshold + additionalWaitTime;
- expect(@(didCallSingleTap)).withTimeout(timeoutTime).toEventually(expectedDidCallSingleTap ? beTruthy() : beFalsy());
- expect(@(didCallDoubleTap)).withTimeout(timeoutTime).toEventually(expectedDidCallDoubleTap ? beTruthy() : beFalsy());
- expect(@(didCallBeginPan)).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPan ? beTruthy() : beFalsy());
- expect(@(didCallMovePan)).withTimeout(timeoutTime).toEventually(expectedDidCallMovePan ? beTruthy() : beFalsy());
- expect(@(didCallEndPan)).withTimeout(timeoutTime).toEventually(expectedDidCallEndPan ? beTruthy() : beFalsy());
- expect(@(didCallCancelPan)).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPan ? beTruthy() : beFalsy());
- expect(@(didCallBeginPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallBeginPinch ? beTruthy() : beFalsy());
- expect(@(didCallMovePinch)).withTimeout(timeoutTime).toEventually(expectedDidCallMovePinch ? beTruthy() : beFalsy());
- expect(@(didCallEndPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallEndPinch ? beTruthy() : beFalsy());
- expect(@(didCallCancelPinch)).withTimeout(timeoutTime).toEventually(expectedDidCallCancelPinch ? beTruthy() : beFalsy());
-
- expect(numTimesHandlerCalled).to(equal(@(expectedNumTimesHandlerCalled)));
- });
});
});